diff --git a/.vscode/settings.json b/.vscode/settings.json index 7dc64af..e1258fd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,3 @@ { - "python.pythonPath": "C:\\Users\\wjs\\Anaconda3\\python.exe" + "python.pythonPath": "/Users/wjsjwr/.pyenv/versions/anaconda3-5.0.1/bin/python" } \ No newline at end of file diff --git a/dist_of_k.py b/dist_of_k.py new file mode 100644 index 0000000..6484007 --- /dev/null +++ b/dist_of_k.py @@ -0,0 +1,45 @@ +import json +from matplotlib import pyplot as plt +from island.match import Match +from island.matches import Matches +from numpy import mean, std +import numpy as np + + +matches = Matches('wos-data-new') +max_round = 15 + + + +fig = plt.figure(figsize=(6.4, 3.6)) +ax = fig.gca() +index = np.arange(11) +ax.set_xlabel('k') +ax.set_ylabel('p(k)') + +c = ['#00b894','#00cec9','#0984e3','#6c5ce7','#e84393','#d63031','#e17055','#fdcb6e','#2d3436','#6ab04c','#30336b','#ED4C67'] + +for i in range(len(matches.data)): + k = np.zeros(11) + 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']] + for j in n.keys(): + k[len(n[j])] += 1 + pk = k / np.sum(k) + print(i) + ax.scatter(index, pk, color=c[i]) + +# ax.set_title('Scores by group and gender') +fig.tight_layout() +plt.show() +# plt.savefig('graph/neigh_per_round.eps') \ No newline at end of file diff --git a/island/match.py b/island/match.py index 59bbae8..ad89b88 100644 --- a/island/match.py +++ b/island/match.py @@ -95,6 +95,55 @@ class Match: return len(self.raw_data) + + def get_tr(self, i, target, nb, sv): + """ + # 计算tau_p的方式是统计周围邻居剩余的tr + # 本函数计算第i轮,所有有消耗tr的player,最后剩余的tr + # 由于是计算剩余tr,所以不能计算和target之间的交互 + # nb是target的邻居 + """ + trs = {} + req = self.query('action', 'request').where(lambda x: x['rno'] == i+1) + app = self.query('action', 'approve').where(lambda x: x['rno'] == i+1).raw_data + can = self.query('action', 'cancel').where(lambda x: x['rno'] == i+1).raw_data + den = self.query('action', 'deny').where(lambda x: x['rno'] == i+1).raw_data + + fr = [] + for r in self.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 + @staticmethod def read_from_json(json_path): """ diff --git a/tau_p_co.py b/tau_p_co.py index bcd6d16..e5a8a1e 100644 --- a/tau_p_co.py +++ b/tau_p_co.py @@ -10,197 +10,150 @@ 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 +if __name__ == '__main__': - 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']) + matches = Matches('wos-data-new') + max_round = 15 - truenb = [] - for r in nb: - if r not in fr and r in sv: - truenb.append(r) - trs[r] = 1440 + survivals = {} + with open('survivals.json', 'r') as f: + survivals = json.load(f) - 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'] + neighbors = {} + coopr = [] + x = np.arange(1, max_round) + mwCo = {} # Match-wise frequency of cooperation + mwTau = {} # Match-wise Tau + bx = [] + tau = [] - 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 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']] - 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'] + if r['b'] in n: + n[r['b']].append(r['a']) + else: + n[r['b']] = [r['a']] + neighbors[matches.names[i]] = n - 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'] + 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 - return trs + 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)) -matches = Matches('wos-data-new') -max_round = 15 + 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 = 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]: + if l in trs: + t += trs[l] + tp.append(t if t < 1440 else 1440) + mwTau["%s-%d"%(j,i)] = tp[-1] -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']) + if tp: + tau.append(np.average(tp)) else: - n[r['a']] = [r['b']] + tau.append(0) - if r['b'] in n: - n[r['b']].append(r['a']) + + 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: - n[r['b']] = [r['a']] - neighbors[matches.names[i]] = n + tau_r.append(tau[i]) + coopr_r.append(coopr[i]) -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 + # 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) - 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') + 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 + # 皮尔逊相关系数 + print("pearson: %f, p-value: %f" % pearsonr(tau2, coopr2)) \ No newline at end of file diff --git a/taup_and_new_partner.py b/taup_and_new_partner.py new file mode 100644 index 0000000..e474f88 --- /dev/null +++ b/taup_and_new_partner.py @@ -0,0 +1,122 @@ +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(0, 1441, 144) +succ = np.zeros(11) +total = np.zeros(11) + +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 + t = 0 + trs = m.get_tr(i, pid, neighbors[matches.names[m_i]][pid], survivals[matches.names[m_i]][str(i-1)]) + for l in neighborhood: + if l in trs: + t += trs[l] + t = t if t <= 1440 else 1440 + succ[t//144] += new_partner_succ + total[t//144] += 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() +ax.plot(k, succ, color='#00b894', lw=2, marker='*', ls='none') +ax.plot(k, total, color='#fdcb6e', lw=2, marker='+', ls='none') +for i in range(11): + if total[i] == 0: + total[i] = 1 +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