Redistribuer les ressources équitablement - Divers - Programmation
Marsh Posté le 28-02-2011 à 13:53:23
Tu autorises des sommes de type "float"? parce que pour déterminer la somme à obtenir, suffit de faire la somme des Somme / nb d'individus.
Après, un algo d'ordonnancement basé sur LPT : je classerais les individus par rapport à la moyenne obtenue pour savoir s'ils vont donner ou recevoir. Classement dans l'ordre décroissant de la somme pouvant être donnée ou à recevoir.
Ensuite, une boucle sur les individus donnant :
tant qu'un individu peut donner, lui prendre le max(ce qu'il peut donner;ce que l'individu doit recevoir pour atteindre la moyenne). Si l'individu n'a pas assez à donner, passer au suivant pour compléter ce qu'il faut à celui qui reçoit.
Si l'individu recevant a assez reçu, passer au suivant en prenant au donneur courant
fin de boucle.
Un truc de ce genre devrait le faire, non?
ps : si tu travailles qu'avec des nb entiers, là, ça peut être plus chaud déjà... ca voudra aussi dire que tous n'auront pas exactement la même somme ou alors, tu refuses de traiter le cas si la moyenne obtenue n'est pas entière...
Marsh Posté le 28-02-2011 à 13:56:53
rufo a écrit : Tu autorises des sommes de type "float"? parce que pour déterminer la somme à obtenir, suffit de faire la somme des Somme / nb d'individus. |
Ca doit être mieux que ce que j'ai fait jusqu'à présent.
Merci, je vais implémenter et tester.
Marsh Posté le 28-02-2011 à 14:40:11
Ca fonctionne nikel. Merci rufo.
Marsh Posté le 28-02-2011 à 16:03:00
Pas de quoi... Par curiosité, t'avais fait quoi comme algo initialement?
Marsh Posté le 28-02-2011 à 16:28:36
Alors, j'affecte pas le système immédiatement, au lieu, je construit un tableau de donations à effectuer.
En partant avec un tableau de Users trier dans l'ordre croissant.
Code :
|
Le tiens donne ceci dans le même langage.
Code :
|
Marsh Posté le 28-02-2011 à 16:56:35
Je demandais pas le code, juste l'algo (le principe auquel t'avais pensé)... Parce que retrouver l'algo à partir du code, c'est pas évident...
Marsh Posté le 28-02-2011 à 17:10:15
L'idée générale était de trier le tableau en croisant ou décroissant, peut importe avec Ada, j'ai reverse;
et du donner au plus pauvre à partir du plus riche. j'usqu'à ce que les deux index ce rencontre au centre avec des somme égale à n -1
partir du début ou la fin donc; pour parcourir avec Index, le tableau d'users
affecter donation avec users(index).somme - moyenne
tant que donation > 0.0; -- je travail avec des float donc.
parcourir avec Ki, le tableau users dans e sens inverse de index.
si users(Ki).somme < moyenne alors
affecter user(Ki).somme avec moyenne - users(Ki).somme
soustraire moyenne - users(Ki).somme à donation;
fin si
fait;
fait.
fait.
Marsh Posté le 28-02-2011 à 18:47:48
Mon implementation à pas l'air de fonctionner parfaitement en fait.
J'avais testé sur 4 item, mais là sur 70 c'est pas les bon résultat.
Le premier et le dernier users
|
Le premier et le dernier dons
|
Le premier et le dernier users après les dons
|
Donc, il y a un problème.
Marsh Posté le 28-02-2011 à 19:38:48
J'ai vu où est le problème.
Ben non, pouratnt, c'est pas ça... Heu !
Marsh Posté le 28-02-2011 à 21:13:24
En fait je crois que j'éssaie de résoudre un cas particulier pour cette méthode.
Elle marche que sur les premiers rang.
Après faux entrer quelque chose de plus aléatoire. Que de 1 à N attribuer N à somme initiale.
Voil alors, j'ai fais avec un générateur aléatoire, ça fonctionne après l'introduction d'un variable supplémentaire pour soustraire le reste de don à la somme devant être théoriquement perçu.
En fin ça c'est dans mon cas, qui doit effectuer les donation à par la suite.
Voici mon code actuel.
Code :
|
Et- encore ça fait pas l'équilibre exact en fait.
Marsh Posté le 01-03-2011 à 00:01:47
Sur 100_000 users ça fait un sacré écart tout de même, quand ça veux bien fonctionner.
First and last users : |
Marsh Posté le 01-03-2011 à 09:34:33
T'as peut-être un pb d'arrondi des nombres, parce que là, tu bosses avec de très grands nombres. Regardes si avec 50 users et des sommes allant de 1 à 100 (par ex), si l'algo fonctionne. Si oui, alors c'est qu'il est bon et que ton pb vient du stockage des grands nbs...
Marsh Posté le 01-03-2011 à 10:50:39
Bonjour rufo,
Effectivement, sur un petit nombre d'users et des sommes raisonnables, les écart sont moins grand, voir nul.
De plus si je ne m'abuse, il n'y a d'écart qu'entre le plus petit et le plus grand élément, tous les autre sont égaux.
Mais le programme plante tout de même 3 fois sur 4.
Marsh Posté le 01-03-2011 à 11:11:31
C'est quand même bizarre On sait établir avec précision la somme cible (la moyenne des sommes de chaque utilisateur). Donc après en classant le groupe des donneurs (au-dessus de la moyenne) et de le groupe des receveurs (en-dessous de la moyenne) dans l'ordre décroissant de leur écart à la moyenne (en valeur absolue) puis en parcourant le groupe des donneurs pour alimenter le groupe des receveurs, j'ai du mal à comprendre pourquoi ça ne marche pas
T'as bien pris en compte qu'un donneur continue de donner tant qu'il n'est pas arrivé à un écart de 0 à la moyenne et qu'un receveur continue de recevoir également tant que son écart à la moyenne n'est pas arrivé à 0?
Marsh Posté le 01-03-2011 à 11:19:22
ReplyMarsh Posté le 01-03-2011 à 11:39:57
Ca, ça donne une explication à son pb avec de très grands nbs. Mais ça ne répond pas à la question pour l'algo que j'ai proposé semble ne pas fonctionner...
Marsh Posté le 01-03-2011 à 11:59:09
Qu'est ce qui ne fonctionne pas ? Parce que les deux seuls moments où tu évoque un algo, tu as une somme et une moyenne à chaque fois :
rufo a écrit : Tu autorises des sommes de type "float"? parce que pour déterminer la somme à obtenir, suffit de faire la somme des Somme / nb d'individus. |
rufo a écrit : C'est quand même bizarre On sait établir avec précision la somme cible (la moyenne des sommes de chaque utilisateur). Donc après en classant le groupe des donneurs (au-dessus de la moyenne) et de le groupe des receveurs (en-dessous de la moyenne) dans l'ordre décroissant de leur écart à la moyenne (en valeur absolue) puis en parcourant le groupe des donneurs pour alimenter le groupe des receveurs, j'ai du mal à comprendre pourquoi ça ne marche pas |
Tu parles de classement, et donc de comparaison, sur tes résultats. Normal que ça pète...
Marsh Posté le 01-03-2011 à 14:42:11
Bon, ben j'ai implémenté mon algo, pour 200 users et une somme par utilisateur allant de 1 à 1000, ça marche.
Marsh Posté le 03-03-2011 à 06:36:44
rufo a écrit : Bon, ben j'ai implémenté mon algo, pour 200 users et une somme par utilisateur allant de 1 à 1000, ça marche. |
Je suis bien contant pour toi.
Marsh Posté le 03-03-2011 à 09:42:07
Pour toi, avec 200 users et une somme par user allant de 1 à 1000, ça marche pas? Si c'est le cas, je peux te filer mon code (en php).
Marsh Posté le 03-03-2011 à 09:57:24
Bonjour rufo,
Pour une somme de 5 à 1000 sur 200 users, ça marche.
(comment fais-tu pour commencer à 1 et finir à 1000 sur 200 users ?)
En php, non ça me dit rien.
Merci.
Je regarderais pourquoi mon code fonctionne pas à tout les coup.
Je vous tiens au courant.
Marsh Posté le 03-03-2011 à 11:22:58
j'initialise la somme aléatoirement entre 1 et 1000 pour chacun des 200 users...
Marsh Posté le 03-03-2011 à 11:25:16
Ok, c'est à peu près ce que je faisais.
Avec 10_000 users dans les même condition financière, chez toi, ça fonctionne ?
Marsh Posté le 03-03-2011 à 13:46:49
oui (et c'est super rapide en +)
Marsh Posté le 03-03-2011 à 18:34:15
Ok !
Donc, pour 10_000 users, moi ça plante carrément.
Finalement rufo, Je bien mater ton code PHP ou un pseudo code un peu plus poilu.
Marsh Posté le 04-03-2011 à 10:14:16
Voici mon code, fait l'autre jour entre 12h00 et 14h00, vite fait pour vérifier si mon algo marchait ou pas...
Code :
|
Marsh Posté le 04-03-2011 à 10:17:49
Merci rufo
For()
While()
T'as que deux boucles. J'en ai trois, ça fais une de trop. Je vais potasser.
Marsh Posté le 04-03-2011 à 15:59:29
Bon, ça ça fonctionne. Merci encore rufo !
Maintenant ça marche sur 10_000 et ça marche plus sur 100_000
Marsh Posté le 04-03-2011 à 17:26:36
Le for -> parcours des donneurs
Le while -> tant que le donneur peu donner aux receveurs
Marsh Posté le 04-03-2011 à 19:14:07
Merci encore rufo.
Alors, c'est bizarre... Ca marche pour 50_000 pour une somme aléatoire et une somme fixe.
Mais pour 100_000 j'ai un écart conséquant, peut-être pas à tout les coup, mais c'est pas normal.
Mon code avec Ada :
J'avais oublié le reverse, parce que mes tableaux sont trier dans l'ordre croissant.
De plus, comme je n'effectue pas les donation immédiatement, j'ai une variable rest en plus.
Code :
|
Marsh Posté le 28-02-2011 à 01:35:20
Bonjour,
je souhaite redistribuer les ressources que chacun détient équitablement.
j'ai un ensemble d'individu (nom, somme) et je dois trouver la liste des dont à faire pour qu'au final tous les individus possède la même somme.
Merci de votre contribution.
Message édité par Profil supprimé le 28-02-2011 à 10:14:05