-
Notifications
You must be signed in to change notification settings - Fork 0
/
main2.py
152 lines (138 loc) · 6.87 KB
/
main2.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
150
151
152
'''
Parse input and run appropriate code.
Don't use this file for the actual work; only minimal code should be here.
We just parse input and call methods from other modules.
'''
# do NOT import ways. This should be done from other files
# simply import your modules and call the appropriate functions
from astar import astar
import ways.graph as graph
import ways.tools as tools
import sys
# aux function for Euclidious distance based heuristic function. returns the air distance between to junctions in meters.
def h_func_aux(junc1, junc2):
return 1000*tools.compute_distance(junc1.lat, junc1.lon, junc2.lat, junc2.lon)
# perform a_star search with air distance based heuristic
def a_star(source, target):
Roads = graph.load_map_from_csv()
result = astar(Roads, source, target, h_func=lambda junc: h_func_aux(junc, Roads[target]))
return result[0]
# same as a_star, returns information relevant for the experiment.
def a_star_exp(Roads, source, target):
result = astar(Roads, source, target, h_func=lambda junc: h_func_aux(junc, Roads[target]))
return result[2], result[1]
##########################################################################################
# perform a_star_exp3 search with air distance based heuristic with experiment=False
def a_star_exp3(source, target, abstractMap):
Roads = graph.load_map_from_csv()
return a_star_exp3_aux(Roads, source, target, abstractMap)
# same as a_star_exp3, returns information relevant for the experiment if experiment=True.
def a_star_exp3_aux(Roads, source, target, abstractMap, experiment=False):
develped_a = 0
develped_b = 0
develped_c = 0
cost = 0
'call function to find path using better ways algorithm, and return list of indices'
if not abstractMap:
raise NotImplementedError # You should load the map you were asked to pickle
# Note: pickle might give you an error for the namedtuples, even if they
# are imported indirectly from ways.graph. You might need to declare, for
# example: Link = ways.graph.Link
try:
# phase a
# find the closet abstract space node to A by air distance
junc1_index = -1
junc1_min_distance = sys.maxsize
# iterate over all possible nodes
for center in list(abstractMap.keys()):
# compute the distance using provided func
current_distance = tools.compute_distance(Roads[center].lat, Roads[center].lon, Roads[source].lat,
Roads[source].lon)
# update if new node is closer to A
if current_distance < junc1_min_distance:
junc1_index = center
junc1_min_distance = current_distance
# run a_star from A to junc2 to get the path
(a_star_path, a_cost, develped_a) = astar(Roads, source, junc1_index,
h_func=lambda junc: h_func_aux(junc, Roads[junc1_index]))
cost += a_cost
if a_star_path:
junc1_path = a_star_path
# if this phase failed run normal a_star from A to B by throwing exception that is dealt after
else:
raise Exception("Phase a failed")
# phase b
# find the closet abstract space node to B by air distance
junc2_index = -1
junc2_min_distance = sys.maxsize
# iterate over all possible nodes
for center in list(abstractMap.keys()):
# compute the distance using provided func
current_distance = tools.compute_distance(Roads[center].lat, Roads[center].lon, Roads[target].lat,
Roads[target].lon)
# update if new node is closer to B
if current_distance < junc2_min_distance:
junc2_index = center
junc2_min_distance = current_distance
# run a_star from junc2 to B to get the path
(a_star_path, b_cost, develped_b) = astar(Roads, junc2_index, target,
h_func=lambda junc: h_func_aux(junc, Roads[target]))
cost += b_cost
if a_star_path:
junc2_path = a_star_path
# if this phace failed run normal ucs from A to B by throwing exception that is dealt after
else:
raise Exception("Phase b failed")
# phase c
# run a_star from junc1 to junc2 in abstract search space
(a_star_path, c_cost, develped_c) = astar(abstractMap, junc1_index, junc2_index,
h_func=lambda junc: h_func_aux(junc, Roads[junc2_index]),
cost_func=lambda x: x.cost)
cost += c_cost
if a_star_path:
# path from j1 to j2
abstract_index_list = a_star_path
if junc1_index == junc2_index:
junc_1_2_path = [junc1_index]
else:
expanded_list = []
for i in range(1, len(abstract_index_list)):
# should return single value
# get the the links list which ucs returned
abstact_link_list = [lnk.path for lnk in abstractMap[abstract_index_list[i - 1]].links if
lnk.target == abstract_index_list[i]]
abstact_link_list = abstact_link_list[0]
# extract the path from junc1 to junc2 from the link
expanded_list = expanded_list + abstact_link_list[1:len(abstact_link_list)]
junc_1_2_path = expanded_list
# if this phace failed run normal a_star from A to B by throwing exception that is dealt after
else:
raise Exception("Phase c failed")
# append all three paths from phases a,b,c respectively
if experiment:
return (develped_a + develped_b + develped_c, cost)
else:
return junc1_path + junc_1_2_path + junc2_path[1:len(junc2_path)]
# exception is caught therefor we need to run norma ucs from A to B
except:
print('astar failed!!')
# a_star_exp3 failed. run a_star in the real space. then return relevan information
(a_star_path, cost, fail_num_dev) = astar(Roads, source, target,
h_func=lambda junc: h_func_aux(junc, Roads[target]))
if experiment:
return (develped_a + develped_b + develped_c + fail_num_dev, cost)
else:
return a_star_path
def dispatch(argv):
from sys import argv
source, target = int(argv[2]), int(argv[3])
if argv[1] == 'a_star':
path = a_star(source, target)
if argv[1] == 'a_star_exp3':
import pickle as pkl
abstractMap = pkl.load(open(argv[4], 'rb'))
path = a_star_exp3(source, target, abstractMap)
print(' '.join(str(j) for j in path))
if __name__ == '__main__':
from sys import argv
dispatch(argv)