Skip to content

Instantly share code, notes, and snippets.

@Uiuran
Last active December 15, 2015 19:49
Show Gist options
  • Save Uiuran/5314019 to your computer and use it in GitHub Desktop.
Save Uiuran/5314019 to your computer and use it in GitHub Desktop.
Preliminar version of random agent in complex network topology simulation AND animation
#agent002, agent simulation in a General Topology with 1 float field for each agent (node) and random sampling of interactions (egdes) between time step, the process evaluation is a adition of the mean interaction to the fields { fieldA[time] =( fieldA[ time-1] + fieldB[time-1])/2 , the same is true for fieldB}, ie homophilic interaction, the agents start with random float number sampled from uniform [0,1). This process prints the visualization of the network.
#import paintGraph as pg
import numpy as np
import networkx as nx
import GraphMovie as gm
import igraph
class AgentModel(object):
'''
Agent models simulation
'''
def __init__(self, gml_file = "", model = { "model":"random", "node_number": 50, 'digraph': False, 'weighted': False, }, fields_dim = 1, time = 200):
'''
Constructor
'''
self.models = {
"random":self.random,
"scalefree":self.scalefree,
"smallworld":self.smallworld,
}
self.time = time;
a = self.topology( arquivo_gml = gml_file, mtype = model);
self.fields = np.random.rand(fields_dim,len(a));
self.edges = [(v,j) for v in range(len(a)) for j in a[v]];
def random(self, param, digraph = False):
''' Returns a adjacency matrix for random graph in numpy array '''
a = np.random.randint(0,2,(param["node_number"],param["node_number"]));
if digraph == False:
return (a + a.T)/2 + (a + a.T)%2 - np.diag(np.diag((a + a.T)/2 + (a + a.T)%2));
else:
return a;
def scalefree(self, param):
''' Returns a adjacency list, not matrix, ie a list of lists with the number labels of the neighbors for each node. One must supply a dictionarie with the number of nodes of the final model and the number of edges to attach in each iteration of the preferential attachment rule: param["nodes_number"], param["edges_to_attach"] '''
a = nx.generators.barabasi_albert_graph(param["node_number"], 2);
return np.array([v.keys() for v in a.adj.itervalues()]);
def smallworld(self, param):
''' Returns a adjacency list, not matrix, ie a list of lists with the number labels of the neighbors for each node. One must supply a dictionarie with the number of nodes of the final model, the number of nearest neighbors to start attached in the ring topology and the probability of re-attachment: param["nodes_number"], param["k"], param["p"] '''
a = nx.generators.watts_strogatz_graph(param["node_number"], 4, 0.45);
return np.array([v.keys() for v in a.adj.itervalues()]);
def runSimulation(self, plot = 'print'):
full = self.time;
if plot == 'movie':
self.movie = gm.GraphMovie();
while full > 0:
if self.time == full:
self.net = igraph.read(self.string+".gml");
for i,v in enumerate(self.net.vs):
v['label'] = str(i);
v['color'] = self.fields[0,i];
self.movie.addGraph(self.net);
elif self.time != full:
self.net = igraph.read(self.string+".gml")
for i,v in enumerate(self.net.vs):
v['label'] = str(i);
if i == self.edges[sampvar[0]][0] or i == self.edges[sampvar[0]][1]:
v['color'] = 0.0;
else:
v['color'] = self.fields[0,i];
self.movie.addGraph(self.net);
sampvar = np.random.randint(0,len(self.edges),(1));
interact = float(self.fields[0,self.edges[sampvar[0]][0]]+self.fields[0,self.edges[sampvar[0]][1]])/2;
self.fields[0,self.edges[sampvar[0]][0]] = float(self.fields[0,self.edges[sampvar[0]][0]] + interact)/2;
self.fields[0,self.edges[sampvar[0]][1]] = float(self.fields[0,self.edges[sampvar[0]][1]] + interact)/2;
full = full - 1;
self.movie.doMovieLayout();
self.movie.renderMovie(name = self.string);
elif plot == 'print':
while full > 0:
sampvar = np.random.randint(0,len(self.edges),(1)); # the edge(interaction) sampling process
interact = float(self.fields[0,self.edges[sampvar[0]][0]]+self.fields[0,self.edges[sampvar[0]][1]])/2;
self.fields[0,self.edges[sampvar[0]][0]] = float(self.fields[0,self.edges[sampvar[0]][0]] + interact)/2;
self.fields[0,self.edges[sampvar[0]][1]] = float(self.fields[0,self.edges[sampvar[0]][1]] + interact)/2;
full = full - 1;
print self.fields;
else:
while full > 0:
sampvar = np.random.randint(0,len(self.edges),(1)); # the edge(interaction) sampling process
interact = float(self.fields[0,self.edges[sampvar[0]][0]]+self.fields[0,self.edges[sampvar[0]][1]])/2;
self.fields[0,self.edges[sampvar[0]][0]] = float(self.fields[0,self.edges[sampvar[0]][0]] + interact)/2;
self.fields[0,self.edges[sampvar[0]][1]] = float(self.fields[0,self.edges[sampvar[0]][1]] + interact)/2;
full = full - 1;
def topology(self, arquivo_gml = "", mtype = { "model":"random", "node_number":50 , 'digraph' : False, 'weighted' : False, } ):
if arquivo_gml == "":
param = mtype.copy();
param.pop("model");
return self.models[mtype["model"]](param);
else:
self.net = igraph.read(arquivo_gml+".gml");
self.string = arquivo_gml;
return np.array([self.net.neighbors(v) for v in range(len(self.net.vs))]);
def demo(dtype = "smallworld"):
if dtype == "smallworld":
model = AgentModel( model = { "model":"smallworld", "node_number": 50, 'digraph': False, 'weighted': False,});
model.runSimulation();
elif dtype == "gml":
model = AgentModel( gml_file = "humannoise03_03_2013" );
model.runSimulation();
elif dtype == "random":
model = AgentModel( model = { "model":"random", "node_number": 50, 'digraph': False, 'weighted': False,});
model.runSimulation();
elif dtype == "movie":
model = AgentModel( gml_file = "humannoise03_03_2013" , time = 20 );
model.runSimulation(plot = 'movie');
elif dtype == "scalefree":
model = AgentModel( model = { "model":"scalefree", "node_number": 50, 'digraph': False, 'weighted': False,} );
model.runSimulation();
# Multiplex Randomic Rizhoma
# Copyleft ()) 2013 - Uiuran
# This program is free software: you can redistisbute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
# You should have received a copy of the GNU Affero General Public License, or see on internet
#multiplex networking simulation. Another homofilic agent model, but being taylored to multiplex interaction, not complete yet, but de monoplex case works fine
#import paintGraph as pg
import numpy as np
import networkx as nx
import GraphMovie as gm
import igraph
class AgentModel(object):
'''
Agent models simulation
'''
def __init__(self, gml_file = {}, netsetup = { 0 : { "model":"random", "node_number": 50, 'digraph': False, 'weighted': False, 'degenerescency' : 1 }}, fields_dim = 1, time = 200):
'''
Constructor
'''
self.models = {
"random":self.random,
"scalefree":self.scalefree,
"smallworld":self.smallworld,
}
self.nets_len = np.zeros(len(netsetup)); # number of nodes/net any node greater thann self.nets_len.min() is a newcomer, i.e. there is a network that he has 0 connections
self.time = time;
a = self.topology( arquivos_gml = gml_file, ntype = netsetup); # is dict() with topologies of all networks
if len(a) > fields_dim:
fields_dim = len(a);
else:
self.degenerated_nets = dict(); # this sets the degenerescency of some topologies in relation to the number of available fields;
for n in netsetup.iteritems():
if n[1].has_key('degenerescency'):
self.degenerated_nets[n[0]] = n[1]['degenerescency'];
self.fields = np.random.rand(fields_dim, self.nets_len.max());
self.edges = dict();
for n in netsetup.iteritems():
self.edges[n[0]] = [(v,j) for v in np.arange(self.nets_len[n[0]]) for j in a[n[0]][v] ]; #TODO mudar selecao de arestas por rede
def random(self, param, digraph = False):
''' Returns a adjacency matrix for random graph in numpy array '''
a = np.random.randint(0,2,(param["node_number"],param["node_number"]));
if digraph == False:
return (a + a.T)/2 + (a + a.T)%2 - np.diag(np.diag((a + a.T)/2 + (a + a.T)%2));
else:
return a;
def scalefree(self, param):
''' Returns a adjacency list, not matrix, ie a list of lists with the number labels of the neighbors for each node. One must supply a dictionarie with the number of nodes of the final model and the number of edges to attach in each iteration of the preferential attachment rule: param["nodes_number"], param["edges_to_attach"] '''
a = nx.generators.barabasi_albert_graph(param["node_number"], 2);
return np.array([v.keys() for v in a.adj.itervalues()]);
def smallworld(self, param):
''' Returns a adjacency list, not matrix, ie a list of lists with the number labels of the neighbors for each node. One must supply a dictionarie with the number of nodes of the final model, the number of nearest neighbors to start attached in the ring topology and the probability of re-attachment: param["nodes_number"], param["k"], param["p"] '''
a = nx.generators.watts_strogatz_graph(param["node_number"], 4, 0.45);
return np.array([v.keys() for v in a.adj.itervalues()]);
def runSimulation(self, plot = 'print'):
full = self.time;
if plot == 'movie':
self.movie = gm.GraphMovie();
while full > 0:
if self.time == full:
self.net = igraph.read(self.string+".gml");
for i,v in enumerate(self.net.vs):
v['label'] = str(i);
v['color'] = self.fields[0,i];
self.movie.addGraph(self.net);
elif self.time != full:
self.net = igraph.read(self.string+".gml")
for i,v in enumerate(self.net.vs):
v['label'] = str(i);
if i == self.edges[sampvar[0]][0] or i == self.edges[sampvar[0]][1]:
v['color'] = 0.0;
else:
v['color'] = self.fields[0,i];
self.movie.addGraph(self.net);
sampvar = np.random.randint(0,len(self.edges),(1));
interact = float(self.fields[0,self.edges[sampvar[0]][0]]+self.fields[0,self.edges[sampvar[0]][1]])/2;
self.fields[0,self.edges[sampvar[0]][0]] = float(self.fields[0,self.edges[sampvar[0]][0]] + interact)/2;
self.fields[0,self.edges[sampvar[0]][1]] = float(self.fields[0,self.edges[sampvar[0]][1]] + interact)/2;
full = full - 1;
self.movie.doMovieLayout();
self.movie.renderMovie(name = self.string);
elif plot == 'print':
while full > 0:
sampvar = self.sampling(); # the sampling process selects the interaction that will take place returning interaction and network
interact = float(self.fields[sampvar[0],self.edges[sampvar[0]][sampvar[1]][0]]+self.fields[sampvar[0],self.edges[sampvar[0]][sampvar[1]][1]])/2; # TODO - generalize for crossed multiplex interaction
self.fields[sampvar[0],self.edges[sampvar[0]][sampvar[1]][0]] = float(self.fields[sampvar[0],self.edges[sampvar[0]][sampvar[1]][0]] + interact)/2;
self.fields[sampvar[0],self.edges[sampvar[0]][sampvar[1]][1]] = float(self.fields[sampvar[0],self.edges[sampvar[0]][sampvar[1]][1]] + interact)/2;
full = full - 1;
print self.fields;
else:
while full > 0:
sampvar = self.sampling(); # the sampling process selects the interaction that will take place returning interaction and network
interact = float(self.fields[sampvar[0],self.edges[sampvar[0]][sampvar[1]][0]]+self.fields[sampvar[0],self.edges[sampvar[0]][sampvar[1]][1]])/2; # TODO - generalize for crossed multiplex interaction
self.fields[sampvar[0],self.edges[sampvar[0]][sampvar[1]][0]] = float(self.fields[sampvar[0],self.edges[sampvar[0]][sampvar[1]][0]] + interact)/2;
self.fields[sampvar[0],self.edges[sampvar[0]][sampvar[1]][1]] = float(self.fields[sampvar[0],self.edges[sampvar[0]][sampvar[1]][1]] + interact)/2;
full = full - 1;
def topology(self, arquivos_gml = {}, ntype = {0 : { "model":"random", "node_number":50 , 'digraph' : False, 'weighted' : False, } } ):
topos = dict();
if arquivos_gml == {}:
for n in ntype.iteritems():
self.nets_len[n[0]] = n[1]["node_number"];
topos[n[0]] = self.models[n[1]["model"]](n[1]);
else:
self.net = dict();
for f in arquivos_gml.iteritems():
self.net[f[0]] = igraph.read(f[1]+".gml");
self.string = arquivos_gml;
self.nets_len[f[0]] = len(self.net[f[0]].vs);
topos[f[0]] = np.array([self.net[f[0]].neighbors(v) for v in range(self.nets_len[f[0]])]);
return topos;
def sampling(self):
step0 = np.random.randint(0,len(self.edges),(1))[0]; #TODO general probability sampling process, this selects nets from uniform probability function
return ( step0, np.random.randint(0,len(self.edges[step0]),(1))[0] ); # this returns network number and the number of the edge selected
def demo(dtype = "smallworld"):
if dtype == "smallworld":
model = AgentModel( netsetup = {0:{ "model":"smallworld", "node_number": 50, 'digraph': False, 'weighted': False,}});
model.runSimulation();
elif dtype == "gml":
model = AgentModel( gml_file = {0:"humannoise03_03_2013"} );
model.runSimulation();
elif dtype == "random":
model = AgentModel( netsetup = {0:{ "model":"random", "node_number": 50, 'digraph': False, 'weighted': False,}});
model.runSimulation();
elif dtype == "movie":
model = AgentModel( gml_file = {0:"humannoise03_03_2013"} , time = 20 );
model.runSimulation(plot = 'movie');
elif dtype == "scalefree":
model = AgentModel( netsetup = {0:{ "model":"scalefree", "node_number": 50, 'digraph': False, 'weighted': False,}});
model.runSimulation();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment