From 2bc594c0804ed74bb1de3d5b9e8d07fbb1a8de27 Mon Sep 17 00:00:00 2001 From: Eliah REBSTOCK <eliah.rebstock@ensiie.fr> Date: Mon, 25 Apr 2016 15:04:54 +0200 Subject: [PATCH] =?UTF-8?q?Suppression=20du=20syst=C3=A8me=20de=20courbe?= =?UTF-8?q?=20de=20progression=20et=20r=C3=A9=C3=A9quilibrage=20de=20l'alg?= =?UTF-8?q?orithme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ELO_function.php | 80 +++++++++++++--------- ELO_function_progress.php | 138 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+), 30 deletions(-) create mode 100644 ELO_function_progress.php diff --git a/ELO_function.php b/ELO_function.php index d60f30a..1898402 100644 --- a/ELO_function.php +++ b/ELO_function.php @@ -15,24 +15,26 @@ * @param int $SB : score actuel du second joueur * @param int $RB : score (valant 0 ou 1) du second joueur * @param int $K : la quantité max de points gagnable ou perdable sur une partie - * @param int $nmax : le nombre de parties pour considérer "qu'un joueur est aguerri". Vaut 20 par défaut. - * @param int $nA : le nombre de parties effectués par le premier joueur sur le jeu. - * @param int $nB : le nombre de parties effectués par le second joueur sur le jeu. * @return array : le différentiel de score du premier joueur et du second joueur */ srand(); -function ELO_duel($SA, $RA, $SB, $RB, $K, $nmax=20, $nA=20, $nB=20) +function ELO_duel($SA, $RA, $SB, $RB, $K) { - if ($nA > $nmax) - $nA = $nmax; - if ($nB > $nmax) - $nB = $nmax; - $EA = 1/(1+10**(($SB-$SA)/400)); $EB = 1/(1+10**(($SA-$SB)/400)); - $newRA = ($K*$nB)/$nmax * ($RA-$EA); - $newRB = ($K*$nA)/$nmax * ($RB-$EB); + $newRA = $K * ($RA-$EA); + $newRB = $K * ($RB-$EB); + + if ($newRA>0) + $newRA = ceil($newRA); + else + $newRA = floor($newRA); + + if ($newRB>0) + $newRB = ceil($newRB); + else + $newRB = floor($newRB); return array($newRA, $newRB); } @@ -44,52 +46,70 @@ function ELO_duel($SA, $RA, $SB, $RB, $K, $nmax=20, $nA=20, $nB=20) * On suppose qu'il y a correpondance entre les indices de $S et les indices de $R. * @param array $S : scores actuels des joueurs * @param array $R : classement des joueurs - * @param int $nmax : le nombre de parties pour considérer "qu'un joueur est aguerri". Vaut 20 par défaut. - * @param array $n : nombre de parties de chaque joueurs * @param int $K : la quantité max de points gagnable ou perdable sur une partie * @return array : le différentiel de score de chaque joueur * @throws DomainException */ -function ELO_classement($S, $R, $n, $K, $nmax=20) +function ELO_classement($S, $R, $K) { - $m = count($S); if (count($R) != $m) throw new DomainException; $count = array_fill(0, $m, 0); $res = array_fill(0, $m, 0); - for ($i = 0; $i<$m; $i++) - { - for($j=$i+1; $j<$m; $j++) - { - if ($R[$i]<$R[$j]) - $newSAB = ELO_duel($S[$i], 1, $S[$j], 0, $K, $nmax, $n[$i], $n[$j]); + for ($i = 0; $i < $m; $i++) { + for ($j = $i + 1; $j < $m; $j++) { + if ($R[$i] < $R[$j]) + $newSAB = ELO_duel($S[$i], 1, $S[$j], 0, $K); else - $newSAB = ELO_duel($S[$i], 0, $S[$j], 1, $K, $nmax, $n[$i], $n[$j]); - $res[$i] = 1/($count[$i] + 1) * ($count[$i] * $res[$i] + $newSAB[1]); + $newSAB = ELO_duel($S[$i], 0, $S[$j], 1, $K); + $res[$i] = 1 / ($count[$i] + 1) * ($count[$i] * $res[$i] + $newSAB[0]); $count[$i]++; - $res[$j] = 1/($count[$j] + 1) * ($count[$j] * $res[$j] + $newSAB[2]); + $res[$j] = 1 / ($count[$j] + 1) * ($count[$j] * $res[$j] + $newSAB[1]); $count[$j]++; + + } + } + for ($i = 0; $i < $m; $i++) { + if ($res[$i] > 0) + $res[$i] = ceil($res[$i]); + else + $res[$i] = floor($res[$i]); + } + + $e = array_sum($res); + + if($e != 0){ + $se = 0; + + if ($e < 0) { + $se = min($res); } + else if($e>0) { + $se = max($res); + } + $i = array_search($se, $res); + $res[$i] += -$e; } + return $res; } -/* -function random_scores($n, $min, $max) + +function random_classement($n) { $r = array(); for ($j=0; $j<$n; $j++) { - array_push($r, rand($min,$max)); + array_push($r, $j+1); } + shuffle($r); return $r; - } -*/ + /* Test */ -/* + print("<html><body><table><th>Itération</th><th>Joueur 1</th><th>Joueur 2</th><th>Joueur 3</th><th>Joueur 4</th><th>Joueur 5</th><th>Somme</th></tr>"); $DS = array(1000,1000,1000,1000,1000); diff --git a/ELO_function_progress.php b/ELO_function_progress.php new file mode 100644 index 0000000..90ff28f --- /dev/null +++ b/ELO_function_progress.php @@ -0,0 +1,138 @@ +<?php +/** + * Created by PhpStorm. + * User: phoenix + * Date: 01/04/16 + * Time: 18:32 + * + */ + +/** + * Fonction qui calcule les différentiels de scores obtenus après une partie d'un jeu à deux joueurs + * où l'on peut perdre (0) ou gagner (1). + * @param int $SA : score actuel du premier joueur + * @param int $RA : score (valant 0 ou 1) du premier joueur + * @param int $SB : score actuel du second joueur + * @param int $RB : score (valant 0 ou 1) du second joueur + * @param int $K : la quantité max de points gagnable ou perdable sur une partie + * @param int $nmax : le nombre de parties pour considérer "qu'un joueur est aguerri". Vaut 20 par défaut. + * @param int $nA : le nombre de parties effectués par le premier joueur sur le jeu. + * @param int $nB : le nombre de parties effectués par le second joueur sur le jeu. + * @return array : le différentiel de score du premier joueur et du second joueur + */ +srand(); + +function ELO_duel($SA, $RA, $SB, $RB, $K, $nmax=20, $nA=20, $nB=20) +{ + if ($nA > $nmax) + $nA = $nmax; + if ($nB > $nmax) + $nB = $nmax; + + $EA = 1/(1+10**(($SB-$SA)/400)); + $EB = 1/(1+10**(($SA-$SB)/400)); + $newRA = ($K*$nB)/$nmax * ($RA-$EA); + $newRB = ($K*$nA)/$nmax * ($RB-$EB); + + if ($newRA>0) + $newRA = floor($newRA); + else + $newRA = ceil($newRA); + + if ($newRB>0) + $newRB = floor($newRB); + else + $newRB = ceil($newRB); + + return array($newRA, $newRB); +} + +/** + * Fonction qui calcule les différentiels de scores obtenus après une partie à count($S) joueurs + * en considérant que $R correspond au classement des joueurs dans ce jeu (du type array(1,3,4,2) pour + * le premier joueur est 1er, le second est 2e, etc). + * On suppose qu'il y a correpondance entre les indices de $S et les indices de $R. + * @param array $S : scores actuels des joueurs + * @param array $R : classement des joueurs + * @param int $nmax : le nombre de parties pour considérer "qu'un joueur est aguerri". Vaut 20 par défaut. + * @param array $n : nombre de parties de chaque joueurs + * @param int $K : la quantité max de points gagnable ou perdable sur une partie + * @return array : le différentiel de score de chaque joueur + * @throws DomainException + */ +function ELO_classement($S, $R, $n, $K, $nmax=20) +{ + + $m = count($S); + if (count($R) != $m) + throw new DomainException; + + $count = array_fill(0, $m, 0); + $res = array_fill(0, $m, 0); + for ($i = 0; $i<$m; $i++) + { + for($j=$i+1; $j<$m; $j++) + { + if ($R[$i]<$R[$j]) + $newSAB = ELO_duel($S[$i], 1, $S[$j], 0, $K, $nmax, $n[$i], $n[$j]); + else + $newSAB = ELO_duel($S[$i], 0, $S[$j], 1, $K, $nmax, $n[$i], $n[$j]); + $res[$i] = 1/($count[$i] + 1) * ($count[$i] * $res[$i] + $newSAB[0]); + $count[$i]++; + $res[$j] = 1/($count[$j] + 1) * ($count[$j] * $res[$j] + $newSAB[1]); + $count[$j]++; + } + } + for ($i = 0; $i<$m; $i++) + { + if ($res[$i]>0) + $res[$i] = floor($res[$i]); + else + $res[$i] = ceil($res[$i]); + + } + return $res; +} + + +function random_classement($n) +{ + $r = array(); + for ($j=0; $j<$n; $j++) + { + array_push($r, $j+1); + } + shuffle($r); + return $r; +} + +/* Test */ + +print("<html><body><table><th>Itération</th><th>Joueur 1</th><th>Joueur 2</th><th>Joueur 3</th><th>Joueur 4</th><th>Joueur 5</th><th>Somme</th></tr>"); +$DS = array(1000,1000,1000,1000,1000); +$n = array(0,0,0,0,0); + +print("<tr><td>0</td>"); +foreach ($DS as $value) { + print("<td>$value</td>"); +} +$p = array_sum($DS); +print("<td>$p</td></tr>"); + +for($j=1;$j<100;$j++){ + $sa = random_classement(5); + $res = ELO_classement($DS, $sa, $n, 32); + print("<tr><td>$j</td>"); + + for ($i=0;$i<count($DS);$i++) { + $DS[$i] = $DS[$i] + $res[$i]; + $k1 = $DS[$i]; + $k2 = $res[$i]; + $k3 = $sa[$i]; + $n[$i]++; + print("<td>$k1 ($k2) ($k3)</td>"); + } + $p = array_sum($DS); + print("<td>$p</td></tr>"); +} +print("</table></body></html>"); -- GitLab