├── example 1.png ├── example 2.png ├── example 3.png ├── README.md └── Shortest_Path_Finder_Code.py /example 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anuj-99/Shortest-Path-Finder/HEAD/example 1.png -------------------------------------------------------------------------------- /example 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anuj-99/Shortest-Path-Finder/HEAD/example 2.png -------------------------------------------------------------------------------- /example 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anuj-99/Shortest-Path-Finder/HEAD/example 3.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Shortest-Path-Finder 2 | Using A* Algorithm it finds the shortest possible path possible between two points even around any present obstacles 3 | -------------------------------------------------------------------------------- /Shortest_Path_Finder_Code.py: -------------------------------------------------------------------------------- 1 | from matplotlib import pyplot as plt 2 | import random 3 | 4 | 5 | # Creating a class 'station' which would be like a node on the screen 6 | class Station: 7 | def __init__(self, i, j): 8 | """ Set is present for the coloring purpose""" 9 | self.set = 0 10 | self.i = i 11 | self.j = j 12 | # f is the cost function 13 | # g is like the actual distance from the starting point 14 | # h is the heuristic - shortest possible distance - here, it would be displacement (euclidean distance) 15 | self.f = 0 16 | self.g = 0 17 | self.h = 0 18 | # To trace back the path, we need to record parents 19 | self.parent = None 20 | self.wall = False 21 | # list of neighbors of a station 22 | self.neighbors = [] 23 | if random.random() < 0.5: 24 | self.wall = True 25 | 26 | def add_neighbors(self, grid_passed): 27 | """Returns list of neighbor stations""" 28 | i = self.i 29 | j = self.j 30 | if j < size - 1: 31 | self.neighbors.append(grid_passed[i][j + 1]) 32 | if i > 0: 33 | self.neighbors.append(grid_passed[i - 1][j]) 34 | if j > 0: 35 | self.neighbors.append(grid_passed[i][j - 1]) 36 | if i < size - 1: 37 | self.neighbors.append(grid_passed[i + 1][j]) 38 | if i < size - 1 and j < size - 1: 39 | self.neighbors.append(grid_passed[i + 1][j + 1]) 40 | if i > 0 and j < size - 1: 41 | self.neighbors.append(grid_passed[i - 1][j + 1]) 42 | if i < size - 1 and j > 0: 43 | self.neighbors.append(grid_passed[i + 1][j - 1]) 44 | if i > 0 and j > 0: 45 | self.neighbors.append(grid_passed[i - 1][j - 1]) 46 | 47 | 48 | # Used a class instead of array just to update the value of set every time a station is added to open_set 49 | class Set: 50 | def __init__(self, array): 51 | self.array = array 52 | 53 | def add(self, station, var): 54 | if var == 'open': 55 | station.set = -5 56 | self.array.append(station) 57 | 58 | 59 | def heuristic(a, b): 60 | """Our heuristic function""" 61 | dist = ((a.i - b.i)**2 + (a.j - b.j)**2)**0.5 62 | return dist 63 | 64 | 65 | open_set = [] 66 | open_set = Set(open_set) 67 | closed_set = [] 68 | closed_set = Set(closed_set) 69 | size = 50 70 | grid = [] 71 | 72 | # Making a grid 73 | for i in range(size): 74 | row = [Station(0, 0) for i in range(size)] 75 | grid.append(row) 76 | 77 | # Allotting one Station object to each of the element in the grid 78 | for i in range(size): 79 | for j in range(size): 80 | grid[i][j] = Station(i, j) 81 | 82 | # Filling neighbours 83 | for i in range(size): 84 | for j in range(size): 85 | grid[i][j].add_neighbors(grid) 86 | 87 | start = grid[00][0] 88 | end = grid[size - 1][size - 1] 89 | grid[0][0].wall = False 90 | grid[size - 1][size - 1].wall = False 91 | 92 | # Adding the start point to the open_set 93 | open_set.add(start, 'open') 94 | 95 | # Actual loop 96 | a = 0 97 | while a < 1: 98 | if open_set.array: 99 | winner = 0 100 | for i in range(len(open_set.array)): 101 | if open_set.array[i].f < open_set.array[winner].f: 102 | winner = i 103 | current = open_set.array[winner] 104 | 105 | if current == end: 106 | # Calculating path 107 | current.set = 8 108 | while current.parent: 109 | current.parent.set = 16 110 | current = current.parent 111 | print('Done') 112 | a = a + 1 113 | 114 | # Remove the evaluated point from open_set and add to closed_set 115 | open_set.array.pop(winner) 116 | closed_set.array.append(current) 117 | 118 | # Adding a new point to evaluate in open_set 119 | neighbors = current.neighbors 120 | for neighbor in neighbors: 121 | if neighbor not in closed_set.array: 122 | if not neighbor.wall: 123 | temp_g = current.g + 1 124 | new_path = False 125 | if neighbor in open_set.array: 126 | if temp_g < neighbor.g: 127 | neighbor.g = temp_g 128 | new_path = True 129 | else: 130 | neighbor.g = temp_g 131 | new_path = True 132 | open_set.add(neighbor, 'open') 133 | if new_path: 134 | neighbor.h = heuristic(neighbor, end) 135 | neighbor.f = neighbor.g + neighbor.h 136 | neighbor.parent = current 137 | # print(neighbor.parent) 138 | else: 139 | current.set = 12 140 | while current.parent: 141 | current.parent.set = 8 142 | current = current.parent 143 | print('No path found!') 144 | a = a + 1 145 | 146 | # For debugging purpose - Visualisation 147 | vis_grid = [] 148 | for i in range(size): 149 | row = [0 for i in range(size)] 150 | vis_grid.append(row) 151 | 152 | start.set = 20 153 | end.set = 25 154 | for i in range(size): 155 | for j in range(size): 156 | if grid[i][j].wall: 157 | vis_grid[i][j] = grid[i][j].set - 10 158 | else: 159 | vis_grid[i][j] = grid[i][j].set 160 | 161 | plt.figure(figsize =(12, 12)) 162 | plt.title('A* Algorithm - Shortest Path Finder\n') 163 | plt.imshow(vis_grid) 164 | plt.show() 165 | --------------------------------------------------------------------------------