mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-11-28 07:21:07 +00:00
Merge pull request #395 from FarhanKasmani/ExtraAlgortihms
Extra Algorithms added
This commit is contained in:
commit
e09bf504a0
44
Graphs/ArticulationPoints.py
Normal file
44
Graphs/ArticulationPoints.py
Normal file
|
@ -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)
|
43
Graphs/CheckBipartiteGraph_BFS.py
Normal file
43
Graphs/CheckBipartiteGraph_BFS.py
Normal file
|
@ -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))
|
31
Graphs/FindingBridges.py
Normal file
31
Graphs/FindingBridges.py
Normal file
|
@ -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)
|
30
Graphs/KahnsAlgorithm_long.py
Normal file
30
Graphs/KahnsAlgorithm_long.py
Normal file
|
@ -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)
|
32
Graphs/KahnsAlgorithm_topo.py
Normal file
32
Graphs/KahnsAlgorithm_topo.py
Normal file
|
@ -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)
|
111
Graphs/MinimumSpanningTree_Prims.py
Normal file
111
Graphs/MinimumSpanningTree_Prims.py
Normal file
|
@ -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))
|
70
Maths/BasicMaths.py
Normal file
70
Maths/BasicMaths.py
Normal file
|
@ -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))
|
||||||
|
|
||||||
|
|
46
Maths/SegmentedSieve.py
Normal file
46
Maths/SegmentedSieve.py
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
import math
|
||||||
|
|
||||||
|
def sieve(n):
|
||||||
|
in_prime = []
|
||||||
|
start = 2
|
||||||
|
end = int(math.sqrt(n)) # Size of every segment
|
||||||
|
temp = [True] * (end + 1)
|
||||||
|
prime = []
|
||||||
|
|
||||||
|
while(start <= end):
|
||||||
|
if temp[start] == True:
|
||||||
|
in_prime.append(start)
|
||||||
|
for i in range(start*start, end+1, start):
|
||||||
|
if temp[i] == True:
|
||||||
|
temp[i] = False
|
||||||
|
start += 1
|
||||||
|
prime += in_prime
|
||||||
|
|
||||||
|
low = end + 1
|
||||||
|
high = low + end - 1
|
||||||
|
if high > n:
|
||||||
|
high = n
|
||||||
|
|
||||||
|
while(low <= n):
|
||||||
|
temp = [True] * (high-low+1)
|
||||||
|
for each in in_prime:
|
||||||
|
|
||||||
|
t = math.floor(low / each) * each
|
||||||
|
if t < low:
|
||||||
|
t += each
|
||||||
|
|
||||||
|
for j in range(t, high+1, each):
|
||||||
|
temp[j - low] = False
|
||||||
|
|
||||||
|
for j in range(len(temp)):
|
||||||
|
if temp[j] == True:
|
||||||
|
prime.append(j+low)
|
||||||
|
|
||||||
|
low = high + 1
|
||||||
|
high = low + end - 1
|
||||||
|
if high > n:
|
||||||
|
high = n
|
||||||
|
|
||||||
|
return prime
|
||||||
|
|
||||||
|
print(sieve(10**6))
|
24
Maths/SieveOfEratosthenes.py
Normal file
24
Maths/SieveOfEratosthenes.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import math
|
||||||
|
n = int(input("Enter n: "))
|
||||||
|
|
||||||
|
def sieve(n):
|
||||||
|
l = [True] * (n+1)
|
||||||
|
prime = []
|
||||||
|
start = 2
|
||||||
|
end = int(math.sqrt(n))
|
||||||
|
while(start <= end):
|
||||||
|
if l[start] == True:
|
||||||
|
prime.append(start)
|
||||||
|
for i in range(start*start, n+1, start):
|
||||||
|
if l[i] == True:
|
||||||
|
l[i] = False
|
||||||
|
start += 1
|
||||||
|
|
||||||
|
for j in range(end+1,n+1):
|
||||||
|
if l[j] == True:
|
||||||
|
prime.append(j)
|
||||||
|
|
||||||
|
return prime
|
||||||
|
|
||||||
|
print(sieve(n))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user