Autor Zpráva
BuBu6
Profil *
Zdravím, potřeboval bych poradit.
Mám tabulku s odehranými zápasy (id_hrac_a, id_hrac_b) a nyní bych potřeboval náhodně vylosovat další zápasy (celkem 8 hráčů) tak, aby se mi neopakovali stejné zápasy. V podstatě má ještě druhou tabulku, kde jsou vypsány všechny možné kombinace, tedy každý s každým, pomocí které vyfiltruji již odehrané zápasy. Vypadá to takto:
SELECT vsichni.id_hrac_a, vsichni.id_hrac_b
            FROM vsichni
            LEFT JOIN zapasy ON vsichni.id_hrac_a = zapasy.id_hrac_a AND vsichni.id_hrac_b = zapasy.id_hrac_b
            WHERE zapasy.id_hrac_a IS NULL
            GROUP BY vsichni.id_hrac_a
            ORDER BY RAND() LIMIT 4
Funguje to vcelku dobře, jen je průšvih v tom, že mi to vylosuje 4 náhodné zápasy, ale na místě hráče B se mi ukáže třeba hráč A, který hraje už jiný zápas. Tedy některý hráč se mi v daném kole opakuje.
Vypadá to třeba nějak takto:
id_hrac_a / id_hrac_b
   5      /      3
   8      /      1
   1      /      5
   4      /      7
Nevěděl by prosím někdo, jak na to?
Kajman
Profil
Pokud v turnaji hraje každý s každým, tak si do tabulky vsichni přidejte i číslo kola, kdy se má dvojice utkat.
en.wikipedia.org/wiki/Round-robin_tournament#Scheduling_algorithm
BuBu6
Profil *
Právě, že nehraje každý s každým, to mám jen jako pomocnou tabulku. Mám právě z té pak vylosovat náhodně třeba 4 kola, ale to je různé, jak počet hráčů, tak počet kol.
Kajman
Profil
Když není plný počet kol, nebyl by pro určení dvojic lepší švýcarský systém než to dávat celé náhodě?
en.wikipedia.org/wiki/Swiss-system_tournament
BuBu6
Profil *
Nad tím už jsem koumal také, ale nějak nevím, jak docílit toho, aby se mi v dalších kolech neopakoval stejný zápas.
Př. V prvním losování bude hrát třeba id1 s id5. Po třetím kole bude v průběžné tabulce pořadí na prvním místě id1 a na druhém id5, takže dle švýcarského systému by měli hrát spolu. Ale jak to udělat, aby hrál s dalším v pořadí (pokud už tedy spolu také nehráli) aby tedy byl výsledek třeba první ze třetím a druhý ze čtvrtým, atd...?
BuBu6
Profil *
Kajman:
Ještě tedy prosím o jednu radu. Jak v php vygeneruji kompletní tabulku, aby byl jeden zápas každý s každým? kruhový algoritmus chápu, jen nevím, jak ho použít v php a vygenerovat. Díky.
_es
Profil
BuBu6 [#5]:
Podľa švajčiarskeho systému hrajú dvaja hráči v turnaji spolu len najviac raz. A ako ho spraviť - asi si nájsť nejaké hotové riešenie v PHP. No je to vhodné len na veľa hráčov a najviac polovicu kôl z počtu hráčov, inak môže systém „zhavarovať“ a ďalšie kolo nepôjde vylosovať.

kruhový algoritmus chápu, ...
Hľadaj „Bergerovy tabulky“, použi už hotovú tabuľku pre 8 hráčov alebo niečo hotové v PHP.
BuBu6
Profil *
_es:
Jj, znám podmínky švýcarského systému, proto jsem chtěl každé kolo losovat náhodně, ale aby se samozřejmě neopakovali soupeři.

Zkoušel jsem už hodně hledat, i Bergerov tabulky, ale většinou mi to najde spíše stránky, kde mi to vygeneruje, nikoliv náhled kódu nebo alespoň návod, jak si kód napsat a já jsem si zatím bezradný.
_es
Profil
BuBu6:
Jj, znám podmínky švýcarského systému
Zjavne nepoznáš, keďže si špekuloval, že by vo 4. kole mali znova spolu hrať hráči, čo už spolu hrali v 1. kole.

nebo alespoň návod, jak si kód napsat
Návod, ako sú tabuľky vytvorené, je predsa voľne dostupný - na Wikipédii a pod. Je to tak jednoduché, že si snáď z toho PHP kód na vygenerovanie tabuľky spravíš. Alebo použi „hotovú“ tabuľku na 8 hráčov.
NoxOne
Profil
Já bych na to šel od lesa. Všechny hráče bych nacpal do dvou polí. Z nich bych náhodně vybral dvojici a podmínkou bych řídil zda již spolu hráli nebo ne.
Keeehi
Profil
NoxOne:
Problém je, že už klidně ve druhém kole se ti může stát, že téměř všechny napáruješ a zbývá ti poslední člověk v každém z těch dvou polí. Nezbývá nikdo jiný, s kým bys to napároval. Problém je, že tihle už spolu hráli. Při velkém počtu hráčů a malém počtu kol není pravděpodobnost problému vysoká, čím je ale kol více tím to bude častější.

Co by ale rozhodně šlo je rozházet hráče do dvou polí. Spolu by hráli vždy si odpovídající hráči. první s prvním, druhý s druhým, ... Po prvním kole jedno z těch polí orotuješ (prvního přesuneš na konec, druhého na první místo, třetího na druhé místo ...). V druhém kole spolu budou hrát zase odpovídající si hráči ale už podle nového pořadí. Tímto způsobem můžeš mít až tolik kol, kolik je polovina hráčů.
_es
Profil
NoxOne [#10]:
Netreba nič také vymýšľať, existuje jednoduchý algoritmus na vytvorenie Bergerovej tabuľky, náhodu možno použiť len na vylosovanie čísel na začiatku, hlavný problém tvojho nápadu dobre vysvetlil Keeehi.
Keeehi [#11]:
Takýto rýchly nápad má zase iné nedostatky. Na konci turnaja môžu byť viacerí hráči s plným počtom bodov. V prípade hier, kde má jeden z hráčov nejakú výhodu, sa tá výhoda nebude nejako spravodlivejšie striedať. Problematické vyriešenie toho, ak jeden z hráčov odstúpi z turnaja...
NoxOne
Profil
Nezabíjejte mě :)

Jsem to přečetl moc rychle .... bral jsem to tak že to je pro jedno kolo. Ale do druhého kola by jsi mohl použít kritéria z prvního kola ( jako "A hrál s "B" v prvním kole tak nemůže hrát "B" s "A" v druhém ) je to jenom matematika.

Ale je pravdou že při větším počtu kol už by bylo šílené to vše sledovat.
Pokud ale víš kolik bude celkem hráčů a celkem kol tak se to dá taky matematicky dopočítat.

Kdysi jsem takto počítal turnaj v TMN a vše fungovalo .... ale byl daný počet hráčů, počet zápasů na den. Podle toho se vypočítal celkový počet kol a udělal se rozpis.

ps: když někdo nenastoupil tak bod měl ten kdo s ním měl hrát
Keeehi
Profil
_es:
Takýto rýchly nápad má zase iné nedostatky.
Jsem si jich vědom. Chtěl jsem tím hlavně opravit ten nedostatek v návrhu NoxOne. Nicméně se zdá, že BuBu6 se do implementace nějakého lepšího avšak algoritmicky složitějšího systému moc nechce. Takže možná pro něj nakonec bude tohle celkem triviální řešení i přes své nedostatky good enough.
_es
Profil
NoxOne:
Ale do druhého kola by jsi mohl použít kritéria z prvního kola ( jako "A hrál s "B" v prvním kole tak nemůže hrát "B" s "A" v druhém
Systém, že by sa zo všetkých hráčov náhodne vylosovali dvojice a v ďalšom kole sa postupovalo rovnako, len stačí losovať znovu, ak už dvojica hrala, nefunguje. Čím viac sa blížia záverečné kolá, tým viac hrozí, že nejakí hráči nemajú s kým hrať, lebo všetci hráči, s ktorými ešte nehrali, sú už vylosovaní na aktuálne kolo. Musí byť nastavené také poradie jednotlivých zápasov, aby to nenastalo, napríklad spomenuté Bergerove tabuľky.
NoxOne
Profil
Máš pravdu ale jak BUBU6 píše #3 "nehraje každý s každým"

Jasně že existují sofistikované skripty které tohle vše mají v malíku ale jak tu bylo psáno do toho se BUBU6 asi nechce pouštět.

Přijde mi to jako když má X hráčů ... kteří mají odehrát Y kol tak aby se neopakovali vzájemné zápasy. A na to stačí tužka + papír + pár minut času to celé se rovná skript za pár minut.
BuBu6
Profil *
Já bych se rád klidně do něčeho složitějšího pustil, ale nejsem v tom tak zkušený. Už jsem vyzkoušel několik možností a strávil nad tím dost času.
I jak psal _es, zkoušel jsem vyhledat i Bergerovu tabulku, resp. její script, protože fakt nevím, jak ho napsat, ale buď neumím hledat nebo jsem totální trouba, protože jsem nic nenašel :(

Asi by bylo tu Bergerovu tabulku nejlepší vytvořit, uložit v MySql do samostatné tabulky a z té pak jen vybírat náhodně vybraná kola s vyloučením kol, která už proběhla. Teorie myslím dobrá, ale prostě ta praxe na Bergerovu tabulku mi nejde :(
NoxOne
Profil
Když se zeptáš strýčka googla tak je tam milion odkazů na Bergerovu tabulku ale myslím že php skript proto hned tak nenajdeš. Většinou je to VBA nebo šablona do excelu.

Ale jak jsem psal tužka + papír = tabulka :)

Kolik máš hráčů a kolik má být kol ?
_es
Profil
BuBu6:
Ale Bergerove tabuľky sú určené len na bezproblémové odohranie celého kruhového turnaja (každý s každým), nie na premenlivý počet kôl. Môžeš ich nájsť aj pod názvom Schurigovy tabulky, aj s popisom, ako si ich vytvoriť na papieri, z toho by už snáď PHP kód na vytvorenie nemalo byť ťažké. Na premenlivý počet kôl je určený švajčiarsky systém. Alebo, pre osem hráčov máš jednoduchý KO systém na tri kolá a hrať môžu každé kolo aj vyradení o umiestnenie.
Keeehi
Profil
NoxOne:
Myslím, že to BuBu6 spouštět chce. Kdyby to chtěl jednorázově, tak by použil některý z těch mnoha online generátorů které existují a o kterých evidentně ví.
BuBu6
Profil *
NoxOne:
Kolik máš hráčů a kolik má být kol ?

Tak ono je to různé. Prostě mezi kamarády hrajeme různé turnaje, tak chci pro to stvořit nějaký systém, že to nebudeme pořád vypisovat a rozpočítávat, a budou se nám i hlavně výsledky ukládat a vzájemně porovnávat.
Proto si myslím, že Bergrova tabulka by mi vyřešila všechny možnosti. Na každý turnaj bych vygeneroval každý s každým a s tím už bych dál pracoval. Zřejmě jsem si vzal ale moc velké sousto a budu to muset nechat být, protože ať se snažím sebevíc, chápu systém Bergerové tabulky, ale prostě ho nedokážu převést do php. Matematika nikdy nebyla moje kámoška.
_es
Profil
BuBu6:
Proto si myslím, že Bergrova tabulka by mi vyřešila všechny možnosti.
Ešte raz znovu: Bergerova tabuľka je určená LEN na systém každý s každým: napr. 10 hráčov 9 kôl, 16 hráčov 15 kôl. Na voliteľný počet hráčov a voliteľný počet kôl potrebuješ švajčiarsky systém. Ak to nemusí byť v PHP a vo forme webovej stránky, tak si na to stiahni nejaký voľne dostupný softvér a v tom rob losovanie a evidenciu zápasov. Možno na to existuje aj softvér v PHP.
BuBu6
Profil *
_es:
Tak očividně jsi mě nepochopil.
Znám dobře jednotlivé systémy, k tomu fakt rady nepotřebuji, chtěl jsem tady jen získat nějakou nápovědu, jak na to. Argument, že mi stačí tužka a papír mi opravdu nepomůže, když netuším, jak to přenést do php a vygenerovat tak podle počtu hráčů všechny zápasy (každý s každým). A podobně je na tom švýcarský systém.

Ale jinak díky za diskuzi, zajdu si za nějakým programátorem, který mi to snad vysvětlí.
_es
Profil
BuBu6:
jak to přenést do php a vygenerovat tak podle počtu hráčů všechny zápasy (každý s každým).
No tak systém každý s každým snáď vytvoríš úplne jednoducho:
Pre n hráčov si vytvoríš dvojrozmerné pole s n-1 „riadkami“ (počet kôl)
a n/2 „stĺpcami“ (počet zápasov v kole).
Každý prvok poľa bude obsahovať dvojicu (hráči zápasu).
A keď máš toto celé pole, tak podľa neho už len určuješ zápasy v každom kole.
Dobrý návod na zostavenie celej tabuľky je napríklad: sachyzora.braillnet.cz/p_schurig.html
NoxOne
Profil
Asi mi praskne cévka. Nevím že prostě nenapíšeš rovnou " mohl by mi někdo udělat "

Do tabulky atd si to snad už nacpeš sám. :)

<?php

function rozpis($hracu){
    if (count($hracu)%2 != 0){
        array_push($hracu,"konec");
    }
    $host = array_splice($hracu,(count($hracu)/2));
    $domaci = $hracu;
    for ($i=0; $i < count($domaci)+count($host)-1; $i++){
        for ($j=0; $j<count($domaci); $j++){
            $kolo[$i][$j]["Domácí"]=$domaci[$j];
            $kolo[$i][$j]["Host"]=$host[$j];
        }
        if(count($domaci)+count($host)-1 > 2){
            array_unshift($host,array_shift(array_splice($domaci,1,1)));
            array_push($domaci,array_pop($host));
        }
    }
    return $kolo;
}

//jména/čísla hráčů
 $hraci = array(1,2,3,4,5,6,7,8,9,10);
 
 $rozpis = rozpis($hraci);
 
 foreach($rozpis AS $kolo => $hra){
    echo "Kolo: ".($kolo+1)."<BR>";
    foreach($hra AS $hrac){
        echo $hrac["Domácí"]." - ".$hrac["Host"]."<BR>";
    }
    echo "<BR>";
}

?>
_es
Profil
NoxOne [#25]:
Výsledok nesedí s tým, čo by malo vyjsť. Číslo 1 by podľa tvojho výstupu hralo všetky zápasy ako domáce, aj číslo 10 nevyhovuje.
NoxOne
Profil
Máš pravdu č.1 je vždy domácí .... ale to je jenom popisek zadej si místo "Domácí" třeba "Hráč jedna" a místo "Host" protihráč.
č.10 ... kde je problém ?

Myslím že jako jednoduché rozlosování mu to bude stačit a upravit si to k obrazu svému už si může sám. :)
_es
Profil
BuBu6:
Losovacia funkcia v JS, podľa návodu z [#24] _es:
function losovanie(n) {
  n += n % 2;
  var t = Array(n-1);
  for(var i = 0, c1 = 0, c2 = n*n - 2; i < t.length; i++) {
    t[i] = Array(n/2);
    t[i][0] = Array(2);
    t[i][0][i%2] = c1%(n-1) + 1; c1++;
    t[i][0][(i+1)%2] = n;
    for(var j = 1; j < t[i].length; j++) {
      t[i][j]=[c1%(n-1) + 1, c2%(n-1) + 1];
      c1++; c2--;
    }
  }
  return t;
}
function vypis(t) {
  var s = "";
  for(var i = 0; i < t.length; i++) {
    for(var j = 0; j < t[i].length; j++) {
      s += "[ " + t[i][j][0]+ " - " + t[i][j][1] + " ]";
    }
    s += "\n";
  }
  return s;
}
alert(vypis(losovanie(10)));
Dúfam, že nebudeš požadovať, aby ti to niekto prepísal do PHP kódu.
Kcko
Profil
_es:
Hezké, ale není to ještě (alespoň myslím) úplně správně. Pozice týmu se v každém kole musí posouvat, 10 tým nemůže v každém kole hrát jako první.
_es
Profil
Kcko [#29]:
Ale to je systém každý s každým, kde hrajú všetci v jednom kole naraz. Či je zápas kola v riadku na prvom alebo poslednom mieste je úplne jedno.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0