Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge from master #1

Merged
merged 51 commits into from
May 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
e6e5f4b
Added naive string search algorithm (#715)
Reshad-Hasan Feb 23, 2019
9a44eb4
Organize graph algorithms (#719)
Reshad-Hasan Feb 25, 2019
2bbf8cd
Added extended euclidean algorithm (#720)
svaniksharma Feb 27, 2019
dd9f0b3
fix comma spelling from coma to comma (#722)
Feb 27, 2019
e6eb6db
Delete Maths/find_hcf.py (#636)
SandersLin Feb 27, 2019
88b6caa
fixed balanced_parentheses, Added infix-prefix & postfix evaluation (…
ashwek Mar 1, 2019
6f65106
Update heap.py (#726)
AkashAli506 Mar 4, 2019
2c67f61
Update basic_binary_tree.py (#725)
AkashAli506 Mar 7, 2019
8e67ac3
Fix '__bool__' method (#735)
SemeniukMN Mar 10, 2019
96c36f8
added wiggle_sort.py (#734)
Ishani08 Mar 17, 2019
d27968b
Create Searching in sorted matrix (#738)
Ishani08 Mar 20, 2019
8b8a6d8
reduce indentation (#741)
louisparis Mar 27, 2019
441b82a
More matrix algorithms (#745)
RayCurse Mar 27, 2019
bb29dc5
Bitmasking and DP added (#705)
adMenon Mar 27, 2019
5b7730b
Added Trafid Cipher (#746)
nowakowsky Apr 3, 2019
15bc87f
Create is_Palindrome (#740)
Ishani08 Apr 4, 2019
56de3df
Update basic_binary_tree.py (#748)
Ahish9009 Apr 7, 2019
137871b
feature to add input (#749)
rohankhatwani Apr 7, 2019
52d2fbf
Add lowest common ancestor to data structures (#732)
Reshad-Hasan Apr 10, 2019
b2f1d9c
implementation of tower_of_hanoi algorithm (#756)
willx75 Apr 14, 2019
a170997
Add animation for heap sort
jfeng43 Apr 19, 2019
a91f0e7
Updated Euler problem 21 sol1.py
SandersLin Apr 19, 2019
48bba49
Rename is_Palindrome to is_Palindrome.py (#752)
poyea Apr 20, 2019
df04d94
Some directories had a capital in their name [fixed]. Added a recursi…
vysor Apr 22, 2019
2fc2ae3
Created a generalized algo to edmonds karp (#724)
viraatdas Apr 25, 2019
48553da
variable in function should be lowercase (#768)
Azarealice Apr 26, 2019
06dbef0
Adding quick sort where random pivot point is chosen (#774)
gattlin1 Apr 30, 2019
7b89d03
Added an O(1) solution to problem 002 (#776)
melonbreadjin May 1, 2019
c5c3a74
Update README.md
AnupKumarPanwar May 4, 2019
e22ea7e
Update Directed and Undirected (Weighted) Graph.py
AnupKumarPanwar May 4, 2019
7677c37
update 'sorted' to 'ascending sorted' in comments (#789)
weixuanhu May 6, 2019
30a3582
fix: replaced outdated url (#791)
LorenzNickel May 8, 2019
56513cb
add-binary-exponentiation (#790)
junthbasnet May 10, 2019
36828b1
[FIX] maths/PrimeCheck (#796)
Julien00859 May 11, 2019
d8badcc
Update README.md
AnupKumarPanwar May 12, 2019
3f7bec6
Added page-rank algorithm implementation (#780)
bhushan-borole May 12, 2019
70bb6b2
Added Huffman Coding Algorithm (#798)
raviolliii May 13, 2019
3c40fda
More elegant coding for merge_sort_fastest (#804)
liuzhen153 May 14, 2019
c4d1682
Fix typo (#806)
Erfaniaa May 14, 2019
76061ab
added eulerian path and circuit finding algorithm (#787)
Reshad-Hasan May 16, 2019
c47c1ab
enhancement (#803)
nikolasvargas May 16, 2019
13c0c16
Update graph.py (#809)
ImNandha May 16, 2019
a65efd4
Implement check_bipartite_graph using DFS. (#808)
Erfaniaa May 16, 2019
5b86928
Use ==/!= to compare str, bytes, and int literals (#767)
cclauss May 16, 2019
f3608ac
Created shortest path using bfs (#794)
dubesar May 17, 2019
b6c3fa8
Interpolation search - fix endless loop bug, divide 0 bug and update …
weixuanhu May 18, 2019
f5abc04
Update bucket_sort.py (#821)
May 19, 2019
316d5ff
Add NQueens backtracking search implementation (#504)
DaveAxiom May 19, 2019
c113049
fix spelling on line 44 of bucket sort (#824)
coderpower0 May 20, 2019
b5667e5
Removed the (incorrectly named) redundant file graph_list.py and rena…
anirudhajith May 21, 2019
023f5e0
fix empty list validation and code data structures (#826)
nikolasvargas May 22, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ install:
- pip install flake8 # pytest # add another testing frameworks later
before_script:
# stop the build if there are Python syntax errors or undefined names
- flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
- flake8 . --count --select=E9,F63,F72,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
- flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
script:
Expand Down
93 changes: 93 additions & 0 deletions Graphs/Eulerian path and circuit for undirected graph.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Eulerian Path is a path in graph that visits every edge exactly once.
# Eulerian Circuit is an Eulerian Path which starts and ends on the same
# vertex.
# time complexity is O(V+E)
# space complexity is O(VE)


# using dfs for finding eulerian path traversal
def dfs(u, graph, visited_edge, path=[]):
path = path + [u]
for v in graph[u]:
if visited_edge[u][v] == False:
visited_edge[u][v], visited_edge[v][u] = True, True
path = dfs(v, graph, visited_edge, path)
return path


# for checking in graph has euler path or circuit
def check_circuit_or_path(graph, max_node):
odd_degree_nodes = 0
odd_node = -1
for i in range(max_node):
if i not in graph.keys():
continue
if len(graph[i]) % 2 == 1:
odd_degree_nodes += 1
odd_node = i
if odd_degree_nodes == 0:
return 1, odd_node
if odd_degree_nodes == 2:
return 2, odd_node
return 3, odd_node


def check_euler(graph, max_node):
visited_edge = [[False for _ in range(max_node + 1)] for _ in range(max_node + 1)]
check, odd_node = check_circuit_or_path(graph, max_node)
if check == 3:
print("graph is not Eulerian")
print("no path")
return
start_node = 1
if check == 2:
start_node = odd_node
print("graph has a Euler path")
if check == 1:
print("graph has a Euler cycle")
path = dfs(start_node, graph, visited_edge)
print(path)


def main():
G1 = {
1: [2, 3, 4],
2: [1, 3],
3: [1, 2],
4: [1, 5],
5: [4]
}
G2 = {
1: [2, 3, 4, 5],
2: [1, 3],
3: [1, 2],
4: [1, 5],
5: [1, 4]
}
G3 = {
1: [2, 3, 4],
2: [1, 3, 4],
3: [1, 2],
4: [1, 2, 5],
5: [4]
}
G4 = {
1: [2, 3],
2: [1, 3],
3: [1, 2],
}
G5 = {
1: [],
2: []
# all degree is zero
}
max_node = 10
check_euler(G1, max_node)
check_euler(G2, max_node)
check_euler(G3, max_node)
check_euler(G4, max_node)
check_euler(G5, max_node)


if __name__ == "__main__":
main()
182 changes: 182 additions & 0 deletions Graphs/edmonds_karp_Multiple_SourceAndSink.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
class FlowNetwork:
def __init__(self, graph, sources, sinks):
self.sourceIndex = None
self.sinkIndex = None
self.graph = graph

self._normalizeGraph(sources, sinks)
self.verticesCount = len(graph)
self.maximumFlowAlgorithm = None

# make only one source and one sink
def _normalizeGraph(self, sources, sinks):
if sources is int:
sources = [sources]
if sinks is int:
sinks = [sinks]

if len(sources) == 0 or len(sinks) == 0:
return

self.sourceIndex = sources[0]
self.sinkIndex = sinks[0]

# make fake vertex if there are more
# than one source or sink
if len(sources) > 1 or len(sinks) > 1:
maxInputFlow = 0
for i in sources:
maxInputFlow += sum(self.graph[i])


size = len(self.graph) + 1
for room in self.graph:
room.insert(0, 0)
self.graph.insert(0, [0] * size)
for i in sources:
self.graph[0][i + 1] = maxInputFlow
self.sourceIndex = 0

size = len(self.graph) + 1
for room in self.graph:
room.append(0)
self.graph.append([0] * size)
for i in sinks:
self.graph[i + 1][size - 1] = maxInputFlow
self.sinkIndex = size - 1


def findMaximumFlow(self):
if self.maximumFlowAlgorithm is None:
raise Exception("You need to set maximum flow algorithm before.")
if self.sourceIndex is None or self.sinkIndex is None:
return 0

self.maximumFlowAlgorithm.execute()
return self.maximumFlowAlgorithm.getMaximumFlow()

def setMaximumFlowAlgorithm(self, Algorithm):
self.maximumFlowAlgorithm = Algorithm(self)


class FlowNetworkAlgorithmExecutor(object):
def __init__(self, flowNetwork):
self.flowNetwork = flowNetwork
self.verticesCount = flowNetwork.verticesCount
self.sourceIndex = flowNetwork.sourceIndex
self.sinkIndex = flowNetwork.sinkIndex
# it's just a reference, so you shouldn't change
# it in your algorithms, use deep copy before doing that
self.graph = flowNetwork.graph
self.executed = False

def execute(self):
if not self.executed:
self._algorithm()
self.executed = True

# You should override it
def _algorithm(self):
pass



class MaximumFlowAlgorithmExecutor(FlowNetworkAlgorithmExecutor):
def __init__(self, flowNetwork):
super(MaximumFlowAlgorithmExecutor, self).__init__(flowNetwork)
# use this to save your result
self.maximumFlow = -1

def getMaximumFlow(self):
if not self.executed:
raise Exception("You should execute algorithm before using its result!")

return self.maximumFlow

class PushRelabelExecutor(MaximumFlowAlgorithmExecutor):
def __init__(self, flowNetwork):
super(PushRelabelExecutor, self).__init__(flowNetwork)

self.preflow = [[0] * self.verticesCount for i in range(self.verticesCount)]

self.heights = [0] * self.verticesCount
self.excesses = [0] * self.verticesCount

def _algorithm(self):
self.heights[self.sourceIndex] = self.verticesCount

# push some substance to graph
for nextVertexIndex, bandwidth in enumerate(self.graph[self.sourceIndex]):
self.preflow[self.sourceIndex][nextVertexIndex] += bandwidth
self.preflow[nextVertexIndex][self.sourceIndex] -= bandwidth
self.excesses[nextVertexIndex] += bandwidth

# Relabel-to-front selection rule
verticesList = [i for i in range(self.verticesCount)
if i != self.sourceIndex and i != self.sinkIndex]

# move through list
i = 0
while i < len(verticesList):
vertexIndex = verticesList[i]
previousHeight = self.heights[vertexIndex]
self.processVertex(vertexIndex)
if self.heights[vertexIndex] > previousHeight:
# if it was relabeled, swap elements
# and start from 0 index
verticesList.insert(0, verticesList.pop(i))
i = 0
else:
i += 1

self.maximumFlow = sum(self.preflow[self.sourceIndex])

def processVertex(self, vertexIndex):
while self.excesses[vertexIndex] > 0:
for neighbourIndex in range(self.verticesCount):
# if it's neighbour and current vertex is higher
if self.graph[vertexIndex][neighbourIndex] - self.preflow[vertexIndex][neighbourIndex] > 0\
and self.heights[vertexIndex] > self.heights[neighbourIndex]:
self.push(vertexIndex, neighbourIndex)

self.relabel(vertexIndex)

def push(self, fromIndex, toIndex):
preflowDelta = min(self.excesses[fromIndex],
self.graph[fromIndex][toIndex] - self.preflow[fromIndex][toIndex])
self.preflow[fromIndex][toIndex] += preflowDelta
self.preflow[toIndex][fromIndex] -= preflowDelta
self.excesses[fromIndex] -= preflowDelta
self.excesses[toIndex] += preflowDelta

def relabel(self, vertexIndex):
minHeight = None
for toIndex in range(self.verticesCount):
if self.graph[vertexIndex][toIndex] - self.preflow[vertexIndex][toIndex] > 0:
if minHeight is None or self.heights[toIndex] < minHeight:
minHeight = self.heights[toIndex]

if minHeight is not None:
self.heights[vertexIndex] = minHeight + 1

if __name__ == '__main__':
entrances = [0]
exits = [3]
# graph = [
# [0, 0, 4, 6, 0, 0],
# [0, 0, 5, 2, 0, 0],
# [0, 0, 0, 0, 4, 4],
# [0, 0, 0, 0, 6, 6],
# [0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0],
# ]
graph = [[0, 7, 0, 0], [0, 0, 6, 0], [0, 0, 0, 8], [9, 0, 0, 0]]

# prepare our network
flowNetwork = FlowNetwork(graph, entrances, exits)
# set algorithm
flowNetwork.setMaximumFlowAlgorithm(PushRelabelExecutor)
# and calculate
maximumFlow = flowNetwork.findMaximumFlow()

print("maximum flow is {}".format(maximumFlow))
72 changes: 72 additions & 0 deletions Graphs/pagerank.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'''
Author: https://github.com/bhushan-borole
'''
'''
The input graph for the algorithm is:

A B C
A 0 1 1
B 0 0 1
C 1 0 0

'''

graph = [[0, 1, 1],
[0, 0, 1],
[1, 0, 0]]


class Node:
def __init__(self, name):
self.name = name
self.inbound = []
self.outbound = []

def add_inbound(self, node):
self.inbound.append(node)

def add_outbound(self, node):
self.outbound.append(node)

def __repr__(self):
return 'Node {}: Inbound: {} ; Outbound: {}'.format(self.name,
self.inbound,
self.outbound)


def page_rank(nodes, limit=3, d=0.85):
ranks = {}
for node in nodes:
ranks[node.name] = 1

outbounds = {}
for node in nodes:
outbounds[node.name] = len(node.outbound)

for i in range(limit):
print("======= Iteration {} =======".format(i+1))
for j, node in enumerate(nodes):
ranks[node.name] = (1 - d) + d * sum([ ranks[ib]/outbounds[ib] for ib in node.inbound ])
print(ranks)


def main():
names = list(input('Enter Names of the Nodes: ').split())

nodes = [Node(name) for name in names]

for ri, row in enumerate(graph):
for ci, col in enumerate(row):
if col == 1:
nodes[ci].add_inbound(names[ri])
nodes[ri].add_outbound(names[ci])

print("======= Nodes =======")
for node in nodes:
print(node)

page_rank(nodes)


if __name__ == '__main__':
main()
22 changes: 0 additions & 22 deletions Maths/find_hcf.py

This file was deleted.

Loading