diff --git a/.gitignore b/.gitignore index ce5e416..4207bac 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ graph wos-data-new wos-data-casual *.svg -__pycache__ \ No newline at end of file +__pycache__ +.vscode/ \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index e1258fd..7dc64af 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,3 @@ { - "python.pythonPath": "/Users/wjsjwr/.pyenv/versions/anaconda3-5.0.1/bin/python" + "python.pythonPath": "C:\\Users\\wjs\\Anaconda3\\python.exe" } \ No newline at end of file diff --git a/coopr_per_round.py b/coopr_per_round.py index 0b6f1aa..011eeda 100644 --- a/coopr_per_round.py +++ b/coopr_per_round.py @@ -2,14 +2,15 @@ import json from matplotlib import pyplot as plt from island.match import Match from island.matches import Matches +import numpy as np matches = Matches('wos-data-new') -max_round = 17 +max_round = 15 coopr = [] yerr_min = [] yerr_max = [] -x = [] +x = np.arange(1, max_round+1) bx = [] survivals = {} @@ -36,10 +37,11 @@ for i in range(max_round): 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])) - x.append(i+1) + plt.figure() # plt.errorbar(x, coopr, yerr=[yerr_min, yerr_max], fmt='o', capsize=4) -plt.boxplot(bx, showmeans=True, meanline=True) -# plt.show() -plt.savefig('graph/co_per_round.png') \ No newline at end of file +# plt.boxplot(bx, showmeans=True, meanline=True) +plt.plot(x, coopr) +plt.show() +# plt.savefig('graph/co_per_round.png') \ No newline at end of file diff --git a/interactions_per_round.py b/interactions_per_round.py index ec745dc..65c899c 100644 --- a/interactions_per_round.py +++ b/interactions_per_round.py @@ -5,7 +5,7 @@ from island.matches import Matches import numpy as np matches = Matches('wos-data-new') -max_round = 15 +max_round = 14 coopr = [] yerr_min = [] @@ -54,11 +54,11 @@ ax = fig.gca() ax.stackplot(x+1, y, labels=labels, colors=colors) ax.set_xticks(x+1) ax.set_xticklabels(x+1) -ax.set_xlim(1,15) +ax.set_xlim(1,max_round) ax.set_ylim(0, 1) ax.set_xlabel('Round') ax.set_ylabel('Fraction of k') ax.legend() plt.tight_layout() -# plt.show() -plt.savefig('graph/interaction_per_round.eps') \ No newline at end of file +plt.show() +# plt.savefig('graph/interaction_per_round.eps') \ No newline at end of file diff --git a/k_and_new_partner.py b/k_and_new_partner.py new file mode 100644 index 0000000..1163a4d --- /dev/null +++ b/k_and_new_partner.py @@ -0,0 +1,113 @@ +import json +from matplotlib import pyplot as plt +from island.match import Match +from island.matches import Matches +import numpy as np +from scipy.stats import pearsonr + + +matches = Matches('wos-data-new') + +k = np.arange(2, 11) +succ = np.zeros(9) +total = np.zeros(9) + +survivals = {} +with open('survivals.json', 'r') as f: + survivals = json.load(f) + +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 + +for m_i in range(len(matches.data)): + m = matches.data[m_i] + info = m.query('game', 'created').select('info').first()['info'] + conf = json.loads(info['config']) + game_end_at = int(info['game_end_at']) + + for p in m.query('player', 'join').raw_data: + pid = p['pid'] + for i in range(2, game_end_at): + neighborhood = [] + if pid not in neighbors[matches.names[m_i]]: + break + for j in neighbors[matches.names[m_i]][pid]: + if j in survivals[matches.names[m_i]][str(i-1)]: + neighborhood.append(j) + if len(neighborhood) < 2: + break + previous_round_partner = [] + for r in m.query('action', 'done').where(lambda x: x['rno']==i-1 and (x['a']==pid or x['b']==pid)).raw_data: + if r['a'] == pid: + previous_round_partner.append(r['b']) + else: + previous_round_partner.append(r['a']) + new_partner_request = 0 + for r in m.query('action', 'request').where(lambda x: x['rno']==i and (x['from']==pid or x['to']==pid)).raw_data: + if r['from'] == pid: + if r['to'] not in previous_round_partner: + new_partner_request += 1 + else: + if r['from'] not in previous_round_partner: + new_partner_request += 1 + if new_partner_request == 0: + continue + new_partner_succ = 0 + for r in m.query('action', 'done').where(lambda x: x['rno']==i and (x['a']==pid or x['b']==pid)).raw_data: + if r['a'] == pid: + if r['b'] not in previous_round_partner: + new_partner_succ += 1 + else: + if r['a'] not in previous_round_partner: + new_partner_succ += 1 + succ[len(neighborhood)-2] += new_partner_succ + total[len(neighborhood)-2] += new_partner_request + + +red = '#d63031' +fig = plt.figure(figsize=(6.4, 4)) +ax = fig.gca() +bar_width = 0.35 +opacity = 1 +error_config = {'ecolor': '0.3', 'capsize': 4} +rects1 = ax.bar(k, succ, bar_width, + alpha=opacity, color='#00b894', + # yerr=c_req_suc_std, error_kw=error_config, + label='Success') +rects3 = ax.bar(k + bar_width, total, bar_width, + alpha=opacity, color='#fdcb6e', + # yerr=d_req_suc_mean, error_kw=error_config, + label='Requests') + +ax.set_xlabel('k') +ax.set_ylabel('Count') +# ax.set_title('Scores by group and gender') +ax.set_xticks(k + bar_width / 2) +ax.set_xticklabels(k) +ax.legend() +ax2 = ax.twinx() +ax2.plot(k, succ/total,linewidth=2,color=red, ls='--') +ax2.set_ylabel("Frequency of new partners", family='sans-serif', color=red) +ax2.tick_params(axis='y', labelcolor=red) +ax2.set_ylim(0,1) +fig.tight_layout() +# plt.show() +# plt.savefig('graph/k_and_new_partner.eps') + +print("[succ vs k]pearson: %f, p-value: %f" % pearsonr(succ, k)) +print("[total vs k]pearson: %f, p-value: %f" % pearsonr(total, k)) +print("[rate vs k]pearson: %f, p-value: %f" % pearsonr(succ/total, k)) +print(np.average(succ/total)) \ No newline at end of file diff --git a/tau_p_co.py b/tau_p_co.py new file mode 100644 index 0000000..bcd6d16 --- /dev/null +++ b/tau_p_co.py @@ -0,0 +1,206 @@ +import json +from matplotlib import pyplot as plt +from island.match import Match +from island.matches import Matches +import numpy as np +import scipy as sp +from scipy.stats import pearsonr +from matplotlib import markers + +def error(f,x,y): + return sp.sum((f(x)-y)**2) + +def get_tr(m, i, target, nb, sv): + """ + # 计算tau_p的方式是统计周围邻居剩余的tr + # 本函数计算第i轮,所有有消耗tr的player,最后剩余的tr + # 由于是计算剩余tr,所以不能计算和target之间的交互 + # nb是target的邻居 + """ + trs = {} + req = m.query('action', 'request').where(lambda x: x['rno'] == i+1) + app = m.query('action', 'approve').where(lambda x: x['rno'] == i+1).raw_data + can = m.query('action', 'cancel').where(lambda x: x['rno'] == i+1).raw_data + den = m.query('action', 'deny').where(lambda x: x['rno'] == i+1).raw_data + + fr = [] + for r in m.query('action', 'done').where(lambda x: x['rno'] == i and (x['a'] == target or x['b'] == target)).raw_data: + if r['a'] == target: + fr.append(r['b']) + elif r['b'] == target: + fr.append(r['a']) + + truenb = [] + for r in nb: + if r not in fr and r in sv: + truenb.append(r) + trs[r] = 1440 + + for r in req.raw_data: + if r['from'] in truenb and r['to'] != target : + if r['from'] not in trs: + trs[r['from']] = 1440 + trs[r['from']] -= r['tr'] + + for r in app: + if r['from'] in truenb and r['to'] != target: + if r['from'] not in trs: + trs[r['from']] = 1440 + trs[r['from']] -= r['tr'] + + for r in can: + if r['from'] in trs and r['to'] != target: + trs[r['from']] += req.where(lambda x: x['from'] == r['from'] and x['to'] == r['to'] and x['log_id'] < r['log_id']).orderby('log_id').raw_data[-1]['tr'] + + for r in den: + if r['to'] in trs and r['from'] != target: + trs[r['to']] += req.where(lambda x: x['from'] == r['to'] and x['to'] == r['from'] and x['log_id'] < r['log_id']).orderby('log_id').raw_data[-1]['tr'] + + return trs + + +matches = Matches('wos-data-new') +max_round = 15 + +survivals = {} +with open('survivals.json', 'r') as f: + survivals = json.load(f) + +neighbors = {} +coopr = [] +x = np.arange(1, max_round) +mwCo = {} # Match-wise frequency of cooperation +mwTau = {} # Match-wise Tau +bx = [] +tau = [] + +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 + +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': + coop += 1 + if row['act_b'] == 'C': + coop += 1 + + if rows: + co.append(float(coop) / float(len(rows)*2)) + mwCo["%s-%d"%(j,i)] = co[-1] + bx.append(co) + if co: + coopr.append(np.average(co)) + + +for i in range(max_round-1): + tp = [] + for j in range(len(matches.data)): + if i == 0: + for r in matches.data[j].query('player', 'join').raw_data: + t = 0 + k = r['pid'] + if k not in neighbors[matches.names[j]]: + print("[%s(%d)] alone: %d" % (matches.names[j], i+1, k)) + else: + t = 1440 * len(neighbors[matches.names[j]][k]) + tp.append(t if t < 1440 else 1440) + mwTau["%s-%d"%(j,i)] = tp[-1] + else: + if str(i) not in survivals[matches.names[j]]: + continue + for k in survivals[matches.names[j]][str(i)]: + t = 0 + if k not in neighbors[matches.names[j]]: + print("[%s(%d)] alone: %d" % (matches.names[j], i+1, k)) + else: + trs = get_tr(matches.data[j], i, k, neighbors[matches.names[j]][k], survivals[matches.names[j]][str(i)]) + for l in neighbors[matches.names[j]][k]: + if l in trs: + t += trs[l] + tp.append(t if t < 1440 else 1440) + mwTau["%s-%d"%(j,i)] = tp[-1] + + if tp: + tau.append(np.average(tp)) + else: + tau.append(0) + + +blue = '#0984e3' +red = '#d63031' + +# p1折线图 +# fig = plt.figure(figsize=(6.4, 3.6)) +# ax = fig.gca() +# ax.plot(x, coopr, color=blue, linewidth=3) +# ax.set_ylim(0.5, 1) +# ax2 = ax.twinx() +# ax2.plot(x, tau, color=red, linewidth=3) +# ax2.set_ylim(0,1440) +# ax.set_xlim(1,14) +# ax.set_xlabel("Rounds") +# ax.set_ylabel("Frequency of Cooperation", color=blue) +# ax.tick_params(axis='y', labelcolor=blue) +# ax2.set_ylabel("$\\tau_{p}$", family='sans-serif', color=red) +# ax2.tick_params(axis='y', labelcolor=red) + +# plt.tight_layout() +# # plt.show() +# plt.savefig('graph/tau_p_co_plot.eps') + +tau2 = [] +coopr2 = [] +tau_r = [] +coopr_r = [] +for i in range(len(tau)): + if tau[i] <= 720: + tau2.append(tau[i]) + coopr2.append(coopr[i]) + else: + tau_r.append(tau[i]) + coopr_r.append(coopr[i]) + +# p2散点图 +fig = plt.figure(figsize=(6.4, 3.6)) +ax = fig.gca() +# ax.set_ylim(0.5, 1) +fp1,residuals,rank,sv,rcond = sp.polyfit(tau2, coopr2, 1, full=True) +print("残差:",residuals) +print('Model parameter:',fp1) +f1 = sp.poly1d(fp1) +print("error= %f" % error(f1, tau2, coopr2)) +# fx = sp.linspace(0,max(tau2),1000) +fx = sp.linspace(0,720,2) + +plt.plot(fx,f1(fx),linewidth=2,color=red, ls='--', zorder=0) +plt.scatter(tau2, coopr2, color=blue, linewidths=2, zorder=100) +plt.scatter(tau_r, coopr_r, color='white', edgecolors=blue, linewidths=2, zorder=101) +ax.set_xlabel('$\\tau_{p}$', family='sans-serif') +ax.set_ylabel('Frequency of Cooperation') +ax.set_xlim(0, 1440) +ax.set_xticks(sp.linspace(0, 1440, 13)) +ax.set_ylim(0.5, 1) +plt.tight_layout() +plt.show() +# plt.savefig('graph/tau_p_co_sca.eps') + + + +# 皮尔逊相关系数 +print("pearson: %f, p-value: %f" % pearsonr(tau2, coopr2)) \ No newline at end of file