cleanup-backend #13
							
								
								
									
										10082
									
								
								backend/landmarks_Strasbourg.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10082
									
								
								backend/landmarks_Strasbourg.txt
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -15,5 +15,5 @@ OSM_CACHE_DIR = Path(cache_dir_string) | |||||||
| logger = logging.getLogger(__name__) | logger = logging.getLogger(__name__) | ||||||
| logging.basicConfig( | logging.basicConfig( | ||||||
|     level = logging.INFO, |     level = logging.INFO, | ||||||
|     format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' |     format = '%(asctime)s - %(name)s\t- %(levelname)s\t- %(message)s' | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -49,10 +49,10 @@ class Optimizer: | |||||||
|         dist = 0 |         dist = 0 | ||||||
|         for elem in L :  |         for elem in L :  | ||||||
|             if elem.time_to_reach_next is not None : |             if elem.time_to_reach_next is not None : | ||||||
|                 print('- ' + elem.name + ', time to reach next = ' + str(elem.time_to_reach_next)) |                 self.logger.info(f"  {elem.name}, time to next = {elem.time_to_reach_next}") | ||||||
|                 dist += elem.time_to_reach_next |                 dist += elem.time_to_reach_next | ||||||
|             else :  |             else :  | ||||||
|                 print('- ' + elem.name) |                 self.logger.info(f"  {elem.name}") | ||||||
|         self.logger.info(f'Minutes walked : {dist}') |         self.logger.info(f'Minutes walked : {dist}') | ||||||
|         self.logger.info(f'Visited {len(L)-2} landmarks') |         self.logger.info(f'Visited {len(L)-2} landmarks') | ||||||
|  |  | ||||||
| @@ -478,7 +478,7 @@ class Optimizer: | |||||||
|  |  | ||||||
|  |  | ||||||
|     # Main optimization pipeline |     # Main optimization pipeline | ||||||
|     def solve_optimization (self) : |     def solve_optimization (self, hide_log=False) : | ||||||
|         """ |         """ | ||||||
|         Main optimization pipeline to solve the landmark visiting problem. |         Main optimization pipeline to solve the landmark visiting problem. | ||||||
|  |  | ||||||
| @@ -506,6 +506,9 @@ class Optimizer: | |||||||
|         A, b = self.respect_user_must_do(self.landmarks)                      # Check if there are user_defined must_see. Also takes care of start/goal |         A, b = self.respect_user_must_do(self.landmarks)                      # Check if there are user_defined must_see. Also takes care of start/goal | ||||||
|         A_eq = np.vstack((A_eq, A), dtype=np.int8) |         A_eq = np.vstack((A_eq, A), dtype=np.int8) | ||||||
|         b_eq += b |         b_eq += b | ||||||
|  |         A, b = self.respect_user_must_avoid(self.landmarks)                      # Check if there are user_defined must_see. Also takes care of start/goal | ||||||
|  |         A_eq = np.vstack((A_eq, A), dtype=np.int8) | ||||||
|  |         b_eq += b | ||||||
|         A, b = self.respect_start_finish(L)                  # Force start and finish positions |         A, b = self.respect_start_finish(L)                  # Force start and finish positions | ||||||
|         A_eq = np.vstack((A_eq, A), dtype=np.int8) |         A_eq = np.vstack((A_eq, A), dtype=np.int8) | ||||||
|         b_eq += b |         b_eq += b | ||||||
| @@ -540,13 +543,13 @@ class Optimizer: | |||||||
|                     b_eq += b |                     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) |                 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) | ||||||
|                 if not res.success : |                 if not res.success : | ||||||
|                     self.logger.info("Solving failed because of overconstrained problem") |                     raise ArithmeticError("Solving failed because of overconstrained problem") | ||||||
|                     return None |                     return None | ||||||
|                 order, circles = self.is_connected(res.x) |                 order, circles = self.is_connected(res.x) | ||||||
|                 #nodes, edges = is_connected(res.x) |                 #nodes, edges = is_connected(res.x) | ||||||
|                 if circles is None : |                 if circles is None : | ||||||
|                     break |                     break | ||||||
|                 print(i) |                 # print(i) | ||||||
|                 i += 1 |                 i += 1 | ||||||
|              |              | ||||||
|             if i == timeout : |             if i == timeout : | ||||||
| @@ -556,8 +559,9 @@ class Optimizer: | |||||||
|             tour = self.link_list(order, self.landmarks) |             tour = self.link_list(order, self.landmarks) | ||||||
|              |              | ||||||
|             # logging |             # logging | ||||||
|  |             if not hide_log : | ||||||
|                 if i != 0 : |                 if i != 0 : | ||||||
|                 self.logger.info(f"Neded to recompute paths {i} times because of unconnected loops...") |                     self.logger.info(f"Neded to recompute paths {i} times") | ||||||
|                 self.print_res(tour)  # how to do better ?   |                 self.print_res(tour)  # how to do better ?   | ||||||
|                 self.logger.info(f"Total score : {int(-res.fun)}") |                 self.logger.info(f"Total score : {int(-res.fun)}") | ||||||
|  |  | ||||||
|   | |||||||
| @@ -15,8 +15,6 @@ class Refiner : | |||||||
|  |  | ||||||
|     logger = logging.getLogger(__name__) |     logger = logging.getLogger(__name__) | ||||||
|      |      | ||||||
|     all_landmarks: List[Landmark]   # list of all landmarks |  | ||||||
|     base_tour: List[Landmark]       # base tour that needs to be refined |  | ||||||
|     max_time: int = None            # max visit time (in minutes) |     max_time: int = None            # max visit time (in minutes) | ||||||
|     detour: int = None              # accepted max detour time (in minutes) |     detour: int = None              # accepted max detour time (in minutes) | ||||||
|     detour_factor: float            # detour factor of straight line vs real distance in cities |     detour_factor: float            # detour factor of straight line vs real distance in cities | ||||||
| @@ -24,11 +22,9 @@ class Refiner : | |||||||
|     max_landmarks: int              # max number of landmarks to visit |     max_landmarks: int              # max number of landmarks to visit | ||||||
|  |  | ||||||
|  |  | ||||||
|     def __init__(self, max_time: int, detour: int, all_landmarks: List[Landmark], base_tour: List[Landmark]) : |     def __init__(self, max_time: int, detour: int) : | ||||||
|         self.max_time = max_time |         self.max_time = max_time | ||||||
|         self.detour = detour |         self.detour = detour | ||||||
|         self.all_landmarks = all_landmarks |  | ||||||
|         self.base_tour = base_tour |  | ||||||
|  |  | ||||||
|         # load parameters from file |         # load parameters from file | ||||||
|         with constants.OPTIMIZER_PARAMETERS_PATH.open('r') as f: |         with constants.OPTIMIZER_PARAMETERS_PATH.open('r') as f: | ||||||
| @@ -290,7 +286,7 @@ class Refiner : | |||||||
|  |  | ||||||
|  |  | ||||||
|     # Second stage of the optimization. Use linear programming again to refine the path |     # Second stage of the optimization. Use linear programming again to refine the path | ||||||
|     def refine_optimization(self) -> List[Landmark] : |     def refine_optimization(self, all_landmarks: List[Landmark], base_tour: List[Landmark]) -> List[Landmark] : | ||||||
|         """ |         """ | ||||||
|         Refine the initial tour path by considering additional minor landmarks and optimizing the path. |         Refine the initial tour path by considering additional minor landmarks and optimizing the path. | ||||||
|  |  | ||||||
| @@ -309,20 +305,20 @@ class Refiner : | |||||||
|             new_tour = base_tour |             new_tour = base_tour | ||||||
|          |          | ||||||
|         else : |         else : | ||||||
|             minor_landmarks = self.get_minor_landmarks(self.all_landmarks, self.base_tour, 200) |             minor_landmarks = self.get_minor_landmarks(all_landmarks, base_tour, 200) | ||||||
|  |  | ||||||
|             self.logger.info(f"Using {len(minor_landmarks)} minor landmarks around the predicted path") |             self.logger.info(f"Using {len(minor_landmarks)} minor landmarks around the predicted path") | ||||||
|  |  | ||||||
|             # full set of visitable landmarks |             # full set of visitable landmarks | ||||||
|             full_set = self.base_tour[:-1] + minor_landmarks   # create full set of possible landmarks (without finish) |             full_set = base_tour[:-1] + minor_landmarks   # create full set of possible landmarks (without finish) | ||||||
|             full_set.append(self.base_tour[-1])                # add finish back |             full_set.append(base_tour[-1])                # add finish back | ||||||
|  |  | ||||||
|             # get a new tour |             # get a new tour | ||||||
|             optimizer = Optimizer(self.max_time + self.detour, full_set) |             optimizer = Optimizer(self.max_time + self.detour, full_set) | ||||||
|             new_tour = optimizer.solve_optimization() |             new_tour = optimizer.solve_optimization(hide_log=True) | ||||||
|  |  | ||||||
|             if new_tour is None : |             if new_tour is None : | ||||||
|                 new_tour = self.base_tour |                 new_tour = base_tour | ||||||
|  |  | ||||||
|         # Link the new tour |         # Link the new tour | ||||||
|         new_tour, new_dist = link_list_simple(new_tour) |         new_tour, new_dist = link_list_simple(new_tour) | ||||||
| @@ -335,7 +331,7 @@ class Refiner : | |||||||
|         better_tour, better_poly = self.find_shortest_path_through_all_landmarks(new_tour) |         better_tour, better_poly = self.find_shortest_path_through_all_landmarks(new_tour) | ||||||
|  |  | ||||||
|         # Fix the tour using Polygons if the path looks weird |         # Fix the tour using Polygons if the path looks weird | ||||||
|         if self.base_tour[0].location == self.base_tour[-1].location and not better_poly.is_valid : |         if base_tour[0].location == base_tour[-1].location and not better_poly.is_valid : | ||||||
|             better_tour = self.fix_using_polygon(better_tour) |             better_tour = self.fix_using_polygon(better_tour) | ||||||
|          |          | ||||||
|         # Link the tour again |         # Link the tour again | ||||||
| @@ -348,6 +344,7 @@ class Refiner : | |||||||
|             final_tour = better_tour |             final_tour = better_tour | ||||||
|  |  | ||||||
|         self.logger.info("Refined tour (result of second stage optimization): ") |         self.logger.info("Refined tour (result of second stage optimization): ") | ||||||
|  |         optimizer.print_res(final_tour) | ||||||
|          |          | ||||||
|         return final_tour |         return final_tour | ||||||
|  |  | ||||||
|   | |||||||
| @@ -41,7 +41,7 @@ def test(start_coords: tuple[float, float], finish_coords: tuple[float, float] = | |||||||
|                                   type='shopping', |                                   type='shopping', | ||||||
|                                   score = 0), |                                   score = 0), | ||||||
|  |  | ||||||
|                     max_time_minute=180, |                     max_time_minute=45, | ||||||
|                     detour_tolerance_minute=0 |                     detour_tolerance_minute=0 | ||||||
|                     ) |                     ) | ||||||
|  |  | ||||||
| @@ -49,7 +49,7 @@ def test(start_coords: tuple[float, float], finish_coords: tuple[float, float] = | |||||||
|     if finish_coords is None : |     if finish_coords is None : | ||||||
|         finish_coords = start_coords |         finish_coords = start_coords | ||||||
|     start = Landmark(name='start', type='start', location=start_coords, osm_type='', osm_id=0, attractiveness=0, n_tags = 0) |     start = Landmark(name='start', type='start', location=start_coords, osm_type='', osm_id=0, attractiveness=0, n_tags = 0) | ||||||
|     finish = Landmark(name='finish', type='start', location=finish_coords, osm_type='', osm_id=0, attractiveness=0, n_tags = 0) |     finish = Landmark(name='finish', type='finish', location=finish_coords, osm_type='', osm_id=0, attractiveness=0, n_tags = 0) | ||||||
|     #finish = Landmark(name='finish', type=LandmarkType(landmark_type='finish'), location=(48.8777055, 2.3640967), osm_type='finish', osm_id=0, attractiveness=0, must_do=True, n_tags = 0) |     #finish = Landmark(name='finish', type=LandmarkType(landmark_type='finish'), location=(48.8777055, 2.3640967), osm_type='finish', osm_id=0, attractiveness=0, must_do=True, n_tags = 0) | ||||||
|     #start = Landmark(name='start', type=LandmarkType(landmark_type='start'), location=(48.847132, 2.312359), osm_type='start', osm_id=0, attractiveness=0, must_do=True, n_tags = 0) |     #start = Landmark(name='start', type=LandmarkType(landmark_type='start'), location=(48.847132, 2.312359), 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.843185, 2.344533), osm_type='finish', osm_id=0, attractiveness=0, must_do=True, n_tags = 0) |     #finish = Landmark(name='finish', type=LandmarkType(landmark_type='finish'), location=(48.843185, 2.344533), osm_type='finish', osm_id=0, attractiveness=0, must_do=True, n_tags = 0) | ||||||
| @@ -62,7 +62,7 @@ def test(start_coords: tuple[float, float], finish_coords: tuple[float, float] = | |||||||
|     landmarks, landmarks_short = manager.generate_landmarks_list() |     landmarks, landmarks_short = manager.generate_landmarks_list() | ||||||
|      |      | ||||||
|     # Store data to file for debug purposes |     # Store data to file for debug purposes | ||||||
|     #write_data(landmarks, "landmarks_Wien.txt") |     # write_data(landmarks, "landmarks_Strasbourg.txt") | ||||||
|  |  | ||||||
|     # Insert start and finish to the landmarks list |     # Insert start and finish to the landmarks list | ||||||
|     landmarks_short.insert(0, start) |     landmarks_short.insert(0, start) | ||||||
| @@ -73,8 +73,8 @@ def test(start_coords: tuple[float, float], finish_coords: tuple[float, float] = | |||||||
|     base_tour = optimizer.solve_optimization() |     base_tour = optimizer.solve_optimization() | ||||||
|  |  | ||||||
|     # Second stage using linear optimization |     # Second stage using linear optimization | ||||||
|     refiner = Refiner(max_time = preferences.max_time_minute, detour = preferences.detour_tolerance_minute, all_landmarks=landmarks, base_tour=base_tour) |     refiner = Refiner(max_time = preferences.max_time_minute, detour = preferences.detour_tolerance_minute) | ||||||
|     refined_tour = refiner.refine_optimization() |     refined_tour = refiner.refine_optimization(all_landmarks=landmarks, base_tour=base_tour) | ||||||
|  |  | ||||||
|  |  | ||||||
|     return refined_tour |     return refined_tour | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user