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)
This diff is collapsed.
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