from heapq import heappush, heappop
from collections import deque
from fixtures import weighted_graph, expanded_weights_graph
# UnweightedGraph(a) :: Map(a, Set(a))
# WeightedGraph(a) :: Map(a, Set(a))
# shortest_path_dijkstra :: Vertex -> Vertex -> WeightedGraph(Vertex)
def shortest_path_dijkstra(a, b, g):
q = []
seen = set()
heappush(q, (0, a, [a]))
while q:
w0, v0, path = heappop(q)
if v0 in seen:
continue
elif v0 == b:
return w0, path
for w1, v1 in g.get(v0):
heappush(q, (w0 + w1, v1, path + [v1]))
seen.add(v0)
return 'weighted', 'pizza'
# expand_edge :: Vertex -> (Weight, Vertex) -> Map(Vertex, [Vertex])
def expand_edge(v0, wv):
w, v1 = wv
assert w > 1
result = {v0: ['{}-{}'.format(v1, 1)]}
for x in range(w - 2):
result['{}-{}'.format(v1, x + 1)] = ['{}-{}'.format(v1, x + 2)]
result['{}-{}'.format(v1, w - 1)] = [v1]
return result
# expand_weights :: Vertex -> WeightedGraph(Vertex) -> UnweightedGraph(Vertex)
def expand_weights(v, g):
result = {}
q = deque()
seen = set()
q.append(v)
while q:
v = d.popleft()
if v in seen:
continue
x = expand_edge(v, g.get)
for w, v1 in g.get(v):
if w > 1:
ws = expand_edge(v, (w, v1))
result = {**result, **ws}
q.append(v)
pass
# shortest_path_inject :: Vertex -> Vertex -> WeightedGraph(Vertex)
def shortest_path_inject(a, b, g):
q = deque()
seen = set()
q.append((a, [a]))
while q:
v0, path = q.popleft()
if v0 == 'dummy':
continue
elif v0 in seen:
continue
elif v0 == b:
return len(path), path
for _, v1 in g.get(v0):
q.append((v1, path + [v1]))
seen.add(v0)
continue
return None, None
print(expand_edge('a', (4, 'b')))
print(expand_edge('a', (5, 'e')))
assert expand_weights('a', weighted_graph) == expanded_weights_graph
# a = 'a'
# b = 'd'
# w, x = shortest_path_dijkstra(a, b, weighted_graph)
# w1, x1 = shortest_path_inject(a, b, weighted_graph)
# print("[dijkstra] Shortest path from {} to {} is {} with weight {}".format(
# a, b, x, w))
# print("[injection] Shortest path from {} to {} is {} with weight {}".format(
# a, b, x1, w1))