Skip to content

Commit

Permalink
Added dynamic models; bug fix to multimode.py
Browse files Browse the repository at this point in the history
  • Loading branch information
Max committed Aug 17, 2011
1 parent 06b4102 commit ba653e3
Show file tree
Hide file tree
Showing 3 changed files with 232 additions and 1 deletion.
6 changes: 5 additions & 1 deletion chapter4/multimode.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ def plot_multimode(m,layout=net.spring_layout, type_string='type', with_labels=T
#Now we need to find groups of nodes that need to be colored differently
nodesets=defaultdict(list)
for n in m.nodes():
t=m.node[n][type_string]
try:
t=m.node[n][type_string]
except KeyError:
##this happens if a node doesn't have a type_string -- give it a None value
t='None'
nodesets[t].append(n)

## Draw each group of nodes separately, using its own color settings
Expand Down
134 changes: 134 additions & 0 deletions chapter6/construct.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#!/usr/bin/env python
# encoding: utf-8
"""
friedkin.py
Created by Maksim Tsvetovat on 2011-08-08.
Copyright (c) 2011 __MyCompanyName__. All rights reserved.
"""

import sys
import os
import networkx as net
import matplotlib.pyplot as plot
import matplotlib.colors as colors
import random as r

class Person(object):

def __init__(self, id):
#Start with a single initial preference
self.id=id
self.i = r.random()
self.a = self.i
#we value initial opinion and subsequent information equally
self.alpha=0.9

def __str__(self):
return(str(self.id))

def _roulette_choice(self,names,values, inverse=False):
"""
roulette method makes unequally weighted choices based on a set of values
Names and values should be lists of equal lengths
values are between 0 and 1
if inverse=False, names with higher values have a higher probability of being chosen;
if inverse=True, names with lower values have hight probability
"""
wheel=names
for i in range(len(names)):
if not inverse:
wheel.extend([names[i] for x in range(1+int(values[i]*10))])
else:
wheel.extend([names[i] for x in range(1+int((1-values[i])*10))])
return(r.choice(wheel))


def interact(self):
"""
instead of looking at all of the neighbors, let's pick a random node and exchange information with him
this will create an edge and weigh it with their similarity.
Phase II -- make roulette choice instead of random choice
"""
neighbors=g[self].keys()
values=[v['weight'] for v in g[self].values()]

## roll dice and decide to communicate with similar (0.6), dissimilar(0.3) or random (0.1)
roll=r.random()
if r <= 0.1 or len(neighbors)==0:
partner=r.choice(g.nodes())
elif r<=0.1:
partner=self._roulette_choice(neighbors,values,inverse=True)
else:
partner=self._roulette_choice(neighbors,values,inverse=False)

w=0.5
s=self.a*w + partner.a*w
# update my beliefs = initial belief plus sum of all influences
self.a=(1-self.alpha)*self.i + self.alpha*s
g.add_edge(self,partner,weight=(1-self.a-partner.a))



def consensus(g):
"""
Calculcate consensus opinion of the graph
"""
aa=[n.a for n in g.nodes()]
return min(aa),max(aa),sum(aa)/len(aa)

def trim_edges(g, weight=1):
g2=net.Graph()
for f, to, edata in g.edges(data=True):
if edata != {}:
if edata['weight'] > weight:
g2.add_edge(f,to,edata)
return g2

density=0.05
decay_rate=0.01
network_size=100
runtime=200
g=net.Graph()


## create a network of Person objects
for i in range(network_size):
p=Person(i)
g.add_node(p)

##this will be a simple random graph, with random weights
for x in g.nodes():
for y in g.nodes():
if r.random()<=density: g.add_edge(x,y,weight=r.random())

col=[n.a for n in g.nodes()]
pos=net.spring_layout(g)
net.draw_networkx(g,pos=pos, node_color=col,cmap=plot.cm.Reds)

cons=[]
for i in range(runtime):
for node in g.nodes():
node.interact()

#degrade edge weights by a fixed rate
for f,t,data in g.edges(data=True):
data['weight']=data['weight']*(1-decay_rate)
if data['weight']<0.1: g.remove_edge(f,t)

col=[n.a for n in g.nodes()]
ew=[1000*edata['weight'] for f,to,edata in g.edges(data=True)]
plot.figure(2)
plot.plot(col)

cons.append(consensus(g))

plot.figure(i)
g2=trim_edges(g, weight=0.3)
col=[n.a for n in g2.nodes()]
net.draw_networkx(g2,node_color=col, cmap=plot.cm.Reds) #,edge_color=ew,edge_cmap=plot.cm.RdPu)

plot.figure(i+1)
plot.plot(cons)
93 changes: 93 additions & 0 deletions chapter6/friedkin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/usr/bin/env python
# encoding: utf-8
"""
friedkin.py
Created by Maksim Tsvetovat on 2011-08-08.
Copyright (c) 2011 __MyCompanyName__. All rights reserved.
"""

import sys
import os
import networkx as net
import matplotlib.pyplot as plot
import matplotlib.colors as colors
import random as r

class Person(object):

def __init__(self, id):
#Start with a single initial preference
self.id=id
self.i = r.random()
self.a = self.i
#we value initial opinion and subsequent information equally
self.alpha=0.9

def __str__(self):
return(str(self.id))

def step(self):
#loop through the neighbors and aggregate their preferences
neighbors=g[self]
#all nodes in the list of neighbors are equally weighted, including self
w=1/float((len(neighbors)+1))
s=w*self.a
for node in neighbors:
s+=w*node.a

# update my beliefs = initial belief plus sum of all influences
self.a=(1-self.alpha)*self.i + self.alpha*s


class Influencer(Person):
def __init__(self,id):
self.id=id
self.i = r.random()
self.a = 1 ## opinion is strong and immovable

def step(self):
pass

density=0.6
g=net.Graph()

time=100

## create a network of Person objects
for i in range(10):
p=Person(i)
g.add_node(p)

##this will be a simple random graph
for x in g.nodes():
for y in g.nodes():
if r.random()<=density: g.add_edge(x,y)


influencers=4
connections=4
##add the influencers to the network and connect each to 3 other nodes
for i in range(influencers):
inf=Influencer("Inf"+str(i))
for x in range(connections):
g.add_edge(r.choice(g.nodes()), inf)



col=[n.a for n in g.nodes()]
pos=net.spring_layout(g)
net.draw_networkx(g,pos=pos, node_color=col,cmap=plot.cm.Reds)
plot.figure(2)

for i in range(time):
for node in g.nodes():
node.step()

col=[n.a for n in g.nodes()]
print col
plot.plot(col)
plot.figure(i)
net.draw_networkx(g, pos=pos ,node_color=col, cmap=plot.cm.Reds)


0 comments on commit ba653e3

Please sign in to comment.