1
+ import sys
2
+ import networkx as nx
3
+ from networkx .algorithms .connectivity import edge_disjoint_paths , node_disjoint_paths
4
+ from networkx .algorithms .flow import shortest_augmenting_path
5
+ import matplotlib .pyplot as plt
6
+ import statistics
7
+ from itertools import islice
8
+ import numpy as np
9
+ import copy
10
+ from operator import itemgetter
11
+
12
+ graph = {}
13
+ E = {}
14
+ topology = {}
15
+ num = None
16
+
17
+
18
+
19
+ def read_positions (pos_file ,ignore ):
20
+ """ Read node positions from the given pos_file. Return a dictionary that
21
+ maps each node in the file to a tuple (x,y) with its x,y coordinates """
22
+ pos = {}
23
+ with open (pos_file ) as f :
24
+ for line in f :
25
+ # each line is like: 1 41.505880 -81.609169 # Case Western
26
+ parts = line .split ()
27
+ node = int (parts [0 ])
28
+ if node in ignore : continue # to ignore any nodes
29
+ lat = float (parts [1 ])
30
+ lon = float (parts [2 ])
31
+ pos [node ] = (lon , lat )
32
+ return pos
33
+
34
+ def create_graph (input_graph ,ignore ):
35
+ with open (input_graph ) as f :
36
+ for line in f :
37
+ parts = line .split ()
38
+ if parts != []:
39
+ node1 = int (parts [0 ])
40
+ node2 = int (parts [1 ])
41
+ if node1 in ignore or node2 in ignore : continue
42
+ weight = int (parts [2 ])
43
+ E [(node1 ,node2 )] = int (weight )
44
+ if not (node1 in graph ):
45
+ graph [node1 ]= {}
46
+ graph [node1 ][node2 ] = int (weight )
47
+
48
+ def create_topology (input_graph ,ignore ):
49
+ with open (input_graph ) as f :
50
+ for line in f :
51
+ parts = line .split ()
52
+ if parts != []:
53
+ node1 = int (parts [0 ])
54
+ node2 = int (parts [1 ])
55
+ if node1 in ignore or node2 in ignore : continue
56
+ weight = int (parts [2 ])
57
+ if not (node1 in topology ):
58
+ topology [node1 ]= {}
59
+ topology [node1 ][node2 ] = int (weight )
60
+
61
+ def dfs (visited ,node ,end ,path ,edge ):
62
+ if node in visited :
63
+ return
64
+ path .append (node )
65
+
66
+ if node == end :
67
+ edge .append (copy .deepcopy (path ))
68
+ path .remove (node )
69
+ return
70
+ visited .append (node )
71
+ for nei in topology [node ]:
72
+ dfs (visited ,nei ,end ,path ,edge )
73
+ visited .remove (node )
74
+ path .remove (node )
75
+
76
+ def add_path (path_sum ,n ,m ,edge ):
77
+ l = len (edge )
78
+ print (f'has { l } paths' )
79
+ if l not in list (path_sum .keys ()):
80
+ path_sum [l ]= []
81
+ path_sum [l ].append ([n ,m ])
82
+
83
+ #print(path_sum)
84
+
85
+ def add_cal_weight (edge , weights ,min_P ,max_P ,max_all_P ,Orig ):
86
+ print (f"direct:{ Orig } \n " )
87
+ for i in edge :
88
+ weight = 0
89
+ for j in range (len (i )- 1 ):
90
+ #print(E[(i[j],i[j+1])])
91
+ weight += E [(i [j ],i [j + 1 ])]/ 2
92
+ weights .append ((weight ,i ))
93
+
94
+ if len (edge ) >= 3 :
95
+ weights .sort (key = lambda x :x [0 ])
96
+ Min = weights [0 ]
97
+ Max = weights [2 ]
98
+ Max_of_all = weights [- 1 ]
99
+ min_P .append (((Min [0 ] - Orig )/ Orig * 100 ,Min [0 ] - Orig ,Min [1 ]))
100
+ max_P .append (((Max [0 ] - Orig )/ Orig * 100 ,Max [0 ] - Orig ,Max [1 ]))
101
+ max_all_P .append (((Max_of_all [0 ] - Orig )/ Orig * 100 ,Max_of_all [0 ] - Orig ,Max_of_all [1 ]))
102
+ print (weights )
103
+ print (f"min : { Min } , max : { Max } , original : { Orig } , max of 6th pathes: { Max_of_all } " )
104
+ print (f"min : { round ((Min [0 ] - Orig )/ Orig * 100 )} % { Min [0 ] - Orig } , max : { round ((Max [0 ] - Orig )/ Orig * 100 )} % { Max [0 ] - Orig } , max of 6th pathes: { round ((Max_of_all [0 ] - Orig )/ Orig * 100 )} % { Max_of_all [0 ] - Orig } \n " )
105
+ else :
106
+ print ("not enough paths" )
107
+
108
+ def sum_path (path_sum ):
109
+ for num in sorted (path_sum .keys ()):
110
+ print (f"{ len (list (path_sum [num ]))} pairs of nodes have { num } disjoint path" )
111
+
112
+ def sum_weight (p ):
113
+ l = []
114
+ for i in p : l .append (i [0 ])
115
+ form ("min:" ,min (p ))
116
+ form ("max:" , max (p ))
117
+ print (f"mean:{ round (statistics .mean (l ))} %" )
118
+
119
+ def form (mes ,l ):
120
+ print (f"{ mes } { round (l [0 ])} % weight: { l [1 ]} path: { l [2 ]} " )
121
+
122
+ def get_total_edge ():
123
+ result = 0
124
+ for n in topology :
125
+ result += len (topology [n ])- 1
126
+ return result / 2
127
+
128
+
129
+ def each_degree ():
130
+ degree = {}
131
+ total_dis_over_deg = 0
132
+ print ( "\n Degrees total disjoint path total disjoint path/Degrees: " )
133
+ for i in topology :
134
+ degree [i ]= len (topology [i ])- 1
135
+ print (f"node { i } has { degree [i ]} { topology [i ]['disjoint' ]} { round (topology [i ]['disjoint' ]/ degree [i ],2 )} " )
136
+ total_dis_over_deg += topology [i ]['disjoint' ]/ degree [i ]
137
+ print (total_dis_over_deg / get_total_edge ())
138
+
139
+
140
+
141
+ def main (argv ):
142
+ inputGraph = argv [0 ]
143
+ posGraph = argv [1 ]
144
+ result = argv [2 ]
145
+ ignore = [int (i ) for i in argv [3 :]]
146
+ print ("--ignore nodes: " ,ignore ,"--\n " )
147
+
148
+
149
+ create_graph (inputGraph ,ignore )
150
+ create_topology (result ,ignore )
151
+ pos = read_positions (posGraph ,ignore )
152
+
153
+
154
+
155
+ draw = nx .DiGraph ()
156
+ for n in topology :
157
+ for m in topology [n ]:
158
+ weight = topology [n ][m ]
159
+ draw .add_edge (n , m , weight = weight )
160
+ draw .add_edge (m , n , weight = weight )
161
+
162
+ """
163
+ from here is the caculation of one-way absolute latency difference
164
+ """
165
+
166
+ path_sum = {}
167
+ min_P = []
168
+ max_P = []
169
+ max_all_P = []
170
+ for n in graph :
171
+ total_disjoint_path = 0
172
+ for m in graph [n ]:
173
+ edge = []
174
+ visited = []
175
+ path = []
176
+ weights = []
177
+ Orig = E [(n ,m )]/ 2
178
+ print (f"{ n } ->{ m } " )
179
+ #dfs(visited, n, m,path,edge)
180
+ edge = list (nx .node_disjoint_paths (draw ,n ,m ,flow_func = shortest_augmenting_path ,cutoff = num ))
181
+ add_path (path_sum ,n ,m ,edge )
182
+ add_cal_weight (edge , weights ,min_P ,max_P ,max_all_P ,Orig )
183
+ total_disjoint_path += len (edge )
184
+ topology [n ]['disjoint' ] = total_disjoint_path
185
+
186
+
187
+ print ("\n --ignore nodes: " ,ignore ,"--\n " )
188
+ sum_path (path_sum )
189
+ print ("\n the first min weight sum:" )
190
+ sum_weight (min_P )
191
+ print ("\n the 3ed min weight sum:" )
192
+ sum_weight (max_P )
193
+ if num != 3 :
194
+ print ("\n the max weight sum:" )
195
+ sum_weight (max_all_P )
196
+ totalEdges = get_total_edge ()
197
+ print (f"total edges is { totalEdges } " )
198
+ degree = each_degree ()
199
+ nx .draw_networkx (draw , pos )
200
+ plt .show ()
201
+
202
+
203
+
204
+
205
+ if __name__ == "__main__" :
206
+ main (sys .argv [1 :])
0 commit comments