Однією з найпоширеніших систем голосування на виборах з переможцями одночасно є метод множинного голосування. Простіше кажучи, виграє кандидат з найбільшою кількістю голосів. Однак голосування за множинність є математично необґрунтованим і може створювати ситуації, коли виборці змушені голосувати за "менше двох злом" на відміну від кандидата, якого вони справді віддають перевагу.
У цій грі ви напишете програму, яка користується перевагою множинної системи голосування. Він буде голосувати за одного з трьох кандидатів на виборах. Кожен кандидат пов’язаний з певною виплатою для себе, і ваша мета - максимально збільшити очікуваний виграш.
Виплати розподіляються "рівномірно" випадковим чином, змінюються з кожними виборами, і додаються до 100. Кандидат А може мати виплату 40, Кандидат В міг виплатити 27, а Кандидат С міг виплатити 33. Кожен гравець має різний набір виплат.
Коли настане ваша черга голосувати, у вас з’явиться неповна інформація. Нижче перерахована інформація, яка буде вам доступна. Оскільки ви не знаєте, якими є індивідуальні виплати інших гравців, вам буде передбачити, як вони проголосують, враховуючи поточні результати опитування.
- Часткові результати виборів поки що
- Кількість учасників (крім вас), які ще не проголосували
- Ваші особисті виплати за кожного з кандидатів
- Загальна сума виплат за кожного з кандидатів
Після того, як кожен гравець отримав шанс голосувати, кандидат, що отримав найбільшу кількість голосів, виграє відповідно до множинного голосування. Потім кожен гравець отримує кількість балів, що відповідає їх виплаті від цього кандидата. Якщо в голосах буде зрівняно число, то кількість присвоєних балів буде середньою кількістю зв'язаних кандидатів.
Структура турніру
Коли вперше буде проведено реєстрацію, учаснику буде повідомлено кількість виборів, проведених на турнірі. Я спробую провести надзвичайно велику кількість виборів. Тоді кожні вибори будуть проводитися по одному.
Після того, як учасників перетасують, кожному надається черга на голосування. Їм надають обмежену інформацію, перелічену вище, і повертають номер, що означає їх голос. Після закінчення виборів кожному боту надаються остаточні результати опитування та їх бал збільшується від цих виборів.
Переможцем буде той, хто отримав найвищий загальний бал після того, як відбудеться велика кількість виборів. Контролер також обчислює "нормалізований" бал для кожного учасника, порівнюючи його бал з розподілом балів, передбачуваним для бота, що має випадкове голосування.
Деталі подання
Представлення буде мати форму Java 8 класів. Кожен учасник повинен реалізувати наступний інтерфейс:
public interface Player
{
public String getName();
public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs);
public void receiveResults(int[] voteCounts, double result);
}
- Ваш конструктор повинен прийняти єдиний
int
параметр, який буде представляти кількість виборів, які будуть проведені. getName()
Метод повертає ім'я , яке буде використовуватися в списку лідерів. Це дозволяє вам мати добре відформатовані імена, просто не збожеволійте.- У
getVote(...)
метод повертає0
,1
або2
для позначення яких кандидат отримає голоси. receiveResults(...)
Метод головним чином для того, щоб існування більш складних стратегій , які використовують історичні дані.- Вам дозволяється створювати будь-які інші змінні методів / екземплярів, які ви хочете записати та обробити надану вам інформацію.
Турнірний цикл, розширений
- Кожен учасник має інстанцію
new entrantName(int numElections)
. - Для кожного вибору:
- Контролер випадковим чином визначає виплати для кожного гравця за ці вибори. Код для цього наведено нижче. Потім він переміщує гравців і примушує їх почати голосувати.
- Метод конкурсанта
public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs)
викликається, і учасник повертає свій голос з0
,1
або2
за кандидата на свій вибір. - Вступникам, чий
getVote(...)
метод не повертає дійсний голос, буде призначено випадкове голосування. - Після того, як всі проголосували, контролер визначає результати виборів методом множини.
- Вступники інформуються про остаточний підрахунок голосів та їх виплату, називаючи їх метод
public void receiveResults(int[] voteCounts, double result)
.
- Після проведення всіх виборів переможцем стає той, хто має найвищий бал.
Випадковий розподіл виплат
Точне розподіл матиме значний вплив на ігровий процес. Я вибрав розподіл із великим стандартним відхиленням (приблизно 23,9235), який здатний створити як дуже високі, так і дуже низькі окупності. Я перевірив, що кожна з трьох виплат має однаковий розподіл.
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;
}
Більше правил
Ось кілька більш узагальнених правил.
- Ваша програма не повинна запускати / змінювати / інстанціювати будь-які частини контролера або інших учасників або їх пам'ять.
- Оскільки ваша програма залишається "живою" протягом усього турніру, не створюйте жодних файлів.
- Не взаємодійте з іншими програмами-учасниками, не допомагайте та не націлюйте їх на них.
- Ви можете подати декілька учасників, якщо вони досить різні, і дотримуйтесь наведених вище правил.
- Я не вказав точний часовий ліміт, але дуже вдячний би час виконання, який значно менше секунди за дзвінок. Я хочу мати можливість провести стільки виборів, наскільки це можливо.
Контролер
Контролер можна знайти тут . Основна програма - Tournament.java
. Є також два простих бота, які будуть змагатися, з титулом RandomBot
та PersonalFavoriteBot
. Я опублікую цих двох ботів у відповідь.
Таблиця лідерів
Схоже, ExpectantBot є поточним лідером, за ним слідує Монте-Карло, а потім 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.
Ось декілька старих турнірів, але жоден із ботів не змінив функціональність з моменту цих запусків.
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.
Я також провів другий турнір на 10 м, підтвердив лідерство 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
вміст підрахунку всіх голосів. Я прав?