これは、フォートナイトリーチャレンジ#3です。テーマ:遺伝的アルゴリズム
この挑戦はちょっとした実験です。私たちは、遺伝的アルゴリズムを使用して、挑戦的に何ができるかを見たかったのです。すべてが最適であるとは限りませんが、アクセスできるように最善を尽くしました。これがうまくいけば、誰が私たちが将来見るかもしれないことを知っています。おそらく遺伝的なキングオブザヒルですか?
仕様は非常に長いです!仕様をThe Basics(フレームワークでプレイを開始し、回答を送信するために知っておく必要のある最低限)と、The Gory Details-コントローラーに関するすべての詳細を含む完全な仕様に分割しようとしました。自分で書くことができます。
ご質問がある場合は、お気軽にチャットに参加してください!
あなたは行動心理学の研究者です。金曜日の夕方、あなたと同僚は楽しい時間を過ごし、実験用のネズミを小さなネズミのレースに使用することにしました。実際、私たちが感情的になりすぎる前に、それらを標本と呼びましょう。
標本用の小さなレーストラックを設定しました。さらに面白くするために、トラック全体にいくつかの壁とトラップとテレポーターを配置しました。今、あなたの標本はまだネズミです...彼らはトラップやテレポーターが何であるかを知りません。彼らが見るのは、色の違うものだけです。彼らはまた、どんな種類の記憶も持っていません-彼らができることは、彼らの現在の環境に基づいて決定を下すことだけです。自然選択は、そうでないものからのtrapを避ける方法を知っている標本を選ぶと思います(この種族はしばらく時間がかかります...)。ゲームを始めよう!†
†84,465個の標本がこの課題の作成で被害を受けました。
基礎
これはシングルプレイヤーゲームです(あなたと同僚は人口を混同したくないので、それぞれが独自のレーストラックを構築しました)。レーストラックは、高さ15セル、幅50セルの長方形のグリッドです。左端(ここでx = 0)のランダム(必ずしも別個ではない)セルの15個の標本から始めます。あなたの標本は、任意の細胞である目標到達しようとする必要があり、X≥49と14≤Y≤0を(標本が右にトラックをオーバーシュートがあります)。これが起こるたびに、あなたはポイントを獲得します。また、1ポイントでゲームを開始します。10,000ターン後にポイントを最大化するようにしてください。
複数の標本が同じセルを占有する場合があり、相互作用しません。
各ターンで、各標本は周囲の5x5グリッド(中央にある)を見ます。そのグリッドの各セルにはの色が含ま-1
れ15
ます。-1
境界外のセルを表します。標本が範囲外に移動すると、標本は死にます。他の色については、空のセル、トラップ、壁、テレポーターを表します。しかし、あなたの標本はどの色が何を表しているのか分からず、あなたもそうではありません。ただし、いくつかの制約があります。
- 8色は空のセルを表します。
- 4色はテレポーターを表します。テレポーターは、9x9エリア内の特定のセルに標本を送ります。このオフセットは、同じ色のすべてのテレポーターで同じです。
- 2色が壁を表します。壁に移動することは、じっと立っているのと同じです。
- 2色はトラップを表します。トラップは、すぐ近くにある9 つのセルの1つが致命的であることを示します(トラップセル自体である必要はありません)。このオフセットは、同じ色のすべてのトラップで同じになります。
さて、その自然選択について...各標本にはゲノムがあり、それは100ビットの数字です。新しい標本は、2つの既存の標本を交配し、ゲノムをわずかに変異させることによって作成されます。標本が成功すればするほど、繁殖の可能性が大きくなります。
ここにあなたのタスクがあります:標本が見る色の5x5グリッドとそのゲノムを入力として受け取る単一の関数を書きます。関数は、標本の移動(Δx、Δy)を返し{-1, 0, 1}
ます。ここで、ΔxとΔyはそれぞれの1つです。関数呼び出し間でデータを永続化しないでください。これには、独自の乱数ジェネレーターの使用が含まれます。関数にはシードされたRNGが提供され、必要に応じて自由に使用できます。
提出のスコアは、50のランダムトラック全体のポイント数の幾何平均です。このスコアにはかなりのばらつきがあることがわかりました。したがって、これらのスコアは暫定的なものです。この課題が終了すると、締め切りが発表されます。締め切りの終わりに、100のボードがランダムに選ばれ、すべての提出物がこれらの100のボードで採点されます。推定スコアを回答に自由に入力してください。ただし、だれもチートしないように、すべての提出物にスコアを付けます。
コントローラープログラムは少数の言語で提供されています。現在、Python(2または3)、Ruby、C ++、C#またはJavaで提出物を書くことができます。コントローラーはボードを生成し、ゲームを実行し、遺伝的アルゴリズムのフレームワークを提供します。必要なのは、移動機能を提供することだけです。
待って、それではゲノムを使って正確に何をしますか?
課題はそれを理解することです!
標本には記憶がないため、与えられたターンで得られるのは、あなたにとって何の意味もない5x5の色のグリッドだけです。そのため、目標を達成するにはゲノムを使用する必要があります。一般的な考え方は、ゲノムの一部を使用して色またはグリッドレイアウトに関する情報を保存し、ボットはゲノムに保存されている追加情報に基づいて決定を下すというものです。
もちろん、手動で何かを実際に保存することはできません。したがって、そこに保存される実際の情報は、最初は完全にランダムになります。しかし、遺伝的アルゴリズムは間もなく、ゲノムに正しい情報が含まれる標本を選択し、間違った情報を持つ標本を殺します。目標は、ゲノムビットと視野から移動へのマッピングを見つけることです。これにより、目標へのパスを迅速に見つけ、一貫して勝利戦略に進化することができます。
これは、開始するのに十分な情報である必要があります。必要に応じて、次のセクションをスキップして、下部のコントローラーのリストから選択するコントローラーを選択できます(特定のコントローラーの使用方法に関する情報も含まれています)。
すべてが必要な場合は読んでください...
ゴーリーの詳細
この仕様は完全です。すべてのコントローラーはこれらのルールを実装する必要があります。
特に明記しない限り、すべてのランダム性は均一な分布を使用します。
トラック生成:
- トラックは、X = 53セル幅、Y = 15セル高さの長方形のグリッドです。有する細胞のx≥49は、ある目標セル(ここで、xはゼロベースです)。
- 各セルは単一の色を有し、またはあってもなくてもよい致死 -以下の細胞型のいずれかで指定されない限り、細胞は致死的ではありません。
- からまでラベル付けされた16の異なるセルの色があり、その意味はゲームごとに変わります。さらに、境界外のセルを表します-これらは致命的です。
0
15
-1
- 8つのランダムな色を選択します。これらは空のセルになります(効果はありません)。
- さらに4つのランダムな色を選択します。これらはテレポーターです。これらの2つの色について、9x9近傍のゼロ以外のオフセットを選択します((-4、-4)から(0,0)を除く(4,4)まで)。他の2色については、それらのオフセットを反転します。標本がテレポーターに乗ると、そのオフセット分だけすぐに移動します。
- さらに2つのランダムな色を選択します。これらはトラップです。これらの各色について、3x3近傍のオフセットを選択します((-1、-1)から(1,1)まで)。トラップは、そのオフセットのセルが致命的であることを示します。注:トラップセル自体は必ずしも致命的ではありません。
- 残りの2色は壁で、動きを妨げます。壁のセルに移動しようとすると、移動が静止したままになります。壁細胞自体は致命的です。
- グリッドの非目標セルごとに、ランダムな色を選択します。各ゴールセルに対して、ランダムな空の色を選択します。
- トラックの左端にある各セルについて、100ターン以内に目標に到達できるかどうかを決定します(以下のターン順序規則に従って)。その場合、このセルは許容可能な開始セルです。開始セルが10未満の場合は、トラックを破棄して新しいセルを生成します。
- 15個の標本を作成します。各標本にはランダムなゲノムがあり、年齢は0です。ランダムな開始セルに各標本を置きます。
順番を変える:
- 次の手順は、各標本に対して順番に実行されます。標本は相互に作用したり、互いに見えたりせず、同じ細胞を占有する場合があります。
- 標本の年齢が100歳の場合、死にます。そうでない場合は、経過時間を1ずつ増やします。
- 標本には視野が与えられます-標本を中心とした色の5x5グリッド-3x3の周辺で動きを返します。この範囲外に移動すると、コントローラーが終了します。
- ターゲットセルが壁の場合、移動は(0,0)に変更されます。
- ターゲットセルがテレポーターの場合、標本はテレポーターのオフセット分だけ移動します。注:このステップは、反復ではなく1回実行されます。
- 標本が現在占有しているセルが(可能性として1つのテレポーターを使用した後に)致命的である場合、標本は死にます。これは、標本が死ぬ唯一の時間です(上記のステップ1.1を除く)。特に、致命的な細胞に出現する新しい標本はすぐに死ぬことはありませんが、最初に危険な細胞から移動する機会があります。
- 標本が目標セルを占有している場合、ポイントを獲得し、標本をランダムな開始セルに移動して、その年齢を0にリセットします。
- ボードに残っている標本が2つ未満の場合、ゲームは終了します。
- 年齢0の新しい標本を10個作成します。各ゲノムは、以下の育種ルールによって(個別に)決定されます。ランダムな開始セルに各標本を置きます。
育種:
新しい標本が作成されると、2つの異なる親をランダムに選択し、さらに右に進む標本へのバイアスを選択します。標本が選択される確率は、現在の適応度スコアに比例します。標本のフィットネススコアは
1 + x + 50 *目標に到達した回数
ここで、xは 0系の水平インデックスです。同じターンに作成された標本を親として選択することはできません。
2つの親のうち、最初のゲノムビットを取得するランダムな親を選択します。
- ゲノムを歩きながら、0.05の確率で親を切り替え、結果の親からビットを取り続けます。
- 完全に組み立てられたゲノムを突然変異させます:各ビットごとに、確率0.01でそれを反転させます。
得点:
- 1ゲームは10,000ターン続きます。
- プレイヤーは1ポイントでゲームを開始します(幾何平均を使用できるようにするため)。
- 標本が目標に到達するたびに、プレーヤーはポイントを獲得します。
- 現時点では、各プレイヤーの提出は、それぞれが異なるランダムトラックを持つ50ゲームで実行されます。
- 上記のアプローチは、望ましいよりも多くの分散をもたらします。この課題が終了すると、締め切りが発表されます。締め切りの終わりに、100のボードがランダムに選ばれ、すべての提出物がこれらの100のボードで採点されます。
- プレーヤーの総合スコアは、これらの個々のゲームのスコアの幾何平均です。
コントローラー
次のコントローラーのいずれかを選択できます(機能的に同等であるため)。すべてテストしましたが、バグを見つけたり、コードやパフォーマンスを改善したり、グラフィック出力のような機能を追加したい場合は、GitHubで問題を提起するか、プルリクエストを送信してください!別の言語で新しいコントローラーを追加することもできます!
各コントローラーの言語名をクリックして、GitHubの正しいディレクトリに移動します。このディレクトリには、README.md
正確な使用手順が記載されています。
gitやGitHubに精通していない場合は、フロントページからリポジトリ全体をZIPとしてダウンロードできます(サイドバーのボタンを参照)。
Python
- 最も徹底的にテストされています。これがリファレンス実装です。
- Python 2.6+とPython 3.2+の両方で動作します!
- とても遅いです。大幅な高速化のために、PyPyで実行することをお勧めします。
pygame
またはを使用してグラフィカル出力をサポートしますtkinter
。
ルビー
- Ruby 2.0.0でテスト済み。新しいバージョンで動作するはずです。
- また、かなり遅いですが、Rubyは提出のアイデアをプロトタイプ化するのに便利かもしれません。
C ++
- C ++ 11が必要です。
- オプションでマルチスレッドをサポートします。
- 群を抜いて最速のコントローラー。
C#
- LINQを使用するため、.NET 3.5が必要です。
- むしろ遅い。
Java
- 特に遅くはありません。特に高速ではありません。
予備リーダーボード
すべてのスコアは予備的なものです。それにもかかわらず、何かが明らかに間違っているか時代遅れである場合、私に知らせてください。サンプルの送信は比較のためにリストされていますが、競合ではありません。
Score | # Games | User | Language | Bot
===================================================================================
2914.13 | 2000 | kuroi neko | C++ | Hard Believers
1817.05097| 1000 | TheBestOne | Java | Running Star
1009.72 | 2000 | kuroi neko | C++ | Blind faith
782.18 | 2000 | MT0 | C++ | Cautious Specimens
428.38 | | user2487951 | Python | NeighborsOfNeighbors
145.35 | 2000 | Wouter ibens | C++ | Triple Score
133.2 | | Anton | C++ | StarPlayer
122.92 | | Dominik Müller | Python | SkyWalker
89.90 | | aschmack | C++ | LookAheadPlayer
74.7 | | bitpwner | C++ | ColorFarSeeker
70.98 | 2000 | Ceribia | C++ | WallGuesser
50.35 | | feersum | C++ | Run-Bonus Player
35.85 | | Zgarb | C++ | Pathfinder
(34.45) | 5000 | Martin Büttner | <all> | ColorScorePlayer
9.77 | | DenDenDo | C++ | SlowAndSteady
3.7 | | flawr | Java | IAmARobotPlayer
1.9 | | trichoplax | Python | Bishop
1.04 | 2000 | fluffy | C++ | Gray-Color Lookahead
クレジット
この課題は、大きな共同作業でした。
- Nathan Merril: PythonおよびJavaコントローラーを作成しました。チャレンジコンセプトをキングオブザヒルからラットレースに変えました。
- trichoplax:プレイテスト。Pythonコントローラーで作業しました。
- feersum: C ++コントローラーを作成しました。
- VisualMelon: C#コントローラーを作成しました。
- MartinBüttner:コンセプト。Rubyコントローラーを作成しました。プレイテスト。Pythonコントローラーで作業しました。
- Tアブラハム:プレイテスト。Pythonをテストし、C#およびC ++コントローラーを確認しました。
上記のすべてのユーザー(およびおそらく私が忘れていたさらに2、3人)は、チャレンジの全体的な設計に貢献しました。
C ++コントローラーの更新
Visual StudioとマルチスレッドでC ++を使用している場合は、ボードの複製を生成できる乱数ジェネレーターのシードにバグがあるため、最新の更新プログラムを入手する必要があります。
'In particular, a new specimen which spawns on a lethal cell will not die immediately, but has a chance to move off the dangerous cell first.'