でこの質問、ゲームはプレイヤーは、囚人のジレンマでペアでペアオフお互いに直面する他の人に対する最高得点反復どの戦略を決定するためにここで考案されました。
で、この質問、私は複数の人が同時に互いに全てに対して囚人のジレンマを再生する方法を考案しました。このバリエーションでは、ペイオフマトリックスは不要であり、2人のプレーヤーの各ペア間の各結果は、機能的に独立した2つの決定の合計です。
あなたの仕事は、可能な限り最高のスコアを達成するマルチプレイヤーPrisoner's Dilemmaのこの対称的で一般化されたバージョンをプレイするAIを構築することです。
ゲームのルール
このマルチプレイヤー、マルチラウンドの囚人のジレンマの各ラウンドでは、プレイヤーはA
他のプレイヤーから「1」を取ることを決定できB
ます。この状況では、A
のスコアは1増加しますが、B
のスコアは2減少します。この決定は、順序付けられた各プレーヤーペア間で行われます。
これは、各プレイヤーに対して行われる唯一の決定です。他のプレイヤーから「1をテイク」するか、「テイク1」をしないかは、それぞれ離反と協力に相似です。2人の選手間の効果的なペイオフ行列P1
とP2
ルックス、次のように:
P1/P2 P1 Take1 P1 Don't
P2 Take1 -1/-1 -2/+1
P2 Don't +1/-2 0/ 0
トーナメント手順
ゲームはP * 25
ラウンドで構成されますP
。ここで、参加しているプレーヤーの数です。すべてのプレーヤーはスコアで始まり0
ます。各ラウンドは次の手順で構成されます。
ラウンドの開始時に、各プログラムには、次の形式で標準入力から以前のラウンドの履歴が与えられます。
3つの数字を含む一行、
P
、D
、とN
。P
ゲーム内のプレイヤーの総数です。各プレイヤーはランダムにID番号が割り当てられている1
とP
、ゲームの開始時に。D
現在のプレーヤーのIDです。N
プレイされたラウンドの数です。
N
行。各行はラウンドの結果を表します。の行k
にN
、スペースで区切られたいくつかn_k
の順序付きペア(a, b)
があります。これは、a
IDb
を持つプレイヤーがそのラウンドのID を持つプレイヤーから「1を奪った」ことを表します。から(2 64-1)
R
までの一様な乱数。擬似乱数シードとして機能します。これらの数値は、事前に生成されたファイルから読み取られます。このファイルは、トーナメントの終了時にリリースされるため、ユーザーは自分で結果を確認できます。0
18446744073709551615
前のラウンドでプログラムがこのような出力を生成した場合、プログラムに読み込まれる何らかの形式の状態を表す1行追加。ゲームの開始時には、この行は常に空です。この行は、スコアリングコードまたは他のプログラムによって変更されません。
各プログラムは、以下を生成するための戦略を使用する標準出力に:
K
このラウンドから「1」を取得するプログラムのIDである番号のリスト。空の出力は、何もしないことを意味します。必要に応じて、後のラウンドに渡す状態の何らかの形式を表す1つの追加行。この正確な行は、次のラウンドでプログラムにフィードバックされます。
以下は、3
4人用のゲームでIDのプレイヤーのゲームを開始するための入力例です。
4 3 0
4696634734863777023
以下は、すでにいくつかのラウンドがプレイされている同じゲームの入力例です。
4 3 2
(1, 2) (1, 3) (1, 4) (4, 2)
(1, 3) (2, 1) (2, 4) (3, 1) (4, 1)
4675881156406346380
各プログラムにはD
、各プログラムに固有のID番号を除いて、ラウンドでまったく同じ入力が与えられます。
以下は、プレーヤー3
が他の全員から1を取得する出力例です。
1 2 4
必要なすべてのラウンドの終わりに、最終スコアが最も高いプレーヤーが勝者になります。
タイムライン
このトーナメントのコーディングは、合計7日間続きます。提出期限は2014-05-09 00:00 UTC
です。
この日付より前に実際のプログラムを投稿しないでください-プログラムのソースコードのSHA256ハッシュをコミットメントとして投稿してください。このハッシュは、締め切り前であればいつでも変更できますが、締め切り後に投稿されたコミットメントは判断のために受け入れられません。(私の検証プログラムはbase 64を吐き出し、よりコンパクトな表記法なので、ハッシュにはbase 64表記を使用してください。)
期限が過ぎた後、あなたは2014-05-10 00:00 UTC
あなたの提出のためにあなたのプログラムの実際のソースコードを投稿するために1日(まで)を持っています。投稿されたソースコードのSHA256ハッシュが、締め切り前に投稿したどのハッシュとも一致しない場合、コードはトーナメントに受け入れられません。
この後、すべての提出物を自分のコンピューターにダウンロードし、このバトルロワイヤルのすべてのトーナメントエントリを実行します。できれば2日以内に結果を投稿します2014-05-12 00:00 UTC
。
最も高いスコアの回答を受け入れ、その最終スコアがより大きい場合、その回答に+100の賞金を授与し0
ます。
トーナメントが終わったら、コンテストの運営に使用するランダムシードファイルを投稿します。そして、トーナメントで使用されているものに勝つために、他のソリューションの投稿を開始するかもしれません。しかし、彼らは受け入れや報奨金の対象にはなりません。
ホストマシン
コンピューター上の仮想マシンでこれらのソリューションを実行します。この仮想マシンは、2ギガバイトのRAMを備えたUbuntu Linux 14.04を実行します。私のベースマシンには、3.40 GHzで動作するIntel i7-2600Kプロセッサが搭載されています。
必要条件
プログラムは、プログラムをコンパイルするコンパイラーまたはインタープリターが存在し、Ubuntu Linuxの最新バージョンですぐに使用できる言語で作成する必要があります。これにより、すべての提出物を実行し、仮想マシンでそれらを判断できます。
あなたのプログラムは、2.000 seconds
各ラウンドを実行するのに必要な時間を超えてはいけません。プログラムが時間切れになるか、エラーが発生した場合、そのラウンドの出力は空と見なされます。
プログラムは確定的でなければなりません。つまり、同じ入力に対して常に同じ出力を返す必要があります。擬似ランダムソリューションが許可されます。ただし、それらのランダム性は、入力として与えられたランダムシードに依存する必要があります。シードファイルはPythonを使用して生成されましたos.urandom
。合計500行(必要に応じてさらに生成されます)が含まれ、SHA256ハッシュはK+ics+sFq82lgiLanEnL/PABQKnn7rDAGmO48oiYxZk=
です。トーナメントが終了すると、ここにアップロードされます。
植物
物事を開始するために、初期のナイーブ戦略を表す4つの「植物」があります。これらはあなたの提出物とともにトーナメントでプレイされます。ただし、それらの1つが勝つというまれなケースでは、植物以外のプレーヤーが獲得した最高スコアが勝者と見なされます。
各プラントのファイルのハッシュを計算するには、4つのスペースのすべてのグループをタブに置き換えます。ここでのフォーマッターはタブ文字を好まないようです。
怠zy-何もしません。
n1bnYdeb/bNDBKASWGywTRa0Ne9hMAkal3AuVZJgovI=
pass
The Greedy —常に他の全員から1を受け取ります。
+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 —最初のラウンドで他の全員から1枚を受け取り、その後、前のラウンドで1枚を取ったすべての人から1枚を受け取ります。
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
The Envious —現在の最高スコアのプレイヤーの50%から1を取り、それ自体を切り捨てます。
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
これら4つの中100ラウンドのトーナメントでは、以下のスコアを受け取ります:
Lazy: -204
Greedy: -100
Wrathful: -199
Envious: -199
審査プログラム
Githubで使用するジャッジプログラムを投稿しました。それをダウンロードしてテストします。(バグを見つけた場合は、1つまたは2つ修正してください。:P)
現時点ではPython以外のコンパイルオプションはありません。後でそれらを含めます-他の言語のコンパイルまたは解釈スクリプトを人々が提供できるなら、私は大いに義務づけられるでしょう。
フェーズ2:ソースコードの提出
tournament
コンテストのGithubリポジトリに、pd_randファイルと他のプラントエントリを含む新しいブランチを投稿しました。ここにソースコードを投稿するか、プルリクエストとしてそのブランチに送信できます。
出場者の順番は次のとおりです。
'begrudger'
'regular'
'patient'
'lazy'
'backstab'
'bully'
'lunatic'
'envious'
'titfortat'
'greedy'
'wrathful'
'judge'
'onepercent'
最終スコア
私のテストプログラムの出力:
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
ランキング:
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
それで、勝者は確かにプレーヤーであることがわかります-それは-204ポイントで、レギュラーです!
残念ながら、そのスコアはポジティブではありませんでしたが、誰もが勝つためにプレイしているIterated Prisoner's Dilemmaのシミュレーションでは、ほとんど期待できません。
いくつかの驚くべき結果(少なくとも驚くべきことだと思った):
貪欲はTatでTitを上回り、実際、一般的にほとんどの得点者よりも高くなっています。
ジャッジは、一種の「道徳エンフォーサー」キャラクター(基本的には、平均以上の回数で誰かから1を獲得した人から1を獲得した)を意図していましたが、シミュレーションテストでは実際にスコアが高くなりました。かなり低いスコアを取得します。
そして、(私が思った)それほど驚くことではなかった他のもの:
患者は、The Wrathfulよりも484ポイント満点でした。初めて協力することは本当に有益です。
彼らがダウンしている間、1パーセントはすぐにキックする人がほとんどいませんでした。ゲームに参加しているプレイヤーの数が多いため、1%はそのようにしかとれないようです。
とにかく、トーナメントが終わったので、好きなだけ多くの追加のプレイヤーを投稿して、ジャッジプログラムを使って彼らと一緒にテストしてください。