一般に、じゃんけん は、「グーはチョキに勝ち、チョキはパーに勝ち、パーはグーに勝つ」。そして、もう一つ重要なことは、どんな勝ち方でも、1勝とカウントされることだ。
しかし、現実において、同じ勝利でも、その1つの勝利当たりの価値は、勝ち方によって異なるのが大半だ。大差をつけて楽に勝つより、接戦の末、逆転サヨナラ勝ちの方が、勝利の価値は大きい。
というわけで、じゃんけんに勝ち方に応じて、点数をつけて見た。その前に、Rock、Scissor、Paperの頭文字を以降グーチョキパーを表す記号とする。
Rで勝つ→1点
Sで勝つ→2点
Pで勝つ→5点
とする。
合計100回勝負するものとして、あいこならもう一度出せるものとする。
もし、自分の相手が、常にランダムに手を出す(rspすべて1/3の確率で出す)とすると、自分はどうすれば良いか、学習させてみる。
import random
def oponent():
num = random.random()
if num<1/3:
return 0
elif 1/3<=num<2/3:
return 1
else:
return 2
rewards= [1,2,5]
def judge(my_action, oponent_action):
if my_action == oponent_action:
return 0
elif (my_action-oponent_action)%3==2:
return rewards[my_action]
else:
return -rewards[oponent_action]
def get_action(actions):
num = random.random()
if num<actions[0]/sum(actions):
return 0
elif num>= 1-actions[2]/sum(actions):
return 2
else:
return 1
def learning(alpha):
# sum_score = 0
# for j in range(10):
score = 0
for i in range(1000):
while True:
action = get_action(actions)
reward = judge(action, oponent())
if reward != 0:
break
actions[action] += alpha*reward
score += reward
# sum_score += score
return score
% matplotlib inline
import matplotlib.pyplot as plt
actions = [100,100,100]
x = [i for i in range(100)]
y = [learning(i) for i in range(100)]
z = [learning(i)]
print(sum(y)/len(y))
plt.plot(x, y)
1000回勝負させてみた時、横軸は学習のしやすさに関するパラメータα、横軸は1000回勝負したときの相対的な点差。
およそ1500くらいにとどまる。これは、常にパーを出す戦略の時の期待値である。実際に、α=20の時の、それぞれの重みは、-9, 4494, 7529199となり、圧倒的にパーを出している。
よって、期待値の計算通り、相手が何も考えない人(失礼)の時は、パーを出していこう。