三枪手决斗问题的计算机解答
由来
前几天在一个游戏设计群里看到有人发的一份数值策划笔试题,虽然不知道是不是真的是数值策划的笔试题,但每个题都还挺有意思的。这第一题就在我们宿舍中产生了一段短暂的讨论,当时的讨论都是定性的,没有严格分析,今个闲着就把这一道我也不知道叫什么名字就暂且叫做“三枪手决斗”问题用编程的方法看一下结果。
题目
彼此痛恨的ABC三个枪手准备决斗。A枪法最好,平均十发八中。B的枪法次之,平均十发六中。C枪法最差,平均十发四中。假设他们了解彼此实力,也能做出理性判断。
三人同时开枪,谁的存活概率大?
解法一
秉承着由简单到复杂的做法,我先假设这是个只有一回合的静态博弈,每个人想让自己存活的概率最高,这应该是直观上最容易想到的情景了。
在这样的假设下,策略空间一共是2*2*2(A、B、C分别选择射杀另外的谁),然后每个策略组合下会有三个值,分别是三人的存活概率,代码如下:
import numpy as np
prob=[0.8,0.6,0.4]
value=np.zeros((2,2,2,3))
print(value.shape)
for i in range(0,2):
for j in range(0,2):
for k in range(0,2):
a,b,c=1,1,1
if i==0:
b*=0.2
else:
c*=0.2
if j==0:
a*=0.4
else:
c*=0.4
if k==0:
a*=0.6
else:
b*=0.6
value[i][j][k][0]=a
value[i][j][k][1]=b
value[i][j][k][2]=c
print(value)
下面是输出,第一维是A的两个选择(杀B\C),第二维是B的两个选择(杀A\C),第三维是C的两个选择(杀A\B),最后一维就是三人分别的存活概率了。(应该不会有人选择自杀吧,大概)
可以看到啊,每一种策略组合都是此静态博弈的纳什均衡点(),这也很好理解,因为自己无论做出什么选择都没办法改变自己被杀的概率(除了朝自己开枪),只是改变了别人被杀的概率。这就没意思了,但是另外再想,既然他们三个要进行决斗,那么自己活着肯定就不是唯一的目的(不然不决斗不就完事了),他们还想让对方死!基于这点,做出如下解法二的改进。
解法二
因为题中提到是“彼此痛恨”的枪手,那按道理讲,每个人应该也很乐意看到对方死亡。如果把自己活着视为奖赏1,其他的每一个人死亡给自己的奖赏也为1,则
value2=np.zeros((2,2,2,3))
for i in range(0,2):
for j in range(0,2):
for k in range(0,2):
value2[i][j][k][0]=value[i][j][k][0]*1+value[i][j][k][1]*(-1)+value[i][j][k][2]*(-1)
value2[i][j][k][1]=value[i][j][k][0]*(-1)+value[i][j][k][1]*1+value[i][j][k][2]*(-1)
value2[i][j][k][2]=value[i][j][k][0]*(-1)+value[i][j][k][1]*(-1)+value[i][j][k][2]*1
print(value2)
直接基于已经求解出的存活概率进行进一步的计算即可。结果如下:
再写一个判断纳什均衡的函数,如下:
def nash(v):
whether_nash=np.ones((2,2,2))
for i in range(0,2):
for j in range(0,2):
for k in range(0,2):
if v[i][j][k][0]!=np.max(np.array([v[t][j][k][0] for t in range(0,2)])):
whether_nash[i][j][k]=0
if v[i][j][k][1]!=np.max(np.array([v[i][t][k][1] for t in range(0,2)])):
whether_nash[i][j][k]=0
if v[i][j][k][2]!=np.max(np.array([v[i][j][t][2] for t in range(0,2)])):
whether_nash[i][j][k]=0
return whether_nash
对value2张量调用nash函数,输出结果存在两个纳什均衡点,分别为(>代表开枪):
- A>B、B>C、C>A
- A>C、C>B、B>A
有意思的来了,可以发现,这两个纳什均衡点的决策均构成一种射杀环,不会有两个人打算同时射杀一个人。我的理解是,每个人都想做“螳螂捕蝉黄雀在后”中的黄雀,借你之手除掉一个人之后再除掉你。另外,还有一种解释,就是如果我已经知道你在杀另一个人了,那么我为了让除了我以外死的人最多,我不会选择浪费我手中的这颗子弹,我会选择杀另外的人,因为如果都朝同一个人开枪,那么最多也就死一个人,而朝不同的人开枪可能死两个人。
而且更有意思的是,这两种情况,所有人的期望收益都是负的!这可能就是囚徒困境的一个版本吧,不过究竟算不算囚徒困境呢我也没深入思考啊,只是感觉这种每个人都输的结局很像是囚徒困境。
补:对每一种情况的结果的三人收益求和发现,这两个纳什均衡的所有人总收益竟然是最高的-1.2,那意思是这种纳什均衡达到了总体收益的最大化!那意思是这不是囚徒困境而恰恰相反,“所有人共同努力(指互相杀戮)以使大家的总体期望收益最大化”!
def reward_sum(v):
rs=np.sum(v,axis=3)
return rs
另外,并不是所有纳什均衡都是最厉害的A收益最高,在第二个纳什均衡处B的收益最高。可见人也不一定是自己越厉害越好,如果能通过某些方法改变别人的决策使之落入另一个纳什均衡点也能使自己获得最多的收益。
解法三
按道理讲,一次射击可能不会结束决斗,可能一个人都不剩,可能只有一个人活着,可能还有两方活着,再或者大家都射偏了每个人都活着。最贴合实际的应该是将其视为一种多回合的动态博弈。画决策树分析可就太复杂啦,因为这是个无限深的树。我觉着,如果每个人这时候简单地只想自己活着(不再考虑想让别人死啦),那么每个人存活的概率可以由如下公式导出(以A为例):
式中,Ra是我要求的最终存活概率,pa/pb/pc是三人在第一回合存活的概率,0.4和0.6分别是a如果单独与b/c决斗存活的概率。如果此回合没人死亡,那么下一回合和此回合完全一致,这就是上式中右式中括号内的第一项;如果b活c死,那么a在单独与b决斗的回合中存活的概率为0.4,对应右式第二项;第三项同理;第四项是这一回合b/c都死了,那么a不用进行下一回合的决斗了,存活概率为1,对应最后一项。
简单地计算出Ra的表达式,编程计算:
value3=np.zeros((2,2,2,3))
for i in range(0,2):
for j in range(0,2):
for k in range(0,2):
value3[i][j][k][0]=(value[i][j][k][1]*(1-value[i][j][k][2])*0.4+value[i][j][k][2]*(1-value[i][j][k][1])*0.6+(1-value[i][j][k][1])*(1-value[i][j][k][2]))/(1.0/value[i][j][k][0]-value[i][j][k][1]*value[i][j][k][2])
value3[i][j][k][1]=(value[i][j][k][0]*(1-value[i][j][k][2])*0.2+value[i][j][k][2]*(1-value[i][j][k][0])*0.6+(1-value[i][j][k][0])*(1-value[i][j][k][2]))/(1.0/value[i][j][k][1]-value[i][j][k][0]*value[i][j][k][2])
value3[i][j][k][2]=(value[i][j][k][0]*(1-value[i][j][k][1])*0.2+value[i][j][k][1]*(1-value[i][j][k][0])*0.4+(1-value[i][j][k][0])*(1-value[i][j][k][1]))/(1.0/value[i][j][k][2]-value[i][j][k][0]*value[i][j][k][1])
print(value3)
whether_nash2=nash(value3)
print(whether_nash2)
同样,这次也有两个纳什均衡,并且这次两个结果对应着不同的逻辑:
- A>B B>A C>A 这种逻辑代表B、C为了使自己进入下一回合后自己的对手能弱一些,都会选择先射杀最厉害的A,以免自己第二回合和最厉害的A对线,A同理,会先射杀B、C中最厉害的B
- A>C B>A C>B 这种逻辑,以A举例,A知道C在射B,它会想,如果我在第一回合射杀C,那么是不是决斗就会在第一回合结束,自己直接获胜,不用第二回合再拼杀了。同理,B、C也是这样想的,这就形成了一种环。
然后就是看谁最可能活着。第一种纳什均衡,最弱的C反而是最可能活着的(概率为0.74285714,已经可以说是超级高了)第二种纳什均衡,最可能活着的是中规中矩的B(概率为0.38823529)。反正就是最厉害的A不太可能活下来(所以大家不要再卷啦,最厉害的人最容易暴毙,大家和我一起躺平为了明天的活着而努力吧!)。
最后看一下总体收益。第一种均衡的总收益是所有总收益中最高的,应该是帕累托最优的,而第二种均衡的总收益恰恰相反是所有总收益中最低的,这点不太懂。
(本来不是很想写的,但是感觉结果还挺有意思的,虽然写了也没人看,不过还是写出来了,另外也不知道自己想的对不对,尤其是那个动态的那个概率公式,如果这真的能被大佬看到的话还请指教指教)