chore(Python): add graph (#495)
Co-authored-by: Ming Tsai <37890026+ming-tsai@users.noreply.github.com>pull/562/head
parent
aa717b0f5c
commit
1f9bcd2a93
|
@ -56,6 +56,13 @@
|
||||||
- [Catalan Sequence](dynamic_programming/catalan_sequence.py)
|
- [Catalan Sequence](dynamic_programming/catalan_sequence.py)
|
||||||
- [0/1 Knapsack Problem](dynamic_programming/knapsack.py)
|
- [0/1 Knapsack Problem](dynamic_programming/knapsack.py)
|
||||||
|
|
||||||
|
## Trees
|
||||||
|
- [Binary Tree](trees/binary_tree.py)
|
||||||
|
|
||||||
|
## Graphs
|
||||||
|
- [Simple Graph](graphs/graph.py)
|
||||||
|
|
||||||
## Trees
|
## Trees
|
||||||
- [Binary Tree](trees/binary_tree.py)
|
- [Binary Tree](trees/binary_tree.py)
|
||||||
- [Binary Search Tree](trees/binary-search-tree.py)
|
- [Binary Search Tree](trees/binary-search-tree.py)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
# author: @hashfx
|
||||||
|
|
||||||
|
# Graph Visualization
|
||||||
|
|
||||||
|
# member1--member5
|
||||||
|
# |
|
||||||
|
# member3--member0--member2
|
||||||
|
# |
|
||||||
|
# member4
|
||||||
|
|
||||||
|
|
||||||
|
# |------city1----city3
|
||||||
|
# | | |
|
||||||
|
# city4----city2------|
|
||||||
|
# city5
|
||||||
|
|
||||||
|
|
||||||
|
# Graph Usage
|
||||||
|
# Facebook Friends Suggestion
|
||||||
|
# [m0 is friend of m1 & m5 is friend of m1; it is likely that m0 is friend of m5 too...
|
||||||
|
# FB will suggest m5 as friend suggestion to m0]
|
||||||
|
# Flight Routes : To find shortest path between two nodes
|
||||||
|
# [(city1,city2),(city1,city3),(city1,city4),
|
||||||
|
# (city2,city1),(city2,city4),(city2,city5),
|
||||||
|
# (city3,city1),(city3,city5),
|
||||||
|
# (city4,city1),(city4,city2),
|
||||||
|
# (city5,city2),(city5,city3)]
|
||||||
|
# Google Maps
|
||||||
|
# Internet
|
||||||
|
# E-commerce shopping Recommendation
|
||||||
|
|
||||||
|
# Difference between TREE and GRAPH:
|
||||||
|
# In TREE, there is only one path between two nodes. GRAPH is a complex DS where two nodes can randomly be connected
|
||||||
|
|
||||||
|
|
||||||
|
class Graph:
|
||||||
|
def __init__(self, edges):
|
||||||
|
self.edges = edges
|
||||||
|
# Transform route tuple to route dictionary
|
||||||
|
self.graph_dict = {} # blank dictionary
|
||||||
|
for start, end in self.edges:
|
||||||
|
if start in self.graph_dict: # element1 is already in dictionary
|
||||||
|
self.graph_dict[start].append(end) # add another element associated to element1 in graph_dictionary
|
||||||
|
else:
|
||||||
|
self.graph_dict[start] = [end] # if element1 is not present, add it to graph_dictionary
|
||||||
|
print("Graph dictionary: ", self.graph_dict) # print route dictionary
|
||||||
|
|
||||||
|
# get paths between start-point and end-point
|
||||||
|
def getpath(self, start, end, path=[]):
|
||||||
|
path = path + [start]
|
||||||
|
if start == end:
|
||||||
|
return [path]
|
||||||
|
|
||||||
|
if start not in self.graph_dict: # if one-way between one node, say Chennai; return []
|
||||||
|
# Chennai is not as a starting point, so it has no route associated
|
||||||
|
return []
|
||||||
|
|
||||||
|
paths = []
|
||||||
|
for node in self.graph_dict[start]:
|
||||||
|
if node not in path:
|
||||||
|
new_path = self.getpath(node, end, path)
|
||||||
|
for p in new_path:
|
||||||
|
paths.append(p)
|
||||||
|
return paths
|
||||||
|
|
||||||
|
# method to find shortest path between start-point and end-point
|
||||||
|
def getShortestPath(self, start, end, path=[]):
|
||||||
|
path = path + [start]
|
||||||
|
|
||||||
|
# if starting-point and end-point are same
|
||||||
|
if start == end:
|
||||||
|
return path
|
||||||
|
|
||||||
|
# If no path available from a point, return None
|
||||||
|
if start not in self.graph_dict:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# searching for shortest path
|
||||||
|
shortest_path = None # shortest path initialised
|
||||||
|
for node in self.graph_dict[start]:
|
||||||
|
if node not in path:
|
||||||
|
sp = self.getShortestPath(node, end, path)
|
||||||
|
if sp:
|
||||||
|
# if no shortest path is available; but in later iteration, we may have a path
|
||||||
|
# so check if it is shorter than original path (array of routes) or not
|
||||||
|
if shortest_path is None or len(sp) < len(shortest_path):
|
||||||
|
shortest_path = sp # shortest path returned
|
||||||
|
|
||||||
|
return shortest_path
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
routes = [
|
||||||
|
("Mumbai","Pune"),
|
||||||
|
("Mumbai", "Surat"),
|
||||||
|
("Surat", "Bangaluru"),
|
||||||
|
("Pune","Hyderabad"),
|
||||||
|
("Pune","Mysuru"),
|
||||||
|
("Hyderabad","Bangaluru"),
|
||||||
|
("Hyderabad", "Chennai"),
|
||||||
|
("Mysuru", "Bangaluru"),
|
||||||
|
("Chennai", "Bangaluru")
|
||||||
|
]
|
||||||
|
|
||||||
|
routes = [
|
||||||
|
("Mumbai", "Paris"),
|
||||||
|
("Mumbai", "Dubai"),
|
||||||
|
("Paris", "Dubai"),
|
||||||
|
("Paris", "New York"),
|
||||||
|
("Dubai", "New York"),
|
||||||
|
("New York", "Toronto"),
|
||||||
|
]
|
||||||
|
|
||||||
|
route_graph = Graph(routes)
|
||||||
|
|
||||||
|
''' start == end
|
||||||
|
start = "Mumbai"
|
||||||
|
end = "Mumbai"
|
||||||
|
[op]: [['Mumbai']]'''
|
||||||
|
|
||||||
|
''' start not in self.graph_dict
|
||||||
|
start = "Chennai"
|
||||||
|
end = "Mumbai"
|
||||||
|
[op]: []'''
|
||||||
|
|
||||||
|
start = "Mumbai"
|
||||||
|
end = "New York"
|
||||||
|
|
||||||
|
print(f"All paths between: {start} and {end}: ",route_graph.getpath(start,end))
|
||||||
|
print(f"Shortest path between {start} and {end}: ", route_graph.getShortestPath(start,end))
|
||||||
|
|
||||||
|
start = "Dubai"
|
||||||
|
end = "New York"
|
||||||
|
|
||||||
|
print(f"All paths between: {start} and {end}: ",route_graph.getpath(start,end))
|
||||||
|
print(f"Shortest path between {start} and {end}: ", route_graph.getShortestPath(start,end))
|
Loading…
Reference in New Issue