TourDeJeu, le réseau des jeux en ligne alternatifs : jeux web multijoueurs, jeux par forum. En savoir +

Flux RSS des discussions du forum : pour les joueurs, et pour les créateurs et MJ
  Reply to this topicStart new topicStart Poll

> Problème Velu D'algorithmique, mélangeage d'un tableau sous contrainte
zumba
Ecrit le : Mercredi 25 Avril 2007 à 13h26
Quote Post


Ouf
*

Groupe : Membre
Messages : 496


Hello,
j'ai un problème d'algorithmique à fortes contraintes que je voudrais vous soumettre, je pense que c'est un cas qu'on doit retrouver dans d'autres besoins que le mien. Si vous avez une soluce ou de la littérature à me conseiller, je suis preneur.

J'expose :
il me faudrait une fonction mélanger_tableau(tableau, clé) qui mélange les valeurs de tableau en fonction de la valeur de clé (de sorte que si on fourtnit le meme tableau et la meme clé on obtient toujours le même résultat). On doit bien sur retrouver toutes les valeurs de la distrib d'entrée dans la distrib de sortie.
Bon ca c'est simple mais la grosse contrainte c'est qu'il faudrait que l'algo garantisse que pour espace de valeur de clé (disons 1 à 100) on obtienne à peu près (à peu près= + ou - 10%) le même nombre pour chaque paire [valeur, indice dans le tableau].
Plus concrètement qu'on garantisse que chaque valeur se retrouve le même nombre de fois à chaque position.

en gros je prends mon tableau distribution initial TI[v1,v2,v3,...,v14]
je balance 100 fois mélanger_tableau(TI,1 à100)
j'obtiens 100 tableaux T1,T2,T3,....T100
si je les mets les un au dessus des autres et que je compte les nombre d'occurence de chaque V je voudrais avoir à peu près autant de V1 que de V2 que de Vx dans la colonne 1, pareil dan sla colonne 2 etc...

l'application de ça dans mon jeu (pour se accrocher à du concret) est de répartir des bonus (les V) sur les ressources naturelles(les indices) géographiquement (x-y me donne la clé) en garantissant que dans une province donnée on retrouvera bien à peu près le même nombre de fois toutes les valeurs différence de bonus pour chaque ressource.
illustration avec notre algo actuel :
http://www.the-continent.org/site/cartes_ressources.php
on voit que la répartition est totalement inégale sur certaines denrées (bois, bétail, peaux...)

voilivoilo. Si vou sconnaissez d'autres fofo de devs chevronnés ou je pourrai poster ça m'intéresse aussi.
zumba


--------------------
Z
PMEmail Poster
Top
Mindiell
Ecrit le : Mercredi 25 Avril 2007 à 14h31
Quote Post


Kid
*

Groupe : Membre
Messages : 48


[HS]10 essais pour répondre, je ne sais pas si c'est le forum qui a du mal, mais bon smile.gif[/HS]

Alors, je te rpopose un moyen super simple, qui devrait, à vue de nez (et je l'ai long), résoudre ton problème :

Suivant la clé utilisée, tu rajoutes celle-ci à l'indice utilisé au départ, modulo le nombre d'éléments -1. Tu choisis l'élément de départ égal à la clé.

Pour clé = 1, les valeurs sont placées dans le même ordre que le tableau de base, déclaés de 1 (puisque la clé vaut 1 et que le premier élément vaut 0).
Pour clé=2, les valeurs sont placées dans le même ordre, mais décalées de 2 en 2 :
2, 4, 6, etc..., 98, 100 (modulo 99, donc 1), 3, 5, etc..., 99 (modulo 99, donc 0)

A priori, les valeurs seront forcément distribuées de manière régulière (si je me trompe pas, mais là c'est du pif, plus du nez biggrin.gif )
En tout cas, ca reste super simple et surement rapide. La même clé donne toujours le même résultat. Tu peux augmenter la taille du tableau sans souci, etc...

Le modulo, ca sauve la vie wink.gif


--------------------
Mindiell
Rôliste - Troll - Nain - etc...
Créateur de jeu
PMEmail Poster
Top
naholyr
Ecrit le : Mercredi 25 Avril 2007 à 19h44
Quote Post


Ouf
*

Groupe : Membre
Messages : 423


Le problème de l'algorithme précédent est qu'il garantit une distribution beaucoup trop homogène, ce n'est pas naturel. Il est normal qu'il y ait des inégalités : ça s'appelle le hasard !
De plus j'ai peur que pour certaines valeurs on ne puisse pas aller au bout de l'algorithme, je pense notamment aux clés multiples de longueur(tableau)-1, à vue de nez cela pourrait poser des problèmes.

De toute façon soit tu acceptes qu'il puisse y avoir des inégalités (le hasard ne donne une distribution équitable que sur de très grands nombres d'essais) soit tu renonces au hasard et tu ne pourras alors pas obtenir d'allure aléatoire de ta distribution.

Personnellement j'aime bien partir de ce qui existe déjà, donc j'aurais utilisé les mt_rand() de PHP.
En spécifiant mt_srand($clé) je suis sûr que l'algo se comportera toujours de la même façon pour la même valeur de $clé.
Et même avec un peu de chance array_shuffle() se base sur mt_srand(), je vais tester et je reviens te dire ça.
PMEmail PosterUsers WebsiteICQYahoo
Top
naholyr
Ecrit le : Mercredi 25 Avril 2007 à 20h21
Quote Post


Ouf
*

Groupe : Membre
Messages : 423


Je peux te proposer ça, à double avantage :
- vraiment aléatoire, puisque basé sur mt_rand()
- algo à cout fini, il est O(n) (n la longueur du tableau)
a priori il devrait offrir une répartition homogène puisqu'il est basé sur un aléatoire robuste, mais c'est à vérifier :
CODE
<?php

function calcul_cle($cle)
{
   if (is_number($cle)) {
       // la clé est déjà un entier, on renvoie sa valeur actuelle
       return (int) $cle;
   }
   else {
       // on fait une conversion en entier très basique :
       // Somme(position*code ascii du caractère)
       $cle_finale = 0;
       $len = strlen($cle);
       for ($i=0; $i<$len; $i++) {
           $cle_finale += ($i+1)*ord($cle{$i});
       }
       return $cle_finale;
   }
}

function melanger_tableau($tableau, $cle, $passes = 1)
{
   // on force le hasard en utilisant une valeur entière calculée à partir de la clé
   mt_srand(calcul_cle($cle));
   // si on force plusieurs passes
   if ($passes > 1) {
       // on fait $passes mélanges
       for ($i=0; $i<$passes; $i++) {
           $tableau = melanger_tableau($tableau, $cle, 1);
       }
   }
   // sinon, on fait un mélange direct
   else {
       $len = count($tableau);
       foreach ($tableau as $i => $v) {
           // on prend une clé au hasard
           $i2 = mt_rand(0,$len-1);
           // on inverse ces deux éléments
           $tableau[$i] = $tableau[$i2];
           $tableau[$i2] = $v;
       }
   }
   return $tableau;
}

// test de la fonction de mélange
$nb_passes_max = 4; // passes à tester, de 1 à X passes
$nb_melanges = 200; // nombre de mélanges à réaliser, clés de 1 à X
$tableau = array('01','02','03','04','05','06','07','08','09','10','11','12'); // tableau à mélanger

for ($p=1; $p<$nb_passes_max; $p++) {
   // mélanges en $p passes
   $resultats = array();
   echo "$nb_melanges mélanges à  $p passes...\n";
   for ($i=0; $i<$nb_melanges; $i++) {
       // mélange à $p passes avec la clé $i
       $melange = melanger_tableau($tableau, $i, $p);
       echo "[" . implode(",",$melange) . "]\n";
   }
}

?>


Edit : remise en forme du code
PMEmail PosterUsers WebsiteICQYahoo
Top
zumba
Ecrit le : Jeudi 26 Avril 2007 à 08h56
Quote Post


Ouf
*

Groupe : Membre
Messages : 496


Hello,
Merci pour vos réponses ! en effet il faut tout d emême un caractère aléatoire dans
Naholyr, encore une fois ton aide m'est précieuse (tu m'avais déjà fourni un algo d'ordonancement de poules sportives qui marche du tonnere). On va étudier ce code et tenter de l'implémenter. Je te tiens au courant !

A+ et merci.


--------------------
Z
PMEmail Poster
Top
« Sujets + anciens | Programmer | Sujets + récents »

Reply to this topicStart new topicStart Poll