-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathSimulationStats.py
155 lines (138 loc) · 6.46 KB
/
SimulationStats.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
""" Keeping track of statistics for agents
"""
from simutil import *
class SimulationStats(object):
def __init__ (self, NUM_FACTS, NUM_NOISE, num_cc=0, size_lcc=0, sa_increment=10):
self.NUM_FACTS = float(NUM_FACTS)
self.NUM_NOISE = NUM_NOISE
self.sa = [] ## triples of the form mean, std, max sa of all agents
self.sa0 = [] ## a single value, sa of agent at 0
self.comm = [] ## list of total communication values
## over all agents for each at time step
self.comm0 = [] ## list of communication values for agent at 0
self.steps = [] ## steps at which all other stats are recorded.
self.total_filtered = 0
self.num_cc = num_cc
self.size_lcc = size_lcc
self.num_appended = 1.0 ## how many stats objects are combined
self.EPSILON = 0.01
self.sa_increment = sa_increment
def __str__ (self):
return (str(self.sa0) + "\n" + str(self.comm))
def merge_stats( self, other ):
for i in xrange(len(self.steps)):
self.sa[i][0] += other.sa[i][0]
self.sa[i][1] += other.sa[i][1]
self.sa[i][2] += other.sa[i][2]
self.sa0[i] += other.sa0[i]
self.comm[i] += other.comm[i]
self.comm0[i] += other.comm0[i]
self.total_filtered += other.total_filtered
self.num_cc += other.num_cc
self.size_lcc += other.size_lcc
self.num_appended += 1
def normalize( self ):
for i in xrange(len(self.steps)):
self.sa[i][0] /= self.num_appended
self.sa[i][1] /= self.num_appended
self.sa[i][2] /= self.num_appended
self.sa0[i] /= self.num_appended
self.comm[i] /= self.num_appended
self.comm0[i] /= self.num_appended
self.total_filtered /= self.num_appended
self.num_cc /= self.num_appended
self.size_lcc /= self.num_appended
self.num_appended = 1.0
def num_good_facts(self, agent):
x = list( agent.knowledge )
x.sort()
last_fact = -1
for i in x:
if i > self.NUM_FACTS:
last_fact = i
break
if last_fact == -1:
return len(x)
else:
return x.index(last_fact)-1
def find_sa(self, agents):
cur_sa = []
for agent in agents:
cur_sa.append ( self.num_good_facts(agent) )
return (max(cur_sa), meanstd(cur_sa))
def full_comms(self, agents):
val = 0
filtered = 0
for agent in agents:
val += agent.numsent
filtered += agent.num_filtered
return (val, filtered)
def update_stats(self, agents, steps):
(maxsa, (m,s)) = self.find_sa(agents)
self.sa0.append( self.num_good_facts(agents[0]) )
self.sa.append ( [m,s, maxsa] )
(c,f) = self.full_comms(agents)
self.comm.append(c)
self.comm0.append( agents[0].numsent )
self.total_filtered += f
self.steps.append(steps)
def process_sa( self ):
self.normalize()
## First AVG SA processing
## Find max value
highest_index = len(self.sa)-1 #avg sa
highest_value = self.sa[-1][0]
max_highest_index = len(self.sa)-1 # max sa
max_highest_value = self.sa[-1][2]
for i in xrange(-2, -len(self.sa)-1,-1):
if highest_value - self.sa[i][0] <= self.EPSILON:
highest_index = i
highest_value = self.sa[i][0]
if max_highest_value - self.sa[i][2] <= self.EPSILON:
max_highest_index = i
max_highest_value = self.sa[i][2]
## Summarize stats for specific avg SA
sa_at_value = [] ## comm & steps values for a specific sa
next_sa_to_search = self.sa_increment
for i in xrange(len(self.sa)):
if self.sa[i][0] >= next_sa_to_search:
sa_at_value.append (
{'sa': next_sa_to_search/self.NUM_FACTS,\
'comm': self.comm[i],\
'steps': self.steps[i]})
next_sa_to_search += self.sa_increment
## Now processs the SA for agent 0
highest_index0 = len(self.sa0)-1 #avg sa
highest_value0 = self.sa0[-1]
max_highest_index0 = len(self.sa0)-1 # max sa
max_highest_value0 = self.sa0[-1]
for i in xrange(-2, -len(self.sa0)-1,-1):
if highest_value0 - self.sa0[i] <= self.EPSILON:
highest_index0 = i
highest_value0 = self.sa0[i]
sa0_at_value = [] ## comm & steps values for a specific sa
next_sa_to_search = self.sa_increment
for i in xrange(len(self.sa0)):
if self.sa0[i] >= next_sa_to_search:
sa0_at_value.append (
{'sa': next_sa_to_search/self.NUM_FACTS,\
'comm': self.comm0[i],\
'commtotal': self.comm[i],\
'steps': self.steps[i]})
next_sa_to_search += self.sa_increment
summary = { 'steps': self.steps[highest_index], \
'sa': highest_value/self.NUM_FACTS, \
'comm': self.comm[highest_index], \
'steps_maxsa': self.steps[max_highest_index], \
'maxsa': max_highest_value/self.NUM_FACTS, \
'comm_maxsa': self.comm[max_highest_index], \
'steps0': self.steps[highest_index0], \
'sa0': highest_value0/self.NUM_FACTS, \
'comm0': self.comm0[highest_index0], \
'commtotal0': self.comm[highest_index0], \
'sa_at_value': sa_at_value ,\
'sa0_at_value': sa0_at_value ,\
'total_filtered': self.total_filtered, \
'num_cc' : self.num_cc, \
'size_lcc' : self.size_lcc}
return summary