From 1f9bcd2a93aceedde790e29c1da34be6d0cb6019 Mon Sep 17 00:00:00 2001 From: "Harsh_f(x)" <69109482+hashfx@users.noreply.github.com> Date: Mon, 11 Oct 2021 20:48:53 +0530 Subject: [PATCH] chore(Python): add graph (#495) Co-authored-by: Ming Tsai <37890026+ming-tsai@users.noreply.github.com> --- algorithms/Python/README.md | 7 ++ algorithms/Python/graphs/graph.py | 139 ++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 algorithms/Python/graphs/graph.py diff --git a/algorithms/Python/README.md b/algorithms/Python/README.md index ff63d082..3095ee25 100644 --- a/algorithms/Python/README.md +++ b/algorithms/Python/README.md @@ -56,6 +56,13 @@ - [Catalan Sequence](dynamic_programming/catalan_sequence.py) - [0/1 Knapsack Problem](dynamic_programming/knapsack.py) +## Trees +- [Binary Tree](trees/binary_tree.py) + +## Graphs +- [Simple Graph](graphs/graph.py) + ## Trees - [Binary Tree](trees/binary_tree.py) - [Binary Search Tree](trees/binary-search-tree.py) + diff --git a/algorithms/Python/graphs/graph.py b/algorithms/Python/graphs/graph.py new file mode 100644 index 00000000..0269f068 --- /dev/null +++ b/algorithms/Python/graphs/graph.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))