forked from davidoiknine/algo_inclass_S4
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Bellman_cor.py
79 lines (64 loc) · 1.87 KB
/
Bellman_cor.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
# -*- coding: utf-8 -*-
"""
S4 - Shortest paths
Bellman implementations
"""
from algopy import graph, stack, queue
inf = float('inf')
def dfsSuff(G, s, M, st):
M[s] = True
for adj in G.adjlists[s]:
if not M[adj]:
dfsSuff(G, adj, M, st)
st.push(s)
def topologicalOrder(G, src):
'''
make topological order of subgraph from vertices
that are reachable from src
'''
M = [False] * G.order
order = stack.Stack()
dfsSuff(G, src, M, order)
return order
def Bellman1(G, src, dst = None):
dist = [inf] * G.order
dist[src] = 0
p = [-1] * G.order
order = topologicalOrder(G, src)
x = order.pop()
while not order.isempty() and (x != dst):
for y in G.adjlists[x]:
if dist[x] + G.costs[(x, y)] < dist[y]:
dist[y] = dist[x] + G.costs[(x, y)]
p[y] = x
x = order.pop()
return (dist, p)
# another version: using the in-degree vector (only in the subgraph from reachable vertices)
def dfsIndeg(G, s, M, din):
M[s] = True
for adj in G.adjlists[s]:
din[adj] += 1
if not M[adj]:
dfsIndeg(G, adj, M, din)
def indegreesSubGraph(G, src):
din = [0] * G.order
M = [False] * G.order
dfsIndeg(G, src, M, din)
return din
def Bellman2(G, src):
dist = [inf] * G.order
dist[src] = 0
p = [-1] * G.order
din = indegreesSubGraph(G, src)
q = queue.Queue()
q.enqueue(src)
while not q.isempty():
x = q.dequeue()
for y in G.adjlists[x]:
din[y] -= 1
if din[y] == 0:
q.enqueue(y)
if dist[x] + G.costs[(x, y)] < dist[y]:
dist[y] = dist[x] + G.costs[(x, y)]
p[y] = x
return (dist, p)