forked from swamiiyer/woa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
continuous_omain.py
185 lines (157 loc) · 6.52 KB
/
continuous_omain.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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# This is the offline version of the script that runs the simulation of
# the model for the game using parameters specified by the user. The results
# of simulation are saved in results.pkl file, the plots produced from them
# are saved in plot*.pdf files, and the mean trait value over the last 10
# percent of the generations is written to STDOUT. The script is offline in
# the sense that the plots are generated after the simulation is over.
#
# This script can also be used to extend an existing experiment to include
# more generations. That can be done by updating the "generations" parameter
# in the experiment.py file for the experiment to the new value and running
# the modified file. If a results.pkl file is present in the folder, the
# script continues the experiment from where left off. Note that when
# extending an experiment, it is very important that any graph_seed specified
# in params map be the value from the original experiment, so that the network
# structure (if any) in the extended experiment is the same as that in the
# original experiment.
import math, numpy, os, pickle, pylab, random
import matplotlib.cm as cm
from matplotlib.colors import normalize as Norm
from continuous import *
def run(params, payoff):
"""
Run simulation of the model for the game using the parameters specified
in params map, and the given payoff function. Once the simulation is
over call gen_plots() to generate plots from the results of simulation.
"""
# Extension of an experiment.
if os.path.isfile("results.pkl"):
fh = open("results.pkl", "r")
old_params = pickle.load(fh)
population = pickle.load(fh)
fh.close()
start = old_params["generations"] + 1
net = network.build_network(population, params["network_topology"],
params["network_params"])
# Seed the random number generator for the experiment.
random.seed(params["seed"])
# New experiment.
else:
start = 0
# Create a population.
population = [Player(i) for i in range(0, params["population"])]
# Create a network.
net = network.build_network(population, params["network_topology"],
params["network_params"])
# Seed the random number generator for the experiment.
random.seed(params["seed"])
# Assign a trait for each individual in the population.
for p in population:
p.inherit_trait(params["init_trait"])
p.commit_inheritance()
# Create a dynamics module based on network (complete or other)
# type and update rule selected.
dynamics = dynamics_module(params["network_topology"],
params["update_rule"])(net, params, payoff)
# The dynamics.
for time_step in range(start, params["generations"] + 1):
# Pre interaction.
dynamics.pre_interaction()
# Save state at report_freq.
if time_step % params["report_freq"] == 0:
print("Generation %d of %d" %(time_step, params["generations"]))
for p in population:
p.save()
# Interact.
for count in range(0, params["population"]):
dynamics.interact()
# Post interaction.
dynamics.post_interaction()
# Update.
for count in range(0, params["population"]):
dynamics.update()
# Post update; commit trait inheritance.
dynamics.post_update()
# Pickle (save) the results of the experiment.
output = open("results.pkl", "w")
pickle.dump(params, output)
pickle.dump(population, output)
output.close()
# Generate plots.
gen_plots()
def gen_plots():
"""
Create plots and save them in plot*.pdf files, and write the mean trait
value over the last 10 percent of the generations to STDOUT.
"""
# Open and load the stuff from the results file.
fh = open("results.pkl", "r")
params = pickle.load(fh)
population = pickle.load(fh)
fh.close()
# generations axis ticks.
y = [i * params["report_freq"] \
for i in range(0, params["generations"] / \
params["report_freq"] + 1)]
# Plot 1 (low, mean, high trait vs generations)
low = []
mean = []
high = []
for i in range(0, len(y)):
l = []
for p in population:
trait = p.get_trait_list()[i]
payoff = p.get_payoff_list()[i]
l.append(trait)
low.append(min(l))
high.append(max(l))
mean.append(numpy.average(l))
pylab.figure(1, figsize = (7, 4.5), dpi = 500)
pylab.xlabel(r"$t$")
pylab.ylabel(r"$x_{min}, \bar{x}, x_{max}$")
pylab.plot(y, low, "#FF0000", alpha = 0.6, linewidth = 2.0)
pylab.plot(y, mean, "#000000", alpha = 0.6, linewidth = 2.0)
pylab.plot(y, high, "#0000FF", alpha = 0.6, linewidth = 2.0)
pylab.xlim(0, params["generations"])
pylab.ylim(0, params["max_trait"])
ax = pylab.gca()
ax.xaxis.major.formatter.set_powerlimits((0,0))
pylab.legend((r"$x_{min}$", r"$\bar{x}$", r"$x_{max}$"),
'best', shadow = False)
pylab.savefig("plot1.pdf", format = "pdf", bbox_inches = "tight")
pylab.close(1)
# Plot 2 (trait distribution)
m = []
vmin = 1.0
vmax = 0.0
for i in range(0, len(y)):
l = []
for p in population:
l.append(p.get_trait_list()[i])
l = pylab.histogram(l, 100, range = (0, params["max_trait"]), normed = False)[0]
r = []
for bin in l:
trait = bin / (1.0 * params["population"])
c = 1.0 - trait
if c < vmin and c > 0:
vmin = c
if c > vmax and c < 1:
vmax = c
r.append(c)
m.append(r)
pylab.figure(1, figsize = (7, 4.5), dpi = 500)
pylab.xlabel(r"$x$")
pylab.ylabel(r"$t$")
pylab.imshow(m, interpolation = "bilinear", origin = "l",
cmap = cm.gray, norm = Norm(vmin, vmax),
extent = [0, params["max_trait"], 1, params["generations"]])
pylab.axis("tight")
ax = pylab.gca()
ax.yaxis.major.formatter.set_powerlimits((0,0))
pylab.savefig("plot2.pdf", format = "pdf", bbox_inches = "tight")
pylab.close(1)
# Print mean trait over the last 10% of the generations to STDOUT.
last = int(params["generations"] * 0.1)
i = (params["generations"] / params["report_freq"]) - \
(last / params["report_freq"])
print numpy.average(mean[i:])