forked from TheAlgorithms/Python
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0e76ee9
commit a7948f1
Showing
9 changed files
with
431 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# Finding Articulation Points in Undirected Graph | ||
def computeAP(l): | ||
n = len(l) | ||
outEdgeCount = 0 | ||
low = [0] * n | ||
visited = [False] * n | ||
isArt = [False] * n | ||
|
||
def dfs(root, at, parent, outEdgeCount): | ||
if parent == root: | ||
outEdgeCount += 1 | ||
visited[at] = True | ||
low[at] = at | ||
|
||
for to in l[at]: | ||
if to == parent: | ||
pass | ||
elif not visited[to]: | ||
outEdgeCount = dfs(root, to, at, outEdgeCount) | ||
low[at] = min(low[at], low[to]) | ||
|
||
# AP found via bridge | ||
if at < low[to]: | ||
isArt[at] = True | ||
# AP found via cycle | ||
if at == low[to]: | ||
isArt[at] = True | ||
else: | ||
low[at] = min(low[at], to) | ||
return outEdgeCount | ||
|
||
for i in range(n): | ||
if not visited[i]: | ||
outEdgeCount = 0 | ||
outEdgeCount = dfs(i, i, -1, outEdgeCount) | ||
isArt[i] = (outEdgeCount > 1) | ||
|
||
for x in range(len(isArt)): | ||
if isArt[x] == True: | ||
print(x, end=" ") | ||
|
||
# Adjacency list of graph | ||
l = {0:[1,2], 1:[0,2], 2:[0,1,3,5], 3:[2,4], 4:[3], 5:[2,6,8], 6:[5,7], 7:[6,8], 8:[5,7]} | ||
computeAP(l) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# Check whether Graph is Bipartite or Not using BFS | ||
|
||
# A Bipartite Graph is a graph whose vertices can be divided into two independent sets, | ||
# U and V such that every edge (u, v) either connects a vertex from U to V or a vertex | ||
# from V to U. In other words, for every edge (u, v), either u belongs to U and v to V, | ||
# or u belongs to V and v to U. We can also say that there is no edge that connects | ||
# vertices of same set. | ||
def checkBipartite(l): | ||
queue = [] | ||
visited = [False] * len(l) | ||
color = [-1] * len(l) | ||
|
||
def bfs(): | ||
while(queue): | ||
u = queue.pop(0) | ||
visited[u] = True | ||
|
||
for neighbour in l[u]: | ||
|
||
if neighbour == u: | ||
return False | ||
|
||
if color[neighbour] == -1: | ||
color[neighbour] = 1 - color[u] | ||
queue.append(neighbour) | ||
|
||
elif color[neighbour] == color[u]: | ||
return False | ||
|
||
return True | ||
|
||
for i in range(len(l)): | ||
if not visited[i]: | ||
queue.append(i) | ||
color[i] = 0 | ||
if bfs() == False: | ||
return False | ||
|
||
return True | ||
|
||
# Adjacency List of graph | ||
l = {0:[1,3], 1:[0,2], 2:[1,3], 3:[0,2]} | ||
print(checkBipartite(l)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Finding Bridges in Undirected Graph | ||
def computeBridges(l): | ||
id = 0 | ||
n = len(l) # No of vertices in graph | ||
low = [0] * n | ||
visited = [False] * n | ||
|
||
def dfs(at, parent, bridges, id): | ||
visited[at] = True | ||
low[at] = id | ||
id += 1 | ||
for to in l[at]: | ||
if to == parent: | ||
pass | ||
elif not visited[to]: | ||
dfs(to, at, bridges, id) | ||
low[at] = min(low[at], low[to]) | ||
if at < low[to]: | ||
bridges.append([at, to]) | ||
else: | ||
# This edge is a back edge and cannot be a bridge | ||
low[at] = min(low[at], to) | ||
|
||
bridges = [] | ||
for i in range(n): | ||
if (not visited[i]): | ||
dfs(i, -1, bridges, id) | ||
print(bridges) | ||
|
||
l = {0:[1,2], 1:[0,2], 2:[0,1,3,5], 3:[2,4], 4:[3], 5:[2,6,8], 6:[5,7], 7:[6,8], 8:[5,7]} | ||
computeBridges(l) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Finding longest distance in Directed Acyclic Graph using KahnsAlgorithm | ||
def longestDistance(l): | ||
indegree = [0] * len(l) | ||
queue = [] | ||
longDist = [1] * len(l) | ||
|
||
for key, values in l.items(): | ||
for i in values: | ||
indegree[i] += 1 | ||
|
||
for i in range(len(indegree)): | ||
if indegree[i] == 0: | ||
queue.append(i) | ||
|
||
while(queue): | ||
vertex = queue.pop(0) | ||
for x in l[vertex]: | ||
indegree[x] -= 1 | ||
|
||
if longDist[vertex] + 1 > longDist[x]: | ||
longDist[x] = longDist[vertex] + 1 | ||
|
||
if indegree[x] == 0: | ||
queue.append(x) | ||
|
||
print(max(longDist)) | ||
|
||
# Adjacency list of Graph | ||
l = {0:[2,3,4], 1:[2,7], 2:[5], 3:[5,7], 4:[7], 5:[6], 6:[7], 7:[]} | ||
longestDistance(l) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Kahn's Algorithm is used to find Topological ordering of Directed Acyclic Graph using BFS | ||
def topologicalSort(l): | ||
indegree = [0] * len(l) | ||
queue = [] | ||
topo = [] | ||
cnt = 0 | ||
|
||
for key, values in l.items(): | ||
for i in values: | ||
indegree[i] += 1 | ||
|
||
for i in range(len(indegree)): | ||
if indegree[i] == 0: | ||
queue.append(i) | ||
|
||
while(queue): | ||
vertex = queue.pop(0) | ||
cnt += 1 | ||
topo.append(vertex) | ||
for x in l[vertex]: | ||
indegree[x] -= 1 | ||
if indegree[x] == 0: | ||
queue.append(x) | ||
|
||
if cnt != len(l): | ||
print("Cycle exists") | ||
else: | ||
print(topo) | ||
|
||
# Adjacency List of Graph | ||
l = {0:[1,2], 1:[3], 2:[3], 3:[4,5], 4:[], 5:[]} | ||
topologicalSort(l) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import sys | ||
from collections import defaultdict | ||
|
||
def PrimsAlgorithm(l): | ||
|
||
nodePosition = [] | ||
def getPosition(vertex): | ||
return nodePosition[vertex] | ||
|
||
def setPosition(vertex, pos): | ||
nodePosition[vertex] = pos | ||
|
||
def topToBottom(heap, start, size, positions): | ||
if start > size // 2 - 1: | ||
return | ||
else: | ||
if 2 * start + 2 >= size: | ||
m = 2 * start + 1 | ||
else: | ||
if heap[2 * start + 1] < heap[2 * start + 2]: | ||
m = 2 * start + 1 | ||
else: | ||
m = 2 * start + 2 | ||
if heap[m] < heap[start]: | ||
temp, temp1 = heap[m], positions[m] | ||
heap[m], positions[m] = heap[start], positions[start] | ||
heap[start], positions[start] = temp, temp1 | ||
|
||
temp = getPosition(positions[m]) | ||
setPosition(positions[m], getPosition(positions[start])) | ||
setPosition(positions[start], temp) | ||
|
||
topToBottom(heap, m, size, positions) | ||
|
||
# Update function if value of any node in min-heap decreases | ||
def bottomToTop(val, index, heap, position): | ||
temp = position[index] | ||
|
||
while(index != 0): | ||
if index % 2 == 0: | ||
parent = int( (index-2) / 2 ) | ||
else: | ||
parent = int( (index-1) / 2 ) | ||
|
||
if val < heap[parent]: | ||
heap[index] = heap[parent] | ||
position[index] = position[parent] | ||
setPosition(position[parent], index) | ||
else: | ||
heap[index] = val | ||
position[index] = temp | ||
setPosition(temp, index) | ||
break | ||
index = parent | ||
else: | ||
heap[0] = val | ||
position[0] = temp | ||
setPosition(temp, 0) | ||
|
||
def heapify(heap, positions): | ||
start = len(heap) // 2 - 1 | ||
for i in range(start, -1, -1): | ||
topToBottom(heap, i, len(heap), positions) | ||
|
||
def deleteMinimum(heap, positions): | ||
temp = positions[0] | ||
heap[0] = sys.maxsize | ||
topToBottom(heap, 0, len(heap), positions) | ||
return temp | ||
|
||
visited = [0 for i in range(len(l))] | ||
Nbr_TV = [-1 for i in range(len(l))] # Neighboring Tree Vertex of selected vertex | ||
# Minimum Distance of explored vertex with neighboring vertex of partial tree formed in graph | ||
Distance_TV = [] # Heap of Distance of vertices from their neighboring vertex | ||
Positions = [] | ||
|
||
for x in range(len(l)): | ||
p = sys.maxsize | ||
Distance_TV.append(p) | ||
Positions.append(x) | ||
nodePosition.append(x) | ||
|
||
TreeEdges = [] | ||
visited[0] = 1 | ||
Distance_TV[0] = sys.maxsize | ||
for x in l[0]: | ||
Nbr_TV[ x[0] ] = 0 | ||
Distance_TV[ x[0] ] = x[1] | ||
heapify(Distance_TV, Positions) | ||
|
||
for i in range(1, len(l)): | ||
vertex = deleteMinimum(Distance_TV, Positions) | ||
if visited[vertex] == 0: | ||
TreeEdges.append((Nbr_TV[vertex], vertex)) | ||
visited[vertex] = 1 | ||
for v in l[vertex]: | ||
if visited[v[0]] == 0 and v[1] < Distance_TV[ getPosition(v[0]) ]: | ||
Distance_TV[ getPosition(v[0]) ] = v[1] | ||
bottomToTop(v[1], getPosition(v[0]), Distance_TV, Positions) | ||
Nbr_TV[ v[0] ] = vertex | ||
return TreeEdges | ||
|
||
# < --------- Prims Algorithm --------- > | ||
n = int(input("Enter number of vertices: ")) | ||
e = int(input("Enter number of edges: ")) | ||
adjlist = defaultdict(list) | ||
for x in range(e): | ||
l = [int(x) for x in input().split()] | ||
adjlist[l[0]].append([ l[1], l[2] ]) | ||
adjlist[l[1]].append([ l[0], l[2] ]) | ||
print(PrimsAlgorithm(adjlist)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import math | ||
|
||
def primeFactors(n): | ||
pf = [] | ||
while n % 2 == 0: | ||
pf.append(2) | ||
n = int(n / 2) | ||
|
||
for i in range(3, int(math.sqrt(n))+1, 2): | ||
while n % i == 0: | ||
pf.append(i) | ||
n = int(n / i) | ||
|
||
if n > 2: | ||
pf.append(n) | ||
|
||
return pf | ||
|
||
def numberOfDivisors(n): | ||
div = 1 | ||
|
||
temp = 1 | ||
while n % 2 == 0: | ||
temp += 1 | ||
n = int(n / 2) | ||
div = div * (temp) | ||
|
||
for i in range(3, int(math.sqrt(n))+1, 2): | ||
temp = 1 | ||
while n % i == 0: | ||
temp += 1 | ||
n = int(n / i) | ||
div = div * (temp) | ||
|
||
return div | ||
|
||
def sumOfDivisors(n): | ||
s = 1 | ||
|
||
temp = 1 | ||
while n % 2 == 0: | ||
temp += 1 | ||
n = int(n / 2) | ||
if temp > 1: | ||
s *= (2**temp - 1) / (2 - 1) | ||
|
||
for i in range(3, int(math.sqrt(n))+1, 2): | ||
temp = 1 | ||
while n % i == 0: | ||
temp += 1 | ||
n = int(n / i) | ||
if temp > 1: | ||
s *= (i**temp - 1) / (i - 1) | ||
|
||
return s | ||
|
||
def eulerPhi(n): | ||
l = primeFactors(n) | ||
l = set(l) | ||
s = n | ||
for x in l: | ||
s *= (x - 1)/x | ||
return s | ||
|
||
print(primeFactors(100)) | ||
print(numberOfDivisors(100)) | ||
print(sumOfDivisors(100)) | ||
print(eulerPhi(100)) | ||
|
||
|
Oops, something went wrong.