信任的演化
第一种情况
变量说明 | 变量名 | 参数 |
---|---|---|
犯错的机率 | MISTAKERATE | 0 |
淘汰-复制个体数 | RECOPY | 5 |
迭代次数 | ITERTIMES | 10 |
每轮博弈次数 | GAMETIMES | 10 |
一直欺骗 | allCheat | 20 |
一直合作 | allCooperation | 20 |
第一轮合作,一报还一报 | copyCat | 0 |
先合作,直到被欺骗,以后全部选择欺骗 | grudger | 0 |
合作 欺骗 合作 合作,如果反击,则变为copyCat 否则变为 allCheat | detective | 0 |
在演化的开始阶段,一直合作的player和一直欺骗的player种群个数相同。但是随着博弈进行,一直选择合作的种群比例逐渐降低,直到为0.换句话说,在一个充满自利且理性的社会中,随着老好人是很难存活到的。
第二种情况
变量说明 | 变量名 | 参数 |
---|---|---|
犯错的机率 | MISTAKERATE | 0 |
淘汰-复制个体数 | RECOPY | 5 |
迭代次数 | ITERTIMES | 10 |
每轮博弈次数 | GAMETIMES | 10 |
一直欺骗 | allCheat | 1 |
一直合作 | allCooperation | 23 |
第一轮合作,一报还一报 | copyCat | 1 |
先合作,直到被欺骗,以后全部选择欺骗 | grudger | 0 |
合作 欺骗 合作 合作,如果反击,则变为copyCat 否则变为 allCheat | detective | 0 |
尽管永远欺骗的策略会在初期占有优势,但是在后期被一报还一报策略取代。
第三种情况
变量说明 | 变量名 | 参数 |
---|---|---|
犯错的机率 | MISTAKERATE | 0 |
淘汰-复制个体数 | RECOPY | 5 |
迭代次数 | ITERTIMES | 10 |
每轮博弈次数 | GAMETIMES | 2 |
一直欺骗 | allCheat | 1 |
一直合作 | allCooperation | 23 |
第一轮合作,一报还一报 | copyCat | 1 |
先合作,直到被欺骗,以后全部选择欺骗 | grudger | 0 |
合作 欺骗 合作 合作,如果反击,则变为copyCat 否则变为 allCheat | detective | 0 |
倘若不进行足够多轮的比赛,永远报复就处于绝对的优势。也就是说:人与人之间越来越少的重复互动,所带来的影响就是不信任的加剧扩散。
第四种情况
在第四种情况中,我们调整支付矩阵,我们将(合作,合作)的支付向量从(2,2)调整到(1,1)。得到的结果如图所示:
变量说明 | 变量名 | 参数 |
---|---|---|
犯错的机率 | MISTAKERATE | 0 |
淘汰-复制个体数 | RECOPY | 5 |
迭代次数 | ITERTIMES | 10 |
每轮博弈次数 | GAMETIMES | 2 |
一直欺骗 | allCheat | 1 |
一直合作 | allCooperation | 23 |
第一轮合作,一报还一报 | copyCat | 1 |
先合作,直到被欺骗,以后全部选择欺骗 | grudger | 0 |
合作 欺骗 合作 合作,如果反击,则变为copyCat 否则变为 allCheat | detective | 0 |
当支付策略(合作,合作)的报酬被降低,一直欺骗开始处于优势地位。
第五种情况
现在引入三种策略:
变量说明 | 变量名 |
---|---|
两报还一报 | copykitten |
随机选择策略 | random |
会选择合作。如果对方合作,我会做出跟上一轮一样的选择,即使上一轮犯错了也一样。则会做出跟上一轮相反的选择 | simpleton |
本轮参数设计实验参数如下: |
变量说明 | 变量名 | 参数 |
---|---|---|
犯错的机率 | MISTAKERATE | 0 |
淘汰-复制个体数 | RECOPY | 5 |
迭代次数 | ITERTIMES | 10 |
每轮博弈次数 | GAMETIMES | 2 |
一直欺骗 | allCheat | 0 |
一直合作 | allCooperation | 13 |
第一轮合作,一报还一报 | copyCat | 3 |
先合作,直到被欺骗,以后全部选择欺骗 | grudger | 0 |
合作 欺骗 合作 合作,如果反击,则变为copyCat 否则变为 allCheat | detective | 0 |
两报还一报 | copykitten | 3 |
随机选择策略 | random | 3 |
会选择合作。如果对方合作,我会做出跟上一轮一样的选择,即使上一轮犯错了也一样。则会做出跟上一轮相反的选择 | simpleton | 3 |
simpleton取得了最后的绝对优势,可以说simpleton实际上具备剥削allCooperation的能力。他们都以「合作」开局,但是一旦simpketon犯了错,欺骗了对方,就会一直欺骗下去,因为allCooperation永远不会反击。
第六种情况
我们在第五种情况的基础上,将AllCooperation替换成allCheat,同时引入犯错概率50(此时实际上已经是随机选择方案了),相关参数设置如下:
变量说明 | 变量名 | 参数 |
---|---|---|
犯错的机率 | MISTAKERATE | 0.5 |
淘汰-复制个体数 | RECOPY | 5 |
迭代次数 | ITERTIMES | 10 |
每轮博弈次数 | GAMETIMES | 2 |
一直欺骗 | allCheat | 13 |
一直合作 | allCooperation | 0 |
第一轮合作,一报还一报 | copyCat | 3 |
先合作,直到被欺骗,以后全部选择欺骗 | grudger | 0 |
合作 欺骗 合作 合作,如果反击,则变为copyCat 否则变为 allCheat | detective | 0 |
两报还一报 | copykitten | 3 |
随机选择策略 | random | 3 |
会选择合作。如果对方合作,我会做出跟上一轮一样的选择,即使上一轮犯错了也一样。则会做出跟上一轮相反的选择 | simpleton | 3 |
在犯错概率在 0% 的时候:copyCat是优胜者
在 1% 到 9% 之间:copykitten策略是优胜者
在 10% 到 49% 之间:allcheat策略是优胜者
到了 50%, 没有人会一直赢。
这就是为什么我们说「误解」是达成信任的一个有趣的壁垒:一个小误解可以带来更多的宽容,但是太多的误解带来的却是大范围的不信任!我个人认为,现代科技进步使得的媒介越来越发达,虽然一定程度上帮助了人们增加了交流机会,但它带给人们的误解却其实更多。
结论:
- 重复的互动
信任是保持人际关系长久的基石,但信任能够建立的前提,是你要知道你们未来会有重复的互动。
- 「双赢」并非不可能
你必须进行非零和游戏,而在这样的游戏博弈中,并不要求两个玩家都会变得更好,达到双赢,但至少必须要有达成双赢的可能性。
- 低概率的误解
如果误解发生得过多,信任就会瓦解。但是,如果有一点点误会的时候,它将使宽容蔓延开来。
最后:
游戏是什么,直接决定了玩家做什么。
我们今天的问题并不仅仅是人们正在失去信任,而是我们的环境正在违背信任进化的规律。
「我们仅仅是我们周遭环境的产物」,这个观念可能看起来可能有点犬儒或者天真无邪,但是博弈论也在提醒着,我们就是彼此的环境啊。短期来讲,游戏决定玩家,但是长期来说,决定游戏的正是我们这些玩家。
所以,我们每个人都行动起来,做你力所能及的,去创造一个可以让信任进化的条件。建立人际关系、努力寻求双赢、沟通尽量清晰。或许到了那个时候,我们能够停止向对方开火,走出各自的战壕,穿过战争的无人地带来到彼此面前...
附录
import numpy as np
from matplotlib import pyplot as plt
from pylab import *
import copy
import numpy as np
import pandas as pd
COOPERATION = 0
CHEAT = 1
pay_off = np.array([[2, 2], [-1, 3], \
[3, -1], [0, 0]])
GAMETIMES = 20 # 每轮博弈的游戏次数
MISTAKERATE = .0 # 犯错的机率
RECORY = 5 # 淘汰RECOPY个元素,复制RECOPY个元素
class agent:
def __init__(self):
self.type = ''
self.score = 0
def __init__(self, _type, _score):
self.type = _type
self.score = _score
def __init__(self, _type):
self.type = _type
self.score = 0
def allCheat(gameList, myList):
# 永远欺骗
return CHEAT
def allCooperation(gameList, myList):
# 永远合作
return COOPERATION
def copyCat(gameList, myList):
# 第一轮合作然后一直模仿你的上一轮行动
if len(gameList) == 0:
return COOPERATION
else:
return gameList[-1]
def grudger(gameList, myList):
# 先合作,直到你欺骗,以后全部欺骗
for i in gameList:
if i == CHEAT:
gameList[0] = CHEAT
return CHEAT
return COOPERATION
def detective(gameList, myList):
# 合作 欺骗 合作 合作,如果反击,则变为copyCat 否则变为 allCheat
gameTimes = len(gameList)
if gameTimes > 3:
for i in range(0, 4):
if gameList[i] == CHEAT:
return copyCat(gameList[4:])
else:
return allCheat()
# 合作 欺骗 合作 合作
if gameTimes in [0, 2, 3]:
return COOPERATION
elif gameTimes == 1:
return COOPERATION
def copykitten(gameList, myList):
# 两报还一报
if len(gameList) < 2:
return COOPERATION
else:
if gameList[-1] == CHEAT and gameList[-2] == CHEAT:
return CHEAT
else:
return COOPERATION
def random(gameList, myList):
# 随机返回欺骗还是合作
return np.random.randint(0, 2)
def simpleton(gameList, myList):
#会先合作。如果对方合作,我会做出跟上一轮一样的选择,即使上一轮犯错了也一样。否则会做出跟上一轮相反的选择。
if len(gameList) == 0:
return COOPERATION
if gameList[-1] == COOPERATION:
return myList[-1]
else:
return 1 if myList[-1] == 0 else 1
def getScore(actionA, actionB):
return pay_off[2 * actionA + actionB]
def playGame(playerDistribution):
# 初始化playGroundList
playerList = playerDistribution.keys
playGroundList = []
for k, v in playerDistribution.items():
for i in range(v):
playGroundList.append(agent(_type=k))
# 每个player之间两两进行游戏
for i in range(len(playGroundList)):
for j in range(i + 1, len(playGroundList)):
gameHistoryI = []
gameHistoryJ = []
for k in range(GAMETIMES):
# 根据对方历史行为作出反应
actionA = eval(playGroundList[i].type)(gameHistoryJ, gameHistoryI)
actionB = eval(playGroundList[j].type)(gameHistoryI, gameHistoryJ)
# 添加自己的历史行为
gameHistoryI.append(actionA)
gameHistoryJ.append(actionB)
# 引入随机差错(变异)
if MISTAKERATE + np.random.rand() >= 1.0:
actionA = 0 if actionA == 1 else 1
if MISTAKERATE + np.random.rand() >= 1.0:
actionB = 0 if actionB == 1 else 1
# 计算当前得分
scoreI, scoreJ = getScore(actionA, actionB)
# 更新历史得分
playGroundList[i].score += scoreI
playGroundList[j].score += scoreJ
playGroundList = sorted(playGroundList, key=lambda x:x.score, reverse=True)
# 淘汰
for i in range(RECORY):
playGroundList.pop()
# 复制
for i in range(RECORY):
playGroundList.append(copy.copy(playGroundList[i]))
newPlayerDistribution = {}
# 获取每轮元素的比例
for player in playGroundList:
newPlayerDistribution.setdefault(player.type ,0)
newPlayerDistribution[player.type] += 1
return newPlayerDistribution
if __name__ == '__main__':
distribution = {
'allCheat': 13,
#'allCooperation': 13,
'copyCat': 3,
'random':3,
'copykitten':3,
'simpleton':3
}
init_distribution = copy.deepcopy(distribution)
distribution_df = pd.DataFrame(init_distribution, index=[0])
print(distribution_df)
for i in range(70):
print('Iter: '+ str(i))
distribution = playGame(distribution)
distribution_df = distribution_df.append (distribution, ignore_index=True)
distribution_df.replace (np.nan, 0, inplace=True)
print (distribution)
distribution_df.plot()
plt.show()