Skip to content

Commit

Permalink
Updating Graph Recipes
Browse files Browse the repository at this point in the history
  • Loading branch information
hariharanragothaman committed Jan 19, 2024
1 parent aac1023 commit 5125ab4
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 0 deletions.
18 changes: 18 additions & 0 deletions graphs/classic/bellman_ford.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
def bellman_ford(n, edges, start):
dist = [float("inf")] * n
pred = [None] * n

dist[start] = 0

for _ in range(n):
for u, v, d in edges:
if dist[u] + d < dist[v]:
dist[v] = dist[u] + d
pred[v] = u
"""Sanity Check
for u, v, d in edges:
if dist[u] + d < dist[v]:
return None
"""

return dist, pred
22 changes: 22 additions & 0 deletions graphs/classic/djikstra.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from heapq import heappop, heappush


def dijkstra(graph, start):
"""
Uses Dijkstra's algortihm to find the shortest path from node start
to all other nodes in a directed weighted graph.
"""
n = len(graph)
dist, parents = [float("inf")] * n, [-1] * n
dist[start] = 0

queue = [(0, start)]
while queue:
path_len, v = heappop(queue)
if path_len == dist[v]:
for w, edge_len in graph[v]:
if edge_len + path_len < dist[w]:
dist[w], parents[w] = edge_len + path_len, v
heappush(queue, (edge_len + path_len, w))

return dist, parents
31 changes: 31 additions & 0 deletions graphs/classic/kruskal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
class UnionFind:
def __init__(self, n):
self.parent = list(range(n))

def find(self, a):
acopy = a
while a != self.parent[a]:
a = self.parent[a]
while acopy != a:
self.parent[acopy], acopy = a, self.parent[acopy]
return a

def merge(self, a, b):
self.parent[self.find(b)] = self.find(a)


def kruskal(n, U, V, W):
union = UnionFind(n)
cost, merge_cnt = 0, 0
mst_u, mst_v = [], []
order = sorted(range(len(W)), key=lambda x: W[x])
for i in range(len(W)):
u, v = U[order[i]], V[order[i]]
find_u, find_v = union.find(u), union.find(v)
if find_u != find_v:
cost += W[order[i]]
merge_cnt += 1
union.parent[find_v] = find_u
mst_u.append(u), mst_v.append(v)

return cost, mst_u, mst_v, n == 1 + merge_cnt
28 changes: 28 additions & 0 deletions graphs/classic/prim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
def prim(n, adj):
total_weight = 0
selected, min_e = [False] * n, [[float("inf"), -1] for _ in range(n)]
mst_edges = []

min_e[0][0] = 0

for _ in range(n):
v = -1

for j in range(n):
if (not selected[j]) and ((v == -1) or (min_e[j][0] < min_e[v][0])):
v = j

if min_e[v][0] == float("inf"):
return None, None

selected[v] = True
total_weight += min_e[v][0]

if min_e[v][1] != -1:
mst_edges.append((v, min_e[v][1]))

for to in range(n):
if adj[v][to] < min_e[to][0]:
min_e[to] = [adj[v][to], v]

return mst_edges, total_weight

0 comments on commit 5125ab4

Please sign in to comment.