Skip to content

Commit a7948f1

Browse files
committed
Extra Algorithms added
1 parent 0e76ee9 commit a7948f1

9 files changed

+431
-0
lines changed

Graphs/ArticulationPoints.py

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Finding Articulation Points in Undirected Graph
2+
def computeAP(l):
3+
n = len(l)
4+
outEdgeCount = 0
5+
low = [0] * n
6+
visited = [False] * n
7+
isArt = [False] * n
8+
9+
def dfs(root, at, parent, outEdgeCount):
10+
if parent == root:
11+
outEdgeCount += 1
12+
visited[at] = True
13+
low[at] = at
14+
15+
for to in l[at]:
16+
if to == parent:
17+
pass
18+
elif not visited[to]:
19+
outEdgeCount = dfs(root, to, at, outEdgeCount)
20+
low[at] = min(low[at], low[to])
21+
22+
# AP found via bridge
23+
if at < low[to]:
24+
isArt[at] = True
25+
# AP found via cycle
26+
if at == low[to]:
27+
isArt[at] = True
28+
else:
29+
low[at] = min(low[at], to)
30+
return outEdgeCount
31+
32+
for i in range(n):
33+
if not visited[i]:
34+
outEdgeCount = 0
35+
outEdgeCount = dfs(i, i, -1, outEdgeCount)
36+
isArt[i] = (outEdgeCount > 1)
37+
38+
for x in range(len(isArt)):
39+
if isArt[x] == True:
40+
print(x, end=" ")
41+
42+
# Adjacency list of graph
43+
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]}
44+
computeAP(l)

Graphs/CheckBipartiteGraph_BFS.py

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Check whether Graph is Bipartite or Not using BFS
2+
3+
# A Bipartite Graph is a graph whose vertices can be divided into two independent sets,
4+
# U and V such that every edge (u, v) either connects a vertex from U to V or a vertex
5+
# from V to U. In other words, for every edge (u, v), either u belongs to U and v to V,
6+
# or u belongs to V and v to U. We can also say that there is no edge that connects
7+
# vertices of same set.
8+
def checkBipartite(l):
9+
queue = []
10+
visited = [False] * len(l)
11+
color = [-1] * len(l)
12+
13+
def bfs():
14+
while(queue):
15+
u = queue.pop(0)
16+
visited[u] = True
17+
18+
for neighbour in l[u]:
19+
20+
if neighbour == u:
21+
return False
22+
23+
if color[neighbour] == -1:
24+
color[neighbour] = 1 - color[u]
25+
queue.append(neighbour)
26+
27+
elif color[neighbour] == color[u]:
28+
return False
29+
30+
return True
31+
32+
for i in range(len(l)):
33+
if not visited[i]:
34+
queue.append(i)
35+
color[i] = 0
36+
if bfs() == False:
37+
return False
38+
39+
return True
40+
41+
# Adjacency List of graph
42+
l = {0:[1,3], 1:[0,2], 2:[1,3], 3:[0,2]}
43+
print(checkBipartite(l))

Graphs/FindingBridges.py

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Finding Bridges in Undirected Graph
2+
def computeBridges(l):
3+
id = 0
4+
n = len(l) # No of vertices in graph
5+
low = [0] * n
6+
visited = [False] * n
7+
8+
def dfs(at, parent, bridges, id):
9+
visited[at] = True
10+
low[at] = id
11+
id += 1
12+
for to in l[at]:
13+
if to == parent:
14+
pass
15+
elif not visited[to]:
16+
dfs(to, at, bridges, id)
17+
low[at] = min(low[at], low[to])
18+
if at < low[to]:
19+
bridges.append([at, to])
20+
else:
21+
# This edge is a back edge and cannot be a bridge
22+
low[at] = min(low[at], to)
23+
24+
bridges = []
25+
for i in range(n):
26+
if (not visited[i]):
27+
dfs(i, -1, bridges, id)
28+
print(bridges)
29+
30+
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]}
31+
computeBridges(l)

Graphs/KahnsAlgorithm_long.py

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Finding longest distance in Directed Acyclic Graph using KahnsAlgorithm
2+
def longestDistance(l):
3+
indegree = [0] * len(l)
4+
queue = []
5+
longDist = [1] * len(l)
6+
7+
for key, values in l.items():
8+
for i in values:
9+
indegree[i] += 1
10+
11+
for i in range(len(indegree)):
12+
if indegree[i] == 0:
13+
queue.append(i)
14+
15+
while(queue):
16+
vertex = queue.pop(0)
17+
for x in l[vertex]:
18+
indegree[x] -= 1
19+
20+
if longDist[vertex] + 1 > longDist[x]:
21+
longDist[x] = longDist[vertex] + 1
22+
23+
if indegree[x] == 0:
24+
queue.append(x)
25+
26+
print(max(longDist))
27+
28+
# Adjacency list of Graph
29+
l = {0:[2,3,4], 1:[2,7], 2:[5], 3:[5,7], 4:[7], 5:[6], 6:[7], 7:[]}
30+
longestDistance(l)

Graphs/KahnsAlgorithm_topo.py

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Kahn's Algorithm is used to find Topological ordering of Directed Acyclic Graph using BFS
2+
def topologicalSort(l):
3+
indegree = [0] * len(l)
4+
queue = []
5+
topo = []
6+
cnt = 0
7+
8+
for key, values in l.items():
9+
for i in values:
10+
indegree[i] += 1
11+
12+
for i in range(len(indegree)):
13+
if indegree[i] == 0:
14+
queue.append(i)
15+
16+
while(queue):
17+
vertex = queue.pop(0)
18+
cnt += 1
19+
topo.append(vertex)
20+
for x in l[vertex]:
21+
indegree[x] -= 1
22+
if indegree[x] == 0:
23+
queue.append(x)
24+
25+
if cnt != len(l):
26+
print("Cycle exists")
27+
else:
28+
print(topo)
29+
30+
# Adjacency List of Graph
31+
l = {0:[1,2], 1:[3], 2:[3], 3:[4,5], 4:[], 5:[]}
32+
topologicalSort(l)

Graphs/MinimumSpanningTree_Prims.py

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import sys
2+
from collections import defaultdict
3+
4+
def PrimsAlgorithm(l):
5+
6+
nodePosition = []
7+
def getPosition(vertex):
8+
return nodePosition[vertex]
9+
10+
def setPosition(vertex, pos):
11+
nodePosition[vertex] = pos
12+
13+
def topToBottom(heap, start, size, positions):
14+
if start > size // 2 - 1:
15+
return
16+
else:
17+
if 2 * start + 2 >= size:
18+
m = 2 * start + 1
19+
else:
20+
if heap[2 * start + 1] < heap[2 * start + 2]:
21+
m = 2 * start + 1
22+
else:
23+
m = 2 * start + 2
24+
if heap[m] < heap[start]:
25+
temp, temp1 = heap[m], positions[m]
26+
heap[m], positions[m] = heap[start], positions[start]
27+
heap[start], positions[start] = temp, temp1
28+
29+
temp = getPosition(positions[m])
30+
setPosition(positions[m], getPosition(positions[start]))
31+
setPosition(positions[start], temp)
32+
33+
topToBottom(heap, m, size, positions)
34+
35+
# Update function if value of any node in min-heap decreases
36+
def bottomToTop(val, index, heap, position):
37+
temp = position[index]
38+
39+
while(index != 0):
40+
if index % 2 == 0:
41+
parent = int( (index-2) / 2 )
42+
else:
43+
parent = int( (index-1) / 2 )
44+
45+
if val < heap[parent]:
46+
heap[index] = heap[parent]
47+
position[index] = position[parent]
48+
setPosition(position[parent], index)
49+
else:
50+
heap[index] = val
51+
position[index] = temp
52+
setPosition(temp, index)
53+
break
54+
index = parent
55+
else:
56+
heap[0] = val
57+
position[0] = temp
58+
setPosition(temp, 0)
59+
60+
def heapify(heap, positions):
61+
start = len(heap) // 2 - 1
62+
for i in range(start, -1, -1):
63+
topToBottom(heap, i, len(heap), positions)
64+
65+
def deleteMinimum(heap, positions):
66+
temp = positions[0]
67+
heap[0] = sys.maxsize
68+
topToBottom(heap, 0, len(heap), positions)
69+
return temp
70+
71+
visited = [0 for i in range(len(l))]
72+
Nbr_TV = [-1 for i in range(len(l))] # Neighboring Tree Vertex of selected vertex
73+
# Minimum Distance of explored vertex with neighboring vertex of partial tree formed in graph
74+
Distance_TV = [] # Heap of Distance of vertices from their neighboring vertex
75+
Positions = []
76+
77+
for x in range(len(l)):
78+
p = sys.maxsize
79+
Distance_TV.append(p)
80+
Positions.append(x)
81+
nodePosition.append(x)
82+
83+
TreeEdges = []
84+
visited[0] = 1
85+
Distance_TV[0] = sys.maxsize
86+
for x in l[0]:
87+
Nbr_TV[ x[0] ] = 0
88+
Distance_TV[ x[0] ] = x[1]
89+
heapify(Distance_TV, Positions)
90+
91+
for i in range(1, len(l)):
92+
vertex = deleteMinimum(Distance_TV, Positions)
93+
if visited[vertex] == 0:
94+
TreeEdges.append((Nbr_TV[vertex], vertex))
95+
visited[vertex] = 1
96+
for v in l[vertex]:
97+
if visited[v[0]] == 0 and v[1] < Distance_TV[ getPosition(v[0]) ]:
98+
Distance_TV[ getPosition(v[0]) ] = v[1]
99+
bottomToTop(v[1], getPosition(v[0]), Distance_TV, Positions)
100+
Nbr_TV[ v[0] ] = vertex
101+
return TreeEdges
102+
103+
# < --------- Prims Algorithm --------- >
104+
n = int(input("Enter number of vertices: "))
105+
e = int(input("Enter number of edges: "))
106+
adjlist = defaultdict(list)
107+
for x in range(e):
108+
l = [int(x) for x in input().split()]
109+
adjlist[l[0]].append([ l[1], l[2] ])
110+
adjlist[l[1]].append([ l[0], l[2] ])
111+
print(PrimsAlgorithm(adjlist))

Maths/BasicMaths.py

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import math
2+
3+
def primeFactors(n):
4+
pf = []
5+
while n % 2 == 0:
6+
pf.append(2)
7+
n = int(n / 2)
8+
9+
for i in range(3, int(math.sqrt(n))+1, 2):
10+
while n % i == 0:
11+
pf.append(i)
12+
n = int(n / i)
13+
14+
if n > 2:
15+
pf.append(n)
16+
17+
return pf
18+
19+
def numberOfDivisors(n):
20+
div = 1
21+
22+
temp = 1
23+
while n % 2 == 0:
24+
temp += 1
25+
n = int(n / 2)
26+
div = div * (temp)
27+
28+
for i in range(3, int(math.sqrt(n))+1, 2):
29+
temp = 1
30+
while n % i == 0:
31+
temp += 1
32+
n = int(n / i)
33+
div = div * (temp)
34+
35+
return div
36+
37+
def sumOfDivisors(n):
38+
s = 1
39+
40+
temp = 1
41+
while n % 2 == 0:
42+
temp += 1
43+
n = int(n / 2)
44+
if temp > 1:
45+
s *= (2**temp - 1) / (2 - 1)
46+
47+
for i in range(3, int(math.sqrt(n))+1, 2):
48+
temp = 1
49+
while n % i == 0:
50+
temp += 1
51+
n = int(n / i)
52+
if temp > 1:
53+
s *= (i**temp - 1) / (i - 1)
54+
55+
return s
56+
57+
def eulerPhi(n):
58+
l = primeFactors(n)
59+
l = set(l)
60+
s = n
61+
for x in l:
62+
s *= (x - 1)/x
63+
return s
64+
65+
print(primeFactors(100))
66+
print(numberOfDivisors(100))
67+
print(sumOfDivisors(100))
68+
print(eulerPhi(100))
69+
70+

0 commit comments

Comments
 (0)