Commit ab4c046b authored by O.V.B Sewmina's avatar O.V.B Sewmina

Merge branch 'IT19186566' into 'master'

Algorithm completed

See merge request 2022-020/2022-020!7
parents 3d2059d2 60ab9ba1
from helpers import load_map_test, load_map_bus, load_map_train,route_177
import math
val = 0
class PathPlanner():
def __init__(self, M, start=None, goal=None, type=None):
self.map = M
self.start= start
self.goal = goal
self.type = type
self.dis = 0
self.closedSet = self.create_closedSet() if goal != None and start != None else None
self.openSet = self.create_openSet() if goal != None and start != None else None
self.cameFrom = self.create_cameFrom() if goal != None and start != None else None
self.gScore = self.create_gScore() if goal != None and start != None else None
self.fScore = self.create_fScore() if goal != None and start != None else None
self.path = self.run_search() if self.map and self.start != None and self.goal != None else None
def reconstruct_path(self, current):
total_path = [current]
while current in self.cameFrom.keys():
current = self.cameFrom[current]
total_path.append(current)
return total_path
def _reset(self):
self.closedSet = None
self.openSet = None
self.cameFrom = None
self.gScore = None
self.fScore = None
self.path = self.run_search() if self.map and self.start and self.goal else None
def run_search(self):
""" """
if self.map == None:
raise(ValueError, "Must create map before running search")
if self.goal == None:
raise(ValueError, "Must create goal node before running search")
if self.start == None:
raise(ValueError, "Must create start node before running search")
self.closedSet = self.closedSet if self.closedSet != None else self.create_closedSet()
self.openSet = self.openSet if self.openSet != None else self.create_openSet()
self.cameFrom = self.cameFrom if self.cameFrom != None else self.create_cameFrom()
self.gScore = self.gScore if self.gScore != None else self.create_gScore()
self.fScore = self.fScore if self.fScore != None else self.create_fScore()
while not self.is_open_empty():
current = self.get_current_node()
if current == self.goal:
self.path = [x for x in reversed(self.reconstruct_path(current))]
return self.path
else:
self.openSet.remove(current)
self.closedSet.add(current)
for neighbor in self.get_neighbors(current):
if neighbor in self.closedSet:
continue # Ignore the neighbor which is already evaluated.
if not neighbor in self.openSet: # Discover a new node
self.openSet.add(neighbor)
# The distance from start to a neighbor
if self.getTempGScore(current, neighbor) >= self.get_gScore(neighbor):
continue
# This path is the best until now. Record it!
global val #
val = val + self.dis
self.record_best_path_to(current, neighbor)
print("No Path Found")
self.path = None
return False
def create_closedSet(self):
return set()
def create_openSet(self):
openSet = set()
openSet.add(self.start)
return openSet
def create_cameFrom(self):
cameFrom = {}
return cameFrom
def create_gScore(self):
gScore = {}
for node in self.map.intersections.keys():
if node == self.start:
gScore[node] = 0
else: gScore[node] = float('inf')
return gScore
def create_fScore(self):
if self.start != None:
fScore = {}
for node in self.map.intersections.keys():
if node == self.start:
fScore[node] = self.heuristic_cost_estimate(self.start)
else: fScore[node] = float('inf')
return fScore
raise(ValueError, "Must create start node before creating fScore.")
def set_map(self, M):
"set map attribute "
self._reset(self)
self.start = None
self.goal = None
self.map = M
def set_start(self, start):
" set start attribute "
self._reset(self)
self.start = start
self.goal = None
def set_goal(self, goal):
"set goal attribute "
self._reset(self)
self.goal = goal
#-------------------------------- get information --------------------------------#
def is_open_empty(self):
"returns True if the open set is empty"
return not bool(self.openSet)
def get_current_node(self):
" Returns the node in the open set with the lowest value of f(node)"
current = None
minim = float('inf')
for node in self.openSet:
if self.fScore[node] < minim:
minim = self.fScore[node]
current = node
return current
def get_neighbors(self, node):
"""Returns the neighbors of a node"""
return set(self.map.roads[node])
def get_traveled_distance(self):
#traveled_distance
return self.dis
#-------------------------------- Calculations --------------------------------#
def get_gScore(self, node):
return self.gScore[node]
def getTempGScore(self, current, neighbor):
# distance from the current node to it's neighbors
g_score_current = self.get_gScore(current)
dist_current_neighbor = self.distance(current,neighbor)
return g_score_current+dist_current_neighbor
def heuristic_cost_estimate(self, node):
if self.goal != None:
heuristic_estimate = self.distance(node,self.goal)
return heuristic_estimate
raise(ValueError, "Must create goal node before calculating huristic ")
def calculate_fscore(self, node):
# F = G + H
f_score = self.get_gScore(node) + self.heuristic_cost_estimate(node)
return f_score
# best path
def record_best_path_to(self, current, neighbor):
self.cameFrom[neighbor] = current
self.gScore[neighbor] = self.getTempGScore(current,neighbor)
self.fScore[neighbor] = self.gScore[neighbor] + self.heuristic_cost_estimate(neighbor)
def distance(self, node_1, node_2):
from math import radians, cos, sin, asin, sqrt
#The math module contains a function named
#radians which converts from degrees to radians.
lon1 = radians(self.map.intersections [node_1][0])
lon2 = radians(self.map.intersections [node_2][0])
lat1 = radians(self.map.intersections [node_1][1])
lat2 = radians(self.map.intersections [node_2][1])
# Haversine formula
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
c = 2 * asin(sqrt(a))
# Radius of earth in kilometers. Use 3956 for miles
r = 6371
# calculate the result
dist = (c * r)
#print (dist)
self.dis = dist
return dist
# Get route
def main( a, node1, node2):
if a == 3:
map = load_map_train()
elif a == 2:
map = load_map_bus()
else:
map = load_map_test()
planner = PathPlanner(map,node1,node2)
print(map.roads)
path = planner.path
print('distance =' ,val)
if path == [5, 16, 37, 12, 34]:
print("code works for test path!!!")
print(path)
else:
print("Genarated path")
print(path)
# for x in path:
# if routeNo
# print (x)
#for each in path:
main( 1, 2, 14)
\ No newline at end of file
import networkx as nx
import pickle
from chart_studio import plotly as py
import random
from plotly.graph_objs import *
from plotly.offline import init_notebook_mode, plot, iplot
#init_notebook_mode(connected=True)
route_177 = {
1: 34,
2: 42,
3: 54,
4: 67,
5: 80,
6: 92,
7: 105,
8: 109,
9: 117,
10: 126,
11: 134,
12: 140,
13: 149,
14: 157,
15: 163,
}
map_test = {
0: {'pos': (6.911034627182109, 79.84918916006576), 'connections': [1], 'name' : 'Kollupitiya','type': 0,'routeNo': 177, 'hValue': 1},
1: {'pos': (6.911751932322411, 79.86194701315071), 'connections': [0,2], 'name' : 'Viharamahadevi Park', 'type': 0, 'routeNo': 177, 'hValue': 1},
2: {'pos': (6.911385550864001, 79.87682791026592), 'connections': [1,3], 'name' : 'House Of Fashion', 'type': 0, 'routeNo': 177, 'hValue': 1},
3: {'pos': (6.911031363415147, 79.88498429384545), 'connections': [2,4], 'name' : 'Castle Street', 'type': 0, 'routeNo': 177, 'hValue': 1},
4: {'pos': (6.908462881966912, 79.89338919261249), 'connections': [3,5], 'name' : 'Rajagiriya', 'type': 0, 'routeNo': 177, 'hValue': 1},
5: {'pos': (6.906663916178293, 79.90205413217801), 'connections': [4,6], 'name' : 'Hsbc Rajagiriya', 'type': 0, 'routeNo': 177, 'hValue': 1},
6: {'pos': (6.90333333857459, 79.90747047529919), 'connections': [5,7], 'name' : 'Ethulkotte New', 'type': 0, 'routeNo': 177, 'hValue': 1},
7: {'pos': (6.903185701293392, 79.91168232658337), 'connections': [6,8], 'name' : 'Parliament Junction', 'type': 0, 'routeNo': 177, 'hValue': 1},
8: {'pos': (6.902102452411621, 79.91741047710077), 'connections': [7,9], 'name' : 'Battaramulla Junction', 'type': 0, 'routeNo': 177, 'hValue': 1},
9: {'pos': (6.90431022366131, 79.92400480782847), 'connections': [8,10], 'name' : 'Ganahena', 'type': 0, 'routeNo': 177, 'hValue': 1},
10: {'pos': (6.906173952520986, 79.92862087153598), 'connections': [9,11], 'name' : 'Koswatta', 'type': 0, 'routeNo': 177, 'hValue': 1},
11: {'pos': (6.9084657304543455, 79.9383708894408), 'connections': [10,12], 'name' : 'Kotte-Bope', 'type': 0, 'routeNo': 177, 'hValue': 1},
12: {'pos': (6.9085023402918155, 79.94425286198016), 'connections': [11,13], 'name' : 'Thalahena Junction', 'type': 0, 'routeNo': 177, 'hValue': 1},
13: {'pos': (6.903962700873259, 79.95430199947661), 'connections': [12,14], 'name' : 'Malabe', 'type': 0, 'routeNo': 177, 'hValue': 1},
14: {'pos': (6.933539686667202, 79.85005389798111), 'connections': [15], 'name' : 'Fort', 'type': 1, 'routeNo': 8717, 'hValue': 1},
15: {'pos': (6.923619774894732, 79.84965509086771), 'connections': [14,16], 'name' : 'Kompannavidiya', 'type': 1, 'routeNo': 8717, 'hValue': 1},
16: {'pos': (6.911282166657041, 79.84821747831087), 'connections': [15,1,17], 'name' : 'Kollupitiya', 'type': 1, 'routeNo': 8717, 'hValue': 1},
17: {'pos': (6.893710110662125, 79.85300590028642), 'connections': [16,18], 'name' : 'Bambalapitiya', 'type': 1, 'routeNo': 8717, 'hValue': 1},
18: {'pos': (6.875030063532378, 79.85744793142631), 'connections': [17,19], 'name' : 'Wellawatte', 'type': 1, 'routeNo': 8717, 'hValue': 1},
19: {'pos': (6.850915755796403, 79.8620969312958), 'connections': [18], 'name' : 'Dehiwala ', 'type': 1, 'routeNo': 8717, 'hValue': 1},
}
class Map:
def __init__(self, G):
self._graph = G
self.intersections = nx.get_node_attributes(G, "pos")
self.routeNo = nx.get_node_attributes(G, "routeNo")
self.type = nx.get_node_attributes(G, "type")
self.roads = [list(G[node]) for node in G.nodes()]
def save(self, filename):
with open(filename, 'wb') as f:
pickle.dump(self._graph, f)
def load_map_graph(map_dict):
G = nx.Graph()
for node in map_dict.keys():
G.add_node(node, pos=map_dict[node]['pos'], type=map_dict[node]['type'],routeNo=map_dict[node]['routeNo'])
for node in map_dict.keys():
for con_node in map_dict[node]['connections']:
G.add_edge(node, con_node)
return G
def load_map_b(map_dict):
# G = nx.Graph()
# for node in map_dict.keys():
# #nodeValue =
# if map_dict[node]['type'] != 1:
# continue
# else:
# G.add_node(node, pos=map_dict[node]['pos'], type=map_dict[node]['type'],routeNo=map_dict[node]['routeNo'])
G = nx.Graph()
for node in map_dict.keys():
G.add_node(node, pos=map_dict[node]['pos'], type=map_dict[node]['type'],routeNo=map_dict[node]['routeNo'])
# for node in map_dict.keys():
# for con_node in map_dict[node]['connections']:
# if map_dict[con_node]['type'] != 1:
# continue
# else:
# G.add_edge(node, con_node)
for node in map_dict.keys():
for con_node in map_dict[node]['connections']:
if map_dict[node]['type'] != 1:
continue
elif map_dict[con_node]['type'] != 1:
continue
else:
G.add_edge(node, con_node)
return G
#map for train
def load_map_t(map_dict):
G = nx.Graph()
for node in map_dict.keys():
G.add_node(node, pos=map_dict[node]['pos'], type=map_dict[node]['type'],routeNo=map_dict[node]['routeNo'])
for node in map_dict.keys():
for con_node in map_dict[node]['connections']:
if map_dict[node]['type'] == 1:
continue
elif map_dict[con_node]['type'] == 1:
continue
else:
G.add_edge(node, con_node)
return G
def load_map_test():
G = load_map_graph(map_test)
return Map(G)
def load_map_bus():
G = load_map_b(map_test)
return Map(G)
def load_map_train():
G = load_map_t(map_test)
return Map(G)
import networkx as nx
import pickle
from chart_studio import plotly as py
#import plotly.plotly as py
import random
from plotly.graph_objs import *
from plotly.offline import init_notebook_mode, plot, iplot
init_notebook_mode(connected=True)
map_10_dict = {
0: {'pos': (0.7798606835438107, 0.6922727646627362), 'connections': [7, 6, 5]},
1: {'pos': (0.7647837074641568, 0.3252670836724646), 'connections': [4, 3, 2]},
2: {'pos': (0.7155217893995438, 0.20026498027300055), 'connections': [4, 3, 1]},
3: {'pos': (0.7076566826610747, 0.3278339270610988), 'connections': [5, 4, 1, 2]},
4: {'pos': (0.8325506249953353, 0.02310946309985762), 'connections': [1, 2, 3]},
5: {'pos': (0.49016747075266875, 0.5464878695400415), 'connections': [7, 0, 3]},
6: {'pos': (0.8820353070895344, 0.6791919587749445), 'connections': [0]},
7: {'pos': (0.46247219371675075, 0.6258061621642713), 'connections': [0, 5]},
8: {'pos': (0.11622158839385677, 0.11236327488812581), 'connections': [9]},
9: {'pos': (0.1285377678230034, 0.3285840695698353), 'connections': [8]}
}
class Map:
def __init__(self, G):
self._graph = G
self.intersections = nx.get_node_attributes(G, "pos")
self.roads = [list(G[node]) for node in G.nodes()]
def save(self, filename):
with open(filename, 'wb') as f:
pickle.dump(self._graph, f)
def load_map_graph(map_dict):
G = nx.Graph()
for node in map_dict.keys():
G.add_node(node, pos=map_dict[node]['pos'])
for node in map_dict.keys():
for con_node in map_dict[node]['connections']:
G.add_edge(node, con_node)
return G
def load_map_10():
G = load_map_graph(map_10_dict)
return Map(G)
def load_map_40():
G = load_map_graph(map_40_dict)
return Map(G)
def show_map(M, start=None, goal=None, path=None):
G = M._graph
pos = nx.get_node_attributes(G, 'pos')
edge_trace = Scatter(
x=[],
y=[],
line=Line(width=0.5,color='#888'),
hoverinfo='none',
mode='lines')
for edge in G.edges():
x0, y0 = G.node[edge[0]]['pos']
x1, y1 = G.node[edge[1]]['pos']
edge_trace['x'] += [x0, x1, None]
edge_trace['y'] += [y0, y1, None]
node_trace = Scatter(
x=[],
y=[],
text=[],
mode='markers',
hoverinfo='text',
marker=Marker(
showscale=False,
# colorscale options
# 'Greys' | 'Greens' | 'Bluered' | 'Hot' | 'Picnic' | 'Portland' |
# Jet' | 'RdBu' | 'Blackbody' | 'Earth' | 'Electric' | 'YIOrRd' | 'YIGnBu'
colorscale='Hot',
reversescale=True,
color=[],
size=10,
colorbar=dict(
thickness=15,
title='Node Connections',
xanchor='left',
titleside='right'
),
line=dict(width=2)))
for node in G.nodes():
x, y = G.node[node]['pos']
node_trace['x'].append(x)
node_trace['y'].append(y)
for node, adjacencies in enumerate(G.adjacency_list()):
color = 0
if path and node in path:
color = 2
if node == start:
color = 3
elif node == goal:
color = 1
# node_trace['marker']['color'].append(len(adjacencies))
node_trace['marker']['color'].append(color)
node_info = "Intersection " + str(node)
node_trace['text'].append(node_info)
fig = Figure(data=Data([edge_trace, node_trace]),
layout=Layout(
title='<br>Network graph made with Python',
titlefont=dict(size=16),
showlegend=False,
hovermode='closest',
margin=dict(b=20,l=5,r=5,t=40),
xaxis=XAxis(showgrid=False, zeroline=False, showticklabels=False),
yaxis=YAxis(showgrid=False, zeroline=False, showticklabels=False)))
iplot(fig)
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from maps import Map, load_map_10, show_map\n",
"import math"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"map_10 = load_map_10()\n",
"show_map(map_10)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"map_10.intersections\n",
"#map_10.intersections[0][0]\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# this shows that intersection 0 connects to intersections 7, 6, and 5\n",
"map_10.roads[0] "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# This shows the full connectivity of the map\n",
"map_10.roads"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# parameters in the function\n",
"show_map(map_10, start=7, goal=2, path=[7,5,5])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Planner\n",
"class PathPlanner():\n",
" \"\"\" PathPlanner Object \"\"\"\n",
" def __init__(self, M, start=None, goal=None):\n",
" \n",
" self.map = M\n",
" self.start= start\n",
" self.goal = goal\n",
" self.closedSet = self.create_closedSet() if goal != None and start != None else None\n",
" self.openSet = self.create_openSet() if goal != None and start != None else None\n",
" self.cameFrom = self.create_cameFrom() if goal != None and start != None else None\n",
" self.gScore = self.create_gScore() if goal != None and start != None else None\n",
" self.fScore = self.create_fScore() if goal != None and start != None else None\n",
" self.path = self.run_search() if self.map and self.start != None and self.goal != None else None\n",
" \n",
" def reconstruct_path(self, current):\n",
" total_path = [current]\n",
" while current in self.cameFrom.keys():\n",
" current = self.cameFrom[current]\n",
" total_path.append(current)\n",
" return total_path\n",
" \n",
" def _reset(self):\n",
" self.closedSet = None\n",
" self.openSet = None\n",
" self.cameFrom = None\n",
" self.gScore = None\n",
" self.fScore = None\n",
" self.path = self.run_search() if self.map and self.start and self.goal else None\n",
"\n",
" def run_search(self):\n",
" \"\"\" \"\"\"\n",
" if self.map == None:\n",
" raise(ValueError, \"Must create map before running search\")\n",
" if self.goal == None:\n",
" raise(ValueError, \"Must create goal node before running search\")\n",
" if self.start == None:\n",
" raise(ValueError, \"Must create start node before running search\")\n",
"\n",
" self.closedSet = self.closedSet if self.closedSet != None else self.create_closedSet()\n",
" self.openSet = self.openSet if self.openSet != None else self.create_openSet()\n",
" self.cameFrom = self.cameFrom if self.cameFrom != None else self.create_cameFrom()\n",
" self.gScore = self.gScore if self.gScore != None else self.create_gScore()\n",
" self.fScore = self.fScore if self.fScore != None else self.create_fScore()\n",
"\n",
" while not self.is_open_empty():\n",
" current = self.get_current_node()\n",
"\n",
" if current == self.goal:\n",
" self.path = [x for x in reversed(self.reconstruct_path(current))]\n",
" return self.path\n",
" else:\n",
" self.openSet.remove(current)\n",
" self.closedSet.add(current)\n",
"\n",
" for neighbor in self.get_neighbors(current):\n",
" if neighbor in self.closedSet:\n",
" continue # Ignore the neighbor which is already evaluated.\n",
"\n",
" if not neighbor in self.openSet: # Discover a new node\n",
" self.openSet.add(neighbor)\n",
" \n",
" # The distance from start to a neighbor\n",
" #the \"dist_between\" function may vary as per the solution requirements.\n",
" if self.get_tentative_gScore(current, neighbor) >= self.get_gScore(neighbor):\n",
" continue \n",
" \n",
" self.record_best_path_to(current, neighbor)\n",
" print(\"No Path Found\")\n",
" self.path = None\n",
" return False"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def create_closedSet(self):\n",
" \"\"\" Creates and returns a data structure suitable to hold the set of nodes already evaluated\"\"\"\n",
" # EXAMPLE: return a data structure suitable to hold the set of nodes already evaluated\n",
" return set()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def create_openSet(self):\n",
" if self.start != None:\n",
" # TODO: return a data structure suitable to hold the set of currently discovered nodes \n",
" # that are not evaluated yet. Make sure to include the start node.\n",
" openSet = set()\n",
" openSet.add(self.start)\n",
" return openSet\n",
" \n",
" raise(ValueError, \"Must create start node before creating an open set. Try running PathPlanner.set_start(start_node)\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def create_cameFrom(self):\n",
" # TODO: return a data structure that shows which node can most efficiently be reached from another,\n",
" # for each node. \n",
" cameFrom = {}\n",
" return cameFrom"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def create_gScore(self):\n",
" # TODO: return a data structure that holds the cost of getting from the start node to that node, for each node.\n",
" # for each node. The cost of going from start to start is zero. The rest of the node's values should \n",
" # be set to infinity.\n",
" if self.start != None:\n",
" gScore = {}\n",
" for node in self.map.intersections.keys():\n",
" if node == self.start:\n",
" gScore[node] = 0\n",
" else: gScore[node] = float('inf')\n",
" return gScore\n",
" raise(ValueError, \"Must create start node before creating gScore. Try running PathPlanner.set_start(start_node)\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def create_fScore(self):\n",
" # TODO: return a data structure that holds the total cost of getting from the start node to the goal\n",
" # by passing by that node, for each node. That value is partly known, partly heuristic.\n",
" # For the first node, that value is completely heuristic. The rest of the node's value should be \n",
" # set to infinity.\n",
" if self.start != None:\n",
" fScore = {}\n",
" for node in self.map.intersections.keys():\n",
" if node == self.start:\n",
" fScore[node] = self.heuristic_cost_estimate(self.start)\n",
" else: fScore[node] = float('inf')\n",
" return fScore\n",
" raise(ValueError, \"Must create start node before creating fScore. Try running PathPlanner.set_start(start_node)\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def set_map(self, M):\n",
" \"\"\"Method used to set map attribute \"\"\"\n",
" self._reset(self)\n",
" self.start = None\n",
" self.goal = None\n",
" # TODO: Set map to new value. \n",
" self.map = M"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def set_start(self, start):\n",
" \"\"\"Method used to set start attribute \"\"\"\n",
" self._reset(self)\n",
" # TODO: Set start value. Remember to remove goal, closedSet, openSet, cameFrom, gScore, fScore, \n",
" # and path attributes' values.\n",
" self.start = start\n",
" self.goal = None\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def set_goal(self, goal):\n",
" \"\"\"Method used to set goal attribute \"\"\"\n",
" self._reset(self)\n",
" # TODO: Set goal value. \n",
" self.goal = goal\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def is_open_empty(self):\n",
" \"\"\"returns True if the open set is empty. False otherwise. \"\"\"\n",
" # TODO: Return True if the open set is empty. False otherwise.\n",
" return not bool(self.openSet)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def get_current_node(self):\n",
" \"\"\" Returns the node in the open set with the lowest value of f(node).\"\"\"\n",
" # TODO: Return the node in the open set with the lowest value of f(node).\n",
" current = None\n",
" minim = float('inf')\n",
" for node in self.openSet:\n",
" if self.fScore[node] < minim:\n",
" minim = self.fScore[node]\n",
" current = node\n",
" return current \n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def get_neighbors(self, node):\n",
" \"\"\"Returns the neighbors of a node\"\"\"\n",
" # TODO: Return the neighbors of a node\n",
" return set(self.map.roads[node]) \n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Scores\n",
"\n",
"def get_gScore(self, node):\n",
" \"\"\"Returns the g Score of a node\"\"\"\n",
" # TODO: Return the g Score of a node\n",
" return self.gScore[node]\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def distance(self, node_1, node_2):\n",
" \"\"\" Computes the Euclidean L2 Distance\"\"\"\n",
" # TODO: Compute and return the Euclidean L2 Distance\n",
" x1 = self.map.intersections[node_1][0]\n",
" y1 = self.map.intersections[node_1][1]\n",
" x2 = self.map.intersections[node_2][0]\n",
" y2 = self.map.intersections[node_2][1]\n",
" dist = math.sqrt( (x2-x1)**2 + (y2-y1)**2 )\n",
" return dist\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def get_tentative_gScore(self, current, neighbor):\n",
" \"\"\"Returns the tentative g Score of a node\"\"\"\n",
" # TODO: Return the g Score of the current node \n",
" # plus distance from the current node to it's neighbors\n",
" g_score_current = self.get_gScore(current)\n",
" dist_current_neighbor = self.distance(current,neighbor)\n",
" return g_score_current+dist_current_neighbor\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def heuristic_cost_estimate(self, node):\n",
" \"\"\" Returns the heuristic cost estimate of a node \"\"\"\n",
" # TODO: Return the heuristic cost estimate of a node\n",
" if self.goal != None:\n",
" heuristic_estimate = self.distance(node,self.goal)\n",
" return heuristic_estimate\n",
" raise(ValueError, \"Must create goal node before calculating huristic estimate. Try running PathPlanner.set_goal(goal_node)\")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def calculate_fscore(self, node):\n",
" \"\"\"Calculate the f score of a node. \"\"\"\n",
" # TODO: Calculate and returns the f score of a node. \n",
" # REMEMBER F = G + H\n",
" f_score = self.get_gScore(node) + self.heuristic_cost_estimate(node)\n",
" return f_score\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def record_best_path_to(self, current, neighbor):\n",
" \"\"\"Record the best path to a node \"\"\"\n",
" # TODO: Record the best path to a node, by updating cameFrom, gScore, and fScore\n",
" self.cameFrom[neighbor] = current\n",
" self.gScore[neighbor] = self.get_tentative_gScore(current,neighbor)\n",
" self.fScore[neighbor] = self.gScore[neighbor] + self.heuristic_cost_estimate(neighbor)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Associates implemented functions with PathPlanner class\n",
"PathPlanner.create_closedSet = create_closedSet\n",
"PathPlanner.create_openSet = create_openSet\n",
"PathPlanner.create_cameFrom = create_cameFrom\n",
"PathPlanner.create_gScore = create_gScore\n",
"PathPlanner.create_fScore = create_fScore\n",
"PathPlanner.set_map = set_map\n",
"PathPlanner.set_start = set_start\n",
"PathPlanner.set_goal = set_goal\n",
"PathPlanner.is_open_empty = is_open_empty\n",
"PathPlanner.get_current_node = get_current_node\n",
"PathPlanner.get_neighbors = get_neighbors\n",
"PathPlanner.get_gScore = get_gScore\n",
"PathPlanner.distance = distance\n",
"PathPlanner.get_tentative_gScore = get_tentative_gScore\n",
"PathPlanner.heuristic_cost_estimate = heuristic_cost_estimate\n",
"PathPlanner.calculate_fscore = calculate_fscore\n",
"PathPlanner.record_best_path_to = record_best_path_to"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Visualize result\n",
"start = 7\n",
"goal = 5\n",
"\n",
"show_map(map_10, start=start, goal=goal, path=PathPlanner(map_10, start, goal).path)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.4"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
from helpers import load_map_40
MAP_40_ANSWERS = [
(5, 34, [5, 16, 37, 12, 34]),
(5, 5, [5]),
(8, 24, [8, 14, 16, 37, 12, 17, 10, 24])
]
def test(shortest_path_function):
map_40 = load_map_40()
correct = 0
for start, goal, answer_path in MAP_40_ANSWERS:
path = shortest_path_function(map_40, start, goal).path
if path == answer_path:
correct += 1
print("For start:", start,
"Goal: ", goal,
"Your path:", path,
"Correct: ", answer_path)
else:
print("Error Testing faild !!!" )
if correct == len(MAP_40_ANSWERS):
print("All tests pass ")
else:
print("Only passed", correct, "/", len(MAP_40_ANSWERS), "test cases")
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment