Omdw : Overwegingen poule algoritmen                      Bedum 7-4-1994

Aan  : Henk Kolk

Van  : Menno S Ter Haseborg

Om te komen tot een poule voor de wedstrijd tafel onderscheid ik zes stappen:
a: Poule_indeling
b: Poule_toewijzing
c: Poule_splitsing
d: Poule_mat
e: Poule_plaatsing
f: Poule_afbeelding

Het Poule_indelen heeft inzich het bekende probleem hoe deel ik de judoka's
in , in gewichten/leeftijden (zo mogelijk Klassen,Kyu graden) . Ik wil hier
nu niet verder op ingaan . De Poule_indeling geeft een verzameling Indelingen.
Iedere Indeling bestaat uit een Poul_hoofd en een of meerdere Poule_grenzen.
Poul_hoofd        = ( Matnummer , weegtijd , aanvangstijd , wedstrijdduur ,
                      winnaars ) 
winnaars          = ( 1 , 2 , 3 , 3 ) , ( 1 , 2 , 3 , 4 )
weegtijd          =  aanvangstijd - aantal_tewegen_deelnemers * n min
wedstrijdduur     = ( wedstrijdtijd , aantalwedstrijden )
aantalwedstrijden = ( aantaldeelnemers , poule_systeem )
Poule_grenzen     = ( geslacht , leeftijdgrenzen , gewichtsgrenzen , 
                      klassegrenzen , kyu's )
Indeling          = Poul_hoofd { Poule_grenzen }..
Indelingen        = { Indeling }..

Het Poule_toewijzen geeft iedere deelnemer een Indeling met als resultaat
een Toewijzing welke bestaat uit een verzameling Organisatie's welke op
hun beurt bestaat uit een verzameling deelnemers behorend bij de Indeling.
Toewijzing = ( Indeling , { Organisatiedeelnemers }.. )
Organisatiedeelnemers = { deelnemers }..
De doorsnede Organisatiedeelnemers (over alle Toewijzingen) moet leeg zijn !
De range orde van de Organisatiedeelnemers in de Toewijzing is niet relevant.

De Poule_splitsing verzorgt de binnen de gewenste wedstrijdmethode 
de grote van de poules . Dit is geheel afhankelijk van de doelstelling 
van de tournooiorganisatie .
Afhangkelijk van de gekozen methode geldt voor : 

Eliminatie        : Behalve feitelijke plaatsing is van belang nu te 
                  zeggen wat als akseptabel maximum aantal deelnemers
                  (poulegrote=maxp) wordt gezien en 
                  wat is het minimum aantal deelnemers (=mine) mag zijn .
                  Het minimum bepaald wanneer Eliminatie overgaat in een
                  Halve kompetie systeem . Het maximum bepaald wanneer er
                  meerdere poules moeten worden gemaakt .
                  Dus Eliminatie heeft twee parameters (maxp , mine) .
                  Het aantal nieuw tevormen Toewijzing (=poules) is
                   aantalSplits = (aantal_deelnemers + maxp -1 ) / maxp .
                  Hierin is het aantal_deelnemers de omvang van de 
                  verzameling Toewijzing.Organisatiedeelnemers .
                  (v.b. NWOC geeft aan voor districtkampioenschappen
                        een min van 3 en een max van oneindig .
                        Ik zelf adviseer min 6 en max 32 .)
                  Ofschoon mij geen toepassingen bekent zijn van het
                  splitsen van Eliminatie systemen (waarschijnlijk omdat
                  dit gedaan kan worden via poul_ind en zoniet omdat grote
                  poules geld in het laatje brengen) kan zodra dit wenselijk 
                  is met onderstaande methode voor worden gebruikt . 

Halve kompetie    : Een halve kompetitie systeem bestaat uit plaatsing in 
                  n voorronde-poules gevolgd door een finale systeem waarin 
                  de nummers 1,2 (uit de voorronden) worden geplaatst .
                  Hierbij moet ook gekozen worden voor een maximum aantal
                  deelnemers (=maxp). Tevens moet gekozen worden voor de 
                  maximale voorronde grote (=maxv) .
                  Dus Halvekompetitie heeft twee parameters (maxp , maxv) .
                  (v.b. Ik kies voor gevorderden maxp=15 , maxv=5 .
                        Voor beginners wordt vaak maxp=6 , maxv=6 gekozen.)
                  Het maxp aantal is nogal afhangkelijk van het tevolgen
                  finale systeem . Nu geldt dat :
                   aantalSplits = ( aantal_deelnemers + maxp - 1) / maxp
                  Hierin is het aantal_deelnemers de omvang van de 
                  verzameling Toewijzing.Organisatiedeelnemers .
                  Het idee is dat bij een niet gesplitste poule worden de
                  deelnemers op een afstand van maxv gezet . 
                  In een gesplitste poule wordt de deelnemers een afstand
                   aantalSplits vanelkaar gezet . De achtergrond hiervan
                  is dat bij een gesplitste poule de deelnemers van een 
                  Organisatie mogelijk in twee verschillende poules komen .

De Poule_splitsing vindt dus alleen plaats als de waarde van aantalSplits 
groter 1 is . Het Poule_splitsing deel kan dus de verzameling Indelingen en
Toewijzing vergroten en na gewichtwijzigen(ompouling) ook weer zich verkleinen . 
Overigens kan men dit splitsen van poules meestal voorkomen door 
de Poule_indeling te preziseren.
In de volgende rekenmethode is gevraagt meerdere verzameling p temaken 
waarvan de elementen een element aanwijzen in de verzameling 
Organisatiedeelnemers .
Dit geeft volgende voorbeelden : 
                   maxp=3 , aantalSplit = 3
                   d =  1 2 3 4 5 6 7 8 9 
                   p = |1 4 7|2 5 8|3 6 9| (DUS dit geeft drie poules)
                   maxp=5 , aantalSplit = 2
                   d =  1 2 3 4 5 6 7 8 9 
                   p = |1 3 5 7 9|2 4 6 8| (DUS dit geeft twee poules)
                   Nu moet de geSplitste poule worden geplaatst op de 
                   wedstrijd volgorde als v.b.: (zie Poule_plaatsing)
                   maxv=3 , maxp=5 , aantalSplit = 2
                   d =   1 2 3 4 5 6 7 8 9 
                   p1=  |1 3 5 7 9 |  p2=   |2 4  6 8|
                   a1= ||1 5 9||3 7|| a2=  ||2 6||4 8|| 

Het idee is het transformeren van d(i) -> p(k,j) .
Waarbij k*j <> lengte Organisatiedeelnemers kan zijn . Zodat het wenselijk is
de deelnemers lijst aanvullen met lege elementen (maxp * aantalSplits)
Je zou dit kunnen schrijfen als (meer dimensionale set):
                   VAR p( maxp , aantalSplits) = 0
                       FOR i = 1 TO aantalSplits
                          FOR j = 1 TO maxp
                             p(j,i) = (j - 1) * aantalSplits + i
                          ROF
                       ROF
Alleen moet je nog de Toewijzing sets maken op grond van het aantalSplits . 
Je zou dit ook kunnen schrijfen als (lineare set):
                  VAR p( 1 TO aantaldeelnemers ) = 0 
                   FOR v = 1 TO aantalSplits
                   ' dus iedere poule tel het aktuele aantal
                     count = 0
                     beginpl = (v-1) * aantalSplits + 1
                     eindpl  = v * aantalSplits 
                     IF eindpl > aantaldeelnemers THEN einpl=aantaldeelnemers
                     count = 1
                     p(beginpl) = v
                     FOR o = beginpl+1 TO eindpl
                       count = count + 1
                       p(o) = p(o-1) + aantalSplits
                      ROF
                     ROF
                   ' update Toewijzing(poule) info met count
                   ROF
Het verschil in beide methoden zoals hier gebracht is dat de eerste niet
bestaande elementen (welke dus nul moeten zijn) in Organisatiedeelnemers
aanwijst . Terwijl de tweede methode een nul element aanwijst in de
Organisatiedeelnemer welke dus ook als leeg moet worden gezien . Men kan
zowel de ene als ook de andere benadering schrijven voor beide vormen van
set behandeling .

De Poule_mat indeling is afhankelijk van volgende elementen.
a: doorpoulebaar(altijd kunnen overpoulen) of 
   niet doorpoulebaar(te zwaar gaat u maar) .
b: jongens meisjes poule's aldan niet scheiden (per blok of mat).
c: blok_tyd voor alle matten (=tydblokken) of blok_tyd per mat (=doorlopend)
   dit bepaald de prijsuitrijking (per blok of doorlopend) .
d: scheiding opgrond van mat afmeting (2 min 25 m2 , 3 min 36 m2 , 4 >= 49 m2)
e: tyd wensen deelnemers(i.v.m. vervoer e.d.).Dit lijdt tot tegenstrijdigheid.
Wenselijk is onder alle omstandigheden de wedstrijdtyd per mat/blok indien
meer dan een poule op de mat gepland zijn gelijk te houden .
De gewenste eisen geven een ordening in de verzameling Indelingen .
Mogelijk probleem hierbij is de wens finales op afzonderlijke tijdstippen 
te spelen dit i.v.m. de ordening .
Het is nu de opdracht om zoveel mogelijk elementen uit de geordende set
Indelingen toe tewijzen aan k matten in een minimale tyd .
Het probleem is om n ongelijke luciferstokjes te leggen in k rijen zodanig
dat de rijen allen evenlang(bij benadering) worden . Het zal duidelijk zijn
dat de lengte van een rij de tyd voorsteld en het aantal rijen het aantal
te legen matten . Het maximale (niet berijkbare) optimum in het minimum van
de te leggen matten is de som van de Poul_hoofd.wedstrijdduur te delen op 
de beschikbare (dag)tijd . Oftewel de totale lengte van de luciferstokjes
delen door max gewenste rij lengte . Probeer nu alle stokjes teleggen zonder
ze te breken .

De Poule_plaatsing bestaat uit de systemen n.l. Eliminatie , HalveKompetitie.
In bijde gevallen wordt uitgegaan van een geordende lijst Organisatie welke
bevat een lijst deelnemers  { org { deelnemers }.. }.. .
Bij het afbeelden is de hoofdregel die dat de kans , dat deelnemers van de 
zelfde Organisatie tegen elkaar tegenkomen , minimaal is . 
Eliminatie       : Er moet van uitgegaan worden dat de verzameling te 
                   plaatsen deelnemers een macht van 2 is . (Zoniet vul deze
                   op met lege elementen) De afstand tussen twee opeen 
                   volgende deelnemers is nu de helft van het totaal . Dat wil
                   houdt in dat de te verkregen plaatsings lijst symetrisch is
                   , dus als de helft bepaald is is de andere helft bekend .
                   Bovendien bevat de ene helft de even genummerde deelnemers
                   en de andere de oneven . Bepalen we nu de even reeks .
                   Voor  4 deelnemers is deze 0  2
                                              |  |
                   Voor  8 deelnemers is deze 0  4  2  6
                                              |  |  |  | (*2)
                   Voor 16 deelnemers is deze 0  8  4  12  2  10  6  14 
                                              |  |  |  |___|__|___|__|
                                              |  |  |______|__|___|
                                              |  |_________|__|     (+2)
                   etc.                       |____________|

                   In rekenkundige termen geldt nu : (min deelnemers is 4)
                   VAR     p(1 TO deelnemers) = 0
                           iteratie = 2LOG(deelnemers/2) , p(1)=0 , afstand=1
                           FOR i=1 TO iteratie
                               FOR l=1 TO afstand
                                   p(l)=p(l)*2 , p(l+afstand)=p(l)+2
                               ROF
                               afstand=afstand * 2
                           ROF
                  ' verdubbel de rij en maak het oneven deel en plak dit vast
                  ' aan het reeds bestaande even deel .
                           FOR i=1 TO deelnemers/2
                               p(i+deelnemers/2)=p(i)+1
                           ROF
                  ' Het maakt niet uit of je het even/oneven deel verwisseld
                  ' p(i) bevat nu de deelnemer (referentie) terwijl de 
                  ' volgorde van p die volgorde op het wedstrijd formulier is.

Halve kompetitie :Gegeven moet zijn de (voorronde) poulegrote (=maxv) .
                  Tevens de lijst p welke de geordende org met deelnemers
                  bevat zoals in onderstaand v.b. is getoond .
                   maxv=3 , maxp=5 
                   d =  |1 3 5 7 9 |   Dit moet een plaatsing :
                   p = ||1 5 9||3 7||  geven (dus een voorronde bestaande
                  uit een poule van 3 en een van 2 ). Ook hier gaan we uit
                  van een set p waarvan de elementen een element aanwijst
                  in de verzameling Organisatiedeelnemers .
Je zou dit kunnen schrijven als (meer dimensionale set):
                   aantalVoorRo = (maxp + maxv - 1)/ maxv
                   VAR p( maxv , aantalVoorRo) = 0
                   FOR i = 1 TO aantalVoorRo
                       FOR j = 1 TO maxv
                             p(j,i) = (j - 1) * aantalVoorRo + i
                       ROF
                   ROF
Je zou dit ook kunnen schrijven als (linieare set):
                   VAR   p(1 TO deelnemers) = 0
                   aantalVoorRo = (maxp + maxv - 1)/ maxv{2}
                   FOR v = 1 TO aantalVoorRo             {1->2}
                   'dit is 1 voorronde afbeelding
                    beginpl = (v-1) * aantalVoorRo + 1   {1,4}
                    eindpl  = v * aantalVoorRo           {3,6}
                    IF eindpl > maxp THEN einpl=maxp     {3,5}
                    p(beginpl) = v                       {p(1)=1,p(4)=2
                    FOR o = beginpl+1 TO eindpl          {2->3,5->5}
                     p(o) = p(o-1) + aantalVoorRo        {p(2)=3 p(3)=5,
                    ROF                                   p(4)=2 p(5)=4} 
                   ROF                                   

In de Poule_afbeelding is het de bedoeling een afdruk op papier temaken
van de geplaatste poule . Voor een Eliminatie systeem moet er om worden
gedacht dat de rust perioden tussen de wedstrijden van een kandidaat zo
maximaal mogelijk zijn  . Ten tweede moet de wedstrijd volgorde zo worden
opgesteld dat de kans dat een deelnemer dezelfde deelnemer nog eens ontmoet
zou klein mogelijk is . Idem voor de winnaars ronde geldt dat de kans dat
een deelnemer een deelnemer ontmoet van de eigen organisatie zou klein
mogelijk is . Men kan dit het eenvoudigst berekenen door een ronde patroon
temaken en daarin bijde kriteria teberekenen . Eenmaal gedaan dan ligt het
grond patroon vast en kunnen de veranderingen t.g.v. poule grote het 
eenvoudigst worden ingebracht m.b.v. een beslissing boom . 
(Let wel de voorbeelden gegeven in het Bondsvademecum voldoen in de meeste
gevallen niet aan deze eisen .) 
(Die in het Wedstrijd administratie boek ook niet.)
In afbeelding van de Halve kompetie zitten weinig problemen .
Volgorde van voorronden is niet belangrijk . Er zou alleen rekening moeten
worden gehouden met het feit dat als twee deelnemers behorend tot dezelfde
Organisatie deze in de eerste wedstrijd moeten worden gezet .
Finales blijft een probleem daar dit afhangt van de zinswijze van de
tournooi organisatie .

Resultaten moeten worden toegevoegd aan het Poule_hoofd .
Om te bepalen welke Organisatie de beste resultaten heeft behaald het
volgende algoritme . Bepaal daartoe de kans dat een deelnemer een prijs
kan winnen (ga praktisch uit van de nummers 1 en 2) :
kans = totaal_aantal_deelnemers / aantal_poules * 2 .
De nominale norm voor een organisatie zou dan moeten zijn :
norm = aantal_deelnemers_organisatie * kans .
Het succes van de organisatie wordt bepaald door :
succes = aantal_winnaars(alleen 1 en 2) - norm
De meest succesvolle organisatie wordt nu bepaald door de hoogste in rang
orde van alle organisatie . Deze methode voorkomt de dat het succes wordt
bepaald door het aantal deelnemers van een organisatie .

Ten Slotte :
Implementatie van de aangegeven algoritmen is nogal afhangelijk van
de gewenste optimalisatie en de mogelijkheden die de tegebruiken taal bied.
B.v. lijsten en set worden het makelijkst in SMALLTALK (of LISP , LOGO )
gemaakt . Terwijl variable records (Bestands definitie's) beter in ADA of
OBERON (of Pascal 7.0 , C++) kunnen worden aangegeven . Dynamische array
werken het best in QBASIC en FORTRAN . Een heel ander probleem is 
portebility (overdraagbaarheid) dit bepaald de levensduur (onderhoudbaarheid)
van het programma . Ofschoon ieder verwacht dat dit ADA zal worden blijkt
voorlopig nog dat in praktijk slechts door twee talen wordt berijkt , teweten
FORTRAN en COBOL(met of zonder SQL) . 
Hoe overdraagbaarder de taal teslechter de USER_INTERFACE . Een mogelijke
oplossing is door de kern (90%) in een overdraagbare taal teschrijven en
daaromheen een USER_INTERFACE per platform te maken. (V.b. hiervan is SPICE )
In verband met voorgenoemde overdrachbaarheid is het wenselijk de DATA
bestanden in FLAT ascii te porteren  .