添加EID,唉

This commit is contained in:
wjsjwr 2018-09-23 23:27:01 +08:00
parent 1ccb752566
commit 3180c88173
15 changed files with 367 additions and 56 deletions

24
calc_avg_tr.py Normal file
View File

@ -0,0 +1,24 @@
from island.match import Match
from island.matches import Matches
import numpy as np
import csv
def calc(mode):
matches = Matches.from_profile_expr(lambda a: mode in a)
trs = 0
acts = 0
for m in matches.data:
maxr = int(m.query('game', 'created').first()['info']['game_end_at'])
for r in range(1, maxr+1):
rows = m.query('action', 'done').where(lambda x: x['rno'] == r).raw_data
for row in rows:
trs += row['tr']
acts += len(rows)
return trs, acts, trs / acts
if __name__ == '__main__':
print(calc('CLASSIC'))
print(calc('SURVIVE'))

35
calc_coopr_rate.py Normal file
View File

@ -0,0 +1,35 @@
from island.match import Match
from island.matches import Matches
import numpy as np
import csv
def calcAndSave(mode):
matches = Matches.from_profile(mode)
times = np.zeros(15)
cs = np.zeros(15)
for m in matches.data:
maxr = int(m.query('game', 'created').first()['info']['game_end_at'])
for r in range(1, maxr+1):
rows = m.query('action', 'done').where(lambda x: x['rno'] == r).raw_data
coop = 0
for row in rows:
if row['act_a'] == 'C':
coop += 1
if row['act_b'] == 'C':
coop += 1
if rows:
times[r-1] += len(rows) * 2
cs[r-1] += coop
for i in range(15):
if(times[i] == 0):
times[i] = 1
cs /= times
with open("outputs/CR_%s.csv"%mode, 'w') as f:
csv.writer(f).writerow(cs)
if __name__ == '__main__':
calcAndSave('CLASSIC')
calcAndSave('SURVIVE')

View File

@ -1,50 +0,0 @@
import json
from matplotlib import pyplot as plt
from island.match import Match
from island.matches import Matches
import numpy as np
matches = Matches.from_profile_expr(lambda r: 'CLASSIC' in r)
max_round = 15
coopr = []
yerr_min = []
yerr_max = []
x = np.arange(1, max_round+1)
bx = []
survivals = {}
with open('survivals.json','r') as f:
survivals = json.load(f)
for i in range(max_round):
co = []
for j in range(len(matches.data)):
coop = 0
rows = matches.data[j].query('action', 'done').where(lambda x: x['rno']==i+1).raw_data
for row in rows:
if row['act_a'] == 'C' and row['act_b'] == 'C':
coop += 1
if rows:
co.append(float(coop) / float(len(rows)))
bx.append(co)
if co:
coopr.append(sum(co) / len(co))
yerr_min.append(coopr[-1] - min(co))
yerr_max.append(max(co) - coopr[-1])
print("%f, %f, %f"%(yerr_min[-1], yerr_max[-1], coopr[-1]))
else:
coopr.append(0)
plt.figure()
# plt.errorbar(x, coopr, yerr=[yerr_min, yerr_max], fmt='o', capsize=4)
# plt.boxplot(bx, showmeans=True, meanline=True)
plt.plot(x, coopr)
plt.show()
# plt.savefig('graph/co_per_round.png')

168
eid_calc.py Normal file
View File

@ -0,0 +1,168 @@
"""
计算E_{i,D}
E_{i,D}=所有邻居的剩余时间 - (背叛对象的剩余时间 + 与背叛对象的上轮交互时间)
=除去背叛对象的剩余时间 - 背叛对象的上一轮交互时间
输出
1. json格式(详细)
{
"GID": {
"RID": {
"PID": EID,
}
}
}
2. CSV格式(按轮平均值, CLASSIC/SURVIVE分别对应一个文件)
"""
import csv
import json
from functools import reduce
import numpy as np
from island.match import Match
from island.matches import Matches
class Eid:
def __init__(self):
self.survivals = {}
with open('outputs/survivals.json','r') as f:
self.survivals = json.load(f)
self.neighbors = {}
with open('outputs/neighborhood.json', 'r') as f:
self.neighbors = json.load(f)
self.seasonSurvive = Matches.from_profile('SURVIVE')
self.seasonClassic = Matches.from_profile('CLASSIC')
def getNeighborTR(self, m, r, p, s, d):
"""
获取该玩家所有邻居中除去背叛对象的剩余时间
:param m: Match
:param r: Round ID
:param p: PID
:param s: Survivals list(neighborhood)
:param d: list of victim
:returns: E_{i}
"""
truenb = [i for i in s if i not in d]
trs = dict.fromkeys(truenb, 1440)
req = m.query('action', 'request').where(lambda x: x['rno'] == r and x['from'] in truenb and x['to'] != p)
for d in req.raw_data:
trs[d['from']] -= d['tr']
for d in m.query('action', 'approve').where(lambda x: x['rno'] == r and x['from'] in truenb and x['to'] != p).raw_data:
trs[d['from']] -= d['tr']
for d in m.query('action', 'cancel').where(lambda x: x['rno'] == r and x['from'] in truenb and x['to'] != p).raw_data:
trs[d['from']] += req.where(lambda x: x['from'] == d['from'] and x['to'] == d['to'] and x['log_id'] < d['log_id']).orderby('log_id').raw_data[-1]['tr']
for d in m.query('action', 'deny').where(lambda x: x['rno'] == r and x['to'] in truenb and x['from'] != p).raw_data:
trs[d['to']] += req.where(lambda x: x['from'] == d['to'] and x['to'] == d['from'] and x['log_id'] < d['log_id']).orderby('log_id').raw_data[-1]['tr']
return reduce(lambda x,y: x + max(0,min(y,1440)), trs.values(), 0)
def getNeighborhood(self, m, r, p):
"""
获取该玩家当轮存活邻居
:param m: Match
:param r: Round ID
:param p: PID
:returns: Survivals list(neighborhood)
"""
if str(p) not in self.neighbors[m.name]:
print("Alone(%d)!" % p)
return []
return [i for i in self.survivals[m.name][str(r)] if i in self.neighbors[m.name][str(p)]]
def getVictims(self, m, r, p):
"""
获取该玩家当轮的背叛对象以及与他们的博弈时间资源之和
:param m: Match
:param r: Round ID
:param p: PID
:returns: sum of tr and a list of victim
"""
victim = []
ans = 0
for d in m.query('action', 'done').where(lambda x: x['rno'] == r and (x['a'] == p or x['b'] == p)).raw_data:
if d['a'] == p and d['act_a'] == 'D':
victim.append(d['b'])
ans += d['tr']
elif d['b'] == p and d['act_b'] == 'D':
victim.append(d['a'])
ans += d['tr']
return (ans, victim)
def getVictims2(self, m, r, p):
"""
获取该玩家当轮的背叛对象以及与他们的博弈时间资源之和
## 悲观假设背叛上一轮所有博弈对象
:param m: Match
:param r: Round ID
:param p: PID
:returns: sum of tr and a list of victim
"""
victim = []
ans = 0
for d in m.query('action', 'done').where(lambda x: x['rno'] == r-1 and (x['a'] == p or x['b'] == p)).raw_data:
victim.append(d['b'] if d['a'] == p else d['a'])
ans += d['tr']
return (ans, victim)
def calcRoundData(self, m, r):
"""
计算某场比赛某一轮的Eid值
:param m: Match
:param r: Round ID
:param p: PID
:returns: an average value and a detail dict
"""
ans = {}
sigma = 0.0
for p in self.survivals[m.name][str(r)]:
u, v = self.getVictims2(m, r+1, p)
e = max(0, min(1440, self.getNeighborTR(m, r, p, self.getNeighborhood(m, r, p), v))) - u
ans[p] = e
sigma += e
return (sigma, ans)
def calc(self):
detail = {}
avgC = np.zeros(15)
avgS = np.zeros(15)
cnt = np.zeros(15)
for m in self.seasonClassic.data:
d = {}
maxr = int(m.query('game', 'created').first()['info']['game_end_at'])
for r in range(1, maxr+1):
sigma, ans = self.calcRoundData(m, r)
d[r] = ans
avgC[r-1] += sigma
cnt[r-1] += len(ans)
detail[m.name] = d
avgC /= cnt
cnt = np.zeros(15)
for m in self.seasonSurvive.data:
d = {}
maxr = int(m.query('game', 'created').first()['info']['game_end_at'])
for r in range(1, maxr+1):
sigma, ans = self.calcRoundData(m, r)
d[r] = ans
avgS[r-1] += sigma
cnt[r-1] += len(ans)
detail[m.name] = d
avgS /= cnt
with open('outputs/EID_CLASSIC.csv', 'w') as f:
csv.writer(f).writerow(avgC)
with open('outputs/EID_SURVIVE.csv', 'w') as f:
csv.writer(f).writerow(avgS)
with open('outputs/EID_detail.json', 'w') as f:
json.dump(detail, f)
if __name__ == '__main__':
e = Eid()
e.calc()

99
eid_plot.py Normal file
View File

@ -0,0 +1,99 @@
import numpy as np
from matplotlib import pyplot as plt
import scipy as sp
from scipy.stats import pearsonr
from matplotlib import markers
blue = '#0984e3'
red = '#d63031'
def error(f,x,y):
return sp.sum((f(x)-y)**2)
def p1(x, coopr, e, postfix, show=True):
fig = plt.figure(figsize=(4.5, 3))
ax = fig.gca()
ax.plot(x, coopr, color=blue, linewidth=2, label="$f_c$")
ax.set_ylim(0, 1)
ax.set_yticks(sp.linspace(0, 1, 5))
ax2 = ax.twinx()
ax2.plot(x, e, color=red, linewidth=2, label=r"$E_{i,D}$")
# ax2.set_ylim(0, 1440)
# ax2.set_yticks(sp.linspace(0, 1440, 5))
ax2.tick_params(labelsize=18)
ax.tick_params(labelsize=18)
ax.set_xlim(1, 15)
ax.set_xlabel("Rounds", size=22)
ax.set_ylabel(r"$f_c$", family='sans-serif', color=blue, size=22)
ax.tick_params(axis='y', labelcolor=blue)
ax2.set_ylabel(r"$E_{i,D}$", family='sans-serif', color=red, size=22)
ax2.tick_params(axis='y', labelcolor=red)
plt.tight_layout()
if show:
plt.show()
else:
plt.savefig("graph/eid_co_plot_%s.eps" % postfix)
def p2(e, coopr, postfix, show=True):
# p2散点图
fig = plt.figure(figsize=(4, 3))
ax = fig.gca()
fp1,residuals,rank,sv,rcond = sp.polyfit(e, coopr, 1, full=True)
print("残差:",residuals)
print('Model parameter:',fp1)
print("Other parameters: rank=%s, sv=%s, rcond=%s"%(str(rank), str(sv), str(rcond)))
f1 = sp.poly1d(fp1)
print("error= %f" % error(f1, e, coopr))
fx = sp.linspace(np.min(e), np.max(e), 2)
plt.plot(fx,f1(fx),linewidth=2,color=red, ls='--', zorder=0)
plt.scatter(e, coopr, color='white', edgecolors=blue, linewidths=2, zorder=101)
ax.set_xlabel(r'$E_{i,D}$', family='sans-serif', size=20)
ax.set_ylabel(r'$f_{c}$', family='sans-serif', size=20)
# ax.set_xlim(0, 1440)
# ax.set_xticks(sp.linspace(0, 1440, 5))
ax.tick_params(labelsize=14)
ax.set_ylim(0.5, 1)
ax.set_yticks(sp.linspace(0.5, 1, 5))
plt.tight_layout()
if show:
plt.show()
else:
plt.savefig("graph/eid_co_sca_%s.eps" % postfix)
# 皮尔逊相关系数
print("pearson: %f, p-value: %f" % pearsonr(e, coopr))
if __name__ == '__main__':
mode = 'CLASSIC'
mode = 'SURVIVE'
show = False
show = True
coopr = np.loadtxt("outputs/CR_%s.csv"%mode, delimiter=',')
x = np.arange(1, 16)
e = np.loadtxt("outputs/EID_%s.csv"%mode, delimiter=',')
p1(x,coopr, e, mode, show)
# p2(e, coopr, mode, show)
"""
SURVIVE
残差 [ 0.10769174]
Model parameter: [ 1.33390242e-04 7.29761895e-01]
Other parameters: rank=2, sv=[ 1.37254846 0.34075025], rcond=3.33066907388e-15
error= 0.107692
pearson: 0.709599, p-value: 0.003045
CLASSIC
残差 [ 0.00992721]
Model parameter: [ 3.14661037e-05 7.35284315e-01]
Other parameters: rank=2, sv=[ 1.41231835 0.07319068], rcond=3.33066907388e-15
error= 0.009927
pearson: 0.309326, p-value: 0.261915
"""

25
gen_neighborhood.py Normal file
View File

@ -0,0 +1,25 @@
import json
from island.matches import Matches
matches = Matches.from_profile_expr(lambda r:True)
neighbors = {}
for i in range(len(matches.data)):
m = matches.data[i]
n = {}
for r in m.query('neighbor', 'create').raw_data:
if r['a'] in n:
n[r['a']].append(r['b'])
else:
n[r['a']] = [r['b']]
if r['b'] in n:
n[r['b']].append(r['a'])
else:
n[r['b']] = [r['a']]
neighbors[matches.names[i]] = n
with open('outputs/neighborhood.json', 'w') as f:
json.dump(neighbors, f)

1
outputs/CR_CLASSIC.csv Normal file
View File

@ -0,0 +1 @@
0.771505376344,0.8,0.825980392157,0.848258706468,0.828431372549,0.829383886256,0.837320574163,0.847087378641,0.842592592593,0.842723004695,0.820754716981,0.80487804878,0.783018867925,0.766666666667,0.788461538462
1 0.771505376344 0.8 0.825980392157 0.848258706468 0.828431372549 0.829383886256 0.837320574163 0.847087378641 0.842592592593 0.842723004695 0.820754716981 0.80487804878 0.783018867925 0.766666666667 0.788461538462

1
outputs/CR_SURVIVE.csv Normal file
View File

@ -0,0 +1 @@
0.820512820513,0.784722222222,0.842465753425,0.879581151832,0.939024390244,0.949324324324,0.97265625,0.995833333333,0.987288135593,0.973214285714,0.972602739726,0.872549019608,0.518518518519,0.857142857143,1.0
1 0.820512820513 0.784722222222 0.842465753425 0.879581151832 0.939024390244 0.949324324324 0.97265625 0.995833333333 0.987288135593 0.973214285714 0.972602739726 0.872549019608 0.518518518519 0.857142857143 1.0

1
outputs/EID_CLASSIC.csv Normal file
View File

@ -0,0 +1 @@
180.0,-41.8604651163,-124.186046512,-69.7674418605,-44.6511627907,-164.651162791,-69.7674418605,-92.0930232558,-97.6744186047,-101.860465116,-209.032258065,-213.71024735,-104.939271255,-165.755395683,-649.411764706
1 180.0 -41.8604651163 -124.186046512 -69.7674418605 -44.6511627907 -164.651162791 -69.7674418605 -92.0930232558 -97.6744186047 -101.860465116 -209.032258065 -213.71024735 -104.939271255 -165.755395683 -649.411764706

1
outputs/EID_SURVIVE.csv Normal file
View File

@ -0,0 +1 @@
-58.293956044,-788.740365112,-833.236533958,-1329.43820225,-1278.73417722,-1369.30909091,-1370.60240964,-1343.59832636,-1427.42358079,-1392.89719626,-1440.0,-1440.0,-1390.34482759,-1440.0,-1152.0
1 -58.293956044 -788.740365112 -833.236533958 -1329.43820225 -1278.73417722 -1369.30909091 -1370.60240964 -1343.59832636 -1427.42358079 -1392.89719626 -1440.0 -1440.0 -1390.34482759 -1440.0 -1152.0

1
outputs/EID_detail.json Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
outputs/survivals.json Normal file

File diff suppressed because one or more lines are too long

1
outputs/winner.json Normal file
View File

@ -0,0 +1 @@
{"G153": [], "G203": [], "G254": [], "G272": [3170], "G285": [], "G295": [], "G299": [3558, 3559, 3563, 3575], "G302": [3649], "G307": [3896, 3901], "G318": [3965, 3967, 3970, 3973], "G337": [], "G341": [4462, 4463, 4464, 4476], "G349": [4558, 4559], "G354": [4614, 4615, 4616, 4618, 4623, 4624], "G54": [], "G68": [], "G72": [], "G75": [], "G86": []}

View File

@ -33,7 +33,7 @@ def p1(x, coopr, tau, postfix, show=True):
ax2.set_ylabel(r"$\tau_{f}$", family='sans-serif', color=red, size=22) ax2.set_ylabel(r"$\tau_{f}$", family='sans-serif', color=red, size=22)
ax2.tick_params(axis='y', labelcolor=red) ax2.tick_params(axis='y', labelcolor=red)
fig.legend(fontsize=18) # fig.legend(fontsize=18)
plt.tight_layout() plt.tight_layout()
if show: if show:
plt.show() plt.show()
@ -154,7 +154,8 @@ if __name__ == '__main__':
print("[%s(%d)] alone: %d" % (matches.names[j], i+1, k)) print("[%s(%d)] alone: %d" % (matches.names[j], i+1, k))
else: else:
t = 1440 * len(neighbors[matches.names[j]][k]) t = 1440 * len(neighbors[matches.names[j]][k])
tp.append(t if t < 1440 else 1440) # tp.append(t if t < 1440 else 1440)
tp.append(t)
mwTau["%s-%d"%(j,i)] = tp[-1] mwTau["%s-%d"%(j,i)] = tp[-1]
else: else:
if str(i) not in survivals[matches.names[j]]: if str(i) not in survivals[matches.names[j]]:
@ -167,8 +168,9 @@ if __name__ == '__main__':
trs = matches.data[j].get_tr(i, k, neighbors[matches.names[j]][k], survivals[matches.names[j]][str(i)]) trs = matches.data[j].get_tr(i, k, neighbors[matches.names[j]][k], survivals[matches.names[j]][str(i)])
for l in neighbors[matches.names[j]][k]: for l in neighbors[matches.names[j]][k]:
if l in trs and trs[l] > 0: if l in trs and trs[l] > 0:
t += trs[l] t += trs[l] if trs[l] < 1440 else 1440
tp.append(t if t < 1440 else 1440) tp.append(t if t < 1440 else 1440)
# tp.append(t)
mwTau["%s-%d"%(j,i)] = tp[-1] mwTau["%s-%d"%(j,i)] = tp[-1]
if tp: if tp:
@ -182,10 +184,10 @@ if __name__ == '__main__':
# p1折线图 # p1折线图
# p1(x, coopr, tau, 'classic', False) # p1(x, coopr, tau, 'classic', False)
# p1(x, coopr, tau, 'survive', False) # p1(x, coopr, tau, 'survive', True)
p2(tau[:12], coopr[:12], 720, 'survive', False) p2(tau[:12], coopr[:12], 1322, 'survive', True)
# p2(tau, coopr, 720, 'classic', False) # p2(tau, coopr, 1399, 'classic', True)
''' '''