123 lines
3.5 KiB
Python
123 lines
3.5 KiB
Python
"""
|
||
计算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()
|