[php/MySQL] Tirage au sort avec pondération


HawkEye
WRInaute accro
WRInaute accro
 
Messages: 17005
Inscription: 23 Fév 2004

[php/MySQL] Tirage au sort avec pondération

Message le Mer Déc 12, 2007 10:07

Hello,

Je cherche à faire un tirage au sort, avec une condition et une pondération basée sur un score.

Exemple: Choisir un hamster gagnant parmi ceux qui ne sont pas éliminés, et en les favorisant proportionnellement à leur force.

Les données seraient organisées comme suit:

[ nom_joueur | nom_hamster | valide | force ]

--> (jean, ham_star, 1, 500)
--> (paul, hemmster, 1, 1000)
--> (marc, lobster, 0, 1800)

--> le hamster de marc ne peut pas gagner (il est éliminé)
--> le hamster de paul a 2x plus de chances d'être tiré au sort...

Je ne trouve pas de solution simple :(


oli004
WRInaute passionné
WRInaute passionné
 
Messages: 2173
Inscription: 5 Jan 2005

Message le Mer Déc 12, 2007 10:23

ça ne fonctionne pas ça :

soit x la plus grande force

if rand(1,x) < y {

y gagne ;

}

else {

x gagne ;

}


? :roll:

bien sur, préalablement, tu fais un select sur ta base de deux id aléatoire dont eliminé est à 0
Dernière édition par oli004 le Mer Déc 12, 2007 10:27, édité 1 fois.


moktoipas
WRInaute passionné
WRInaute passionné
 
Messages: 2326
Inscription: 29 Juin 2004

Message le Mer Déc 12, 2007 10:23

Moi je le ferai en duex requettes
1 pour recureper la liste des hamster dansl a courses
1 pour recuperer la somme des forces des hamster dans la course.

la seconde renvoie 1500 donc

et tu choisi un nombre au pif entre 0 et 1500

ensuite, tu parcours (dans n'importe quel ordre, osef) le resultat de la requete des hamster qui sont dans la course.

a chaque hamster( enfin) ligne) tu soustrait de ton random la force du hamster.

Quand juste après ta soustraction tu a ton random qui fait 0 ou est négatif, c'est que tu est tombé sur le hamster gagnant :)

(moi je prefere les gerbilles)


Leonick
WRInaute accro
WRInaute accro
 
Messages: 18819
Inscription: 8 Aoû 2004

Message le Mer Déc 12, 2007 10:41

perso, je ferais un array() qui contiendrait 500 fois jean et 1000 foi paul, un petit shuffle () et tu prends le 1° du tableau


HawkEye
WRInaute accro
WRInaute accro
 
Messages: 17005
Inscription: 23 Fév 2004

Message le Mer Déc 12, 2007 10:42

oli004, j'aurais du préciser qu'il peut y avoir 100 hamsters dans la course... pas obligatoirement 2 ;)

moktoipas, ton idée m'a l'air bien. Aucun souci pour les deux requêtes, mais c'est la suite qui va me poser problème...

Je t'envoie un petit MP pour la partie "php" ;)

Merci


blman
WRInaute accro
WRInaute accro
 
Messages: 3073
Inscription: 5 Sep 2003

Message le Mer Déc 12, 2007 11:03

Moi je ferais pareil que Leonick si tu n'a pas trop d'enregistrement et pareil que moktoipas si tu en a beaucoup

PS : HawkEye, laisse Moktoipas tranquille, il a déjà assez de boulot comme ça ;)


auboutdufil
Nouveau WRInaute
Nouveau WRInaute
 
Messages: 21
Inscription: 19 Mai 2006

Message le Mer Déc 12, 2007 12:08

Moi je pondèrerai sur une échelle de 1 à 10 les forces :
--> (jean, ham_star, 1, 500, 0)
--> (paul, hemmster, 1, 1000, 1)
--> (marc, lobster, 0, 1800, 2)

Ensuite je fais un tableau pondéré :
(lobster, lobster, hemmster)

[note: il n'y a pas ham_star car il a une note de 0, et il y a 2 fois lobster parce qu'il a une note de 2)


et je fais un joli random dessu :-)


athoms
WRInaute discret
WRInaute discret
 
Messages: 244
Inscription: 22 Avr 2004

Message le Mer Déc 12, 2007 15:52

Salut?
Et en sql ça ne serait pas possible de faire ça, avec quelque chose du genre?

Code: Tout sélectionner
select * from hamster where valide=1 order by rand(),force desc limit 1


Leonick
WRInaute accro
WRInaute accro
 
Messages: 18819
Inscription: 8 Aoû 2004

Message le Mer Déc 12, 2007 16:05

non, je crois que la seule solution semble être celle que j'ai donnée. Si on effectue un tri selon un 2° critère (genre la force), que j'ai force 2 ou 2000, je serais juste devant celui qui a une force 1 et j'aurais toujours 1 chance sur 2 d'être tiré au sort.


moktoipas
WRInaute passionné
WRInaute passionné
 
Messages: 2326
Inscription: 29 Juin 2004

Message le Mer Déc 12, 2007 16:10

Non, ta solution n'est pas la seule ^^


La mienne est tout a fait valable et évite de faire un tri sur un tableau de millions d'entrées (1000 hamster de force 1000 et on se retrouve avec un méga tableau).


rog
WRInaute passionné
WRInaute passionné
 
Messages: 1662
Inscription: 21 Sep 2006

Message le Mer Déc 12, 2007 16:43

j'ai l'impression qu'aucune des deux solutions ne convient

ça marche pas avec un tableau de 3
lol

1 - 500
2 - 1000
3 - 2000

= 3500

si on divise par 500, on obient 7
sur 7 affichages on devrait avoir
une fois le 1
deux fois le 2
quatre fois le 3

à moins trouver une fonction mysql qui correspond à cet algo, ça va être un peu plus compliqué à mettre en place que cela ne le paraît

rog


blman
WRInaute accro
WRInaute accro
 
Messages: 3073
Inscription: 5 Sep 2003

Message le Mer Déc 12, 2007 16:45

La solution de Moktoipas fonctionne ainsi, si j'ai tout bien compris.

Ma table :
Tibo -> force 500
Cyril -> force 1000
Yves -> force 100
Jean -> force 2000 (balaise Jean)
Bruno -> force 500

Total des forces : 4100

Test 1 :
-------------------------------------------------------
Nbre prix au pif dans l'interval 0-4100 -> allé au hasard 4000 (voir http://fr3.php.net/rand)

Ensuite, on mélange le tableau des hamsters pour faire un tri aléatoire ( http://fr.php.net/shuffle )
Jean -> 4000 - 2000 = 2000 -> perdu
Cyril -> 2000 - 1000 = 1000 -> perdu
Tibo -> 1000 - 500 = 500 -> perdu
Bruno -> 500 - 500 = 0 -> gagné !!!

Test 2 :
-------------------------------------------------------
Nbre prix au pif dans l'interval 0-4100 -> allé au hasard 2000

Ensuite, on mélange le tableau des hamsters pour faire un tri aléatoire ( http://fr.php.net/shuffle )
Bruno -> 2000 - 500 = 1500 -> perdu
Tibo -> 1500 - 500 = 1000 -> perdu
Jean -> 1000 - 2000 = -1000 -> gagné !!!


Et oui, effectivement, avec cette solution, on consomme moins de ressources sur un nombre important d'enregistrements que de multiplier le nombre d'entrées d'un tableau. Et plus on a de force, plus on a de chance de gagner.


HawkEye
WRInaute accro
WRInaute accro
 
Messages: 17005
Inscription: 23 Fév 2004

Message le Mer Déc 12, 2007 16:47

moktoipas a écrit:Non, ta solution n'est pas la seule ^^


La mienne est tout a fait valable et évite de faire un tri sur un tableau de millions d'entrées (1000 hamster de force 1000 et on se retrouve avec un méga tableau).


C'est aussi la crainte que j'avais ;)

Disons qu'il n'y a qu'une dizaine de hamsters pour l'instant, et que leur force va de 50 à 6500... mais ces deux valeurs sont haussières ;) :roll:

J'ai appliqué la solution de moktoipas (désolé blman, j'te l'ai pris quelques minutes ;) ). Merci à tous.

Note: comme certains l'ont compris, il ne s'agit pas de hamsters ou de force, mais bien de comptes AdSense et de "mérite" ;)


moktoipas
WRInaute passionné
WRInaute passionné
 
Messages: 2326
Inscription: 29 Juin 2004

Message le Mer Déc 12, 2007 16:52

c'est meme pas la peine de faire un shuffle.

meme bruno, qui est a la fin du tableau a des chance de gagner, il gagnera quand le random sera entre 3600 et 4100.
sa proba est donc de (4100-3600)/4100= 500/4100

en fait c marche peu importe l'ordre des hamster (jean est un hamster :o )


moktoipas
WRInaute passionné
WRInaute passionné
 
Messages: 2326
Inscription: 29 Juin 2004

Message le Mer Déc 12, 2007 16:53

Note: comme certains l'ont compris, il ne s'agit pas de hamsters ou de force, mais bien de comptes AdSense et de "mérite"


moi j'avais pas compris :(


je pensais que tu voulais faire un jeu de paris en ligne pour les enfants :$ (véridique)

[php/MySQL] Tirage au sort avec pondération

Si vous avez aimé cette discussion, partagez-la sur vos réseaux sociaux préférés :

Lectures recommandées sur ce thème :



Qui est en ligne

Utilisateurs parcourant ce forum: franckM et 1 invité