-
Notifications
You must be signed in to change notification settings - Fork 0
/
SCC_size_finder.py
155 lines (108 loc) · 3.41 KB
/
SCC_size_finder.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!usr/env/bin python
# Stack in DFS_1 and 2 should be a stack
from collections import Set
import numpy, random, copy, sys
sys.setrecursionlimit(1000000000)
edge_list = numpy.genfromtxt('/home/Damian/Dropbox/Algorithms/SCC_HW_Input.txt',dtype=int) # fill in the rest of the path
# test number of rows, does it equal 875,635 or whatever?
# construct vertex and reverse-vertex adjacency lists
forward_vertex_list = [[] for x in range(875714)]
reverse_vertex_list = [[] for x in range(875714)]
for i in range(len(edge_list)):
edge = edge_list[i,:]
# check lengths, add stuff if necessary
# if len(forward_vertex_list) < edge[0]:
# addition = [[] for x in range(len(forward_vertex_list),edge[0])]
# forward_vertex_list.extend(addition)
# if len(reverse_vertex_list) < edge[1]:
# addition = [[] for x in range(len(reverse_vertex_list),edge[1])]
# reverse_vertex_list.extend(addition)
# add edge[0] to reverse_vertex_list[edge[1]]
# add edge[1] to forward_vertex_list[edge[0]]
forward_vertex_list[edge[0]-1].append(edge[1])
reverse_vertex_list[edge[1]-1].append(edge[0])
# DFS-loop the rev-list and construct the finishing time to vertex dictionary
finish_time_to_vertex = [0 for x in range(len(forward_vertex_list))] # could just be a list
visited_nodes = set([]) # might be faster as a set
global finish_time
finish_time = 0
def DFS_1(Stack=None,start=None): # Stack could be an actual stack
'''
Stack : list
start : int
'''
print "size of stack: ", len(Stack)
if start != None:
Stack.append(start)
visited_nodes.add(start)
if len(Stack) == 0:
return
next_up_list = reverse_vertex_list[Stack[len(Stack)-1]-1]
add_to_stack = []
for next_up in next_up_list:
if next_up not in visited_nodes:
add_to_stack.append(next_up)
visited_nodes.add(next_up)
if len(add_to_stack) == 0:
global finish_time
finish_time_to_vertex[finish_time] = Stack[len(Stack)-1]
finish_time += 1
dummy = Stack.pop()
DFS_1(Stack)
return
else:
Stack.extend(add_to_stack)
DFS_1(Stack)
return
for node in range(1,len(forward_vertex_list)+1):
print "part 1"
print node,"/",875714
if node not in visited_nodes:
DFS_1([],node)
# DFS loop the forward-list and count up the sizes of the SCCs.
SCC_Sizes = []
global last_stack_size
stack_size_before = 0
visited_nodes = set([]) # could be a set
def DFS_2(Stack=None,start=None): # Stack could be an actual stack
'''
Stack : list
start : int
'''
print "size of stack: ", len(Stack)
if start != None:
Stack.append(start)
visited_nodes.add(start)
if len(Stack) == 0:
global stack_size_before
size = len(visited_nodes) - stack_size_before
stack_size_before = len(visited_nodes)
SCC_Sizes.append(size)
return
next_up_list = forward_vertex_list[Stack[len(Stack)-1]-1]
add_to_stack = []
for next_up in next_up_list:
if next_up not in visited_nodes:
add_to_stack.append(next_up)
visited_nodes.add(next_up)
if len(add_to_stack) == 0:
dummy = Stack.pop()
DFS_2(Stack)
return
else:
Stack.extend(add_to_stack)
DFS_2(Stack)
return
for finished in range(len(forward_vertex_list)-1, -1, -1):
print "part 2"
print finished,"/",0
if finish_time_to_vertex[finished] not in visited_nodes:
DFS_2([],finish_time_to_vertex[finished])
# sort and return top 5
SCC_Sizes.sort()
print SCC_Sizes
if len(SCC_Sizes) >= 5:
SCC_Sizes = SCC_Sizes[0:5]
else:
add_on = [0 for x in range(len(SCC_Sizes),5)]
SCC_Sizes.extend(add_on)