1
0
mirror of https://github.com/gsi-upm/soil synced 2024-11-14 07:22:29 +00:00
soil/soil.py

364 lines
14 KiB
Python
Raw Normal View History

2015-12-04 10:41:42 +00:00
from nxsim import NetworkSimulation
from nxsim import BaseNetworkAgent
from nxsim import BaseLoggingAgent
from random import randint
from matplotlib import pyplot as plt
import random
import numpy as np
import networkx as nx
import settings
2015-12-04 11:32:24 +00:00
settings.init() # Loads all the data from settings
2015-12-04 10:41:42 +00:00
2015-12-04 11:32:24 +00:00
####################
# Network creation #
####################
2015-12-04 10:41:42 +00:00
if settings.network_type == 0:
G = nx.complete_graph(settings.number_of_nodes)
if settings.network_type == 1:
G = nx.barabasi_albert_graph(settings.number_of_nodes,3)
if settings.network_type == 2:
G = nx.margulis_gabber_galil_graph(settings.number_of_nodes, None)
2015-12-04 11:32:24 +00:00
# More types of networks can be added here
2015-12-04 10:41:42 +00:00
2015-12-04 11:32:24 +00:00
##############################
# Variables initializitation #
##############################
myList=[] # List just for debugging
networkStatus=[] # This list will contain the status of every node of the network
2015-12-04 10:41:42 +00:00
for x in range(0, settings.number_of_nodes):
networkStatus.append({'id':x})
2015-12-04 11:32:24 +00:00
# Initialize agent states. Let's assume everyone is normal.
init_states = [{'id': 0, } for _ in range(settings.number_of_nodes)] # add keys as as necessary, but "id" must always refer to that state category
2015-12-04 10:41:42 +00:00
2015-12-04 11:32:24 +00:00
# Seed a zombie, just for zombie model
#init_states[5] = {'id': 1}
#init_states[3] = {'id': 1}
2015-12-04 10:41:42 +00:00
2015-12-04 11:32:24 +00:00
####################
# Available models #
####################
2015-12-04 10:41:42 +00:00
2015-12-10 18:18:12 +00:00
class BigMarketModel(BaseNetworkAgent):
def __init__(self, environment=None, agent_id=0, state=()):
super().__init__(environment=environment, agent_id=agent_id, state=state)
self.time_awareness = 0
networkStatus[self.id][self.env.now]=0
if self.id == 0: #Empresa 1
self.state['id']=0
2015-12-14 11:57:21 +00:00
self.tweet_probability = settings.tweet_probability_1
2015-12-10 18:18:12 +00:00
elif self.id == 1: #Empresa 2
self.state['id']=1
2015-12-14 11:57:21 +00:00
self.tweet_probability = settings.tweet_probability_2
2015-12-10 18:18:12 +00:00
else: #Usuarios normales
self.state['id']=2
2015-12-14 11:57:21 +00:00
self.tweet_probability = settings.tweet_probability_users
self.tweet_relevant_probability = settings.tweet_relevant_probability
self.tweet_probability_about = settings.tweet_probability_about #Lista
self.sentiment_about = settings.sentiment_about #Lista
2015-12-10 18:18:12 +00:00
def run(self):
while True:
2015-12-14 11:57:21 +00:00
##Usuario
if random.random() < self.tweet_probability: #Twittea
if random.random() < self.tweet_relevant_probability: #Twittea algo relevante
#Probabilidad de tweet para cada empresa
for i in range(len(self.tweet_probability_about)):
if random.random() < self.tweet_probability_about[i]:
#Se ha cumplido la condicion, evaluo los sentimientos hacia esa empresa
if self.sentiment_about[i] < 0:
#NEGATIVO
elif self.sentiment_about[i] == 0:
#NEUTRO
else:
#POSITIVO
2015-12-10 18:18:12 +00:00
aware_neighbors_1_time_step=[]
#Outside effects
if random.random() < settings.innovation_prob:
if self.state['id'] == 0:
self.state['id'] = 1
myList.append(self.id)
networkStatus[self.id][self.env.now]=1
self.time_awareness = self.env.now #Para saber cuando se han contagiado
yield self.env.timeout(settings.timeout)
else:
yield self.env.timeout(settings.timeout)
#Imitation effects
if self.state['id'] == 0:
aware_neighbors = self.get_neighboring_agents(state_id=1)
for x in aware_neighbors:
if x.time_awareness == (self.env.now-1):
aware_neighbors_1_time_step.append(x)
num_neighbors_aware = len(aware_neighbors_1_time_step)
if random.random() < (settings.imitation_prob*num_neighbors_aware):
myList.append(self.id)
self.state['id'] = 1
networkStatus[self.id][self.env.now]=1
yield self.env.timeout(settings.timeout)
else:
yield self.env.timeout(settings.timeout)
2015-12-04 10:41:42 +00:00
class SentimentCorrelationModel(BaseNetworkAgent):
def __init__(self, environment=None, agent_id=0, state=()):
super().__init__(environment=environment, agent_id=agent_id, state=state)
self.outside_effects_prob = settings.outside_effects_prob
self.anger_prob = settings.anger_prob
self.joy_prob = settings.joy_prob
self.sadness_prob = settings.sadness_prob
self.disgust_prob = settings.disgust_prob
self.time_awareness=[]
2015-12-04 11:32:24 +00:00
for i in range(4): #En este modelo tenemos 4 sentimientos
2015-12-04 10:41:42 +00:00
self.time_awareness.append(0) #0-> Anger, 1-> joy, 2->sadness, 3 -> disgust
networkStatus[self.id][self.env.now]=0
def run(self):
while True:
2015-12-04 11:32:24 +00:00
2015-12-04 10:41:42 +00:00
angry_neighbors_1_time_step=[]
joyful_neighbors_1_time_step=[]
sad_neighbors_1_time_step=[]
disgusted_neighbors_1_time_step=[]
angry_neighbors = self.get_neighboring_agents(state_id=1)
for x in angry_neighbors:
if x.time_awareness[0] > (self.env.now-500):
angry_neighbors_1_time_step.append(x)
num_neighbors_angry = len(angry_neighbors_1_time_step)
joyful_neighbors = self.get_neighboring_agents(state_id=2)
for x in joyful_neighbors:
if x.time_awareness[1] > (self.env.now-500):
joyful_neighbors_1_time_step.append(x)
num_neighbors_joyful = len(joyful_neighbors_1_time_step)
sad_neighbors = self.get_neighboring_agents(state_id=3)
for x in sad_neighbors:
if x.time_awareness[2] > (self.env.now-500):
sad_neighbors_1_time_step.append(x)
num_neighbors_sad = len(sad_neighbors_1_time_step)
disgusted_neighbors = self.get_neighboring_agents(state_id=4)
for x in disgusted_neighbors:
if x.time_awareness[3] > (self.env.now-500):
disgusted_neighbors_1_time_step.append(x)
num_neighbors_disgusted = len(disgusted_neighbors_1_time_step)
anger_prob= settings.anger_prob+(len(angry_neighbors_1_time_step)*settings.anger_prob)
joy_prob= settings.joy_prob+(len(joyful_neighbors_1_time_step)*settings.joy_prob)
sadness_prob = settings.sadness_prob+(len(sad_neighbors_1_time_step)*settings.sadness_prob)
disgust_prob = settings.disgust_prob+(len(disgusted_neighbors_1_time_step)*settings.disgust_prob)
outside_effects_prob= settings.outside_effects_prob
num = random.random()
if(num<outside_effects_prob):
self.state['id'] = random.randint(1,4)
myList.append(self.id)
networkStatus[self.id][self.env.now]=self.state['id'] #Almaceno cuando se ha infectado para la red dinamica
self.time_awareness[self.state['id']-1] = self.env.now
yield self.env.timeout(settings.timeout)
if(num<anger_prob):
myList.append(self.id)
self.state['id'] = 1
networkStatus[self.id][self.env.now]=1
self.time_awareness[self.state['id']-1] = self.env.now
elif (num<joy_prob+anger_prob and num>anger_prob):
myList.append(self.id)
self.state['id'] = 2
networkStatus[self.id][self.env.now]=2
self.time_awareness[self.state['id']-1] = self.env.now
elif (num<sadness_prob+anger_prob+joy_prob and num>joy_prob+anger_prob):
myList.append(self.id)
self.state['id'] = 3
networkStatus[self.id][self.env.now]=3
self.time_awareness[self.state['id']-1] = self.env.now
elif (num<disgust_prob+sadness_prob+anger_prob+joy_prob and num>sadness_prob+anger_prob+joy_prob):
myList.append(self.id)
self.state['id'] = 4
networkStatus[self.id][self.env.now]=4
self.time_awareness[self.state['id']-1] = self.env.now
yield self.env.timeout(settings.timeout)
class BassModel(BaseNetworkAgent):
def __init__(self, environment=None, agent_id=0, state=()):
super().__init__(environment=environment, agent_id=agent_id, state=state)
self.innovation_prob = settings.innovation_prob
self.imitation_prob = settings.imitation_prob
networkStatus[self.id][self.env.now]=0
def run(self):
while True:
#Outside effects
if random.random() < settings.innovation_prob:
if self.state['id'] == 0:
self.state['id'] = 1
myList.append(self.id)
networkStatus[self.id][self.env.now]=1
yield self.env.timeout(settings.timeout)
else:
yield self.env.timeout(settings.timeout)
#Imitation effects
if self.state['id'] == 0:
aware_neighbors = self.get_neighboring_agents(state_id=1)
num_neighbors_aware = len(aware_neighbors)
if random.random() < (settings.imitation_prob*num_neighbors_aware):
myList.append(self.id)
self.state['id'] = 1
networkStatus[self.id][self.env.now]=1
yield self.env.timeout(settings.timeout)
else:
yield self.env.timeout(settings.timeout)
class IndependentCascadeModel(BaseNetworkAgent):
def __init__(self, environment=None, agent_id=0, state=()):
super().__init__(environment=environment, agent_id=agent_id, state=state)
self.innovation_prob = settings.innovation_prob
self.imitation_prob = settings.imitation_prob
self.time_awareness = 0
networkStatus[self.id][self.env.now]=0
def run(self):
while True:
aware_neighbors_1_time_step=[]
#Outside effects
if random.random() < settings.innovation_prob:
if self.state['id'] == 0:
self.state['id'] = 1
myList.append(self.id)
networkStatus[self.id][self.env.now]=1
self.time_awareness = self.env.now #Para saber cuando se han contagiado
yield self.env.timeout(settings.timeout)
else:
yield self.env.timeout(settings.timeout)
#Imitation effects
if self.state['id'] == 0:
aware_neighbors = self.get_neighboring_agents(state_id=1)
for x in aware_neighbors:
if x.time_awareness == (self.env.now-1):
aware_neighbors_1_time_step.append(x)
num_neighbors_aware = len(aware_neighbors_1_time_step)
if random.random() < (settings.imitation_prob*num_neighbors_aware):
myList.append(self.id)
self.state['id'] = 1
networkStatus[self.id][self.env.now]=1
yield self.env.timeout(settings.timeout)
else:
yield self.env.timeout(settings.timeout)
class ZombieOutbreak(BaseNetworkAgent):
def __init__(self, environment=None, agent_id=0, state=()):
super().__init__(environment=environment, agent_id=agent_id, state=state)
self.bite_prob = settings.bite_prob
networkStatus[self.id][self.env.now]=0
def run(self):
while True:
if random.random() < settings.heal_prob:
if self.state['id'] == 1:
self.zombify()
yield self.env.timeout(settings.timeout)
else:
yield self.env.timeout(settings.timeout)
else:
if self.state['id'] == 1:
print("Soy el zombie " + str(self.id) + " y me voy a curar porque el num aleatorio ha sido " + str(num))
networkStatus[self.id][self.env.now]=0
if self.id in myList:
myList.remove(self.id)
self.state['id'] = 0
yield self.env.timeout(settings.timeout)
else:
yield self.env.timeout(settings.timeout)
def zombify(self):
normal_neighbors = self.get_neighboring_agents(state_id=0)
for neighbor in normal_neighbors:
if random.random() < self.bite_prob:
print("Soy el zombie " + str(self.id) + " y voy a contagiar a " + str(neighbor.id))
neighbor.state['id'] = 1 # zombie
myList.append(neighbor.id)
networkStatus[self.id][self.env.now]=1
networkStatus[neighbor.id][self.env.now]=1
print(self.env.now, "Soy el zombie: "+ str(self.id), "Mi vecino es: "+ str(neighbor.id), sep='\t')
break
2015-12-04 11:32:24 +00:00
##############
# Simulation #
##############
2015-12-04 10:41:42 +00:00
sim = NetworkSimulation(topology=G, states=init_states, agent_type=SentimentCorrelationModel,
max_time=settings.max_time, num_trials=settings.num_trials, logging_interval=1.0)
sim.run_simulation()
2015-12-04 11:32:24 +00:00
###########
# Results #
###########
2015-12-04 10:41:42 +00:00
myList = sorted(myList, key=int)
#print("Los zombies son: " + str(myList))
trial = BaseLoggingAgent.open_trial_state_history(dir_path='sim_01', trial_id=0)
2015-12-04 11:32:24 +00:00
status_census = [sum([1 for node_id, state in g.items() if state['id'] == 1]) for t,g in trial.items()]
2015-12-04 10:41:42 +00:00
2015-12-04 11:32:24 +00:00
#################
# Visualization #
#################
2015-12-04 10:41:42 +00:00
#lista = nx.nodes(G)
#print('Nodos: ' + str(lista))
for x in range(0, settings.number_of_nodes):
networkStatusAux=[]
for tiempo in networkStatus[x]:
if tiempo != 'id':
networkStatusAux.append((networkStatus[x][tiempo],tiempo,None))
2015-12-04 11:32:24 +00:00
G.add_node(x, status= networkStatusAux)
2015-12-04 10:41:42 +00:00
#print(networkStatus)
nx.write_gexf(G,"test.gexf", version="1.2draft")
2015-12-04 11:32:24 +00:00
plt.plot(status_census)
2015-12-04 10:41:42 +00:00
plt.draw() # pyplot draw()
2015-12-04 11:32:24 +00:00
plt.savefig("status.png")
2015-12-04 10:41:42 +00:00
#print(networkStatus)
#nx.draw(G)
#plt.show()
#plt.savefig("path.png")
2015-12-04 11:32:24 +00:00