1 |
48 |
alirezamon |
import networkx as nx
|
2 |
|
|
from s_c_c import filter_big_scc
|
3 |
|
|
from s_c_c import get_big_sccs
|
4 |
|
|
from file_io import write_pairs_to_file
|
5 |
|
|
from file_io import read_dict_from_file
|
6 |
|
|
import os.path
|
7 |
|
|
import sys
|
8 |
|
|
sys.setrecursionlimit(5500000)
|
9 |
|
|
|
10 |
|
|
|
11 |
|
|
def get_agony(edge,players):
|
12 |
|
|
u,v = edge
|
13 |
|
|
return max(players[u]-players[v],0)
|
14 |
|
|
|
15 |
|
|
def get_agonies(edges,players):
|
16 |
|
|
edges_agony_dict = {}
|
17 |
|
|
for edge in edges:
|
18 |
|
|
edges_agony_dict[edge] = get_agony(edge,players)
|
19 |
|
|
return edges_agony_dict
|
20 |
|
|
|
21 |
|
|
def remove_cycle_edges_by_agony(graph,players,edges_to_be_removed):
|
22 |
|
|
|
23 |
|
|
pair_agony_dict = {}
|
24 |
|
|
for pair in graph.edges():
|
25 |
|
|
u,v = pair
|
26 |
|
|
agony = max(players[u]-players[v],0)
|
27 |
|
|
pair_agony_dict[pair] = agony
|
28 |
|
|
from helper_funs import pick_from_dict
|
29 |
|
|
pair_max_agony,agony = pick_from_dict(pair_agony_dict)
|
30 |
|
|
|
31 |
|
|
edges_to_be_removed.append(pair_max_agony)
|
32 |
|
|
#print("edge to be removed: %s, agony: %0.4f" % (pair_max_agony,max_agony))
|
33 |
|
|
sub_graphs = filter_big_scc(graph,[pair_max_agony])
|
34 |
|
|
if sub_graphs:
|
35 |
|
|
num_subs = len(sub_graphs)
|
36 |
|
|
for index,sub in enumerate(sub_graphs):
|
37 |
|
|
#print("%d / %d scc: (%d,%d)" % (index+1,num_subs,sub.number_of_nodes(),sub.number_of_edges()))
|
38 |
|
|
remove_cycle_edges_by_agony(sub,players,edges_to_be_removed)
|
39 |
|
|
else:
|
40 |
|
|
return None
|
41 |
|
|
|
42 |
|
|
|
43 |
|
|
def remove_cycle_edges_by_agony_iterately(sccs,players,edges_to_be_removed):
|
44 |
|
|
while True:
|
45 |
|
|
graph = sccs.pop()
|
46 |
|
|
pair_max_agony = None
|
47 |
|
|
max_agony = -1
|
48 |
|
|
for pair in graph.edges():
|
49 |
|
|
u,v = pair
|
50 |
|
|
agony = max(players[u]-players[v],0)
|
51 |
|
|
if agony >= max_agony:
|
52 |
|
|
pair_max_agony = (u,v)
|
53 |
|
|
max_agony = agony
|
54 |
|
|
edges_to_be_removed.append(pair_max_agony)
|
55 |
|
|
#print("graph: (%d,%d), edge to be removed: %s, agony: %0.4f" % (graph.number_of_nodes(),graph.number_of_edges(),pair_max_agony,max_agony))
|
56 |
|
|
graph.remove_edges_from([pair_max_agony])
|
57 |
|
|
#print("graph: (%d,%d), edge to be removed: %s" % (graph.number_of_nodes(),graph.number_of_edges(),pair_max_agony))
|
58 |
|
|
sub_graphs = filter_big_scc(graph,[pair_max_agony])
|
59 |
|
|
if sub_graphs:
|
60 |
|
|
for index,sub in enumerate(sub_graphs):
|
61 |
|
|
sccs.append(sub)
|
62 |
|
|
if not sccs:
|
63 |
|
|
return
|
64 |
|
|
|
65 |
|
|
def scores_of_nodes_in_scc(sccs,players):
|
66 |
|
|
from s_c_c import nodes_in_scc
|
67 |
|
|
scc_nodes = nodes_in_scc(sccs)
|
68 |
|
|
scc_nodes_score_dict = {}
|
69 |
|
|
for node in scc_nodes:
|
70 |
|
|
scc_nodes_score_dict[node] = players[node]
|
71 |
|
|
#print("# scores of nodes in scc: %d" % (len(scc_nodes_score_dict)))
|
72 |
|
|
return scc_nodes_score_dict
|
73 |
|
|
|
74 |
|
|
def scc_based_to_remove_cycle_edges_recursilvely(g,nodes_score):
|
75 |
|
|
big_sccs = get_big_sccs(g)
|
76 |
|
|
scc_nodes_score_dict = scores_of_nodes_in_scc(big_sccs,nodes_score)
|
77 |
|
|
|
78 |
|
|
edges_to_be_removed = []
|
79 |
|
|
for sub in big_sccs:
|
80 |
|
|
scc_edges_to_be_removed = []
|
81 |
|
|
remove_cycle_edges_by_agony(sub,scc_nodes_score_dict,scc_edges_to_be_removed)
|
82 |
|
|
edges_to_be_removed += scc_edges_to_be_removed
|
83 |
|
|
#print(" # edges to be removed: %d" % len(edges_to_be_removed))
|
84 |
|
|
return edges_to_be_removed
|
85 |
|
|
|
86 |
|
|
|
87 |
|
|
def scc_based_to_remove_cycle_edges_iterately(g,nodes_score):
|
88 |
|
|
from remove_self_loops import remove_self_loops_from_graph
|
89 |
|
|
self_loops = remove_self_loops_from_graph(g)
|
90 |
|
|
big_sccs = get_big_sccs(g)
|
91 |
|
|
scc_nodes_score_dict = scores_of_nodes_in_scc(big_sccs,nodes_score)
|
92 |
|
|
edges_to_be_removed = []
|
93 |
|
|
if len(big_sccs) == 0:
|
94 |
|
|
print("After removal of self loop edgs: %s" % nx.is_directed_acyclic_graph(g))
|
95 |
|
|
return self_loops
|
96 |
|
|
|
97 |
|
|
remove_cycle_edges_by_agony_iterately(big_sccs,scc_nodes_score_dict,edges_to_be_removed)
|
98 |
|
|
#print(" # edges to be removed: %d" % len(edges_to_be_removed))
|
99 |
|
|
return edges_to_be_removed+self_loops
|
100 |
|
|
|
101 |
|
|
def remove_cycle_edges(graph_file,players_score):
|
102 |
|
|
return remove_cycle_edges_by_agony(graph_file,players_score)
|