農心杯比賽勝率問題
阿新 • • 發佈:2017-12-31
markdown href pre 國家 函數 水平 += urn wechat
狀態空間中的結點數遠遠小於555*3,實際上只有363種狀態。
題目來源
農心杯世界圍棋團體錦標賽是由韓國日刊體育社主辦,農心集團贊助的一項圍棋國際大賽,是世界上水平最高的圍棋團體賽。每屆由中國、日本和韓國各派出5名棋手,采用擂臺賽的方式,三國棋手輪番上陣,最後留在擂臺上的隊伍獲得冠軍。
中日韓三國擂臺賽,各派出五名選手。首先每方各派出一位選手比賽,其中一國棋手首輪輪空。假設每兩人之間的勝率均為50%,則首輪輪空一方勝率為多少?
這是一道動態規劃問題。
定義狀態為(中方人數,日方人數,韓方人數,當前對局甲方,當前對局乙方),狀態函數為f,f(當前狀態)=(中方獲勝概率,日方獲勝概率,韓方獲勝概率)。
其實狀態也可以描述為(中方人數,日方人數,韓方人數,觀戰方),這樣用4個數字就解決了。
import numpy as np
a = dict() # 備忘錄方法
def get(x):
if tuple(x) not in a:
# 如果已經有兩個國家沒人了,遊戲就可以結束了
if x[0] == 0 and x[1] == 0:
return [0, 0, 1]
elif x[0] == 0 and x[2] == 0:
return [0, 1, 0]
elif x[1] == 0 and x[2] == 0:
return [1, 0, 0]
one = x[3] # 對戰的一方
two = x[4] # 對戰的另一方
three = 3 - one - two # 觀戰的一方
# 如果人數不夠,那就讓觀戰的一方上場
if x[one] == 0:
x[3] = three
return get(x)
if x[two] == 0:
x[4] = three
return get(x)
# 如果two勝利
ne = x[:]
ne[one] -= 1
ans = np.array([0.0, 0.0, 0.0])
ne[3] = two
ne[4] = three
ans += 0.5 * np.array(get(ne))
# 如果one勝利
ne = x[:]
ne[two] -= 1
ne[3] = one
ne[4] = three
ans += 0.5 * np.array(get(ne))
a[tuple(x)] = ans
return a[tuple(x)]
print(get([5, 5, 5, 0, 1]))
農心杯比賽勝率問題