fixed the optimizer_v4

This commit is contained in:
Helldragon67 2024-07-07 16:24:15 +02:00
parent e71c92da40
commit d4e964c5d4
7 changed files with 358 additions and 113 deletions

View File

@ -8,4 +8,5 @@ geological
'tourism'='alpine_hut' 'tourism'='alpine_hut'
'tourism'='viewpoint' 'tourism'='viewpoint'
'tourism'='zoo' 'tourism'='zoo'
#'tourism'='artwork'
'waterway'='waterfall' 'waterway'='waterfall'

View File

@ -1,6 +1,7 @@
'tourism'='museum' 'tourism'='museum'
'tourism'='attraction' 'tourism'='attraction'
'tourism'='gallery' 'tourism'='gallery'
'tourism'='artwork'
historic historic
'amenity'='planetarium' 'amenity'='planetarium'
'amenity'='place_of_worship' 'amenity'='place_of_worship'

View File

@ -179,6 +179,10 @@ def init_ub_dist(landmarks: List[Landmark], max_steps: int):
for j, spot2 in enumerate(landmarks) : for j, spot2 in enumerate(landmarks) :
t = get_time(spot1.location, spot2.location, detour, speed) t = get_time(spot1.location, spot2.location, detour, speed)
dist_table[j] = t dist_table[j] = t
closest = sorted(dist_table)[:22]
for i, dist in enumerate(dist_table) :
if dist not in closest :
dist_table[i] = 10000000
A_ub += dist_table A_ub += dist_table
c = c*len(landmarks) c = c*len(landmarks)
@ -186,7 +190,7 @@ def init_ub_dist(landmarks: List[Landmark], max_steps: int):
# Constraint to respect only one travel per landmark. Also caps the total number of visited landmarks # Constraint to respect only one travel per landmark. Also caps the total number of visited landmarks
def respect_number(L:int, A_ub, b_ub): def respect_number(L: int, A_ub, b_ub, max_landmarks):
ones = [1]*L ones = [1]*L
zeros = [0]*L zeros = [0]*L
@ -195,10 +199,11 @@ def respect_number(L:int, A_ub, b_ub):
A_ub = np.vstack((A_ub, h)) A_ub = np.vstack((A_ub, h))
b_ub.append(1) b_ub.append(1)
# Read the parameters from the file if max_landmarks is None :
with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f : # Read the parameters from the file
parameters = json.loads(f.read()) with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
max_landmarks = parameters['max landmarks'] parameters = json.loads(f.read())
max_landmarks = parameters['max landmarks']
A_ub = np.vstack((A_ub, ones*L)) A_ub = np.vstack((A_ub, ones*L))
b_ub.append(max_landmarks+1) b_ub.append(max_landmarks+1)
@ -361,13 +366,13 @@ def link_list_simple(ordered_visit: List[Landmark])-> List[Landmark] :
# Main optimization pipeline # Main optimization pipeline
def solve_optimization (landmarks :List[Landmark], max_steps: int, printing_details: bool) : def solve_optimization (landmarks :List[Landmark], max_steps: int, printing_details: bool, max_landmarks = None) :
L = len(landmarks) L = len(landmarks)
# SET CONSTRAINTS FOR INEQUALITY # SET CONSTRAINTS FOR INEQUALITY
c, A_ub, b_ub = init_ub_dist(landmarks, max_steps) # Add the distances from each landmark to the other c, A_ub, b_ub = init_ub_dist(landmarks, max_steps) # Add the distances from each landmark to the other
A_ub, b_ub = respect_number(L, A_ub, b_ub) # Respect max number of visits (no more possible stops than landmarks). A_ub, b_ub = respect_number(L, A_ub, b_ub, max_landmarks) # Respect max number of visits (no more possible stops than landmarks).
A_ub, b_ub = break_sym(L, A_ub, b_ub) # break the 'zig-zag' symmetry A_ub, b_ub = break_sym(L, A_ub, b_ub) # break the 'zig-zag' symmetry
# SET CONSTRAINTS FOR EQUALITY # SET CONSTRAINTS FOR EQUALITY
@ -392,7 +397,7 @@ def solve_optimization (landmarks :List[Landmark], max_steps: int, printing_deta
i = 0 i = 0
timeout = 80 timeout = 80
while len(circle) != 0 and i < timeout: while len(circle) != 0 and i < timeout:
#A_ub, b_ub = prevent_config(res.x, A_ub, b_ub) A_ub, b_ub = prevent_config(res.x, A_ub, b_ub)
A_ub, b_ub = break_cricle(order, len(landmarks), A_ub, b_ub) A_ub, b_ub = break_cricle(order, len(landmarks), A_ub, b_ub)
res = linprog(c, A_ub=A_ub, b_ub=b_ub, A_eq=A_eq, b_eq = b_eq, bounds=x_bounds, method='highs', integrality=3) res = linprog(c, A_ub=A_ub, b_ub=b_ub, A_eq=A_eq, b_eq = b_eq, bounds=x_bounds, method='highs', integrality=3)
order, circle = is_connected(res.x) order, circle = is_connected(res.x)

View File

@ -1,8 +1,8 @@
{ {
"city bbox side" : 3, "city bbox side" : 10,
"radius close to" : 50, "radius close to" : 50,
"church coeff" : 0.9, "church coeff" : 0.9,
"park coeff" : 1.2, "park coeff" : 1.2,
"tag coeff" : 10, "tag coeff" : 10,
"N important" : 30 "N important" : 40
} }

View File

@ -1,20 +1,15 @@
from collections import defaultdict
from heapq import heappop, heappush
from itertools import permutations
import os, json import os, json
from shapely import buffer, LineString, Point, Polygon, MultiPoint, convex_hull, concave_hull, LinearRing from shapely import buffer, LineString, Point, Polygon, MultiPoint, concave_hull
from typing import List, Tuple from typing import List, Tuple
from scipy.spatial import KDTree
from math import pi from math import pi
import networkx as nx
from structs.landmarks import Landmark from structs.landmarks import Landmark
from landmarks_manager import take_most_important from landmarks_manager import take_most_important
from optimizer_v4 import solve_optimization, link_list_simple, print_res, get_time from optimizer_v4 import solve_optimization, link_list_simple, print_res, get_time
from optimizer_v2 import generate_path, generate_path2
# Create corridor from tour
def create_corridor(landmarks: List[Landmark], width: float) : def create_corridor(landmarks: List[Landmark], width: float) :
corrected_width = (180*width)/(6371000*pi) corrected_width = (180*width)/(6371000*pi)
@ -25,6 +20,7 @@ def create_corridor(landmarks: List[Landmark], width: float) :
return obj return obj
# Create linestring from tour
def create_linestring(landmarks: List[Landmark])->List[Point] : def create_linestring(landmarks: List[Landmark])->List[Point] :
points = [] points = []
@ -35,11 +31,13 @@ def create_linestring(landmarks: List[Landmark])->List[Point] :
return LineString(points) return LineString(points)
# Check if some coordinates are in area. Used for the corridor
def is_in_area(area: Polygon, coordinates) -> bool : def is_in_area(area: Polygon, coordinates) -> bool :
point = Point(coordinates) point = Point(coordinates)
return point.within(area) return point.within(area)
# Function to determine if two landmarks are close to each other
def is_close_to(location1: Tuple[float], location2: Tuple[float]): def is_close_to(location1: Tuple[float], location2: Tuple[float]):
"""Determine if two locations are close by rounding their coordinates to 3 decimals.""" """Determine if two locations are close by rounding their coordinates to 3 decimals."""
absx = abs(location1[0] - location2[0]) absx = abs(location1[0] - location2[0])
@ -49,6 +47,7 @@ def is_close_to(location1: Tuple[float], location2: Tuple[float]):
#return (round(location1[0], 3), round(location1[1], 3)) == (round(location2[0], 3), round(location2[1], 3)) #return (round(location1[0], 3), round(location1[1], 3)) == (round(location2[0], 3), round(location2[1], 3))
# Rearrange some landmarks in the order of visit
def rearrange(landmarks: List[Landmark]) -> List[Landmark]: def rearrange(landmarks: List[Landmark]) -> List[Landmark]:
i = 1 i = 1
@ -65,6 +64,8 @@ def rearrange(landmarks: List[Landmark]) -> List[Landmark]:
return landmarks return landmarks
# Simple nearest neighbour planner to try to fix the path
def find_shortest_path_through_all_landmarks(landmarks: List[Landmark]) -> Tuple[List[Landmark], Polygon]: def find_shortest_path_through_all_landmarks(landmarks: List[Landmark]) -> Tuple[List[Landmark], Polygon]:
# Read from data # Read from data
@ -106,6 +107,8 @@ def find_shortest_path_through_all_landmarks(landmarks: List[Landmark]) -> Tuple
return path, path_poly return path, path_poly
# Returns a list of minor landmarks around the planned path to enhance experience
def get_minor_landmarks(all_landmarks: List[Landmark], visited_landmarks: List[Landmark], width: float) -> List[Landmark] : def get_minor_landmarks(all_landmarks: List[Landmark], visited_landmarks: List[Landmark], width: float) -> List[Landmark] :
second_order_landmarks = [] second_order_landmarks = []
@ -122,22 +125,7 @@ def get_minor_landmarks(all_landmarks: List[Landmark], visited_landmarks: List[L
return take_most_important(second_order_landmarks, len(visited_landmarks)) return take_most_important(second_order_landmarks, len(visited_landmarks))
# Try fix the shortest path using shapely
"""def refine_optimization(landmarks: List[Landmark], base_tour: List[Landmark], max_time: int, print_infos: bool) -> List[Landmark] :
minor_landmarks = get_minor_landmarks(landmarks, base_tour, 200)
if print_infos : print("There are " + str(len(minor_landmarks)) + " minor landmarks around the predicted path")
full_set = base_tour[:-1] + minor_landmarks # create full set of possible landmarks (without finish)
full_set.append(base_tour[-1]) # add finish back
new_tour = solve_optimization(full_set, max_time, print_infos)
return new_tour"""
def fix_using_polygon(tour: List[Landmark])-> List[Landmark] : def fix_using_polygon(tour: List[Landmark])-> List[Landmark] :
coords = [] coords = []
@ -150,12 +138,18 @@ def fix_using_polygon(tour: List[Landmark])-> List[Landmark] :
tour_poly = Polygon(coords) tour_poly = Polygon(coords)
better_tour_poly = tour_poly.buffer(0) better_tour_poly = tour_poly.buffer(0)
xs, ys = better_tour_poly.exterior.xy try :
xs, ys = better_tour_poly.exterior.xy
if len(xs) != len(tour) : if len(xs) != len(tour) :
better_tour_poly = concave_hull(MultiPoint(coords)) # Create concave hull with "core" of tour leaving out start and finish
xs, ys = better_tour_poly.exterior.xy
except :
better_tour_poly = concave_hull(MultiPoint(coords)) # Create concave hull with "core" of tour leaving out start and finish better_tour_poly = concave_hull(MultiPoint(coords)) # Create concave hull with "core" of tour leaving out start and finish
xs, ys = better_tour_poly.exterior.xy xs, ys = better_tour_poly.exterior.xy
# reverse the xs and ys # reverse the xs and ys
xs.reverse() xs.reverse()
ys.reverse() ys.reverse()
@ -183,6 +177,7 @@ def fix_using_polygon(tour: List[Landmark])-> List[Landmark] :
return better_tour return better_tour
# Second stage of the optimization. Use linear programming again to refine the path
def refine_optimization(landmarks: List[Landmark], base_tour: List[Landmark], max_time: int, print_infos: bool) -> List[Landmark] : def refine_optimization(landmarks: List[Landmark], base_tour: List[Landmark], max_time: int, print_infos: bool) -> List[Landmark] :
# Read from the file # Read from the file
@ -199,7 +194,7 @@ def refine_optimization(landmarks: List[Landmark], base_tour: List[Landmark], ma
full_set.append(base_tour[-1]) # add finish back full_set.append(base_tour[-1]) # add finish back
# get a new tour # get a new tour
new_tour = solve_optimization(full_set, max_time, False) new_tour = solve_optimization(full_set, max_time, False, max_landmarks)
new_tour, new_dist = link_list_simple(new_tour) new_tour, new_dist = link_list_simple(new_tour)
better_tour, better_poly = find_shortest_path_through_all_landmarks(new_tour) better_tour, better_poly = find_shortest_path_through_all_landmarks(new_tour)
@ -218,78 +213,14 @@ def refine_optimization(landmarks: List[Landmark], base_tour: List[Landmark], ma
if print_infos : if print_infos :
print("\n\n\nRefined tour (result of second stage optimization): ") print("\n\n\nRefined tour (result of second stage optimization): ")
print_res(final_tour, len(full_set)) print_res(final_tour, len(full_set))
total_score = 0
for elem in final_tour :
total_score += elem.attractiveness
print("\nTotal score : " + str(total_score))
return final_tour return final_tour
def refine_path(landmarks: List[Landmark], base_tour: List[Landmark], max_time: int, print_infos: bool) -> List[Landmark] :
print("\nRefining the base tour...")
# Read from the file
with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
parameters = json.loads(f.read())
max_landmarks = parameters['max landmarks'] + 3
"""if len(base_tour)-2 >= max_landmarks :
return base_tour"""
minor_landmarks = get_minor_landmarks(landmarks, base_tour, 200)
if print_infos : print("Using " + str(len(minor_landmarks)) + " minor landmarks around the predicted path")
full_set = base_tour + minor_landmarks # create full set of possible landmarks
print("\nRefined tour (result of second stage optimization): ")
new_path = generate_path2(full_set, max_time, max_landmarks)
return new_path
# If a tour is not connected
def correct_path(tour: List[Landmark]) -> List[Landmark] :
# Read the parameters from the file
with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
parameters = json.loads(f.read())
detour = parameters['detour factor']
speed = parameters['average walking speed']
G = nx.Graph()
coords = []
landmap = {}
for i, landmark in enumerate(tour) :
coords.append(landmark.location)
landmap[i] = landmark
G.add_node(i, pos=landmark.location, weight=landmark.attractiveness)
kdtree = KDTree(coords)
k = 3
for node, coord in coords:
indices = kdtree.query(coord, k + 1)[1] # k+1 because the closest neighbor is the node itself
for idx in indices[1:]: # skip the first one (itself)
neighbor = list(coords)[idx]
distance = get_time(coord, coords[neighbor], detour, speed)
G.add_edge(node, neighbor, weight=distance)
path = nx.approximation.traveling_salesman_problem(G, weight='weight', cycle=True)
if len(path) != len(tour) :
print("nope")
lis = [landmap[id] for id in path]
lis, tot_dist = link_list_simple(lis)
print_res(lis, len(tour))
return path

306
backend/src/refiner_v2.py Normal file
View File

@ -0,0 +1,306 @@
from collections import defaultdict
from heapq import heappop, heappush
from itertools import permutations
import os, json
from shapely import buffer, LineString, Point, Polygon, MultiPoint, convex_hull, concave_hull, LinearRing
from typing import List, Tuple
from scipy.spatial import KDTree
from math import pi
import networkx as nx
from structs.landmarks import Landmark
from landmarks_manager import take_most_important
from optimizer_v4 import solve_optimization, link_list_simple, print_res, get_time
from optimizer_v2 import generate_path, generate_path2
def create_corridor(landmarks: List[Landmark], width: float) :
corrected_width = (180*width)/(6371000*pi)
path = create_linestring(landmarks)
obj = buffer(path, corrected_width, join_style="mitre", cap_style="square", mitre_limit=2)
return obj
def create_linestring(landmarks: List[Landmark])->List[Point] :
points = []
for landmark in landmarks :
points.append(Point(landmark.location))
return LineString(points)
def is_in_area(area: Polygon, coordinates) -> bool :
point = Point(coordinates)
return point.within(area)
def is_close_to(location1: Tuple[float], location2: Tuple[float]):
"""Determine if two locations are close by rounding their coordinates to 3 decimals."""
absx = abs(location1[0] - location2[0])
absy = abs(location1[1] - location2[1])
return absx < 0.001 and absy < 0.001
#return (round(location1[0], 3), round(location1[1], 3)) == (round(location2[0], 3), round(location2[1], 3))
def rearrange(landmarks: List[Landmark]) -> List[Landmark]:
i = 1
while i < len(landmarks):
j = i+1
while j < len(landmarks):
if is_close_to(landmarks[i].location, landmarks[j].location) and landmarks[i].name not in ['start', 'finish'] and landmarks[j].name not in ['start', 'finish']:
# If they are not adjacent, move the j-th element to be adjacent to the i-th element
if j != i + 1:
landmarks.insert(i + 1, landmarks.pop(j))
break # Move to the next i-th element after rearrangement
j += 1
i += 1
return landmarks
def find_shortest_path_through_all_landmarks(landmarks: List[Landmark]) -> Tuple[List[Landmark], Polygon]:
# Read from data
with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
parameters = json.loads(f.read())
detour = parameters['detour factor']
speed = parameters['average walking speed']
# Step 1: Find 'start' and 'finish' landmarks
start_idx = next(i for i, lm in enumerate(landmarks) if lm.name == 'start')
finish_idx = next(i for i, lm in enumerate(landmarks) if lm.name == 'finish')
start_landmark = landmarks[start_idx]
finish_landmark = landmarks[finish_idx]
# Step 2: Create a list of unvisited landmarks excluding 'start' and 'finish'
unvisited_landmarks = [lm for i, lm in enumerate(landmarks) if i not in [start_idx, finish_idx]]
# Step 3: Initialize the path with the 'start' landmark
path = [start_landmark]
coordinates = [landmarks[start_idx].location]
current_landmark = start_landmark
# Step 4: Use nearest neighbor heuristic to visit all landmarks
while unvisited_landmarks:
nearest_landmark = min(unvisited_landmarks, key=lambda lm: get_time(current_landmark.location, lm.location, detour, speed))
path.append(nearest_landmark)
coordinates.append(nearest_landmark.location)
current_landmark = nearest_landmark
unvisited_landmarks.remove(nearest_landmark)
# Step 5: Finally add the 'finish' landmark to the path
path.append(finish_landmark)
coordinates.append(landmarks[finish_idx].location)
path_poly = Polygon(coordinates)
return path, path_poly
def get_minor_landmarks(all_landmarks: List[Landmark], visited_landmarks: List[Landmark], width: float) -> List[Landmark] :
second_order_landmarks = []
visited_names = []
area = create_corridor(visited_landmarks, width)
for visited in visited_landmarks :
visited_names.append(visited.name)
for landmark in all_landmarks :
if is_in_area(area, landmark.location) and landmark.name not in visited_names:
second_order_landmarks.append(landmark)
return take_most_important(second_order_landmarks, len(visited_landmarks))
"""def refine_optimization(landmarks: List[Landmark], base_tour: List[Landmark], max_time: int, print_infos: bool) -> List[Landmark] :
minor_landmarks = get_minor_landmarks(landmarks, base_tour, 200)
if print_infos : print("There are " + str(len(minor_landmarks)) + " minor landmarks around the predicted path")
full_set = base_tour[:-1] + minor_landmarks # create full set of possible landmarks (without finish)
full_set.append(base_tour[-1]) # add finish back
new_tour = solve_optimization(full_set, max_time, print_infos)
return new_tour"""
def fix_using_polygon(tour: List[Landmark])-> List[Landmark] :
coords = []
coords_dict = {}
for landmark in tour :
coords.append(landmark.location)
if landmark.name != 'finish' :
coords_dict[landmark.location] = landmark
tour_poly = Polygon(coords)
better_tour_poly = tour_poly.buffer(0)
try :
xs, ys = better_tour_poly.exterior.xy
if len(xs) != len(tour) :
better_tour_poly = concave_hull(MultiPoint(coords)) # Create concave hull with "core" of tour leaving out start and finish
xs, ys = better_tour_poly.exterior.xy
except :
better_tour_poly = concave_hull(MultiPoint(coords)) # Create concave hull with "core" of tour leaving out start and finish
xs, ys = better_tour_poly.exterior.xy
# reverse the xs and ys
xs.reverse()
ys.reverse()
better_tour = [] # List of ordered visit
name_index = {} # Maps the name of a landmark to its index in the concave polygon
# Loop through the polygon and generate the better (ordered) tour
for i,x in enumerate(xs[:-1]) :
y = ys[i]
better_tour.append(coords_dict[tuple((x,y))])
name_index[coords_dict[tuple((x,y))].name] = i
# Scroll the list to have start in front again
start_index = name_index['start']
better_tour = better_tour[start_index:] + better_tour[:start_index]
# Append the finish back and correct the time to reach
better_tour.append(tour[-1])
# Rearrange only if polygon
better_tour = rearrange(better_tour)
return better_tour
def refine_optimization(landmarks: List[Landmark], base_tour: List[Landmark], max_time: int, print_infos: bool) -> List[Landmark] :
# Read from the file
with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
parameters = json.loads(f.read())
max_landmarks = parameters['max landmarks'] + 4
minor_landmarks = get_minor_landmarks(landmarks, base_tour, 200)
if print_infos : print("Using " + str(len(minor_landmarks)) + " minor landmarks around the predicted path")
# full set of visitable landmarks
full_set = base_tour[:-1] + minor_landmarks # create full set of possible landmarks (without finish)
full_set.append(base_tour[-1]) # add finish back
# get a new tour
new_tour = solve_optimization(full_set, max_time, False, max_landmarks)
new_tour, new_dist = link_list_simple(new_tour)
better_tour, better_poly = find_shortest_path_through_all_landmarks(new_tour)
if base_tour[0].location == base_tour[-1].location and not better_poly.is_valid :
better_tour = fix_using_polygon(better_tour)
better_tour, better_dist = link_list_simple(better_tour)
if new_dist < better_dist :
final_tour = new_tour
else :
final_tour = better_tour
if print_infos :
print("\n\n\nRefined tour (result of second stage optimization): ")
print_res(final_tour, len(full_set))
total_score = 0
for elem in final_tour :
total_score += elem.attractiveness
print("\nTotal score : " + str(total_score))
return final_tour
def refine_path(landmarks: List[Landmark], base_tour: List[Landmark], max_time: int, print_infos: bool) -> List[Landmark] :
print("\nRefining the base tour...")
# Read from the file
with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
parameters = json.loads(f.read())
max_landmarks = parameters['max landmarks'] + 3
"""if len(base_tour)-2 >= max_landmarks :
return base_tour"""
minor_landmarks = get_minor_landmarks(landmarks, base_tour, 200)
if print_infos : print("Using " + str(len(minor_landmarks)) + " minor landmarks around the predicted path")
full_set = base_tour + minor_landmarks # create full set of possible landmarks
print("\nRefined tour (result of second stage optimization): ")
new_path = generate_path2(full_set, max_time, max_landmarks)
return new_path
# If a tour is not connected
def correct_path(tour: List[Landmark]) -> List[Landmark] :
# Read the parameters from the file
with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
parameters = json.loads(f.read())
detour = parameters['detour factor']
speed = parameters['average walking speed']
G = nx.Graph()
coords = []
landmap = {}
for i, landmark in enumerate(tour) :
coords.append(landmark.location)
landmap[i] = landmark
G.add_node(i, pos=landmark.location, weight=landmark.attractiveness)
kdtree = KDTree(coords)
k = 3
for node, coord in coords:
indices = kdtree.query(coord, k + 1)[1] # k+1 because the closest neighbor is the node itself
for idx in indices[1:]: # skip the first one (itself)
neighbor = list(coords)[idx]
distance = get_time(coord, coords[neighbor], detour, speed)
G.add_edge(node, neighbor, weight=distance)
path = nx.approximation.traveling_salesman_problem(G, weight='weight', cycle=True)
if len(path) != len(tour) :
print("nope")
lis = [landmap[id] for id in path]
lis, tot_dist = link_list_simple(lis)
print_res(lis, len(tour))
return path

View File

@ -73,7 +73,7 @@ def test4(coordinates: tuple[float, float]) -> List[Landmark]:
sightseeing=Preference( sightseeing=Preference(
name='sightseeing', name='sightseeing',
type=LandmarkType(landmark_type='sightseeing'), type=LandmarkType(landmark_type='sightseeing'),
score = 5), score = 0),
nature=Preference( nature=Preference(
name='nature', name='nature',
type=LandmarkType(landmark_type='nature'), type=LandmarkType(landmark_type='nature'),
@ -105,21 +105,22 @@ def test4(coordinates: tuple[float, float]) -> List[Landmark]:
with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f : with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
parameters = json.loads(f.read()) parameters = json.loads(f.read())
max_landmarks = parameters['max landmarks'] max_landmarks = parameters['max landmarks']
max_walking_time = 120 # minutes max_walking_time = 120 # minutes
detour = 30 # minutes detour = 10 # minutes
# First stage optimization # First stage optimization
#base_tour = solve_optimization(landmarks_short, max_walking_time, True) base_tour = solve_optimization(landmarks_short, max_walking_time, True)
#base_tour = solve_optimization(landmarks_short, max_walking_time, True) #base_tour = solve_optimization(landmarks_short, max_walking_time, True)
# First stage using NetworkX # First stage using NetworkX
base_tour = generate_path(landmarks_short, max_walking_time, max_landmarks) #base_tour = generate_path(landmarks_short, max_walking_time, max_landmarks)
# Second stage using linear optimization # Second stage using linear optimization
refined_tour = refine_optimization(landmarks, base_tour, max_walking_time+detour, True) if detour != 0 :
refined_tour = refine_optimization(landmarks, base_tour, max_walking_time+detour, True)
# Second stage using NetworkX # Second stage using NetworkX
#refined_tour = refine_path(landmarks, base_tour, max_walking_time+detour, True) #refined_tour = refine_path(landmarks, base_tour, max_walking_time+detour, True)
@ -130,8 +131,8 @@ def test4(coordinates: tuple[float, float]) -> List[Landmark]:
return refined_tour return refined_tour
#test4(tuple((48.8344400, 2.3220540))) # Café Chez César test4(tuple((48.8344400, 2.3220540))) # Café Chez César
#test4(tuple((48.8375946, 2.2949904))) # Point random #test4(tuple((48.8375946, 2.2949904))) # Point random
#test4(tuple((47.377859, 8.540585))) # Zurich HB #test4(tuple((47.377859, 8.540585))) # Zurich HB
test4(tuple((45.7576485, 4.8330241))) # Lyon Bellecour #test4(tuple((45.7576485, 4.8330241))) # Lyon Bellecour
#test3('Vienna, Austria') #test3('Vienna, Austria')