Games.jl を使ってみる

まず Games.jl を読み込む:


In [1]:
using Games

support_enumeration

2人 (非退化) ゲームのナッシュ均衡をすべて列挙する.

授業での例

$ \begin{bmatrix} 3, 3 & 3, 2 \\ 2, 2 & 5, 6 \\ 0, 3 & 6, 1 \end{bmatrix} $

Julia では3次元以上の配列を作りにくいので,各プレイヤーごとに Player を作ることにする:

プレイヤー1:


In [2]:
p1 = Player(
    [3 3
     2 5
     0 6]
)


Out[2]:
3×2 Player{2,Int64}:
 3  3
 2  5
 0  6

プレイヤー2:

自分の戦略が行,相手の戦略が列


In [3]:
p2 = Player(
    [3 2 3
     2 6 1]
)


Out[3]:
2×3 Player{2,Int64}:
 3  2  3
 2  6  1

組み合わせて NormalFormGame を作る:


In [4]:
g = NormalFormGame(p1, p2)


Out[4]:
3×2 NormalFormGame{2,Int64}

support_enumeration でナッシュ均衡を列挙する:


In [5]:
support_enumeration(g)


Out[5]:
3-element Array{Tuple{Array{Float64,1},Array{Float64,1}},1}:
 ([1.0, 0.0, 0.0], [1.0, 0.0])
 ([0.7999999999999999, 0.19999999999999998, 0.0], [0.6666666666666666, 0.3333333333333333])
 ([0.0, 0.3333333333333333, 0.6666666666666667], [0.3333333333333335, 0.6666666666666666])

結果を NEs という変数に格納してみる:


In [6]:
NEs = support_enumeration(g);

NEs の要素の数 = ナッシュ均衡の数


In [7]:
length(NEs)


Out[7]:
3

1つ目のナッシュ均衡:


In [8]:
NEs[1]


Out[8]:
([1.0, 0.0, 0.0], [1.0, 0.0])

2つ目のナッシュ均衡:


In [9]:
NEs[2]


Out[9]:
([0.7999999999999999, 0.19999999999999998, 0.0], [0.6666666666666666, 0.3333333333333333])

3つ目のナッシュ均衡:


In [10]:
NEs[3]


Out[10]:
([0.0, 0.3333333333333333, 0.6666666666666667], [0.3333333333333335, 0.6666666666666666])

それぞれ確かにナッシュ均衡になっている:


In [11]:
for NE in NEs
    println(is_nash(g, NE))
end


true
true
true

グレーヴァ『非協力ゲーム理論』第3章練習問題3.3を解かせてみる.

(a)


In [12]:
p1 = Player(
    [0 3
     5 0
     1 1]
);

In [13]:
p2 = Player(
    [1 2 8
     3 0 7]
);

In [14]:
g_a = NormalFormGame(p1, p2)


Out[14]:
3×2 NormalFormGame{2,Int64}

In [15]:
support_enumeration(g_a)


Out[15]:
3-element Array{Tuple{Array{Float64,1},Array{Float64,1}},1}:
 ([1.0, 0.0, 0.0], [0.0, 1.0])
 ([0.0, 1.0, 0.0], [1.0, 0.0])
 ([0.49999999999999994, 0.5, 0.0], [0.375, 0.625])

プレイヤー1の戦略3は被支配戦略になっている:


In [16]:
is_dominated(g_a.players[1], 3)


Out[16]:
true

利得が有理数ならば,厳密計算で実行される:

有理数利得のゲームに変換する:


In [17]:
g_a_rational = NormalFormGame(Rational{Int}, g_a)


Out[17]:
3×2 NormalFormGame{2,Rational{Int64}}

In [18]:
support_enumeration(g_a_rational)


Out[18]:
3-element Array{Tuple{Array{Rational{Int64},1},Array{Rational{Int64},1}},1}:
 ([1//1, 0//1, 0//1], [0//1, 1//1])
 ([0//1, 1//1, 0//1], [1//1, 0//1])
 ([1//2, 1//2, 0//1], [3//8, 5//8])

(b)

最初から有理数で入力してもよい:


In [19]:
p1 = Player(
    [0//1 3
     5 0
     2 2]
)  # 一カ所有理数にすればよい


Out[19]:
3×2 Player{2,Rational{Int64}}:
 0//1  3//1
 5//1  0//1
 2//1  2//1

In [20]:
p2 = Player(
    [1//1 2 8
     3 0 7]
)  # 一カ所有理数にすればよい


Out[20]:
2×3 Player{2,Rational{Int64}}:
 1//1  2//1  8//1
 3//1  0//1  7//1

In [21]:
g_b_rational = NormalFormGame(p1, p2)


Out[21]:
3×2 NormalFormGame{2,Rational{Int64}}

In [22]:
support_enumeration(g_b_rational)


Out[22]:
3-element Array{Tuple{Array{Rational{Int64},1},Array{Rational{Int64},1}},1}:
 ([1//1, 0//1, 0//1], [0//1, 1//1])
 ([0//1, 1//1, 0//1], [1//1, 0//1])
 ([1//3, 0//1, 2//3], [1//3, 2//3])

In [ ]: