""" 计算theta_r theta_r_i=所有邻居的剩余时间 输出: 1. json格式(详细) { "GID": { "RID": { "PID": theta_r_i, } } } 2. CSV格式(按轮平均值, CLASSIC/SURVIVE分别对应一个文件) """ import csv import json from functools import reduce from sre_constants import MAX_REPEAT from tkinter.tix import MAX import numpy as np from island.match import Match from island.matches import Matches MAX_ROUND = 28 class theta_r_i: def __init__(self): self.details = {} self.survivals = {} with open('outputs/survivals_new.json','r') as f: self.survivals = json.load(f) self.neighbors = {} with open('outputs/neighborhood_new.json', 'r') as f: self.neighbors = json.load(f) self.seasons = [ dict(season=Matches('wos-data-2022', network_type='BA'), name='NEW_BA'), dict(season=Matches('wos-data-2022', network_type='WS'), name='NEW_WS') ] # self.seasonSurvive = Matches.from_profile('SURVIVE') # self.seasonClassic = Matches.from_profile('CLASSIC') def getNeighborTR(self, m, r, p, s): """ 获取该玩家所有邻居的剩余时间 :param m: Match :param r: Round ID :param p: PID :param s: Survivals list(neighborhood) :returns: theta_{r}_{i} """ return 1440*len(s) - reduce(lambda a, b: a + b['tr'], m.query('action', 'done').where(lambda x: x['rno'] == r and ((x['a'] in s)or(x['b']in s))).raw_data, 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 calcRoundData(self, m, r): """ 计算某场比赛,某一轮的theta值 :param m: Match :param r: Round ID :param p: PID :returns: an average value and a detail dict """ r += 1 ans = {} sigma = 0.0 for p in self.survivals[m.name][str(r)]: e = max(0, min(144000000, self.getNeighborTR(m, r, p, self.getNeighborhood(m, r, p)))) ans[p] = e sigma += e return (sigma, ans) def calc_season(self, season, name): """ calc E_i,D """ avg = np.zeros(MAX_ROUND) cnt = np.zeros(MAX_ROUND) for m in season.data: d = {} maxr = int(m.query('game', 'created').first()['info']['game_end_at']) for r in range(1, maxr): sigma, ans = self.calcRoundData(m, r) d[r] = ans avg[r-1] += sigma cnt[r-1] += len(ans) self.details[m.name] = d print(cnt) for i in range(MAX_ROUND): if cnt[i] == 0: cnt[i] = 1 avg /= cnt with open(f'outputs/EID_{name}.csv', 'w') as f: csv.writer(f).writerow(avg) return avg def calc(self): for s in self.seasons: self.calc_season(s['season'], s['name']) with open('outputs/EID_new_detail.json', 'w') as f: json.dump(self.details, f) if __name__ == '__main__': e = theta_r_i() e.calc()