Uno dei sistemi di voto più comuni per le elezioni a vincitore singolo è il metodo di voto della pluralità. In poche parole, vince il candidato con il maggior numero di voti. Il voto di pluralità, tuttavia, è matematicamente insensato ed è suscettibile di creare situazioni in cui gli elettori sono spinti a votare per il "minore di due mali" rispetto al candidato che preferiscono veramente.
In questo gioco, scriverai un programma che sfrutta il sistema di voto della pluralità. Si voterà per uno dei tre candidati in una elezione. Ogni candidato è associato a un certo profitto per te stesso e il tuo obiettivo è massimizzare il tuo profitto previsto.
I payoff sono "uniformemente" distribuiti casualmente, cambiano ad ogni elezione e si aggiungono a 100. Il candidato A potrebbe avere un payoff 40, il candidato B potrebbe avere un payoff 27 e il candidato C potrebbe avere un payoff 33. Ogni giocatore ha un diverso set di payoff.
Quando è il tuo turno di votare, avrai informazioni incomplete. Di seguito sono elencate le informazioni che avrai a tua disposizione. Dal momento che non sai quali sono i profitti individuali degli altri giocatori, sarà la tua sfida prevedere in che modo voterebbero alla luce degli attuali risultati del sondaggio.
- I risultati parziali delle elezioni finora
- Il numero di partecipanti (escluso te stesso) che non hanno ancora votato
- I tuoi guadagni personali per ciascuno dei candidati
- Il totale dei profitti del gruppo per ciascuno dei candidati
Dopo che a ciascun giocatore è stata data la possibilità di votare, il candidato con il maggior numero di voti vince secondo il voto della pluralità. Ogni giocatore riceve quindi il numero di punti che corrisponde al proprio payoff da quel candidato. In caso di parità di voti, il numero di punti assegnati sarà la media dei candidati vincolati.
Struttura del torneo
Al momento della prima istanza, al concorrente verrà comunicato il numero di elezioni tenute nel torneo. Tenterò di organizzare un numero estremamente elevato di elezioni. Quindi, ogni elezione verrà effettuata una per una.
Dopo che i partecipanti sono stati mescolati, a ciascuno viene dato un turno di voto. Sono fornite le informazioni limitate sopra elencate e restituiscono un numero che indica il loro voto. Al termine di ogni elezione, a ciascun bot vengono forniti i risultati finali del sondaggio e il loro punteggio aumenta da quella elezione.
Il concorrente vincitore sarà quello con il punteggio totale più alto dopo che si sono tenute alcune elezioni. Il controller calcola anche un punteggio "normalizzato" per ciascun concorrente confrontando il suo punteggio con la distribuzione del punteggio prevista per un bot a voto casuale.
Dettagli di invio
Le iscrizioni assumeranno la forma di classi Java 8. Ogni concorrente deve implementare la seguente interfaccia:
public interface Player
{
public String getName();
public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs);
public void receiveResults(int[] voteCounts, double result);
}
- Il tuo costruttore dovrebbe prendere un singolo
int
come parametro, che rappresenterà il numero di elezioni che si terranno. - Il
getName()
metodo restituisce il nome da utilizzare nella classifica. Questo ti permette di avere nomi ben formattati, semplicemente non impazzire. - Il
getVote(...)
metodo restituisce0
,1
o2
per indicare quale candidato riceverà il voto. - Il
receiveResults(...)
metodo è principalmente quello di consentire l'esistenza di strategie più complesse che utilizzano dati storici. - Puoi creare praticamente qualsiasi altro metodo / variabile di istanza che desideri registrare ed elaborare le informazioni che ti vengono fornite.
Ciclo del torneo, ampliato
- I partecipanti vengono istanziati ciascuno con
new entrantName(int numElections)
. - Per ogni elezione:
- Il controller determina casualmente i payoff per ciascun giocatore per questa elezione. Il codice per questo è riportato di seguito. Quindi, mescola i giocatori e li fa iniziare a votare.
- Il metodo del partecipante
public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs)
viene richiamato, e il concorrente ritorna il loro voto di0
,1
o2
per il candidato di loro scelta. - Ai partecipanti il cui
getVote(...)
metodo non restituisce un voto valido verrà assegnato un voto casuale. - Dopo che tutti hanno votato, il controllore determina i risultati delle elezioni con il metodo della pluralità.
- I partecipanti vengono informati del numero di voti finali e del loro profitto chiamando il loro metodo
public void receiveResults(int[] voteCounts, double result)
.
- Dopo che si sono tenute tutte le elezioni, il vincitore è quello con il punteggio più alto.
La distribuzione casuale dei payoff
L' esatta distribuzione avrà un effetto significativo sul gameplay. Ho scelto una distribuzione con una grande deviazione standard (circa 23.9235) e che è in grado di creare guadagni sia molto alti che molto bassi. Ho verificato che ciascuno dei tre payoff abbia una distribuzione identica.
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;
}
Più regole
Ecco alcune regole più generalizzate.
- Il programma non deve eseguire / modificare / creare istanze di parti del controller o di altri partecipanti o loro memorie.
- Poiché il tuo programma rimane "attivo" per l'intero torneo, non creare alcun file.
- Non interagire, aiutare o indirizzare altri programmi partecipanti.
- È possibile inviare più partecipanti, purché siano ragionevolmente diversi e purché si rispettino le regole di cui sopra.
- Non ho specificato un limite di tempo esatto, ma apprezzerei molto l'autonomia che è significativamente inferiore a un secondo per chiamata. Voglio essere in grado di organizzare quante più elezioni possibili.
Il controller
Il controller può essere trovato qui . Il programma principale è Tournament.java
. Ci sono anche due semplici robot, che saranno in competizione, intitolati RandomBot
e PersonalFavoriteBot
. Invierò questi due robot in una risposta.
Classifica
Sembra che ExpectantBot sia l'attuale leader, seguito da Monte Carlo e poi da 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.
Qui ci sono alcuni tornei più vecchi, ma nessuno dei robot è cambiato in funzionalità da queste corse.
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.
Ho anche corso un secondo torneo da 10m, confermando il vantaggio di 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.
Array
contenente un conteggio di tutti i voti. Ho ragione?