Dalam pertanyaan ini , sebuah permainan dirancang di mana para pemain akan saling berhadapan satu sama lain secara berpasangan di Dilema Tahanan, untuk menentukan strategi berulang mana yang mencetak skor tertinggi melawan yang lain.
Dalam pertanyaan ini , saya menemukan cara bagi banyak orang untuk memainkan Dilema Tahanan satu sama lain secara bersamaan. Dalam variasi ini, matriks hasil tidak perlu, dengan setiap hasil antara setiap pasangan dari dua pemain menjadi jumlah dari dua keputusan independen yang fungsional.
Tugas Anda adalah membangun AI untuk memainkan versi Dilema Tahanan multi-pemain yang simetris dan umum ini yang akan mencapai skor setinggi mungkin.
Aturan main
Di setiap putaran multipemain ini, Dilema Tahanan multi-putaran, seorang pemain A
dapat memutuskan untuk "mengambil 1" dari beberapa pemain lain B
. Dalam keadaan ini, A
skor meningkat sebesar 1, sedangkan B
skor menurun sebesar 2. Keputusan ini diperbolehkan terjadi antara setiap pasangan pemain yang dipesan.
Ini adalah satu-satunya keputusan yang dibuat untuk masing-masing pemain - baik untuk "mengambil 1" atau tidak "mengambil 1" dari masing-masing pemain lain, yang homolog dengan pembelotan dan kerjasama masing-masing. Matriks hasil efektif antara dua pemain P1
dan P2
terlihat sebagai berikut:
P1/P2 P1 Take1 P1 Don't
P2 Take1 -1/-1 -2/+1
P2 Don't +1/-2 0/ 0
Prosedur Turnamen
Permainan akan terdiri dari P * 25
putaran, di mana P
jumlah pemain yang berpartisipasi. Semua pemain mulai dengan skor 0
. Setiap putaran terdiri dari prosedur berikut:
Pada awal putaran, setiap program akan diberi riwayat putaran sebelumnya dari input standar , dalam format berikut:
Salah satu baris yang berisi 3 nomor,
P
,D
, danN
.P
adalah jumlah total pemain dalam game. Setiap pemain secara acak diberi nomor ID dari1
hinggaP
di awal permainan.D
adalah ID pemain saat ini.N
adalah jumlah putaran yang telah dimainkan.
N
garis, masing-masing garis mewakili hasil putaran. On linek
ofN
, akan ada beberapa jumlahn_k
pasangan memerintahkan(a, b)
, dipisahkan oleh spasi, yang menyatakan bahwa pemain dengan IDa
"mengambil 1" dari pemain dengan IDb
di babak itu.Nomor acak seragam
R
dari0
ke18446744073709551615
(2 64 - 1), untuk bertindak sebagai seed pseudorandom. Angka-angka ini akan dibaca dari file yang dibuat sebelumnya, yang akan dirilis pada akhir turnamen sehingga orang dapat memverifikasi hasilnya sendiri.Satu baris tambahan yang mewakili beberapa bentuk keadaan untuk dibaca ke dalam program Anda, jika program Anda menghasilkan output seperti itu di babak sebelumnya. Di awal permainan, baris ini akan selalu kosong. Baris ini tidak akan dimodifikasi oleh kode penilaian atau program lain.
Setiap program kemudian akan menggunakan strateginya untuk menghasilkan yang berikut ke output standar :
Daftar
K
angka, yang merupakan ID program yang akan "diambil 1" dari babak ini. Output kosong berarti tidak akan melakukan apa-apa.Secara opsional, satu baris tambahan yang mewakili beberapa bentuk negara untuk diteruskan ke putaran selanjutnya. Baris persis ini akan diumpankan kembali ke program di babak berikutnya.
Di bawah ini adalah contoh input untuk permulaan gim untuk pemain ID 3
dalam gim 4-pemain:
4 3 0
4696634734863777023
Di bawah ini adalah contoh input untuk game yang sama dengan beberapa putaran yang sudah dimainkan:
4 3 2
(1, 2) (1, 3) (1, 4) (4, 2)
(1, 3) (2, 1) (2, 4) (3, 1) (4, 1)
4675881156406346380
Setiap program akan diberi input yang sama persis untuk satu putaran kecuali untuk nomor ID D
yang unik untuk setiap program.
Di bawah ini adalah contoh output di mana pemain 3
mengambil 1 dari orang lain:
1 2 4
Di akhir semua putaran yang diperlukan, pemain dengan skor akhir tertinggi akan menjadi pemenang.
Linimasa
Pengkodean untuk turnamen ini akan berlangsung selama 7 hari. Batas waktu pengiriman adalah 2014-05-09 00:00 UTC
.
Jangan memposting program aktual sebelum tanggal ini - memposting hash SHA256 dari kode sumber program Anda sebagai komitmen. Anda dapat mengubah hash ini kapan saja sebelum batas waktu, tetapi komitmen yang dipasang setelah batas waktu tidak akan diterima untuk penilaian. (Silakan gunakan notasi base 64 untuk hash Anda, karena program verifikasi saya mengeluarkan basis 64 dan ini notasi yang lebih kompak.)
Setelah batas waktu berakhir, Anda memiliki 1 hari (hingga 2014-05-10 00:00 UTC
) untuk memposting kode sumber aktual program Anda untuk pengiriman Anda. Jika hash SHA256 dari kode sumber Anda yang diposkan tidak cocok dengan hash apa pun yang Anda poskan sebelum batas waktu, kode Anda tidak akan diterima ke dalam turnamen.
Setelah ini, saya akan mengunduh semua kiriman ke komputer saya sendiri, dan menjalankan semua entri turnamen di battle royale ini, semoga memposting hasilnya dalam waktu 2 hari sejak saat itu, oleh 2014-05-12 00:00 UTC
.
Saya akan menerima jawaban dengan skor tertinggi, dan memberikan hadiah +100 untuk jawaban itu jika skor akhirnya lebih besar dari 0
.
Setelah turnamen selesai, saya akan memposting file seed acak yang digunakan untuk menjalankan kompetisi, dan orang-orang dapat mulai memposting solusi lain yang mencoba untuk mengatasi yang digunakan dalam turnamen. Namun, mereka tidak akan menghitung penerimaan atau hadiah.
Mesin Host
Saya akan menjalankan solusi ini pada mesin virtual di komputer saya. Mesin virtual ini akan menjalankan Ubuntu Linux 14.04, dengan 2 gigabytes RAM. Mesin dasar saya memiliki prosesor Intel i7-2600K yang berjalan pada 3,40 GHz.
Persyaratan
Program Anda harus ditulis dalam bahasa yang kompiler atau juru bahasa yang akan mengkompilasi program Anda ada dan sudah tersedia untuk versi terbaru Ubuntu Linux, sehingga saya dapat menjalankan semua pengiriman dan menilai mereka dalam mesin virtual.
Program Anda tidak boleh lebih dari 2.000 seconds
menjalankan setiap putaran. Jika program Anda kehabisan waktu atau menghasilkan kesalahan, hasilnya akan dianggap kosong untuk putaran itu.
Program Anda harus bersifat deterministik; artinya, ia harus selalu mengembalikan output yang sama untuk input yang sama. Solusi pseudorandom diizinkan; Namun, keacakan mereka harus bergantung pada seed acak yang diberikan padanya sebagai input dan bukan yang lain. File seed dihasilkan menggunakan Python os.urandom
. Ini berisi total 500 baris (lebih banyak akan dihasilkan jika perlu), dan hash SHA256-nya adalah K+ics+sFq82lgiLanEnL/PABQKnn7rDAGmO48oiYxZk=
. Ini akan diunggah di sini setelah turnamen selesai.
Tanaman
Untuk memulai, akan ada empat "tanaman", yang mewakili strategi naif awal. Ini akan diputar di turnamen bersama dengan kiriman Anda. Namun, jika salah satu dari mereka menang, skor tertinggi yang diperoleh pemain selain tanaman akan dianggap sebagai pemenang.
Untuk menghitung hash dari setiap file tanaman, ganti setiap grup dengan 4 spasi dengan tab, karena pemformat di sini sepertinya tidak menyukai karakter tab.
Malas - tidak pernah melakukan apa pun.
n1bnYdeb/bNDBKASWGywTRa0Ne9hMAkal3AuVZJgovI=
pass
The Greedy - selalu mengambil 1 dari orang lain.
+k0L8NF27b8+Xf50quRaZFFuflZhZuTCQOR5t5b0nMI=
import sys
line1 = sys.stdin.readline()
n = [int(i) for i in line1.split()]
for i in range(n[0]):
if i+1 != n[1]:
print i+1,
print
The Wrathful - mengambil 1 dari semua orang di ronde pertama, dan mengambil 1 dari semua orang yang mengambil 1 dari ronde sebelumnya sesudahnya.
Ya2dIv8TCh0zWzRfzUIdFKWj1DF9GXWhbq/uN7+CzrY=
import sys
import re
line1 = [int(i) for i in sys.stdin.readline().split()]
players = line1[0]
pid = line1[1]
rounds = line1[2]
lines = []
if rounds == 0:
for i in range(players):
if i+1 != pid:
print i+1,
print
else:
for i in range(rounds):
lines.append(sys.stdin.readline())
lastline = lines[-1]
takes = re.findall(r'\([0-9]+, [0-9]+\)', lastline)
for take in takes:
sides = [int(i) for i in re.findall(r'[0-9]+', take)]
if sides[1] == pid:
print sides[0],
print
Envy - mengambil 1 dari 50% pemain dengan skor tertinggi saat ini tidak termasuk dirinya sendiri, dibulatkan ke bawah.
YhLgqrz1Cm2pEcFlsiIL4b4MX9QiTxuIOBJF+wvukNk=
import sys
import re
line1 = [int(i) for i in sys.stdin.readline().split()]
players = line1[0]
pid = line1[1]
rounds = line1[2]
lines = []
scores = [0] * players
if rounds == 0:
for i in range(players):
if i+1 != pid:
print i+1,
print
else:
for i in range(rounds):
takes = re.findall(r'\([0-9]+, [0-9]+\)', sys.stdin.readline())
for take in takes:
sides = [int(i) for i in re.findall(r'[0-9]+', take)]
scores[sides[0] - 1] += 1
scores[sides[1] - 1] -= 2
score_pairs = [(i+1, scores[i]) for i in range(players)]
score_pairs.sort(key=lambda x:(x[1], x[0]))
score_pairs.reverse()
taken = 0
j = 0
while taken < (players) / 2:
if score_pairs[j][0] != pid:
print score_pairs[j][0],
taken += 1
j += 1
Dalam turnamen 100 putaran hanya di antara empat putaran ini, mereka menerima skor dari:
Lazy: -204
Greedy: -100
Wrathful: -199
Envious: -199
Program Penjurian
Saya telah memposting program juri yang akan saya gunakan di Github . Unduh dan uji. (Dan mungkin memperbaiki satu atau dua bug jika Anda menemukannya.: P)
Itu tidak memiliki opsi kompilasi untuk apa pun selain Python saat ini. Saya akan memasukkannya nanti - jika orang dapat berkontribusi dalam kompilasi atau naskah interpretasi untuk bahasa lain, saya akan sangat berkewajiban.
Fase 2: Pengajuan Kode Sumber
Saya telah memposting cabang baru tournament
ke repositori Github untuk kontes, yang berisi file pd_rand dan entri instalasi lainnya. Anda dapat memposting kode sumber Anda di sini atau mengirimkannya ke cabang itu sebagai permintaan tarik.
Urutan para kontestan adalah sebagai berikut:
'begrudger'
'regular'
'patient'
'lazy'
'backstab'
'bully'
'lunatic'
'envious'
'titfortat'
'greedy'
'wrathful'
'judge'
'onepercent'
Skor Akhir
Output dari program pengujian saya:
Final scores:
begrudger -2862
regular -204
patient -994
lazy -2886
backstab -1311
bully -1393
lunatic -1539
envious -2448
titfortat -985
greedy -724
wrathful -1478
judge -365
onepercent -1921
Peringkat:
1. regular -204
2. judge -365
3. greedy -724
4. titfortat -985
5. patient -994
6. backstab -1311
7. bully -1393
8. wrathful -1478
9. lunatic -1539
10. onepercent -1921
11. envious -2448
12. begrudger -2862
13. lazy -2886
Jadi ternyata pemenangnya adalah seorang pemain - ini adalah The Reguler, dengan -204 poin!
Sayangnya, nilainya tidak positif, tetapi kita tidak bisa berharap bahwa dalam simulasi Dilema Tahanan Iterated di mana semua orang bermain untuk menang.
Beberapa hasil mengejutkan (setidaknya yang saya pikir mengejutkan):
The Greedy mencetak lebih dari Tit untuk Tat, dan pada kenyataannya, umumnya lebih tinggi daripada kebanyakan pencetak gol sama sekali.
Hakim, yang dimaksudkan untuk menjadi semacam karakter "penegak moralitas" (pada dasarnya mengambil 1 dari siapa pun yang mengambil 1 dari siapa pun jumlah rata-rata di atas) berakhir dengan penilaian yang agak tinggi, sementara dalam pengujian simulasi, itu sebenarnya akan dapatkan skor yang agak rendah.
Dan yang lain yang (saya pikir) tidak begitu mengejutkan:
The Patient mencetak 484 poin lebih banyak dari The Wrathful. Sangat bermanfaat untuk bekerja sama untuk pertama kalinya.
Satu Persen dengan sangat cepat hampir tidak ada yang menendang saat mereka turun. Tampaknya 1% hanya bisa tetap seperti itu karena mereka memiliki lebih banyak pemain dalam permainan.
Ngomong-ngomong, sekarang setelah turnamen selesai, jangan ragu untuk mengirim sebanyak mungkin pemain tambahan, dan coba-coba dengan mereka menggunakan program juri.
sumber
Jawaban:
Biasa
Versi entri ini saya pilih untuk turnamen (SHA-256 :)
ggeo+G2psAnLAevepmUlGIX6uqD0MbD1aQxkcys64oc=
menggunakan Joey 's " strategi " Pengisap acak (walaupun dengan perubahan kecil dan kemungkinan tidak signifikan), yang berada di posisi kedua dalam kontes terakhir. Sayangnya, versi yang lebih baru dan lebih efektif dikirimkan hanya 3 menit 25 detik sebelum batas waktu memiliki bug yang serius, sehingga tidak dapat digunakan. Namun demikian, versi ini masih relatif baik.Versi buggy memiliki hash SHA-256
2hNVloFt9W7/uA5aQXg+naG9o6WNmrZzRf9VsQNTMwo=
:Untuk memperbaikinya, lakukan penggantian ini:
$hashOutput = rtrim(fgets(STDIN), "\n");
dengan$line .= fgets(STDIN);
(bukan itu yang benar-benar penting).if ($betterScore >= 3 * $myScore) {
denganif ($betterScore >= 0.5 * $myScore && !psRand(0, $betterPlayer)) {
(inilah yang membunuhnya).sumber
Satu persen
Memandang rendah tahanan-tahanan yang dia pertimbangkan di bawahnya.
Cukup mengambil dari setiap orang yang memiliki poin kurang dari atau sama dengan dirinya sendiri. Asumsinya adalah bahwa para tahanan itu cenderung tidak menerima balasan (atau mereka akan mendapatkan lebih banyak). Saya tidak tahu seberapa bagus asumsi itu, tetapi itulah yang sedang dia lakukan.
Juga mengambil dari semua orang di babak terakhir. Tidak ada kerugian untuk ini, karena tidak ada yang bisa membalas dendam setelah itu.
Jika Anda memiliki masalah dalam mendapatkan hash karena tab / spasi dari kode yang disisipkan, inilah tautan ke file itu sendiri.
sumber
05-09 00:00
batas waktu.Berikut adalah beberapa pabrik lagi yang akan berpartisipasi dalam permainan. Yang ini lebih maju, dan kode sumbernya tidak akan terungkap sampai akhir fase pengkodean.
Sama seperti empat pabrik dalam pertanyaan, jika mereka berhasil mencetak skor lebih tinggi dari semua pemain lain, hanya skor tertinggi yang dicapai oleh kontestan yang sebenarnya akan dianggap sebagai pemenang.
Si pengganggu
29AGVpvJmDEDI5Efe/afmMJRLaJ+TpjwVcz1GkxgYZs=
Pilihan pada orang-orang.
Hakim
yjdCQ3uQ4YKe7xAKxdTFLF4d72fD4ACYpDLwkbzdISI=
Menghukum orang yang bersalah.
Orang gila
m3FsRPocekCcK6GDswgnobV2CYOxX8LquChnKxrx1Wo=
Tidak tahu apa yang dilakukannya.
Pasien
nd7Pt3bVpFnuvDVeHQ5T9EPTq7KjNraVzp/KGtI73Vo=
Tidak pernah melakukan langkah pertama.
sumber
Gayung-untung
Mirip dengan Wrathful, dengan beberapa (semoga) perubahan peningkatan kinerja.
sumber
Backstab
Python 3
Terlepas dari namanya, bot ini sebenarnya cukup ramah. Tapi jangan mencentangnya.
EDIT 2 : Sumber yang diposting. Yay.
EDIT : Setelah beberapa pengujian saya memperbaiki beberapa kekurangan yang saya temukan. Mereka tidak algoritmik, hanya beberapa masalah membaca input.
sumber
Itu Begrudger
Kode
Saya akan mengakui bahwa saya tidak menghabiskan banyak waktu untuk ini ...
sumber
o += a.split(', ')[0]
tidak menyisakan ruang di antara angka-angka.