cleaned up
This commit is contained in:
parent
30ed2bb9ed
commit
4896e95617
@ -55,6 +55,7 @@ def prevent_config(resx):
|
||||
return h, [len(vertices_visited)-1]
|
||||
|
||||
|
||||
# Prevents the creation of the same circle (both directions)
|
||||
def prevent_circle(circle_vertices: list, L: int) :
|
||||
|
||||
l1 = [0]*L*L
|
||||
@ -73,42 +74,9 @@ def prevent_circle(circle_vertices: list, L: int) :
|
||||
|
||||
return np.vstack((l1, l2)), [0, 0]
|
||||
|
||||
# Prevent the possibility of a given solution bit
|
||||
def break_circle(circle_vertices: list, L: int, A_ub: list, b_ub: list):
|
||||
|
||||
if L-1 in circle_vertices :
|
||||
circle_vertices.remove(L-1)
|
||||
|
||||
h = [0]*L*L
|
||||
for i in range(L) :
|
||||
if i in circle_vertices :
|
||||
h[i*L:i*L+L] = [1]*L
|
||||
|
||||
A_ub = np.vstack((A_ub, h))
|
||||
b_ub.append(len(circle_vertices)-1)
|
||||
|
||||
return A_ub, b_ub
|
||||
|
||||
"""
|
||||
def break_circles(circle_edges_list: list, L: int, A_ub: list, b_ub: list):
|
||||
|
||||
for circle_edges in circle_edges_list :
|
||||
if L-1 in circle_vertices :
|
||||
circle_vertices.remove(L-1)
|
||||
|
||||
h = [0]*L*L
|
||||
for i in range(L) :
|
||||
if i in circle_vertices :
|
||||
h[i*L:i*L+L] = [1]*L
|
||||
|
||||
A_ub = np.vstack((A_ub, h))
|
||||
b_ub.append(len(circle_vertices)-1)
|
||||
|
||||
return A_ub, b_ub
|
||||
"""
|
||||
|
||||
# Checks if the path is connected, returns a circle if it finds one and the RESULT
|
||||
def is_connected(resx):
|
||||
# Returns the order of visit as well as any circles if there are some
|
||||
def is_connected(resx) :
|
||||
|
||||
# first round the results to have only 0-1 values
|
||||
for i, elem in enumerate(resx):
|
||||
@ -125,105 +93,6 @@ def is_connected(resx):
|
||||
ind_a = nonzero_tup[0].tolist()
|
||||
ind_b = nonzero_tup[1].tolist()
|
||||
|
||||
edges = []
|
||||
edges_visited = []
|
||||
vertices_visited = []
|
||||
|
||||
for i, a in enumerate(ind_a) :
|
||||
edges.append((a, ind_b[i])) # Create the list of edges
|
||||
|
||||
edge1 = (ind_a[0], ind_b[0])
|
||||
del ind_a[0]
|
||||
|
||||
edges_visited.append(edge1)
|
||||
vertices_visited.append(edge1[0])
|
||||
|
||||
remaining = edges
|
||||
remaining.remove(edge1)
|
||||
|
||||
break_flag = False
|
||||
while len(remaining) > 0 and not break_flag:
|
||||
for edge2 in remaining :
|
||||
if edge2[0] == edge1[1] :
|
||||
"""if edge1[1] in vertices_visited :
|
||||
ind_b.remove(edge2[1])
|
||||
#edges_visited.append(edge2)
|
||||
break_flag = True
|
||||
break
|
||||
else : """
|
||||
vertices_visited.append(edge1[1])
|
||||
ind_a.remove(edge2[0])
|
||||
ind_b.remove(edge2[0])
|
||||
#edges_visited.append(edge2)
|
||||
remaining.remove(edge2)
|
||||
edge1 = edge2
|
||||
|
||||
elif edge1[1] == L-1 or edge1[1] in vertices_visited:
|
||||
ind_b.remove(edge1[1])
|
||||
break_flag = True
|
||||
break
|
||||
|
||||
vertices_visited.append(edge1[1])
|
||||
|
||||
# Return order of visit if all good
|
||||
if len(vertices_visited) == n_edges +1 :
|
||||
return vertices_visited, []
|
||||
|
||||
"""edge1 = (ind_a[0], ind_b[0])
|
||||
|
||||
vertices_visited.clear()
|
||||
edges_visited.clear()
|
||||
|
||||
edges_visited.append(edge1)
|
||||
vertices_visited.append(edge1[0])
|
||||
|
||||
remaining = edges
|
||||
remaining.remove(edge1)
|
||||
|
||||
break_flag = False
|
||||
while len(remaining) > 0 and not break_flag:
|
||||
for edge2 in remaining :
|
||||
if edge2[0] == edge1[1] :
|
||||
# if edge1[1] in vertices_visited :
|
||||
# edges_visited.append(edge2)
|
||||
# break_flag = True
|
||||
# break
|
||||
# else :
|
||||
vertices_visited.append(edge1[1])
|
||||
edges_visited.append(edge2)
|
||||
remaining.remove(edge2)
|
||||
edge1 = edge2
|
||||
|
||||
elif edge1[1] == L-1 or edge1[1] in vertices_visited:
|
||||
break_flag = True
|
||||
break
|
||||
|
||||
vertices_visited.append(edge1[1])
|
||||
"""
|
||||
|
||||
return vertices_visited, edges_visited
|
||||
|
||||
|
||||
def is_connected2(resx) :
|
||||
|
||||
# first round the results to have only 0-1 values
|
||||
for i, elem in enumerate(resx):
|
||||
resx[i] = round(elem)
|
||||
|
||||
N = len(resx) # length of res
|
||||
L = int(np.sqrt(N)) # number of landmarks. CAST INTO INT but should not be a problem because N = L**2 by def.
|
||||
n_edges = resx.sum() # number of edges
|
||||
|
||||
nonzeroind = np.nonzero(resx)[0] # the return is a little funny so I use the [0]
|
||||
|
||||
nonzero_tup = np.unravel_index(nonzeroind, (L,L))
|
||||
|
||||
ind_a = nonzero_tup[0].tolist()
|
||||
ind_b = nonzero_tup[1].tolist()
|
||||
|
||||
# print(f"ind_a = {ind_a}")
|
||||
# print(f"ind_b = {ind_b}")
|
||||
|
||||
# Step 1: Create a graph representation
|
||||
graph = defaultdict(list)
|
||||
for a, b in zip(ind_a, ind_b):
|
||||
@ -232,7 +101,6 @@ def is_connected2(resx) :
|
||||
# Step 2: Function to perform BFS/DFS to extract journeys
|
||||
def get_journey(start):
|
||||
journey_nodes = []
|
||||
#journey_edges = []
|
||||
visited = set()
|
||||
stack = deque([start])
|
||||
|
||||
@ -242,26 +110,21 @@ def is_connected2(resx) :
|
||||
visited.add(node)
|
||||
journey_nodes.append(node)
|
||||
for neighbor in graph[node]:
|
||||
#journey_edges.append((node, neighbor))
|
||||
if neighbor not in visited:
|
||||
stack.append(neighbor)
|
||||
|
||||
return journey_nodes#, journey_edges
|
||||
return journey_nodes
|
||||
|
||||
# Step 3: Extract all journeys
|
||||
all_journeys_nodes = []
|
||||
#all_journeys_edges = []
|
||||
visited_nodes = set()
|
||||
|
||||
for node in ind_a:
|
||||
if node not in visited_nodes:
|
||||
journey_nodes = get_journey(node)
|
||||
all_journeys_nodes.append(journey_nodes)
|
||||
#all_journeys_edges.append(journey_edges)
|
||||
visited_nodes.update(journey_nodes)
|
||||
|
||||
|
||||
|
||||
for l in all_journeys_nodes :
|
||||
if 0 in l :
|
||||
order = l
|
||||
@ -274,16 +137,13 @@ def is_connected2(resx) :
|
||||
return order, all_journeys_nodes
|
||||
|
||||
|
||||
|
||||
|
||||
# Function that returns the distance in meters from one location to another
|
||||
# Function that returns the time in minutes from one location to another
|
||||
def get_time(p1: Tuple[float, float], p2: Tuple[float, float], detour: float, speed: float) :
|
||||
|
||||
# Compute the straight-line distance in km
|
||||
if p1 == p2 :
|
||||
return 0
|
||||
else:
|
||||
#dist = 6371.01 * acos(sin(radians(p1[0]))*sin(radians(p2[0])) + cos(radians(p1[0]))*cos(radians(p2[0]))*cos(radians(p1[1]) - radians(p2[1])))
|
||||
dist = geodesic(p1, p2).kilometers
|
||||
|
||||
# Consider the detour factor for average cityto deterline walking distance (in km)
|
||||
@ -292,12 +152,6 @@ def get_time(p1: Tuple[float, float], p2: Tuple[float, float], detour: float, sp
|
||||
# Time to walk this distance (in minutes)
|
||||
walk_time = walk_dist/speed*60
|
||||
|
||||
"""if walk_time > 15 :
|
||||
walk_time = 5*round(walk_time/5)
|
||||
else :
|
||||
walk_time = round(walk_time)"""
|
||||
|
||||
|
||||
return round(walk_time)
|
||||
|
||||
|
||||
@ -394,8 +248,8 @@ def init_eq_not_stay(L: int):
|
||||
return [l], [0]
|
||||
|
||||
|
||||
# Go through the landmarks and force the optimizer to use landmarks where attractiveness is set to -1
|
||||
def respect_user_mustsee(landmarks: List[Landmark]) :
|
||||
# Go through the landmarks and force the optimizer to use landmarks marked as must_do
|
||||
def respect_user_must_do(landmarks: List[Landmark]) :
|
||||
L = len(landmarks)
|
||||
|
||||
A = [0]*L*L
|
||||
@ -482,6 +336,7 @@ def link_list(order: List[int], landmarks: List[Landmark])->List[Landmark] :
|
||||
return L, total_dist
|
||||
|
||||
|
||||
# Same as link_list but does it on a already ordered list
|
||||
def link_list_simple(ordered_visit: List[Landmark])-> List[Landmark] :
|
||||
|
||||
# Read the parameters from the file
|
||||
@ -528,7 +383,7 @@ def solve_optimization (landmarks :List[Landmark], max_steps: int, printing_deta
|
||||
|
||||
# SET CONSTRAINTS FOR EQUALITY
|
||||
A_eq, b_eq = init_eq_not_stay(L) # Force solution not to stay in same place
|
||||
A, b = respect_user_mustsee(landmarks) # Check if there are user_defined must_see. Also takes care of start/goal
|
||||
A, b = respect_user_must_do(landmarks) # Check if there are user_defined must_see. Also takes care of start/goal
|
||||
A_eq = np.vstack((A_eq, A))
|
||||
b_eq += b
|
||||
A, b = respect_start_finish(L) # Force start and finish positions
|
||||
@ -550,8 +405,8 @@ def solve_optimization (landmarks :List[Landmark], max_steps: int, printing_deta
|
||||
|
||||
# If there is a solution, we're good to go, just check for connectiveness
|
||||
else :
|
||||
order, circles = is_connected2(res.x)
|
||||
#nodes, edges = is_connected2(res.x)
|
||||
order, circles = is_connected(res.x)
|
||||
#nodes, edges = is_connected(res.x)
|
||||
i = 0
|
||||
timeout = 80
|
||||
while circles is not None and i < timeout:
|
||||
@ -564,8 +419,8 @@ def solve_optimization (landmarks :List[Landmark], max_steps: int, printing_deta
|
||||
A_eq = np.vstack((A_eq, A))
|
||||
b_eq += b
|
||||
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, circles = is_connected2(res.x)
|
||||
#nodes, edges = is_connected2(res.x)
|
||||
order, circles = is_connected(res.x)
|
||||
#nodes, edges = is_connected(res.x)
|
||||
if circles is None :
|
||||
break
|
||||
print(i)
|
||||
@ -575,7 +430,7 @@ def solve_optimization (landmarks :List[Landmark], max_steps: int, printing_deta
|
||||
raise TimeoutError(f"Optimization took too long. No solution found after {timeout} iterations.")
|
||||
|
||||
# Add the times to reach and stop optimizing
|
||||
L, total_dist = link_list(order, landmarks)
|
||||
L, _ = link_list(order, landmarks)
|
||||
|
||||
if printing_details is True :
|
||||
if i != 0 :
|
||||
|
@ -1,6 +1,4 @@
|
||||
import pandas as pd
|
||||
import os
|
||||
import json
|
||||
|
||||
from typing import List
|
||||
from landmarks_manager import generate_landmarks
|
||||
@ -25,45 +23,6 @@ def write_data(L: List[Landmark], file_name: str):
|
||||
|
||||
data.to_json(file_name, indent = 2, force_ascii=False)
|
||||
|
||||
def test3(city_country: str) -> List[Landmark]:
|
||||
|
||||
|
||||
preferences = Preferences(
|
||||
sightseeing=Preference(
|
||||
name='sightseeing',
|
||||
type=LandmarkType(landmark_type='sightseeing'),
|
||||
score = 5),
|
||||
nature=Preference(
|
||||
name='nature',
|
||||
type=LandmarkType(landmark_type='nature'),
|
||||
score = 0),
|
||||
shopping=Preference(
|
||||
name='shopping',
|
||||
type=LandmarkType(landmark_type='shopping'),
|
||||
score = 5))
|
||||
|
||||
coordinates = None
|
||||
|
||||
landmarks, landmarks_short = generate_landmarks(preferences=preferences, city_country=city_country, coordinates=coordinates)
|
||||
|
||||
#write_data(landmarks)
|
||||
|
||||
start = Landmark(name='start', type=LandmarkType(landmark_type='start'), location=(48.2044576, 16.3870242), osm_type='start', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
||||
finish = Landmark(name='finish', type=LandmarkType(landmark_type='finish'), location=(48.2044576, 16.3870242), osm_type='finish', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
||||
|
||||
|
||||
test = landmarks_short
|
||||
|
||||
test.insert(0, start)
|
||||
test.append(finish)
|
||||
|
||||
max_walking_time = 2 # hours
|
||||
|
||||
visiting_list = solve_optimization(test, max_walking_time*60, True)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def test4(coordinates: tuple[float, float]) -> List[Landmark]:
|
||||
|
||||
@ -117,4 +76,3 @@ test4(tuple((48.8344400, 2.3220540))) # Café Chez César
|
||||
#test4(tuple((48.8375946, 2.2949904))) # Point random
|
||||
#test4(tuple((47.377859, 8.540585))) # Zurich HB
|
||||
#test4(tuple((45.7576485, 4.8330241))) # Lyon Bellecour
|
||||
#test3('Vienna, Austria')
|
Loading…
x
Reference in New Issue
Block a user