-
Notifications
You must be signed in to change notification settings - Fork 1
/
model.py
127 lines (104 loc) · 4.57 KB
/
model.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
from mesa import Agent, Model
from mesa.time import SimultaneousActivation
from mesa.space import NetworkGrid
from mesa.datacollection import DataCollector
import networkx as nx
import numpy as np
import random
# TODO Instead of double Barabasi-Albert generator, use regular Barabasi - Albert. with m=7. (?)
# TODO Additionally, Use one (?) of the following generators: a) random regular graph generator, b) random graph gen
# TODO In the server.py file, add possibility for user, to select the kind of network they want to use.
# TODO in server.py, make sure the current network's parameters are displayed.
HATER = 1
NO_HATER = 0
def percent_haters(model):
agent_behs = [agent.behavior for agent in model.schedule.agents]
x = sum(agent_behs)/len(agent_behs)
return x
def average_sensitivity(model):
agent_sensitivity = [agent.sensitivity for agent in model.schedule.agents]
x = np.mean(agent_sensitivity)
return x
# Barabasi - Albert
def netgen_ba(n, m):
I = nx.barabasi_albert_graph(n=n, m=m)
degs = [I.degree[node] for node in I.nodes()]
avg_deg = np.mean(degs)
max_deg = np.max(degs)
conn = nx.average_node_connectivity(I)
clust = nx.average_clustering(I)
return I, avg_deg, max_deg, conn, clust
# Erdos-Renyi - number 2
def netgen_er(n, p):
I = nx.erdos_renyi_graph(n=n, p=p)
degs = [I.degree[node] for node in I.nodes()]
avg_deg = np.mean(degs)
max_deg = np.max(degs)
conn = nx.average_node_connectivity(I)
clust = nx.average_clustering(I)
return I, avg_deg, max_deg, conn, clust
# Random Regular - number 3
def netgen_rr(n, d):
I = nx.random_regular_graph(d=d, n=n)
degs = [I.degree[node] for node in I.nodes()]
avg_deg = np.mean(degs)
max_deg = np.max(degs)
conn = nx.average_node_connectivity(I)
clust = nx.average_clustering(I)
return I, avg_deg, max_deg, conn, clust
class NormAgent(Agent):
def __init__(self, unique_id, model):
super().__init__(unique_id, model)
self.behavior = self.random.choices([NO_HATER, HATER], weights=[9,1])[0]
self.contempt = self.random.betavariate(2,5)
self.sensitivity = self.random.betavariate(5,2)
def step(self):
neighbors_nodes = self.model.grid.get_neighbors(self.pos, include_center=False)
neighbors = self.model.grid.get_cell_list_contents(neighbors_nodes)
neigh_beh = [neigh.behavior for neigh in neighbors]
self._nextBehavior = self.behavior
self._nextSensitivity = self.sensitivity
if (self.contempt > self.random.uniform(0,1)) and (self.sensitivity < 0.3):
self._nextBehavior = HATER
else: self._nextBehavior = NO_HATER
if self.sensitivity > 0.1:
self._nextSensitivity = self.sensitivity - np.mean(neigh_beh)*0.2
# self._nextSensitivity = self.sensitivity - np.sum(neigh_beh)*.02
def advance(self):
# self.contempt = self._nextContempt
self.behavior = self._nextBehavior
self.sensitivity = self._nextSensitivity
class NormModel(Model):
def __init__(self, size, net_type):
self.num_agents = size
self.num_nodes = self.num_agents
self.type = net_type
if self.type == 1:
self.G, self.avg_degree, self.big_nodes, self.connectivity, self.clustering = netgen_ba(100, 4)
if self.type == 2:
self.G, self.avg_degree, self.big_nodes, self.connectivity, self.clustering = netgen_er(100, .078)
if self.type == 3:
self.G, self.avg_degree, self.big_nodes, self.connectivity, self.clustering = netgen_rr(100, 4)
self.grid = NetworkGrid(self.G)
self.schedule = SimultaneousActivation(self)
self.running = True
self.step_counter = 1
for i, node in enumerate(self.G.nodes()):
a = NormAgent(i, self)
self.schedule.add(a)
self.grid.place_agent(a, node)
self.datacollector = DataCollector(
model_reporters={"PerHate": percent_haters,
"AverageSens": average_sensitivity,
},
agent_reporters={"Hate": "behavior"}
)
def step(self):
self.datacollector.collect(self)
self.schedule.step()
self.step_counter += 1
if percent_haters(self) > 0.35 or self.step_counter > 250: # When the percentage of haters in the model exceeds 80,
self.running = False # the simulation is stopped, data collected, and next one is started.
# Alternatively:
if average_sensitivity(self) < 0.1 or self.step_counter > 250:
self.running = False