Calcul de durée totale/de session

Calcul de durée totale/de session - Algo - Programmation

Marsh Posté le 09-05-2007 à 21:19:33    

Salut,
bon j'ai une petite question de logique/calcul.
 
Mise en situation :
Dans le cadre d'un tournois, on a un certain nombre de participant. Chacun des participant doit affronter tous les autres participant.
Le tournois se décompose donc en sessions au cours desquelles se déroule un certain nombre de match.
 
Exemple :
Participant : A, B, C, D et E.
 
Session 1 :
A affronte B
C affronte D
E ne joue pas.
 
Session 2 :
E Affronte D
C Affronte B
A ne joue pas.
 
Session 3 :
A affronte E
B affronte D
C ne joue pas.
 
Et ainsi de suite jusqu'à ce que tout le monde ait affronter tout le monde.
 
Ce que j'aimerais calculer c'est le temps qu'il faut prévoir pour le déroulement du tournois sachant qu'on connaît la durée de chaque match et la durée du temps qu'il y a entre chaque session.
 
Où qu'j'en suis :
Je sais qu'on peut calculer le nombre de match à réaliser ainsi, enfin ça me semble correcte :
Soit x le nombre de participant : TotalMatch = x*(x-1) Edit : En fait non faut aussi diviser par 2 donc : TotalMatch = x*(x-1)/2
 
D'autre part je sais qu'on peut approcher le nombre de sessions ainsi :
Soit x le nombre de participant : nbSession = TotalMatch/(x/2)
 
Donc en supposant qu'un match dure 20 minutes et qu'entre chaque session il y a 10 minutes on peut approcher la durée totale ainsi :
DureeTotaleEnMinutes = nbSession*20+(nbSession-1)*10
Enfin il me semble...
 
Ce qui ne va pas dans mes calcules c'est que je n'ai qu'une approche du nombre de sessions, donc je n'ai rien d'exacte au niveau de la durée totale.
Et franchement je sèche sur le calcul exacte du nombre de sessions, donc si quelqu'un a une idée : je suis preneur!
 
En vous remerciant.
 
-------------------------
Nouvelle question
Tant que j'y suis, je pose une nouvelle question :
Comment calculer correctement une session? C'est à dire qu'avec 6 participants je me retrouve bien avec 5 sessions. Parce que pour le moment je me retrouve avec plus que ça...
 
Ce que je fais :
Bon déjà j'ai une fonction MatchPlayed, qui retourne un booléen indiquant si oui ou nom le match a déjà été joué. De même, j'ai une fonction InSession.
 
Ca donne donc quelque chose comme ça :

Code :
  1. team[6] = {'A','B','C','D','E','F'}
  2. i,j:entier
  3. session:session
  4. POUR i DE 1 A 6 FAIRE
  5. POUR j DE 1 A 6 FAIRE
  6.  SI !this.MatchPlayed(team[i],team[j]) ET !session.InSession(team[i],team[j]) ET team[i] != team[j] ALORS
  7.   session.Add(team[i],team[j])
  8. FIN POUR
  9. FIN POUR


 
C'est, en gros ce que fait mon code sauf que ça me donne pas le bon nombre de sessions. Par exemple la ça m'en donne 6.


Message édité par dwogsi le 10-05-2007 à 15:05:30

---------------
-- Debian -- Le système d'exploitation universel | Le gras c'est la vie! | /(bb|[^b]{2})/
Reply

Marsh Posté le 09-05-2007 à 21:19:33   

Reply

Marsh Posté le 10-05-2007 à 01:55:46    

Si le nombre d'equipes est pair, chaque equipe va rencontrer successivement toutes les autres, donc va faire x-1 match (et pareil pour les autres simultanément).
 
Si le nombre d'equipes est impair, il y aura en plus un match ou l'equipe n'aura pas d'amis, donc on en rajoute un, cela donne en résumé :
 
nombre_sessions = x - 1 +x%2
duree_totale = temps_discours_du_debut + nombre_sessions * (temps_match+temps_pause) - temps_pause + temps_faire_la_fête


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 10-05-2007 à 02:13:14    

Oui c'est aussi la théorie que j'avais imaginé... Mais :
Je me suis amusé à faire un petit tableau de correspondance entre nbParticipant, nbSession et pour 6 participant je trouve 7 sessions. Sauf que d'après ce que tu donne je devrais trouver 5 sessions.

 

Le soucis c'est qu'à un moment je me retrouve toujours avec des participant qui ont des match à jouer avec d'autres participant qui sont déjà pris par d'autres match dans la même session. Les match qui pourraient être joués avec les autres participant libres ont déjà étés joués.

 

Peut être que je calcul mal mes sessions...

 

Edit :
Voilà le tableau en question, je sais pas vraiment s'il est exacte. Je l'ai réalisé armé d'un papier et d'un stylo.

 

---------------------------
| NbParticipant | NbSession |
 ---------------------------
|        2          |      1        |
 ---------------------------
|        3          |      3        |
 ---------------------------
|        4          |      3        |
 ---------------------------
|        5          |      6        |
 ---------------------------
|        6          |      6        | // Edit2: Réussit à réduire à 6
 ---------------------------

 

Edit3 : Bon en fait pour 6 participant je trouve bien 6 sessions et non pas 7 qui était finalement une erreur.


Message édité par dwogsi le 10-05-2007 à 02:24:47

---------------
-- Debian -- Le système d'exploitation universel | Le gras c'est la vie! | /(bb|[^b]{2})/
Reply

Marsh Posté le 10-05-2007 à 02:27:19    

pour 5 je trouve bien 5 :
A - BC - DE
B - AD - CE
C - AE - BD
D - AC - BE
E - AB - CD
pour 6 je trouve 5 aussi forcément (en rajoutant F a chaque fois avec celui qui était seul ):
AF - BC - DE
BF - AD - CE
CF - AE - BD
DF - AC - BE
EF - AB - CD


Message édité par 0x90 le 10-05-2007 à 02:32:16

---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 10-05-2007 à 02:31:22    

Une équipe ne joue qu'un seul match par session (j'aurais dû le préciser), c'est essentiel. Surtout pour que le calcul de la durée totale tienne la route, tel que tu l'as donné.
Et dans ce que tu viens de donner, dans les deux, B joue deux match dans la première session.


Message édité par dwogsi le 10-05-2007 à 02:32:08

---------------
-- Debian -- Le système d'exploitation universel | Le gras c'est la vie! | /(bb|[^b]{2})/
Reply

Marsh Posté le 10-05-2007 à 02:32:40    

C'était une typo en recopiant mon tableau, quand tu remplace par E c'est bon et y'a aucun conflit ;)


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 10-05-2007 à 02:39:46    

Effectivement, ya le bon nombre de match, tous les match et aucun conflit. C'est donc faisable en 5 sessions.
Bon et bien merci! Et désolé pour les contradictions.
 
Maintenant va falloir que je contrôle l'algo qui calcul chaque session, histoire de voir si le tournois se déroule avec le bon nombre de session. Sinon j'aurais l'air un peu con avec mes prévisions non respectées par mon soft.


---------------
-- Debian -- Le système d'exploitation universel | Le gras c'est la vie! | /(bb|[^b]{2})/
Reply

Marsh Posté le 10-05-2007 à 03:42:16    

Tant que j'y suis, je pose une nouvelle question :
Comment calculer correctement une session? C'est à dire qu'avec 6 participants je me retrouve bien avec 5 sessions. Parce que pour le moment je me retrouve avec plus que ça...

 

Ce que je fais :
Bon déjà j'ai une fonction MatchPlayed, qui retourne un booléen indiquant si oui ou nom le match a déjà été joué. De même, j'ai une fonction InSession.

 

Ca donne donc quelque chose comme ça :

Code :
  1. team[6] = {'A','B','C','D','E','F'}
  2. i,j:entier
  3. session:session
  4. POUR i DE 1 A 6 FAIRE
  5. POUR j DE 1 A 6 FAIRE
  6.  SI !this.MatchPlayed(team[i],team[j]) ET !session.InSession(team[i],team[j]) ET team[i] != team[j] ALORS
  7.   session.Add(team[i],team[j])
  8. FIN POUR
  9. FIN POUR
 

C'est, en gros ce que fait mon code sauf que ça me donne pas le bon nombre de sessions. Par exemple la ça m'en donne 6.


Message édité par dwogsi le 10-05-2007 à 03:43:55

---------------
-- Debian -- Le système d'exploitation universel | Le gras c'est la vie! | /(bb|[^b]{2})/
Reply

Marsh Posté le 10-05-2007 à 15:09:27    

Donc c'est même pire que ce que je pensais avec l'algo que j'ai donné mon soft me calcule les session suivantes :
AB - CD - EF
AC - BD
AD - BC
AE - BF
AF - BE
CE - DF
CF - DE

 

Pour l'optimisation du l'utilisation du temps on repassera... Mais je sais pas vraiment comment faire pour que çame donne le meilleur ordre de déroulement.
Si quelqu'un a une piste?

 

(UP Caché!)

Message cité 1 fois
Message édité par dwogsi le 10-05-2007 à 15:18:17

---------------
-- Debian -- Le système d'exploitation universel | Le gras c'est la vie! | /(bb|[^b]{2})/
Reply

Marsh Posté le 10-05-2007 à 22:54:52    

dwogsi a écrit :

Donc c'est même pire que ce que je pensais avec l'algo que j'ai donné mon soft me calcule les session suivantes :
AB - CD - EF
AC - BD
AD - BC
AE - BF
AF - BE
CE - DF
CF - DE
 
Pour l'optimisation du l'utilisation du temps on repassera... Mais je sais pas vraiment comment faire pour que çame donne le meilleur ordre de déroulement.
Si quelqu'un a une piste?
 
(UP Caché!)

J'ai écrit un petit programme qui génère la liste des rondes  d'un tournoi et j'avais fait une espèce de doc : http://darkoli.free.fr/programmation/tournoi.html.
Si mes souvenirs sont bon j'utilisais une fonction récursive.


---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
Reply

Marsh Posté le 10-05-2007 à 22:54:52   

Reply

Marsh Posté le 11-05-2007 à 01:02:23    

Merci j'ai enfin un bon point de départ.
Domage qu'il n'y ait pas le code...


---------------
-- Debian -- Le système d'exploitation universel | Le gras c'est la vie! | /(bb|[^b]{2})/
Reply

Marsh Posté le 11-05-2007 à 08:28:50    

Je peux de donner un exemple minimaliste de la fonction récursive qui détermine la liste de toutes les sessions.

Code :
  1. int alterner_basic(int* tours, int* tableau, int numero)
  2. {
  3. int  i=0;
  4. int  j=0;
  5. if (tableau == NULL) return ERREUR;
  6. if (numero > GLOBAL_nb_joueurs) return OK;
  7. while (i <  GLOBAL_nb_joueurs)
  8.   {
  9.    if (tableau[i] == 0)
  10.     {
  11.      tableau[i]=numero;
  12.      /* Fin de la recherche d'une série ? */
  13.      if (numero >= GLOBAL_nb_joueurs)
  14.       {
  15. /*       ajouter_serie(tours, tableau);*/
  16.        for (j=0;j<GLOBAL_nb_joueurs;j++) fprintf(stdout, "%s%02d", (j&1)==1?", ":(j>0?" - ":"" ),tableau[j]);
  17.        fprintf(stdout, "\n" );
  18.       }
  19.      else
  20.       {
  21.        /* Placement des autres joueurs */
  22.        alterner_basic(tours, tableau, numero+1);
  23.       }
  24.      tableau[i]=0;
  25.     }
  26.    i++;
  27.   }
  28. /* Fin */
  29. return OK;
  30. }


Le tableau tableau contient la session en cours de génération, sa taille correspond au nombre de participants (+1 si impair !).
Il ne te reste plus qu'a sélectionner les sessions qui sont compatibles entres-elles ! :D
Pour cela j'utilise le tableau tours qui contient N fois le tableau tableau : N = nombre de rondes.
 
Il y a une variable globale (je sais, c'est pas bien) : GLOBAL_nb_joueurs (le nombre de participants (+1 si impair)).
 
Appel de la fonction :

Code :
  1. int  tableau[6]={0, 0, 0, 0, 0, 0};
  2. int  GLOBAL_nb_joueurs=6;
  3. alterner_basic(NULL, tableau, 1);


Message édité par darkoli le 11-05-2007 à 08:33:15

---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
Reply

Marsh Posté le 11-05-2007 à 15:20:34    

Merci je vais étudier ça.
Et pourquoi utiliser une variable global? Pourquoi pas un paramètre de plus à ta fonction?


---------------
-- Debian -- Le système d'exploitation universel | Le gras c'est la vie! | /(bb|[^b]{2})/
Reply

Marsh Posté le 12-05-2007 à 18:07:18    

dwogsi a écrit :

Merci je vais étudier ça.
Et pourquoi utiliser une variable global? Pourquoi pas un paramètre de plus à ta fonction?


J'étais paresseux à l'époque.


---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
Reply

Marsh Posté le 14-05-2007 à 16:57:34    

dwogsi a écrit :

Merci je vais étudier ça.


En fait je viens de découvrir qu'il existe une méthode assez simple et vachement plus rapide !
Le système (de) Berger ou les tables de Berger.
Pour N joueurs : N pair !
Il faut initialiser un tableau de N/2 lignes et 2 colonnes de la façon suivante :

1   N
2   N-1
3   N-2
...  ...


Pour la première session, le joueur 1 rencontre le joueur N, le joueur 2, le joueur N-1, ...
 
Pour la session suivante, il suffit de faire tourner les joueurs dans le sens inverse des aiguilles d'une montre sauf le joueur N qui ne bouge pas !
Exemple pour N = 6
Session 1

1 6
2 5
3 4


Session 2

5 6
1 4
2 3


Session 3

4 6
5 3
1 2


Ensuite pour que tous les joueurs changent de couleur (pour les échecs par exemple), il suffit d'inverser les deux joueurs de la première ligne sinon le joueur N joue toujours avec la même couleur.
 
Finalement, les tables que tu trouveras sur internet sont présentées de façon à ce que pour chaque session le joueur 1 rencontre le joueur S (numéro de la session), pour la première session il rencontre le joueur N.


Message édité par darkoli le 14-05-2007 à 16:58:04

---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
Reply

Marsh Posté le 15-05-2007 à 09:53:06    

Merveilleux, absolument merveilleux. Merci.
Je me disais bien qu'un type avait déjà dû trouver quelque chose sur ce problème. Ayant son nom, j'ai pu trouver pas mal de truc, après avoir passer les sites de vente de meubles : en effet "table de berger" ne donne pas vraiment ce que j'attendais, au départ.
Encore merci :jap:


---------------
-- Debian -- Le système d'exploitation universel | Le gras c'est la vie! | /(bb|[^b]{2})/
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed