Одной из наиболее распространенных систем голосования на выборах с одним победителем является метод множественного голосования. Проще говоря, кандидат с наибольшим количеством голосов побеждает. Однако голосование во множественном числе математически несостоятельно и может создать ситуации, в которых избиратели вынуждены голосовать за «меньшее из двух зол», а не за кандидата, которого они действительно предпочитают.
В этой игре вы напишите программу, которая использует преимущества системы множественного голосования. Он будет голосовать за одного из трех кандидатов на выборах. Каждый кандидат связан с определенной выплатой за себя, и ваша цель - максимизировать ожидаемую выплату.
Выплаты «равномерно» распределяются случайным образом, меняются при каждом избрании и прибавляются к 100. Кандидат A может получить выплату 40, Кандидат B может получить выплату 27, а Кандидат C может получить выплату 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
. Я опубликую этих двух ботов в ответ.
Leaderboard
Похоже, 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
содержит подсчет всех голосов. Я прав?Ответы:
NoThirdPartyBot
Этот бот пытается угадать, какой кандидат будет третьим, и голосует за кандидата, который ему нравится больше всего из двух лидеров.
CircumspectBot
Этот бот голосует за своего фаворита, который не был математически исключен.
источник
ExpectantBot
Этот бот вычисляет ожидаемую стоимость каждого варианта голосования, предполагая, что все избиратели впоследствии будут голосовать случайным образом.
источник
HipBot
HipBot не заботится о выплатах. Деньги - это просто успокаивающее средство, которое отвлекает от настоящего искусства.
HipBot хочет проголосовать за кого-то настоящего , а не за корпоративный шил. Он также хочет носить их кампанию после их (предположительно) унизительного поражения, поэтому он чувствует себя лучше, когда победитель делает что-то не так.
Таким образом, HipBot голосует за человека с наименьшим количеством голосов, или, если есть ничья, тот, кто получил лучшую выплату. Еда только органическая не бесплатна.
HipBot также не протестирован, поэтому дайте мне знать, если что-то происходит.
РЕДАКТИРОВАТЬ: добавлено в более конкурентных, содержательных комментариев.
источник
PersonalFavoriteBot
Этот бот просто голосует за кандидата с самой высокой личной отдачей, игнорируя все остальное. Одним из основных пунктов этой задачи является демонстрация того, как это не оптимальная стратегия.
RandomBot
Этот бот голосует случайно. Независимо от количества проведенных выборов (если оно достаточно высокое, например, более 100), нормализованный балл этого участника колеблется между -2 и 2.
источник
толкатель
Фолловер хочет вписаться. Он считает, что лучший способ добиться этого - голосовать так же, как и все остальные, или, по крайней мере, пока с множеством. Это разорвет узы к его собственным предпочтениям, чтобы показать немного независимости. Но не слишком много.
Примечание: я не проверял это, поэтому дайте мне знать, если есть какие-либо ошибки.
источник
Монте-Карло
Это имитирует большое количество случайных выборов. Затем он выбирает выбор, который максимизирует его собственную прибыль.
источник
StatBot
StatBot основан на ExpectantBot; однако вместо того, чтобы предполагать, что каждый голос одинаково вероятен, он собирает статистику о том, как люди голосуют, и использует ее для оценки вероятности.
источник
Лучший жизнеспособный кандидат
Довольно сильно переработанная версия моего оригинального представления. Он по-прежнему исключает всех кандидатов, которые не могут победить, учитывая оставшиеся голоса для голосования, но затем использует стратегию, которая пытается оптимизировать относительный выигрыш, а не абсолютный. Первый тест состоит в том, чтобы взять отношение моего личного вознаграждения к общему вознаграждению для каждого кандидата, ища лучшую ценность там. Затем я ищу другие коэффициенты, которые очень близки к лучшим, и, если есть коэффициент с более низким общим выигрышем, чем самый лучший, я выбираю этот коэффициент. Надеюсь, это приведет к снижению выплат других игроков, в то же время оставляя шахту достаточно высокой.
Этот бот делает почти так же хорошо, как оригинал в моем собственном тестировании, но не совсем. Мы должны увидеть, как это происходит в отношении всего поля.
источник
CircumspectBot
?оптимист
Оптимист очень оптимистичен и предполагает, что половина оставшихся избирателей проголосует за кандидата, который дает ему наилучшую отдачу.
источник
ABotDoNotForget
Его цель проста: определить общие тенденции, используя общие выплаты, и подсчитать, сколько раз выиграли нижние / средние / высшие. Затем он проголосует за того, кто наиболее вероятно выиграет.
Редактировать :
Некоторые изменения, внесенные в алгоритм решения, теперь учитывают его собственную лучшую отдачу. Должен теперь быть в состоянии голосовать лучше, когда текущее распределение заставляло его голосовать за своего Нижнего, когда другие голосовали за свои Более высокие выплаты.источник
Приам
Приам ненавидит рекурсию. Он оценивает вероятность каждого оставшегося бота на основе общих выплат, а затем рассчитывает наилучший способ максимизации его выигрыша.
Гораздо быстрее, чем Одиссей, так как нет рекурсии (время O (n ^ 2)) и может сделать миллион выборов за 15 секунд.
источник
NoClueBot
NoClue на самом деле не очень хорошо знает Java или математику, поэтому он понятия не имеет, поможет ли эта весовая пропорция ему победить. Но он пытается.
SomeClueBot
SomeClueBot был списан.
на самом деле использует логику! Он использовал логику, которая оказалась неэффективной, поэтому вместо этого он стал помнить обо всех выигрышах, а не о своей. снова использует логику! Но он не преуспевает со всеми этими последователями и оптимистами, и даже людьми, которым все равно! :)SometimesSecondBestBot
В основном PersonalFavouriteBot, улучшенный (в теории).
источник
Экстремист
Всегда голосуйте за кандидата с самой низкой выплатой
источник
SmashAttemptByEquality
Цель состоит в том, чтобы уравнять всех кандидатов, затем SMASH! все остальные боты в последнем раунде.
Это разрушительный алгоритм, который пытается обмануть всех остальных, чтобы претендовать на победу.
Обратите внимание, что это не проверено !
источник
Базовый бот
Базовый бот просто голосует за кандидатов, которые не исключены и имеют наибольшую максимальную отдачу от этих кандидатов.
источник
Фаворит Келли
Я начал с CircumspectBot, но мало что осталось. Делает своего рода скучное предположение о распределении вероятности оставшихся голосов, а затем делает выбор, который максимизирует его собственную утилиту регистрации (критерий Келли). Не самый быстрый, но в парке мячей некоторых других. Кроме того, он довольно конкурентоспособен с полем (как он стоял, когда я начал работать над этим и загрузил других ботов).
Также доступно на https://gist.github.com/jkominek/dae0b3158dcd253e09e5 на случай, если это будет проще.
источник
CommunismBot
CommunismBot считает, что мы все должны просто обойтись и выбрать кандидата, который подходит всем.
Hatebot
Hatebot всегда выбирает лучшего кандидата. Если они не грязная вонючая вечеринка 1. Эти парни ужасны.
StrategicBot
StrategicBot голосует за лучшего кандидата при условии, что они находятся в пределах одного стандартного отклонения от следующего лучшего кандидата, учитывая количество оставшихся избирателей.
источник
ExpectorBot
Пытается предсказать, как все остальные боты будут голосовать, рассчитав среднюю выплату для остальных. По умолчанию голосуют за лучшую выплату, но будут голосовать за второе место, если у него больше ожидаемых голосов, чем за лучшее, лучше, чем среднее для меня, и худшее из них имеет шанс выиграть эту вещь.
источник
LockBot
Просто одинокий философ, ищущий свое "е" ...
источник
Выиграть потерять
Если вы выиграете, я проиграю! Так просто. Так что этот бот голосует за того, кого он любит, а все остальные не любят.
источник