""" 统计所有的连通子图规模 """ 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()