Pythonで学ぶ探索とゲームAI:A*とミニマックス
古典的AIは、起こりうる状態を探索して問題を解きます。A*はここまでのコストと残りコストの見積もりを足して最も安い経路を見つけ、ミニマックスは相手が最善を尽くすと仮定して二人対戦ゲームの手を選びます。
やさしい言葉で概念を理解する
古典的AIは、起こりうる状態を探索して問題を解きます。A*はここまでのコストと残りコストの見積もりを足して最も安い経路を見つけ、ミニマックスは相手が最善を尽くすと仮定して二人対戦ゲームの手を選びます。
A*探索でグリッド上の最短経路を見つけ、ミニマックスでゲームの最善手を選びます。
重要なポイント
- 見積もり(ヒューリスティック)が実際のコストを決して超えなければ、A*は最良の経路を見つけます。
- ミニマックスは、決まった深さかゲームの終わりまでゲーム木を探索します。
- アルファベータ枝刈りは、判断を変えられない枝をスキップします。
- 遺伝的アルゴリズムは別の方法で探索し、候補解の集団を進化させます。
どのような場面で使う?
- ニューラルネットワークやAIライブラリの内部で何が起きているかを理解する。
- 対応するチャレンジで実装する前に考え方をつかむ。
- 機械学習の講座、面接、プロジェクトに備える。
動かして理解する
再生を押すとA*がグリッドを探索します。セルをクリックすると壁を追加・削除できます。ゲーム木では葉をクリックしてスコアを変えられます。
サンプルコード
main.py
import heapq
# A* finds the cheapest path using cost so far + a guess of the cost left.
grid = ["S..#",
".#..",
"...G"]
start, goal = (0, 0), (2, 3)
guess = lambda r, c: abs(r - goal[0]) + abs(c - goal[1]) # Manhattan distance
frontier = [(guess(*start), 0, start, [start])]
seen = set()
while frontier:
_, cost, (r, c), path = heapq.heappop(frontier)
if (r, c) == goal:
print("path:", path, "cost:", cost)
break
if (r, c) in seen:
continue
seen.add((r, c))
for dr, dc in ((0, 1), (1, 0), (0, -1), (-1, 0)):
nr, nc = r + dr, c + dc
if 0 <= nr < 3 and 0 <= nc < 4 and grid[nr][nc] != "#":
heapq.heappush(frontier, (cost + 1 + guess(nr, nc), cost + 1, (nr, nc), path + [(nr, nc)]))
# Minimax: the maximizer assumes the opponent always picks the worst for it.
def minimax(node, maximizing):
if isinstance(node, int):
return node
values = [minimax(child, not maximizing) for child in node]
return max(values) if maximizing else min(values)
tree = [[3, 5], [2, 9], [0, 7]] # our move, then the opponent's reply
print("best guaranteed score:", minimax(tree, True))
期待される出力
path: [(0, 0), (0, 1), (0, 2), (1, 2), (1, 3), (2, 3)] cost: 5
best guaranteed score: 3
仕組み
優先度付きキューは常に「コスト + 見積もり」が最小のマスを展開します。見積もりはゴールまでのマンハッタン距離なので、A*は壁を回り込んで5ステップでGに到達します。minimax()は自分の手番では最大値、相手の手番では最小値を取ります。最初の手は3を保証し、これは3つの最悪ケースの中で最も良い値です。
値を変更し、PythonをインストールせずにCodeUtilityオンラインPythonコンパイラで実行できます。
練習問題
入力値と境界ケースを変更し、より大きなデータでも動作を確認してください。
- 入力や重みを変えて、実行前に出力を予想してみましょう。
- 途中の値を出力して、計算の各ステップを追いましょう。
- 下のリンクのチャレンジを解いて、自分でアイデアを実装しましょう。
チャレンジで練習する
このレッスンの内容を使って実際の問題を解きましょう。各チャレンジはブラウザで動き、すぐにテストされ、AI のレビューも受けられます。
- 重み付きグリッド上の A* 探索 ゲームやロボットの経路探索を支える A* で、地形コストのグリッドを横切る最安の経路を求めます。 中級
- ミニマックスで三目並べ ミニマックスでゲーム木全体を探索し、三目並べの完璧な一手を選びます。 中級
- アルファベータ枝刈り アルファベータ枝刈り付きのミニマックスでゲーム木を評価し、実際に調べた葉の数を数えます。 中級
- 遺伝的アルゴリズムの 1 世代 トーナメント選択、一点交叉、突然変異でビット列の次の世代を作ります。 中級