Skip to content

Commit

Permalink
[ADD] Create maximum_flow_bfs.py (keon#603)
Browse files Browse the repository at this point in the history
* [ADD] Create maximum_flow_bfs.py

* Update README.md

* Update README.md

* [ADD] Create maximum_flow_dfs.py

* Update README.md

* Add unittest

* Fix no newline end of file
  • Loading branch information
lcw921 authored and keon committed Dec 11, 2019
1 parent cd4f9c7 commit 8261cba
Show file tree
Hide file tree
Showing 5 changed files with 227 additions and 1 deletion.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ If you want to uninstall algorithms, it is as simple as:
- [satisfiability](algorithms/graph/satisfiability.py)
- [tarjan](algorithms/graph/tarjan.py)
- [traversal](algorithms/graph/traversal.py)
- [maximum_flow_bfs](algorithms/graph/maximum_flow_bfs.py)
- [maximum_flow_dfs](algorithms/graph/maximum_flow_dfs.py)
- [all_pairs_shortest_path](algorithms/graph/all_pairs_shortest_path.py)
- [bellman_ford](algorithms/graph/bellman_ford.py)
- [heap](algorithms/heap)
Expand Down
2 changes: 2 additions & 0 deletions algorithms/graph/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from .tarjan import *
from .check_bipartite import *
from .maximum_flow_bfs import *
from .maximum_flow_dfs import *
from .all_pairs_shortest_path import *
from .bellman_ford import *
84 changes: 84 additions & 0 deletions algorithms/graph/maximum_flow_bfs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"""
Given a n*n adjacency array.
it will give you a maximum flow.
This version use BFS to search path.
Assume the first is the source and the last is the sink.
Time complexity - O(Ef)
example
graph = [[0, 16, 13, 0, 0, 0],
[0, 0, 10, 12, 0, 0],
[0, 4, 0, 0, 14, 0],
[0, 0, 9, 0, 0, 20],
[0, 0, 0, 7, 0, 4],
[0, 0, 0, 0, 0, 0]]
answer should be
23
"""
import copy
import queue
import math

def maximum_flow_bfs(adjacency_matrix):
#initial setting
new_array = copy.deepcopy(adjacency_matrix)
total = 0

while(1):
#setting min to max_value
min = math.inf
#save visited nodes
visited = [0]*len(new_array)
#save parent nodes
path = [0]*len(new_array)

#initialize queue for BFS
bfs = queue.Queue()

#initial setting
visited[0] = 1
bfs.put(0)

#BFS to find path
while(bfs.qsize() > 0):
#pop from queue
src = bfs.get()
for k in range(len(new_array)):
#checking capacity and visit
if(new_array[src][k] > 0 and visited[k] == 0 ):
#if not, put into queue and chage to visit and save path
visited[k] = 1
bfs.put(k)
path[k] = src

#if there is no path from src to sink
if(visited[len(new_array) - 1] == 0):
break

#initial setting
tmp = len(new_array) - 1

#Get minimum flow
while(tmp != 0):
#find minimum flow
if(min > new_array[path[tmp]][tmp]):
min = new_array[path[tmp]][tmp]
tmp = path[tmp]

#initial setting
tmp = len(new_array) - 1

#reduce capacity
while(tmp != 0):
new_array[path[tmp]][tmp] = new_array[path[tmp]][tmp] - min
tmp = path[tmp]

total = total + min

return total
84 changes: 84 additions & 0 deletions algorithms/graph/maximum_flow_dfs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"""
Given a n*n adjacency array.
it will give you a maximum flow.
This version use DFS to search path.
Assume the first is the source and the last is the sink.
Time complexity - O(Ef)
example
graph = [[0, 16, 13, 0, 0, 0],
[0, 0, 10, 12, 0, 0],
[0, 4, 0, 0, 14, 0],
[0, 0, 9, 0, 0, 20],
[0, 0, 0, 7, 0, 4],
[0, 0, 0, 0, 0, 0]]
answer should be
23
"""
import copy
import math

def maximum_flow_dfs(adjacency_matrix):
#initial setting
new_array = copy.deepcopy(adjacency_matrix)
total = 0

while(1):
#setting min to max_value
min = math.inf
#save visited nodes
visited = [0]*len(new_array)
#save parent nodes
path = [0]*len(new_array)

#initialize stack for DFS
stack = []

#initial setting
visited[0] = 1
stack.append(0)

#DFS to find path
while(len(stack) > 0):
#pop from queue
src = stack.pop()
for k in range(len(new_array)):
#checking capacity and visit
if(new_array[src][k] > 0 and visited[k] == 0 ):
#if not, put into queue and chage to visit and save path
visited[k] = 1
stack.append(k)
path[k] = src

#if there is no path from src to sink
if(visited[len(new_array) - 1] == 0):
break

#initial setting
tmp = len(new_array) - 1

#Get minimum flow
while(tmp != 0):
#find minimum flow
if(min > new_array[path[tmp]][tmp]):
min = new_array[path[tmp]][tmp]
tmp = path[tmp]

#initial setting
tmp = len(new_array) - 1

#reduce capacity
while(tmp != 0):
new_array[path[tmp]][tmp] = new_array[path[tmp]][tmp] - min
tmp = path[tmp]

total = total + min

return total

56 changes: 55 additions & 1 deletion tests/test_graph.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from algorithms.graph import Tarjan
from algorithms.graph import check_bipartite
from algorithms.graph.dijkstra import Dijkstra
from algorithms.graph import maximum_flow_bfs
from algorithms.graph import maximum_flow_dfs
from algorithms.graph import all_pairs_shortest_path
from algorithms.graph import bellman_ford


import unittest


Expand Down Expand Up @@ -78,6 +81,49 @@ def test_dijkstra(self):

self.assertEqual(g.dijkstra(0), [0, 4, 12, 19, 21, 11, 9, 8, 14])

class TestMaximum_Flow_Bfs(unittest.TestCase):

"""
Test for the file def maximum_flow_bfs.py
Arguments:
unittest {[type]} -- [description]
"""

def test_maximum_flow_bfs(self):
graph = [
[0, 16, 13, 0, 0, 0],
[0, 0, 10, 12, 0, 0],
[0, 4, 0, 0, 14, 0],
[0, 0, 9, 0, 0, 20],
[0, 0, 0, 7, 0, 4],
[0, 0, 0, 0, 0, 0]
]
maximum_flow = maximum_flow_bfs(graph)

self.assertEqual(maximum_flow, 23)

class TestMaximum_Flow_Dfs(unittest.TestCase):

"""
Test for the file def maximum_flow_dfs.py
Arguments:
unittest {[type]} -- [description]
"""

def test_maximum_flow_dfs(self):
graph = [
[0, 16, 13, 0, 0, 0],
[0, 0, 10, 12, 0, 0],
[0, 4, 0, 0, 14, 0],
[0, 0, 9, 0, 0, 20],
[0, 0, 0, 7, 0, 4],
[0, 0, 0, 0, 0, 0]
]
maximum_flow = maximum_flow_dfs(graph)

self.assertEqual(maximum_flow, 23)


class TestAll_Pairs_Shortest_Path(unittest.TestCase):

def test_all_pairs_shortest_path(self):
Expand All @@ -88,7 +134,14 @@ def test_all_pairs_shortest_path(self):
[0.867, 0.119, 0.352, 0.398, 0]]
result = all_pairs_shortest_path(graph)

self.assertEqual(result, [[0, 0.1, 0.101, 0.142, 0.277], [0.436, 0, 0.191, 0.192, 0.34299999999999997], [0.245, 0.345, 0, 0.333, 0.484], [0.706, 0.27, 0.46099999999999997, 0, 0.151], [0.5549999999999999, 0.119, 0.31, 0.311, 0]])
self.assertEqual(result, [
[0, 0.1, 0.101, 0.142, 0.277],
[0.436, 0, 0.191, 0.192, 0.34299999999999997],
[0.245, 0.345, 0, 0.333, 0.484],
[0.706, 0.27, 0.46099999999999997, 0, 0.151],
[0.5549999999999999, 0.119, 0.31, 0.311, 0],
])


class TestBellmanFord(unittest.TestCase):
def test_bellman_ford(self):
Expand All @@ -111,3 +164,4 @@ def test_bellman_ford(self):
}

self.assertEqual(True, bellman_ford(graph2, 'a'))

0 comments on commit 8261cba

Please sign in to comment.