/
main.py
111 lines (107 loc) · 5.37 KB
/
main.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
## @package main
# Simulates a network with peers and diffusion of information
from __future__ import division # to allow integer division to produce a floating point
import networkx as nx
import matplotlib.pyplot as plt
import graph_modification as gm
import random as rd
import numpy as np
import computation as cp
import time
import excp as ex
import sys
import display as d
import datetime
print datetime.datetime.today()
# Macros like variables
start_time = time.time()
# SEED = 14460415
SEED = int(start_time)
NUM_PEERS = 100
G_TYPE = 'geometric' # Graph type: random, geometric, scale_free (barabasi_albert)
# Gaph characterisitic parameter:
#for random graph: probability of having an edge between any 2 neighbours
#for Geometric graph: maximum euclidean distance for a edge to exist between 2 nodes
#for barabasi albert graph: number of nodes starting the graph and number of edges a new node entering the graph will have
G_CHAR = 0.2
ALPHA = 0.3 # weight given to self opinion
STRATEGY1 = 'D' # strategy chosen by first forceful peer ((+1))
BUDGET1 = 10 # number of edges allowed for first forceful peer
STRATEGY2 ='1/D' # strategy chosen by second forceful peer ((-1))
BUDGET2 = 10 # number of edges allowed for second forceful peers
NEUTRAL_RANGE = 0.001 # opinion between +ve and -ve values of this range are considered neutral
SIMULATIONS = 1 # Number of repition of a match between 2 strategies
repeated_sim = 0 # Repeated simulations in case of 1/D strategy
# seed the random generator
np.random.seed(SEED) ;rd.seed(SEED)
# arrays to store the followers percentages of forceful peers (positive or negative) and neutral nodes for each match
S1_followers = np.zeros(SIMULATIONS)
S2_followers = np.zeros(SIMULATIONS)
neutral = np.zeros(SIMULATIONS)
# List that stores [S1_wins, S2_wins, ties]
wins= [0,0,0]
# for analytical reasons, store the winning percentage for each simulation for strategy 1
S1_wins_list = []
# Loop Simulation times to generate graph and evaluate results.
# taking into consideration the possibility of having to redo a simulation in case of an edgeless node appears woth 1/D strategy
i = 0
while i < SIMULATIONS:
# Initialize the graph with normal peers
G = gm.create_graph(G_TYPE,NUM_PEERS, G_CHAR)
# Exception is thrown if the graph is not connected and simulation is repeated
try:
if not nx.is_connected(G): raise nx.NetworkXException('Exception: Graph is not connected, simulation will be repeated')
except nx.NetworkXException as exp:
# Ignore this simulation and do another one
print exp
repeated_sim += 1
continue
# If strategy 1 is not a smart peer, the 2 forceful peers can be added simultaneously
if STRATEGY1 != 'smart':
gm.add_forceful(G, STRATEGY1, BUDGET1, STRATEGY2, BUDGET2)
# If strategy 1 is smart then ofrceful peer with strategy 2 is added first then smart peer
else:
#Add one forceul peer to the graph
gm.add_one_forceful(G, STRATEGY2, BUDGET2)
## Linear programming method to beat an existing peer with minimum budget
BUDGET1 = gm.add_smart(G,ALPHA,BUDGET2, NEUTRAL_RANGE)
# Calculate final opinion vector by equation, considering the presence of
# 2 forceful peers in the last 2 indices of the graph
#R_inf = cp.R_inf(G,ALPHA)
# Calculate final opinion vector by iterations
R_itr = gm.R_itr(G,ALPHA)
# Calculate the percentage of normal peers that followed either of the forceful peers
tmp = cp.percentages(G,NEUTRAL_RANGE)
# Update S1_wins_list for analytical reason
if (tmp[0]>0.5): S1_wins_list.append(1)
else: S1_wins_list.append(0)
# Update percentages arrays
cp.update_percentages(tmp, S1_followers, S2_followers, neutral, i, wins)
i += 1
# Asserting that R_inf calculated by equation and iteration are equal to decimal places
#try:
# np.testing.assert_array_almost_equal(R_inf,R_itr,4)
#except AssertionError:
# sys.exit('ConvergenceError: convergence of R_inf is not correct to 4 decimal places\nProgram will terminate')
wins[0] = (wins[0]/SIMULATIONS)*100
wins[1] = (wins[1]/SIMULATIONS)*100
wins[2] = (wins[2]/SIMULATIONS)*100
print 'seed used: %d\tGraph type: %s\t number of normal nodes: %d' %(SEED,G_TYPE,NUM_PEERS)
print 'After %d simulations: %s strategy budget = %d, %s strategy budget = %d\n\t\t\t %s strategy \t %s strategy\t neutral' %(SIMULATIONS,STRATEGY1,BUDGET1,STRATEGY2,BUDGET2, STRATEGY1,STRATEGY2)
print 'Follwers percentage\t %.2f%% \t\t %.2f%% \t %.2f%%' %(np.mean(S1_followers)*100,np.mean(S2_followers)*100,np.mean(neutral)*100)
print 'Winning percentage:\t %.2f%% \t\t %.2f%% \t %.2f%%' %(wins[0],wins[1], wins[2])
print 'Time elapsed %f' % (time.time() - start_time)
#print 'Repeated simulations: ', repeated_sim
#print 'The number of simulations needed to obtain 0.5% confidence interval: ',str(cp.get_sim_num(np.mean(S1_followers),S1_followers))
#print 'The precision after ', str(SIMULATIONS), 'simulations is:', str(cp.get_precision(np.mean(S1_followers),S1_followers,SIMULATIONS))
sys.stdout.write("\a")
#input("Press Enter to continue...")
#print '\n'.join(map(str, R_itr))
# Save Calculated opinion of nodes by simulation
f = open("smart_peer_info.txt", "a")
f.write('Opinions after simulation\n')
for n in xrange(NUM_PEERS):
f.write('opinion of node: '+ str(n) + ' = ' + str(G.node[n]['opinion']) + '\n')
f.write('===========================\n')
# Display the graph including forceful peers (NUM_PEERS+2) or not (NUM_PEERS)categorizing nodes by category and by opinion based on the neutral range
d.display_graph(G,NEUTRAL_RANGE,NUM_PEERS,SEED)