Skip to content

Commit 59189dd

Browse files
committed
fix algs4/edge_weighted_directed_cycle.py
1 parent 54a920d commit 59189dd

File tree

2 files changed

+68
-39
lines changed

2 files changed

+68
-39
lines changed

algs4/bellman_ford_sp.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from algs4.queue import Queue
22
from algs4.stack import Stack
3+
from algs4.edge_weighted_digraph import EdgeWeightedDigraph
4+
from algs4.edge_weighted_directed_cycle import EdgeWeightedDirectedCycle
35

46
POSITIVE_INFINITY = 999999.0
57

@@ -26,7 +28,7 @@ def __init__(self, g, s):
2628
def relax(self, g, v):
2729
for e in g.adj[v]:
2830
w = e.To()
29-
if self.distTo[w] > self.distTo[v]+e.weight:
31+
if self.distTo[w] > self.distTo[v] + e.weight:
3032
self.distTo[w] = self.distTo[v] + e.weight
3133
self.edgeTo[w] = e
3234
if not self.onQ[w]:

algs4/edge_weighted_directed_cycle.py

Lines changed: 65 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,51 +9,78 @@
99
*
1010
*
1111
"""
12-
from algs4.bag import Bag
12+
import random
13+
14+
from algs4.stack import Stack
1315
from algs4.directed_edge import DirectedEdge
16+
from algs4.edge_weighted_digraph import EdgeWeightedDigraph
1417

1518

1619
class EdgeWeightedDirectedCycle:
17-
def __init__(self, v=0, **kwargs):
18-
self.V = v
19-
self.E = 0
20-
self.adj = {}
21-
for v in range(self.V):
22-
self.adj[v] = Bag()
23-
24-
if 'file' in kwargs:
25-
# init a digraph by a file input
26-
in_file = kwargs['file']
27-
self.V = int(in_file.readline())
28-
for v in range(self.V):
29-
self.adj[v] = Bag()
30-
E = int(in_file.readline())
31-
for i in range(E):
32-
v, w, weight = in_file.readline().split()
33-
self.add_edge(DirectedEdge(int(v), int(w), float(weight)))
34-
35-
def __str__(self):
36-
s = "%d vertices, %d edges\n" % (self.V, self.E)
37-
for i in range(self.V):
38-
adjs = " ".join([str(x) for x in self.adj[i]])
39-
s += "%d: %s\n" % (i, adjs)
40-
return s
41-
42-
def add_edge(self, e):
43-
self.adj[e.From()].add(e)
44-
self.E += 1
45-
46-
def edges(self):
47-
edges = []
48-
for v in range(self.V):
49-
for e in self.adj[v]:
50-
edges.append(e)
51-
return edges
20+
def __init__(self, G):
21+
self.cycle = None
22+
self.marked = [False for _ in range(G.V)]
23+
self.on_stack = [False for _ in range(G.V)]
24+
self.edge_to = [None for _ in range(G.V)]
25+
for v in range(G.V):
26+
if not self.marked[v]:
27+
self.dfs(G, v)
28+
29+
def dfs(self, G, v):
30+
self.on_stack[v] = True
31+
self.marked[v] = True
32+
for e in G.adj[v]:
33+
w = e.To()
34+
if self.cycle is not None:
35+
return
36+
elif not self.marked[w]:
37+
print("push stack", e)
38+
self.edge_to[w] = e
39+
self.dfs(G, w)
40+
elif self.on_stack[w]:
41+
# trace back directed cycle
42+
self.cycle = Stack()
43+
f = e
44+
while f.From() != w:
45+
self.cycle.push(f)
46+
f = self.edge_to[f.From()]
47+
self.cycle.push(f)
48+
return
49+
self.on_stack[v] = False
50+
51+
def has_cycle(self):
52+
return self.cycle is not None
5253

5354

5455
if __name__ == "__main__":
5556
import sys
56-
V, E, F = sys.argv[1:]
57-
graph = EdgeWeightedDirectedCycle(int(V), int(E), int(F))
5857

58+
V, E, F = sys.argv[1:]
59+
V = int(V)
60+
E = int(E)
61+
F = int(F)
62+
graph = EdgeWeightedDigraph(V)
63+
for _ in range(int(E)):
64+
v = 0
65+
w = 0
66+
while v >= w:
67+
v = random.randint(0, V - 1)
68+
w = random.randint(0, V - 1)
69+
weight = random.uniform(0, 1)
70+
graph.add_edge(DirectedEdge(v, w, weight))
71+
# add F extra edges
72+
for _ in range(int(E)):
73+
v = random.randint(0, V - 1)
74+
w = random.randint(0, V - 1)
75+
weight = random.uniform(0, 1)
76+
graph.add_edge(DirectedEdge(v, w, weight))
5977
print(graph)
78+
79+
finder = EdgeWeightedDirectedCycle(graph)
80+
if finder.has_cycle():
81+
print("find cycle:\n")
82+
for e in finder.cycle:
83+
print(e, " ")
84+
print()
85+
else:
86+
print("No directed cycle")

0 commit comments

Comments
 (0)