103 lines
4.0 KiB
Python
103 lines
4.0 KiB
Python
"""
|
|
统计所有的连通子图规模
|
|
"""
|
|
import csv
|
|
import json
|
|
import numpy as np
|
|
from collections import Counter
|
|
from island.matches import Matches
|
|
from island.match import Match
|
|
from matplotlib import pyplot as plt
|
|
|
|
class ClusterStat:
|
|
def __init__(self, cb):
|
|
self.detail = {}
|
|
# self.matches = Matches.from_profile_expr(lambda r: True)
|
|
self.matches = Matches.from_profile('SURVIVE')
|
|
self.life = {} # key(size), value(list of cluster-life)
|
|
self.cluster_born = cb
|
|
|
|
|
|
def stat(self):
|
|
for m in self.matches.data:
|
|
cluster = {}
|
|
dick = {}
|
|
no = 0
|
|
cluster_life = {}
|
|
for r in m.query('player','join').raw_data:
|
|
cluster[r['pid']] = no
|
|
no += 1
|
|
for r in m.query('action', 'done').raw_data:
|
|
if cluster[r['a']] != cluster[r['b']]:
|
|
if cluster[r['a']] < cluster[r['b']]:
|
|
cmax, cmin = cluster[r['b']], cluster[r['a']]
|
|
else:
|
|
cmax, cmin = cluster[r['a']], cluster[r['b']]
|
|
if self.cluster_born == 1 or ((cmin,cmax) in dick and dick[(cmin,cmax)] > self.cluster_born - 1):
|
|
#link
|
|
lmax = [k for (k,v) in cluster.items() if v == cmax]
|
|
for k in lmax:
|
|
cluster[k] = cmin
|
|
else:
|
|
if (cmin, cmax) not in dick:
|
|
dick[(cmin, cmax)] = 1
|
|
else:
|
|
dick[(cmin, cmax)] += 1
|
|
info = m.query('game', 'created').select('info').first()['info']
|
|
conf = json.loads(info['config'])
|
|
game_end_at = int(info['game_end_at'])
|
|
foods = {}
|
|
for p in m.query('player', 'join').select('pid').raw_data:
|
|
foods[p['pid']] = conf['start_resource']
|
|
|
|
for i in range(1, game_end_at + 1):
|
|
for a in m.query('action', 'done').where(lambda x: x['rno'] == i).raw_data:
|
|
foods[a['a']] += conf['payoffs']["%s%s" % (a['act_a'], a['act_b'])][0] * a['tr'] / 1440.0
|
|
foods[a['b']] += conf['payoffs']["%s%s" % (a['act_a'], a['act_b'])][1] * a['tr'] / 1440.0
|
|
for j in foods.keys():
|
|
foods[j] -= conf['rounds']['consumption']
|
|
for k,v in foods.items():
|
|
if -10 < v <= 0:
|
|
if cluster[k] in cluster_life:
|
|
if cluster_life[cluster[k]] < i:
|
|
cluster_life[cluster[k]] = i
|
|
else:
|
|
cluster_life[cluster[k]] = i
|
|
foods[k] = -1000
|
|
for k,v in foods.items():
|
|
if v >= 0:
|
|
if cluster[k] in cluster_life:
|
|
if cluster_life[cluster[k]] < game_end_at:
|
|
cluster_life[cluster[k]] = game_end_at
|
|
else:
|
|
cluster_life[cluster[k]] = game_end_at
|
|
counter = Counter(cluster.values())
|
|
for k,v in counter.items():
|
|
if v not in self.life:
|
|
self.life[v] = []
|
|
self.life[v].append(cluster_life[k])
|
|
res = [v for v in counter.values()]
|
|
# print(m.name, list(sorted(res, reverse=True)))
|
|
self.detail[m.name] = res
|
|
|
|
|
|
def output(self):
|
|
data = []
|
|
for r in self.detail.values():
|
|
data.extend(r)
|
|
res = np.zeros(max(data))
|
|
s = sum(data)
|
|
for d in data:
|
|
res[d-1] += d
|
|
res /= s
|
|
# print(res)
|
|
np.save('outputs/cluster.npy', res)
|
|
with open("outputs/cluster_life_%d.json" % self.cluster_born, 'w') as f:
|
|
json.dump(self.life, f)
|
|
|
|
if __name__ == '__main__':
|
|
for i in range(1, 10):
|
|
c = ClusterStat(i)
|
|
c.stat()
|
|
c.output()
|