Added Krushkals and Dijkstra Algorithm
parent
c6a454590d
commit
1a08165d2e
|
@ -0,0 +1,107 @@
|
|||
# Python program for Dijkstra's single
|
||||
# source shortest path algorithm. The program is
|
||||
# for adjacency matrix representation of the graph
|
||||
"""
|
||||
Time Complexity: O(V2)
|
||||
Auxiliary Space: O(V)
|
||||
|
||||
"""
|
||||
|
||||
# Library for INT_MAX
|
||||
import sys
|
||||
|
||||
|
||||
class Graph():
|
||||
|
||||
def __init__(self, vertices):
|
||||
self.V = vertices
|
||||
self.graph = [[0 for column in range(vertices)]
|
||||
for row in range(vertices)]
|
||||
|
||||
def printSolution(self, dist):
|
||||
print("Vertex \tDistance from Source")
|
||||
for node in range(self.V):
|
||||
print(node, "\t", dist[node])
|
||||
|
||||
# A utility function to find the vertex with
|
||||
# minimum distance value, from the set of vertices
|
||||
# not yet included in shortest path tree
|
||||
def minDistance(self, dist, sptSet):
|
||||
|
||||
# Initialize minimum distance for next node
|
||||
min = sys.maxsize
|
||||
|
||||
# Search not nearest vertex not in the
|
||||
# shortest path tree
|
||||
for u in range(self.V):
|
||||
if dist[u] < min and sptSet[u] == False:
|
||||
min = dist[u]
|
||||
min_index = u
|
||||
|
||||
return min_index
|
||||
|
||||
# Function that implements Dijkstra's single source
|
||||
# shortest path algorithm for a graph represented
|
||||
# using adjacency matrix representation
|
||||
def dijkstra(self, src):
|
||||
|
||||
dist = [sys.maxsize] * self.V
|
||||
dist[src] = 0
|
||||
sptSet = [False] * self.V
|
||||
|
||||
for cout in range(self.V):
|
||||
|
||||
# Pick the minimum distance vertex from
|
||||
# the set of vertices not yet processed.
|
||||
# x is always equal to src in first iteration
|
||||
x = self.minDistance(dist, sptSet)
|
||||
|
||||
# Put the minimum distance vertex in the
|
||||
# shortest path tree
|
||||
sptSet[x] = True
|
||||
|
||||
# Update dist value of the adjacent vertices
|
||||
# of the picked vertex only if the current
|
||||
# distance is greater than new distance and
|
||||
# the vertex in not in the shortest path tree
|
||||
for y in range(self.V):
|
||||
if self.graph[x][y] > 0 and sptSet[y] == False and \
|
||||
dist[y] > dist[x] + self.graph[x][y]:
|
||||
dist[y] = dist[x] + self.graph[x][y]
|
||||
|
||||
self.printSolution(dist)
|
||||
|
||||
|
||||
# Driver's code
|
||||
if __name__ == "__main__":
|
||||
g = Graph(9)
|
||||
g.graph = [[0, 4, 0, 0, 0, 0, 0, 8, 0],
|
||||
[4, 0, 8, 0, 0, 0, 0, 11, 0],
|
||||
[0, 8, 0, 7, 0, 4, 0, 0, 2],
|
||||
[0, 0, 7, 0, 9, 14, 0, 0, 0],
|
||||
[0, 0, 0, 9, 0, 10, 0, 0, 0],
|
||||
[0, 0, 4, 14, 10, 0, 2, 0, 0],
|
||||
[0, 0, 0, 0, 0, 2, 0, 1, 6],
|
||||
[8, 11, 0, 0, 0, 0, 1, 0, 7],
|
||||
[0, 0, 2, 0, 0, 0, 6, 7, 0]
|
||||
]
|
||||
|
||||
g.dijkstra(0)
|
||||
|
||||
|
||||
|
||||
# OutPut
|
||||
"""
|
||||
Vertex Distance from Source
|
||||
0 0
|
||||
1 4
|
||||
2 12
|
||||
3 19
|
||||
4 21
|
||||
5 11
|
||||
6 9
|
||||
7 8
|
||||
8 14
|
||||
|
||||
|
||||
"""
|
|
@ -0,0 +1,133 @@
|
|||
# Python program for Kruskal's algorithm to find
|
||||
# Minimum Spanning Tree of a given connected,
|
||||
# undirected and weighted graph
|
||||
"""
|
||||
Time Complexity:
|
||||
O(ElogE) or O(ElogV), Sorting of edges takes O(ELogE) time.
|
||||
After sorting, we iterate through all edges and apply the find-union algorithm.
|
||||
The find and union operations can take at most O(LogV) time. So overall complexity is O(ELogE + ELogV) time.
|
||||
The value of E can be at most O(V2), so O(LogV) is O(LogE) the same. Therefore, the overall time complexity is O(ElogE) or O(ElogV)
|
||||
|
||||
Auxiliary Space:
|
||||
O(V + E), where V is the number of vertices and E is the number of edges in the graph
|
||||
|
||||
"""
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
# Class to represent a graph
|
||||
|
||||
|
||||
class Graph:
|
||||
|
||||
def __init__(self, vertices):
|
||||
self.V = vertices # No. of vertices
|
||||
self.graph = [] # default dictionary
|
||||
# to store graph
|
||||
|
||||
# function to add an edge to graph
|
||||
def addEdge(self, u, v, w):
|
||||
self.graph.append([u, v, w])
|
||||
|
||||
# A utility function to find set of an element i
|
||||
# (uses path compression technique)
|
||||
def find(self, parent, i):
|
||||
if parent[i] == i:
|
||||
return i
|
||||
return self.find(parent, parent[i])
|
||||
|
||||
# A function that does union of two sets of x and y
|
||||
# (uses union by rank)
|
||||
def union(self, parent, rank, x, y):
|
||||
xroot = self.find(parent, x)
|
||||
yroot = self.find(parent, y)
|
||||
|
||||
# Attach smaller rank tree under root of
|
||||
# high rank tree (Union by Rank)
|
||||
if rank[xroot] < rank[yroot]:
|
||||
parent[xroot] = yroot
|
||||
elif rank[xroot] > rank[yroot]:
|
||||
parent[yroot] = xroot
|
||||
|
||||
# If ranks are same, then make one as root
|
||||
# and increment its rank by one
|
||||
else:
|
||||
parent[yroot] = xroot
|
||||
rank[xroot] += 1
|
||||
|
||||
# The main function to construct MST using Kruskal's
|
||||
# algorithm
|
||||
def KruskalMST(self):
|
||||
|
||||
result = [] # This will store the resultant MST
|
||||
|
||||
# An index variable, used for sorted edges
|
||||
i = 0
|
||||
|
||||
# An index variable, used for result[]
|
||||
e = 0
|
||||
|
||||
# Step 1: Sort all the edges in
|
||||
# non-decreasing order of their
|
||||
# weight. If we are not allowed to change the
|
||||
# given graph, we can create a copy of graph
|
||||
self.graph = sorted(self.graph,
|
||||
key=lambda item: item[2])
|
||||
|
||||
parent = []
|
||||
rank = []
|
||||
|
||||
# Create V subsets with single elements
|
||||
for node in range(self.V):
|
||||
parent.append(node)
|
||||
rank.append(0)
|
||||
|
||||
# Number of edges to be taken is equal to V-1
|
||||
while e < self.V - 1:
|
||||
|
||||
# Step 2: Pick the smallest edge and increment
|
||||
# the index for next iteration
|
||||
u, v, w = self.graph[i]
|
||||
i = i + 1
|
||||
x = self.find(parent, u)
|
||||
y = self.find(parent, v)
|
||||
|
||||
# If including this edge doesn't
|
||||
# cause cycle, then include it in result
|
||||
# and increment the index of result
|
||||
# for next edge
|
||||
if x != y:
|
||||
e = e + 1
|
||||
result.append([u, v, w])
|
||||
self.union(parent, rank, x, y)
|
||||
# Else discard the edge
|
||||
|
||||
minimumCost = 0
|
||||
print("Edges in the constructed MST")
|
||||
for u, v, weight in result:
|
||||
minimumCost += weight
|
||||
print("%d -- %d == %d" % (u, v, weight))
|
||||
print("Minimum Spanning Tree", minimumCost)
|
||||
|
||||
|
||||
# Driver's code
|
||||
if __name__ == '__main__':
|
||||
g = Graph(4)
|
||||
g.addEdge(0, 1, 10)
|
||||
g.addEdge(0, 2, 6)
|
||||
g.addEdge(0, 3, 5)
|
||||
g.addEdge(1, 3, 15)
|
||||
g.addEdge(2, 3, 4)
|
||||
|
||||
# Function call
|
||||
g.KruskalMST()
|
||||
|
||||
# Output
|
||||
"""
|
||||
Following are the edges in the constructed MST
|
||||
2 -- 3 == 4
|
||||
0 -- 3 == 5
|
||||
0 -- 1 == 10
|
||||
Minimum Cost Spanning Tree: 19
|
||||
|
||||
"""
|
Loading…
Reference in New Issue