NSW202207 / Created on 2022/03/10
@author: Suguru Ueda
# 2×2戦略形ゲームのクラス
class Game_mixed:
def __init__(self, P):
self.P = P # 利得行列を保持する変数
def __str__(self):
return str(self.P[0]) + '\t' + str(self.P[1]) + '\n' + str(self.P[2]) + '\t' + str(self.P[3])
# ナッシュ均衡となる戦略の組をすべて求める関数
def find_Nash_equilibrium(self):
# ナッシュ均衡となる戦略の組を格納するリスト
list_of_Nash_equilibrium = []
# 戦略の全組み合わせを走査する2重ループ
for x in [[1, 0], [0, 1]]:
for y in [[1, 0], [0, 1]]:
if self._is_mutually_best_response(x, y):
# xとyの両方が最適反応だったらリストに格納
list_of_Nash_equilibrium.append((x, y))
# 混合戦略でのナッシュ均衡を求める
A = self.P[0][1] - self.P[1][1]
B = self.P[3][1] - self.P[2][1]
C = self.P[3][0] - self.P[1][0]
D = self.P[0][0] - self.P[2][0]
if A + B != 0 and C + D != 0:
list_of_Nash_equilibrium.append(([abs(B)/abs(A + B),
abs(A)/abs(A + B)],
[abs(D)/abs(C + D),
abs(C)/abs(C + D)]))
return list_of_Nash_equilibrium
# xとyの両方が最適反応かどうかを判定する関数
def _is_mutually_best_response(self, x, y):
if self._get_R(x, y) < max(self._get_R([1, 0], y), self._get_R([0, 1], y)):
return False
elif self._get_C(x, y) < max(self._get_C(x, [1, 0]), self._get_C(x, [0, 1])):
return False
return True
# 行プレイヤーの利得を計算する関数
def _get_R(self, x, y):
return self.P[0][0]*x[0]*y[0] + self.P[1][0]*x[0]*y[1] + self.P[2][0]*x[1]*y[0] + self.P[3][0]*x[1]*y[1]
# 列プレイヤーの利得を計算する
def _get_C(self, x, y):
return self.P[0][1]*x[0]*y[0] + self.P[1][1]*x[0]*y[1] + self.P[2][1]*x[1]*y[0] + self.P[3][1]*x[1]*y[1]
# 利得行列の準備
P = [(1, 1), (-3, 3), (3, -3), (-1, 3)]
#P = [(2, 1), (-3, 9), (-1, 1), (-1, -1)]
game = Game_mixed(P) # Gameオブジェクトを作成
print(game)
print(game.find_Nash_equilibrium())
(1, 1) (-3, 3) (3, -3) (-1, 3) [([0, 1], [0, 1])]