Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
2
2022-020
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
O.V.B Sewmina
2022-020
Commits
438d9be1
Commit
438d9be1
authored
May 13, 2022
by
O.V.B Sewmina
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'IT19186566' into 'master'
algorithm implemented See merge request
!4
parents
7864ded6
97ba837b
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
582 additions
and
0 deletions
+582
-0
routeplanner/maps.py
routeplanner/maps.py
+120
-0
routeplanner/project_notebook.ipynb
routeplanner/project_notebook.ipynb
+462
-0
No files found.
routeplanner/maps.py
0 → 100644
View file @
438d9be1
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
)
routeplanner/project_notebook.ipynb
0 → 100644
View file @
438d9be1
{
"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
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment