W tym wyzwaniu zmierzysz się z hałaśliwym, powtarzającym się dylematem więźnia.
W dylemat więźnia jest scenariusz, w teorii gier, gdzie istnieją dwa graczy, każdy z dwóch opcji: współpracuje lub wada. Każdy gracz radzi sobie lepiej, jeśli ma wadę, niż gdyby współpracował, ale obaj gracze wolą wynik, w którym obaj gracze współpracują, niż ten, w którym obaj grają.
Dylemat iterowanego więźnia to ta sama gra, tyle że wielokrotnie grasz przeciwko temu samemu przeciwnikowi i wiesz, w co grał Twój przeciwnik w przeszłości. Twoim celem jest zawsze zdobycie jak najwyższego wyniku, niezależnie od tego, jak robi to twój przeciwnik.
Hałaśliwy iterowany dylemat więźnia wprowadza pewne zakłócenia w komunikacji. Twoja wiedza o tym, w co grał Twój przeciwnik w przeszłości, wprowadzi trochę hałasu. Dowiesz się również, jakie ruchy wykonałeś w przeszłości. Poziom hałasu jest stały w trakcie rundy przeciwko temu samemu przeciwnikowi, ale różny dla różnych rund.
Wyzwanie
W tym wyzwaniu napiszesz program w języku Python 3, który rozwiąże dylemat hałaśliwego iterowanego więźnia.
Twój program otrzyma trzy dane wejściowe:
Twoje własne ruchy, bez losowych rzutów.
Ruchy przeciwnika, z zastosowaniem losowych rzutów.
Zmienna stanu, która zaczyna się jako pusta lista w każdej rundzie i którą możesz zmodyfikować, jeśli chcesz. Możesz to zignorować, jeśli nie chcesz go używać.
Twój program powinien wysyłać dane 'c'
do współpracy lub 'd'
do defektu.
Na przykład, oto program, który współpracuje, jeśli przeciwnik współpracował przez co najmniej 60% czasu w przeszłości, po zastosowaniu losowych rzutów i dla pierwszych 10 rzutów:
def threshold(my_plays, their_flipped_plays, state):
if len(their_flipped_plays) < 10:
return 'c'
opp_c_freq = their_flipped_plays.count('c')/len(their_flipped_plays)
if opp_c_freq > 0.6:
return 'c'
else:
return 'd'
Jeśli nie znasz języka Python, napisz swoje zgłoszenie w pseudokodzie, a ktoś (ja lub inny członek witryny) może utworzyć odpowiedni program w języku Python.
Rozgrywka
Turniej można znaleźć tutaj: noisy-game . Uruchom, noisy-game.py
aby uruchomić turniej. Będę aktualizować to repozytorium o nowe zgłoszenia. Przykładowe programy można znaleźć w basic.py
.
Ogólny wynik programu to suma jego wyników w ponad 100 grach.
Gra składa się z pojedynczych rund każdego gracza przeciwko każdemu graczowi, w tym sobie. Pojedynek składa się ze 100 rund. Runda składa się z 300 ruchów, z których każdy wymaga wykonania 'c'
lub 'd'
.
Twoje zgłoszenie spowoduje rozegranie pojedynku z każdym zgłoszeniem, w tym własnym. Każdy pojedynek będzie się składał ze 100 rund. Podczas każdej rundy prawdopodobieństwo odwrócenia będzie losowo wybierane równomiernie [0, 0.5]
.
Każda runda będzie się składać z 300 ruchów. Przy każdym ruchu oba programy otrzymają wszystkie poprzednie odtworzenia, które próbowały, i wszystkie poprzednie odtworzenia, które wykonał drugi program, po zastosowaniu odwrotności, oraz zmienną stanu, która jest zmienną listą, którą program może modyfikować, jeśli chce. Programy wygenerują swoje ruchy.
Ruchy są punktowane w następujący sposób: Jeśli program zagra 'c'
, program przeciwny otrzymuje 2 punkty. Jeśli jakiś program gra 'd'
, ten program otrzymuje 1 punkt.
Następnie każdy ruch jest odwracany niezależnie z prawdopodobieństwem równym prawdopodobieństwu przewrócenia i zapisywany do pokazania przeciwnikowi.
Po rozegraniu wszystkich rund sumujemy liczbę punktów, jaką każdy gracz otrzymał w każdym pojedynku. Następnie wykorzystujemy następujący system punktacji do obliczenia wyniku każdego gracza w grze. Ta punktacja jest przeprowadzana po zakończeniu wszystkich pojedynków.
Punktacja
Wykorzystamy ewolucyjną punktację. Każdy program zaczyna się od równej wagi. Następnie wagi są aktualizowane w następujący sposób, dla 100 iteracji, z wykorzystaniem sum punktowych z gry:
Nowa waga każdego programu jest proporcjonalna do iloczynu jego poprzedniej wagi i jego średniej sumy punktów, ważonej wagami przeciwników.
Zastosowano 100 takich aktualizacji, a ostateczne wagi są wynikiem każdego programu dla tego przebiegu gry.
Ogólne wyniki będą sumą ponad 100 przebiegów gry.
Gracze otrzymają wszystkie prawidłowe odpowiedzi na to wyzwanie oraz sześć podstawowych programów, które pomogą nam zacząć.
Ostrzeżenia
Nie modyfikuj wejść. Nie próbuj wpływać na wykonanie jakiegokolwiek innego programu, z wyjątkiem współpracy lub uszkodzenia. Nie składaj ofiarnego poddania się, które usiłuje rozpoznać kolejne poddanie się i przynieść korzyści przeciwnikowi na własny koszt. Standardowe luki są zabronione.
EDYCJA: Zgłoszenia nie mogą dokładnie powielać żadnego z podstawowych programów ani żadnego wcześniejszego zgłoszenia.
Jeśli masz jakieś pytania, możesz je zadać.
Aktualne wyniki
nicht_genug: 40.6311
stealer: 37.1416
enough: 14.4443
wait_for_50: 6.947
threshold: 0.406784
buckets: 0.202875
change_of_heart: 0.0996783
exploit_threshold: 0.0670485
kickback: 0.0313357
tit_for_stat: 0.0141368
decaying_memory: 0.00907645
tit_for_whoops: 0.00211803
slider: 0.00167053
trickster: 0.000654875
sounder: 0.000427348
tit_for_tat: 9.12471e-05
stubborn_stumbler: 6.92879e-05
tit_for_time: 2.82541e-05
jedi2sith: 2.0768e-05
cooperate: 1.86291e-05
everyThree: 1.04843e-05
somewhat_naive: 4.46701e-06
just_noise: 1.41564e-06
growing_distrust: 5.32521e-08
goldfish: 4.28982e-09
vengeful: 2.74267e-09
defect: 3.71295e-10
alternate: 2.09372e-20
random_player: 6.74361e-21
Wyniki zawierające tylko odpowiedzi na to pytanie i podstawowe programy, które ignorują grę przeciwnika:
nicht_genug: 39.3907
stealer: 33.7864
enough: 20.9032
wait_for_50: 5.60007
buckets: 0.174457
kickback: 0.0686975
change_of_heart: 0.027396
tit_for_stat: 0.024522
decaying_memory: 0.0193272
tit_for_whoops: 0.00284842
slider: 0.00153227
sounder: 0.000472289
trickster: 0.000297515
stubborn_stumbler: 3.76073e-05
cooperate: 3.46865e-05
tit_for_time: 2.42263e-05
everyThree: 2.06095e-05
jedi2sith: 1.62591e-05
somewhat_naive: 4.20785e-06
just_noise: 1.18372e-06
growing_distrust: 6.17619e-08
vengeful: 3.61213e-09
goldfish: 3.5746e-09
defect: 4.92581e-10
alternate: 6.96497e-20
random_player: 1.49879e-20
Zwycięski
Konkurs będzie otwarty przez czas nieokreślony, ponieważ publikowane będą nowe zgłoszenia. Ogłaszam jednak zwycięzcę (akceptuję odpowiedź) na podstawie wyników 1 miesiąc po opublikowaniu tego pytania.
źródło
exploit_threshold()
kilka razy jakoexploit_threshold1()
itp. i dodałem je doplayers
listy. Dlaczego otrzymuję bardzo różne wyniki dla identycznych strategii?Odpowiedzi:
Genug ist nicht genug
(można również nazwać
enough2
lubstealback
)Dowiedziałem się, że oryginalne sikory na dwa taty tak samo czekały na dwa kolejne taty
tit_for_whoops
, i wydaje się, że powinniśmy wybaczyć i zapomnieć (no prawie ...) wcześniejsze pojedyncze taty. I wielu graczy ucieka w ostatnich rundach. Nadal wolę być miły, gdy do tej pory wszystko było w porządku, ale pasek tolerancji bota wciąż spada.źródło
Tit-For-Whoops
Inspirowany strategią z ncase.me/trust
Wady tylko wtedy, gdy drugi gracz pokonał dwa razy z rzędu, aby uniknąć nieporozumień.
źródło
Zmiana zdania
W międzyczasie zmienia się serce. Zaskakująco dobrze.
źródło
Stealer strategiczny
Zainspirowany wystarczającą ilością, change_of_heart i tit-for-whoops. Powinien być trochę bardziej wyrozumiały. Próbowałem podkręcić liczby, aby uzyskać najlepsze wyniki, ale nie chcieli wiele zmienić.
źródło
Tit-For-Time
Jeśli spędzasz większość czasu raniąc mnie, po prostu cię zranię. Prawdopodobnie.
źródło
Rosnąca nieufność
Im bardziej przeciwnik mnie zdradza, tym mniej mogę ufać, że to tylko hałas.
źródło
state
argument, że domyślnie jest to lista? Listy są zmienne, więc stan można łatwo modyfikować.Jedi2Sith
Zaczyna wszystko ładnie i bezinteresownie, ale z czasem wpływ ciemnej strony staje się coraz silniejszy, aż do momentu bez powrotu. Nie można powstrzymać tego wpływu, ale wszystkie złe rzeczy, które widzi, tylko przyczyniają się do potęgi ciemnej strony ...
Wypróbuj online!
źródło
Suwak
Zaczyna się od „c” i stopniowo przesuwa się w kierunku lub od „d”.
źródło
Uparty Stumbler
Oparte na strategii progu wykorzystywania, tylko spójne gry śledzone w celu przełączania między defektami a przeważnie współpracą
AKTUALIZACJA: Śledzi zarówno dwie kolejne, jak i trzy kolejne gry, karając tylko w trudniejszych warunkach i dodając losowy wybór, gdy nie ma pewności
AKTUALIZACJA 2: Usunięto warunek i dodano funkcję dystrybucji
źródło
Hałas Bot
Jestem zdecydowanie współpracującym botem. To tylko hałas.
źródło
Wystarczy, wystarczy
Zaczyna się jako tit dla dwóch tatów, w których dwa taty nie muszą być kolejne (w przeciwieństwie do
tit_for_whoops
). Jeśli grad
zbyt często, gra sięd
suma.źródło
Goldfish Bot
Złota rybka nigdy nie wybacza, ale szybko zapomina.
źródło
źródło
Rozkładająca się pamięć
Więcej waży najnowszą historię. Powoli zapomina się o przeszłości.
źródło
Odrzut
Niektóre niejasne pomysły ...
źródło
Naprawdę nie odbiera całej „szumowej” rzeczy
Nigdy nie wybacza zdrajcy.
źródło
sonda ultradźwiękowa:
edycja: dodano odwet w prawdopodobnie cichych scenariuszach
Zasadniczo, jeśli wszystkie 4 pierwsze ruchy są ze sobą zgodne, oznacza to, że powinniśmy oczekiwać mniejszego hałasu niż zwykle. co jakiś czas co nieco defektuje, aby zrekompensować sobie mniej punktów, które uzyskalibyśmy od braku defektów i aby można było za to winić hałas. my również podejmiemy działania odwetowe, jeśli będą one wady przeciwko nam
jeśli nasz przeciwnik ma dużo defektów w tych turach (2 lub więcej), po prostu odpuszczamy. gdyby był to tylko hałas, hałas i tak wpłynąłby na nasze ruchy.
w przeciwnym razie, jeśli tylko 1 ruch byłby wadliwy, wykonujemy proste sikanie dla tat przez resztę gry.
źródło
Alternatywny
Wybiera losowo w pierwszej rundzie, a następnie zmienia się. Zawsze defekty w ostatnich 10 rundach.
źródło
Poczekaj na 50
Po 50 defektach pozwól im je mieć!
źródło
Somehwat naiwny
Zakładam tylko, że jeśli w ostatnich n zakrętach zmniejszyłeś prawdopodobieństwo przewrócenia (z grubsza) , był to hałas, a nie to, że jesteś podły!
Nie znalazłem najlepszego n , może przyjrzeć się temu dalej.
źródło
Co trzy
Niezależnie od wad co trzy obroty. Uszkadza również ostatnie 50 tur. Wada także, jeśli jego przeciwnik pokonał 4 z 5 ostatnich rund.
źródło
Wiadra
Miło jest zacząć. Patrzy na ich ostatnie 20, jeśli <25% d, zwraca c,> 75% d, zwraca d, a pomiędzy wybiera losowo wzdłuż funkcji prawdopodobieństwa liniowego. Ostatnie 50, wady. Miałem to co najmniej 10, ale widziałem wiele ostatnich 50 wad.
Po raz pierwszy tutaj, więc daj mi znać, czy coś trzeba naprawić (lub jak mogę to przetestować).
źródło
players
aby uzyskać szybkie iteracje.Tit-For-Stat
Wady, jeśli przeciwnik wykonał więcej niż połowę czasu.
źródło