-
Notifications
You must be signed in to change notification settings - Fork 0
/
visualization.py
151 lines (121 loc) · 3.42 KB
/
visualization.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
from p5 import *
import heapq
import random
# set the size of grid
n = 20
class Point:
def __init__(self, row, col):
self.f = float('inf')
self.g = float('inf')
self.h = 0
self.row = row
self.col = col
self.val = 0
# adds obstacles at random points with a certain prob
# sets the value of every obstacle to -1
if random.randint(1, 10) < 4:
self.val = -1
# colors the point with the given rgb values
def show(self, r,g,b):
fill(r,g,b)
# if point is an obstacle, paint it black
if self.val == -1:
fill(0)
stroke(0)
rect((self.row * w, self.col * h), w, h, mode="CORNER")
def build_grid(n):
# builds a n * n - grid matrix with the given dimension
grid = [[Point(row, col) for col in range(n)] for row in range(n)]
return grid
def set_heuristic_val(grid):
# euclidean distance to find hval
for row in range(len(grid)):
for col in range(len(grid[0])):
grid[row][col].h = (row - end.row)**2 + (col - end.col)**2
def init_std_points(start, end):
# initializes g and f values for start
start.g = 0
start.f = start.h
# overrides value for start and end to not be an obstacle
start.val = 1
end.val = 1
def dist(src, dest):
# weight of the edge from source to dest
# currently all weights are 1
return 1
def create_path(end):
# colors the path from end to start
curr = end
path.append(curr)
while curr in came_from:
path.append(curr)
curr = came_from[curr]
# builds the grid and initializes it with Points
grid = build_grid(n)
# initializes start and end points
start = grid[0][0]
end = grid[-1][-1]
# sets heuristic values for all points on the grid
set_heuristic_val(grid)
# initializes start and end points
init_std_points(start, end)
# min-heap that includes all points to be processed
openset = []
# includes points that are finished to be processed
closedset = set()
# maintains the path from start to end
came_from = {start:None, }
#set of points on the path to be colored in the end
path = []
#add start point in the min_heap
heapq.heappush(openset, (start.f, 0, 0))
def setup():
print('Start')
size(500, 500)
global w
global h
w = width / n
h = height / n
def draw():
background(0)
# colors all the points based on its properties
for row in range(n):
for col in range(n):
grid[row][col].show(255,255,255)
for fval, row, col in openset:
grid[row][col].show(0, 255, 0)
for point in closedset:
point.show(255, 0, 0)
for point in path:
point.show(0, 0, 255)
if openset:
# smallest f-val from all the points to be processed
fval, row, col = heapq.heappop(openset)
point = grid[row][col]
# base-condition when point == end
if point == end:
create_path(end)
no_loop()
print('Done!')
# add curr_point to closedSet
closedset.add(point)
# 8 directions
neighbors = [(-1,0),(-1,1),(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1)]
# checks all neighbors to find lowest f-values
for nei in neighbors:
x = point.row + nei[0]
y = point.col + nei[1]
if x >= 0 and x < len(grid) and y >= 0 and y < len(grid[0]) and grid[x][y].val != -1:
tmp_g = point.g + dist(point, grid[x][y])
# if the dist from start to nei via curr_point is less, update values
if tmp_g < grid[x][y].g:
came_from[grid[x][y]] = point
grid[x][y].g = tmp_g
grid[x][y].f = grid[x][y].g + grid[x][y].h
if grid[x][y] not in closedset:
heapq.heappush(openset, (grid[x][y].f, x,y))
else:
print('End cannot be reached')
no_loop()
if __name__ == '__main__':
run()