L'un des systèmes de vote les plus courants pour les élections à un gagnant est la méthode du vote à la pluralité. En termes simples, le candidat avec le plus de votes gagne. Toutefois, le vote à la pluralité est mathématiquement peu judicieux et risque de créer des situations dans lesquelles les électeurs sont poussés à voter pour le "moindre de deux maux" par opposition au candidat qu'ils préfèrent vraiment.
Dans ce jeu, vous allez écrire un programme qui tire parti du système de vote à la pluralité. Il votera pour l'un des trois candidats à une élection. Chaque candidat est associé à un certain bénéfice pour vous-même et votre objectif est de maximiser le résultat escompté.
Les gains sont "uniformément" distribués au hasard, changent à chaque élection et totalisent 100. Le candidat A pourrait avoir un gain de 40, le candidat B pourrait avoir un gain de 27 et le candidat C pourrait avoir un gain de 33. Chaque joueur a un ensemble de gains différent.
Quand ce sera votre tour de voter, vous aurez des informations incomplètes. Vous trouverez ci-dessous les informations que vous aurez à votre disposition. Puisque vous ne savez pas quels sont les gains individuels des autres joueurs, votre défi sera de prédire comment ils voteraient compte tenu des résultats du sondage actuel.
- Les résultats partiels de l'élection jusqu'à présent
- Le nombre de participants (excluant vous-même), qui n'ont pas encore voté
- Vos gains personnels pour chacun des candidats
- Le total des gains de groupe pour chacun des candidats
Une fois que chaque joueur a eu la possibilité de voter, le candidat ayant obtenu le plus grand nombre de voix gagne conformément au vote à la majorité. Chaque joueur reçoit ensuite le nombre de points correspondant à son gain. En cas d'égalité des voix, le nombre de points attribués sera égal à la moyenne des candidats ex aequo.
Structure du tournoi
Lors de la première instanciation, le participant sera informé du nombre d'élections tenues dans le tournoi. Je vais tenter d'organiser un très grand nombre d'élections. Ensuite, chaque élection se déroulera une à une.
Une fois que les participants sont mélangés, on donne à chacun son tour de voter. Ils reçoivent les informations limitées énumérées ci-dessus et renvoient un numéro indiquant leur vote. Après chaque élection, chaque bot reçoit les résultats finaux du sondage et son score augmente à partir de cette élection.
Le participant victorieux sera celui qui obtiendra le score total le plus élevé après un grand nombre d'élections. Le contrôleur calcule également un score "normalisé" pour chaque concurrent en comparant son score à la distribution des scores prévue pour un bot à vote aléatoire.
Détails de la soumission
Les soumissions prendront la forme de classes Java 8. Chaque participant doit implémenter l'interface suivante:
public interface Player
{
public String getName();
public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs);
public void receiveResults(int[] voteCounts, double result);
}
- Votre constructeur devrait en prendre un
int
comme paramètre, qui représentera le nombre d’élections qui auront lieu. - La
getName()
méthode retourne le nom à utiliser dans le classement. Cela vous permet d'avoir des noms bien formatés, mais ne vous fâchez pas. - Les
getVote(...)
rendements de la méthode0
,1
ou2
pour signifier quel candidat recevra le vote. - La
receiveResults(...)
méthode vise principalement à permettre l’existence de stratégies plus complexes utilisant des données historiques. - Vous êtes autorisé à créer à peu près toutes les autres méthodes / variables d'instance que vous souhaitez enregistrer et à traiter les informations qui vous sont données.
Cycle de tournoi, élargi
- Les participants sont chacun instanciés avec
new entrantName(int numElections)
. - Pour chaque élection:
- Le contrôleur détermine aléatoirement les gains de chaque joueur pour cette élection. Le code pour cela est donné ci-dessous. Ensuite, il mélange les joueurs et les fait voter.
- La méthode du participant
public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs)
est invoqué, et le participant retourne leur vote0
,1
ou2
pour le candidat de leur choix. - Les participants dont la
getVote(...)
méthode ne donne pas un vote valide se verront attribuer un vote au hasard. - Une fois que tout le monde a voté, le contrôleur détermine les résultats de l'élection selon la méthode de la pluralité.
- Les participants sont informés du décompte final des votes et de leurs gains en appelant leur méthode
public void receiveResults(int[] voteCounts, double result)
.
- Une fois toutes les élections organisées, le gagnant est celui qui obtient le score le plus élevé.
La distribution aléatoire des gains
La distribution exacte aura un effet significatif sur le gameplay. J'ai choisi une distribution avec un écart type important (environ 23,9235) et capable de générer des gains très élevés et très bas. J'ai vérifié que chacun des trois gains a une distribution identique.
public int[] createPlayerPayoffs()
{
int cut1;
int cut2;
do{
cut1 = rnd.nextInt(101);
cut2 = rnd.nextInt(101);
} while (cut1 + cut2 > 100);
int rem = 100 - cut1 - cut2;
int[] set = new int[]{cut1,cut2,rem};
totalPayoffs[0] += set[0];
totalPayoffs[1] += set[1];
totalPayoffs[2] += set[2];
return set;
}
Plus de règles
Voici quelques règles plus générales.
- Votre programme ne doit pas exécuter / modifier / instancier des parties du contrôleur, des autres participants ou de leurs mémoires.
- Comme votre programme reste "en direct" pendant tout le tournoi, ne créez aucun fichier.
- Ne pas interagir avec, aider ou cibler tout autre programme entrant.
- Vous pouvez soumettre plusieurs participants, dans la mesure où ils sont raisonnablement différents et dans le respect des règles ci-dessus.
- Je n'ai pas spécifié de limite de temps exacte, mais j'apprécierais énormément les durées d'exécution nettement inférieures à une seconde par appel. Je veux pouvoir organiser autant d'élections que possible.
Le controlle
Le contrôleur peut être trouvé ici . Le programme principal est Tournament.java
. Il y a aussi deux simples robots, qui seront en compétition, intitulés RandomBot
et PersonalFavoriteBot
. Je vais poster ces deux robots dans une réponse.
Classement
Il semble que ExpectantBot soit le leader actuel, suivi de Monte Carlo, puis de StaBot.
Leaderboard - 20000000 elections:
767007688.17 ( 937.86) - ExpectantBot
766602158.17 ( 934.07) - Monte Carlo 47
766230646.17 ( 930.60) - StatBot
766054547.17 ( 928.95) - ExpectorBot
764671254.17 ( 916.02) - CircumspectBot
763618945.67 ( 906.19) - LockBot
763410502.67 ( 904.24) - PersonalFavoriteBot343
762929675.17 ( 899.75) - BasicBot
761986681.67 ( 890.93) - StrategicBot50
760322001.17 ( 875.37) - Priam
760057860.67 ( 872.90) - BestViableCandidate (2842200 from ratio, with 1422897 tie-breakers of 20000000 total runs)
759631608.17 ( 868.92) - Kelly's Favorite
759336650.67 ( 866.16) - Optimist
758564904.67 ( 858.95) - SometimesSecondBestBot
754421221.17 ( 820.22) - ABotDoNotForget
753610971.17 ( 812.65) - NoThirdPartyBot
753019290.17 ( 807.12) - NoClueBot
736394317.17 ( 651.73) - HateBot670
711344874.67 ( 417.60) - Follower
705393669.17 ( 361.97) - HipBot
691422086.17 ( 231.38) - CommunismBot0
691382708.17 ( 231.01) - SmashAttemptByEquality (on 20000000 elections)
691301072.67 ( 230.25) - RandomBot870
636705213.67 ( -280.04) - ExtremistBot
The tournament took 34573.365419071 seconds, or 576.2227569845166 minutes.
Voici quelques tournois plus anciens, mais aucun des robots n'a changé de fonctionnalité depuis ces exécutions.
Leaderboard - 10000000 elections:
383350646.83 ( 661.14) - ExpectantBot
383263734.33 ( 659.99) - LearnBot
383261776.83 ( 659.97) - Monte Carlo 48
382984800.83 ( 656.31) - ExpectorBot
382530758.33 ( 650.31) - CircumspectBot
381950600.33 ( 642.64) - PersonalFavoriteBot663
381742600.33 ( 639.89) - LockBot
381336552.33 ( 634.52) - BasicBot
381078991.83 ( 631.12) - StrategicBot232
380048521.83 ( 617.50) - Priam
380022892.33 ( 617.16) - BestViableCandidate (1418072 from ratio, with 708882 tie-breakers of 10000000 total runs)
379788384.83 ( 614.06) - Kelly's Favorite
379656387.33 ( 612.31) - Optimist
379090198.33 ( 604.83) - SometimesSecondBestBot
377210328.33 ( 579.98) - ABotDoNotForget
376821747.83 ( 574.84) - NoThirdPartyBot
376496872.33 ( 570.55) - NoClueBot
368154977.33 ( 460.28) - HateBot155
355550516.33 ( 293.67) - Follower
352727498.83 ( 256.36) - HipBot
345702626.33 ( 163.50) - RandomBot561
345639854.33 ( 162.67) - SmashAttemptByEquality (on 10000000 elections)
345567936.33 ( 161.72) - CommunismBot404
318364543.33 ( -197.86) - ExtremistBot
The tournament took 15170.484259763 seconds, or 252.84140432938332 minutes.
J'ai également organisé un deuxième tournoi de 10 m, confirmant ainsi l'avance de ExpectantBot.
Leaderboard - 10000000 elections:
383388921.83 ( 661.65) - ExpectantBot
383175701.83 ( 658.83) - Monte Carlo 46
383164037.33 ( 658.68) - LearnBot
383162018.33 ( 658.65) - ExpectorBot
382292706.83 ( 647.16) - CircumspectBot
381960530.83 ( 642.77) - LockBot
381786899.33 ( 640.47) - PersonalFavoriteBot644
381278314.83 ( 633.75) - BasicBot
381030871.83 ( 630.48) - StrategicBot372
380220471.33 ( 619.77) - BestViableCandidate (1419177 from ratio, with 711341 tie-breakers of 10000000 total runs)
380089578.33 ( 618.04) - Priam
379714345.33 ( 613.08) - Kelly's Favorite
379548799.83 ( 610.89) - Optimist
379289709.83 ( 607.46) - SometimesSecondBestBot
377082526.83 ( 578.29) - ABotDoNotForget
376886555.33 ( 575.70) - NoThirdPartyBot
376473476.33 ( 570.24) - NoClueBot
368124262.83 ( 459.88) - HateBot469
355642629.83 ( 294.89) - Follower
352691241.83 ( 255.88) - HipBot
345806934.83 ( 164.88) - CommunismBot152
345717541.33 ( 163.70) - SmashAttemptByEquality (on 10000000 elections)
345687786.83 ( 163.30) - RandomBot484
318549040.83 ( -195.42) - ExtremistBot
The tournament took 17115.327209018 seconds, or 285.25545348363335 minutes.
la source
Array
contenant un décompte de tous les votes. Ai-je raison?Réponses:
NoThirdPartyBot
Ce bot tente de deviner quel candidat sera le troisième et votera le candidat qu'il préfère parmi les deux premiers.
CircumspectBot
Ce bot vote pour son favori qui n'a pas été mathématiquement éliminé.
la source
ExpectantBot
Ce bot calcule la valeur attendue de chaque option de vote en supposant que tous les électeurs voteront ensuite au hasard.
la source
HipBot
HipBot ne se soucie pas des paiements. L'argent n'est qu'un sédatif qui détourne de l'art véritable.
HipBot veut voter pour quelqu'un de vrai , pas seulement pour une entreprise. Il veut également porter leur chemise de campagne après leur défaite (vraisemblablement) humiliante. Il se sent donc supérieur chaque fois que le gagnant fait quelque chose de mal.
Par conséquent, HipBot vote pour la personne avec les votes les plus bas ou, en cas d'égalité des voix, celui qui obtient le meilleur gain. Manger bio-seulement n'est pas gratuit.
HipBot n’a pas non plus été testé, alors laissez-moi savoir s’il se passe quelque chose.
EDIT: ajouté dans des bris d'égalité plus compétitifs, des commentaires pithy.
la source
PersonalFavoriteBot
Ce bot vote simplement pour le candidat ayant le gain personnel le plus élevé, en ignorant tout le reste. L'un des principaux objectifs de ce défi est de démontrer que ce n'est pas la stratégie optimale.
RandomBot
Ce bot vote au hasard. Quel que soit le nombre d’élections effectuées (tant qu’il est raisonnablement élevé, comme plus de 100), le score normalisé de ce candidat oscille entre -2 et 2.
la source
Disciple
Un suiveur veut s’intégrer. Il pense que la meilleure façon de le faire est de voter de la même manière que tout le monde, ou du moins avec la pluralité jusqu’à présent. Cela rompra les liens avec sa propre préférence, de faire preuve d'un peu d'indépendance. Mais pas trop.
Remarque: je n'ai pas testé cela, alors laissez-moi savoir s'il y a des erreurs.
la source
monte Carlo
Cela simule un grand nombre d’élections aléatoires. Il choisit ensuite le choix qui maximise ses propres profits.
la source
StatBot
StatBot est basé sur ExpectantBot; Cependant, au lieu de supposer que chaque vote est également probable, il collecte des statistiques sur la façon dont les gens votent et les utilise pour estimer la probabilité.
la source
Meilleur candidat viable
Version assez fortement révisée de ma soumission originale. Celui-ci élimine encore les candidats qui ne peuvent pas gagner compte tenu du nombre de voix restant à voter, mais utilise ensuite une stratégie qui tente d'optimiser le gain relatif plutôt que celui absolu. Le premier test consiste à prendre le rapport entre mon gain personnel et le gain total pour chaque candidat, en recherchant le meilleur rapport qualité / prix. Je cherche ensuite d'autres ratios qui sont très proches du meilleur et, s'il en existe un qui rapporte moins globalement que le meilleur, je choisis celui-là à la place. Espérons que cela aura tendance à déprimer le gain des autres joueurs tout en gardant le mien raisonnablement élevé.
Ce bot fonctionne presque aussi bien que l'original lors de mes propres tests, mais pas tout à fait. Nous devrons voir comment cela se passe contre tout le terrain.
la source
CircumspectBot
?Optimiste
L’optimiste est très optimiste et présume que la moitié des électeurs restants voteront pour le candidat qui lui rapportera le plus.
la source
ABotDoNotForget
Son objectif est simple: déterminer les tendances globales en utilisant le total des gains et en comptant le nombre de fois où les plus faibles / moyens / supérieurs ont gagné. Il votera ensuite pour celui qui a le plus de chances de gagner.
Modifier :
Certains changements apportés à l’algorythme décisionnel tiennent désormais compte de son meilleur rendement. Devrait maintenant pouvoir mieux voter alors que la répartition actuelle le faisait voter pour son propre membre inférieur alors que d’autres votaient pour leurs gains supérieurs.la source
Priam
Priam déteste la récursion. Il estime la probabilité de chaque bot restant sur la base du total des gains, puis calcule le meilleur moyen de maximiser ses gains.
Beaucoup plus rapide qu'Odysseus car il n'y a pas de récursivité (court dans le temps O (n ^ 2)) et peut faire un million d'élections en environ 15 secondes.
la source
NoClueBot
NoClue ne connaît pas très bien Java ou les mathématiques, il n'a donc aucune idée si ce rapport de pondération l'aidera à gagner. Mais il essaie.
SomeClueBot
SomeClueBot a été mis hors service.
utilise réellement la logique! utilisé pour utiliser la logique, ce qui s’est avéré inefficace, alors il est devenu conscient du gain total, pas du sien. utilise à nouveau la logique! Mais il ne fait pas bien avec tous ces partisans et optimistes, et même les gens qui s'en foutent! :)ParfoisSecondBestBot
Fondamentalement PersonalFavouriteBot, amélioré (en théorie).
la source
L'extrémiste
Toujours voter pour le candidat le moins rentable
la source
SmashAttemptByEgalité
Le but est d’égaliser tous les candidats, puis SMASH! tous les autres robots au dernier tour.
C'est un algorithme destructeur qui tente de dérouter tous les autres, pour réclamer la victoire.
Notez que cela n'a pas été testé !
la source
Bot de base
Basic Bot ne fait que voter pour les candidats, ce qui n’est pas éliminé et offre le rendement maximum le plus élevé de ces candidats.
la source
Le préféré de Kelly
J'ai commencé avec CircumspectBot, mais il ne reste plus grand chose. Fait une sorte de conjecture ennuyeuse sur la distribution de probabilité des votes restants, puis fait le choix qui maximise son propre utilitaire de journal (Kelly Criterion). Pas le plus rapide, mais dans le parc de balle de certains des autres. En outre, il est assez compétitif avec le terrain (tel qu'il était lorsque j'ai commencé à travailler là-dessus et à télécharger les autres robots).
Également disponible à l' adresse https://gist.github.com/jkominek/dae0b3158dcd253e09e5 au cas où ce serait plus simple.
la source
CommunismBot
CommunismBot pense que nous devrions tous nous entendre et choisir le candidat qui convient le mieux à tous.
Hatebot
Hatebot choisit toujours le meilleur candidat. À moins que ce ne soit une sale fête 1. Ces gars-là sont affreux.
StrategicBot
StrategicBot vote pour le meilleur candidat à condition qu'il se situe dans les limites d'un écart-type du candidat le plus proche, compte tenu du nombre d'électeurs restants.
la source
ExpectorBot
Essaie de prédire comment tous les autres Bots voteront en calculant le paiement moyen pour les autres. Les votes par défaut représentent le meilleur gain, mais voteront pour le deuxième meilleur choix, s'il a plus de votes attendus que les meilleurs, un paiement supérieur à la moyenne pour moi et le paiement le plus mauvais ayant une chance de gagner cette chose.
la source
LockBot
Un philosophe solitaire à la recherche de son "e" ...
la source
WinLose
Si vous gagnez, je perds! C'est simple. Donc, ce bot vote pour celui qu'il aime et que tout le monde n'aime pas.
la source