ポケモンWordleの最適戦略
概要
ポケモンWordleの最適戦略を計算しました.
計算済みの戦略をシミュレートできるWebサイトも作ってみたので, ぜひ使ってみてください.
最適戦略とは
戦略とは
次のような図で表されるものを戦略と定義します.
ランクルス
├─ 🟨⬜⬜⬜⬜ => エビワラー
│ ├─ ⬜⬜⬜🟨⬜ => ギラティナ
│ │ └─ 🟩🟩🟩🟩🟩
│ ├─ ⬜⬜🟨🟨⬜ => フワライド
│ │ └─ 🟩🟩🟩🟩🟩
| ├─ ⬜⬜⬜🟩⬜ => マグマラシ
│ │ ├─ ⬜⬜⬜🟩🟩 => ヒノアラシ
│ │ | └─ 🟩🟩🟩🟩🟩
│ │ ├─ 🟨⬜⬜🟩🟩 => タマザラシ
│ │ | └─ 🟩🟩🟩🟩🟩
│ │ └─ 🟩🟩🟩🟩🟩
... ...
図の戦略は, 次のように解釈します.
初手ランクルスを入力します. その返答が
- 🟨⬜⬜⬜⬜ のとき, 次にエビワラーを入力します. その返答が
- ⬜⬜⬜🟨⬜ のとき, 次にギラティナを入力して正答となります.
- ⬜⬜🟨🟨⬜ のとき, 次にフワライドを入力して正答となります.
- ⬜⬜⬜🟩⬜ のとき, 次にマグマラシを入力します. その返答が
- ⬜⬜⬜🟩🟩 のとき, 次にヒノアラシを入力して正答となります.
- 🟨⬜⬜🟩🟩 のとき, 次にタマザラシを入力して正答となります.
- 🟩🟩🟩🟩🟩 のとき, 正答となります.
- ...
- ...
最適とは
最適の定義としては
- 平均入力回数が最小
- 最悪ケースの入力回数が最小
等が考えられると思いますが, ここでは 1. の 「平均入力回数が最小となる戦略」を最適戦略と定義します.
理由
「最悪ケースの入力回数の最小値」で戦略を評価する場合, 例えば次の戦略A,Bの優劣をつけることができません.
- 戦略A:
ケース全てに対して100 回の入力で正答する.5 - 戦略B:
ケースに対して99 回の入力で正答し,4 ケースでのみ1 回の入力で正答する.5
また, 戦略Aは戦略Cよりも優れていることになってしまいます.
- 戦略C:
ケースに対して99 回の入力で正答し,4 ケースでのみ1 回の入力で正答する.6
さらに実際に平均最小戦略を求めたところ, 最悪ケースは
ポケモンWordleでは
最適戦略の計算
入力可能なポケモンは全部で846匹も存在します.
したがって戦略として考えられるものは無数に存在します.
以下では, 最適な戦略を効率よく見つける方法を考えていきます.
動的計画法(メモ化)
「まだ入力していないポケモンで, 答えになり得るポケモンの候補が
このとき,
ただし
例:
この漸化式に従って
さらに
しかしこの計算方法には無駄が多く, このままだと時間がかかり過ぎてしまいます.
分枝限定法
前節で出てきた
の部分は非効率です. なぜなら, 明らかに悪そうな入力も全て考慮する必要があるからです.
分枝限定法は, この無駄な探索をできるだけ省くアルゴリズムです.
今
-
を平均S 回の入力で正答できるような戦略を見つけることができた\mathrm{ub}(S) -
を次の入力にした場合, 平均入力回数がg を下回ることはないことが断定できた\mathrm{lb}(S,g)
とします. このとき
たくさん探索を省くためには, 小さな暫定値
\mathrm{ub}(S) の計算
暫定値候補
を用います. これに従って
\mathrm{lb}(S,g) の計算
下界候補
ここで候補
理由
他の
これを用いて,
高速化
ここまでで, かなり高速に最適戦略を求めることができるようになりました.
あとは細かいチューニングをしていきます.
良さそうな入力から探索する
を計算する際に,
と小さく更新していけるため, 最適な入力
和が暫定値を超えた時点で終了
を計算する際に
|S| が小さいときには例外処理
候補の大きさまた
理由
候補内から入力した場合, 平均入力回数は悪くても
候補外から入力した場合, 今回は絶対当たらないので平均入力回数は良くても
よって候補内から入力する場合だけ考慮すれば十分です.
\mathrm{lb}(S,g) をもう少し正確に計算する
下界とすることで
平均の計算を整数で行う
整数で計算すると除算もなく高速で, さらに誤差のない計算が可能です.
\tilde{g}(S) の改善
暫定的な入力 とした方が僅かに暫定解の精度が上がり, 探索をさらに削減できました.
Rustで実装
高速な言語を使うことも重要です. (初期実装はPythonでした)
並列化
4並列で3倍程度の高速化に成功しました.
数値実験
計算環境は M1 Macbook Pro 2020 を用いました.
答えの候補 | 最小平均入力回数 | 最悪ケース[回] | 計算時間[秒] |
---|---|---|---|
DP以前 | 3.3404 (= 942/282) | 6 | 95 |
BW以前 | 3.4947 (= 1328/380) | 6 | 1051 |
XY以前 | 3.5576 (= 1512/425) | 6 | 3497 |
SM以前 | 3.6139 (= 1713/474) | 7 | 11488 |
剣盾以前 | 3.6379 (= 1859/511) | 6 | 24891 |
計算済みの最適解とソースコードはGitHubに公開している他, Webサイトで使ってみることもできます.
さいごに
ポケモンWordleや本家Wordleの平均入力回数の最小化問題を解いている人は (調べた限り) 見つからなかったので, (ポケモンWordle限定ですが) 現実的な時間で解くことができて良かったです.
それでは皆さん, 最適なポケモンWordleライフを!
Discussion