def solve(self): # Add all required cities solution = Solution(self.origin_city, list(self.required_cities), self.required_cities, self.max_trip_time) solution.update_fitness() if not solution.is_valid(): raise Exception() # Compute ratios ratios = [] for city in self.possible_trip_cities: if city in self.required_cities: continue ratios.append([city, city.value / city.stay_time]) ratios.sort(reverse=True, key=lambda x: x[1]) # Add city until knapsack is full for r in ratios: city = r[0] backup = list(solution.cities) solution.cities.append(city) solution.update_fitness() tsp_optimizer = TSPOptimizerClosestCityStrategy( self.origin_city, solution.cities) solution.cities = tsp_optimizer.optimize() if not solution.is_valid_total_trip_time(): solution.cities = backup solution.update_fitness() break self.improve_solution(solution) return solution
def test_solution_valid_with_just_origin_city(self): required_cities = [] max_trip_time = 999999 route = [] solution = Solution(origin_city=self.origin_city, cities=route, required_cities=required_cities, max_trip_time=max_trip_time) expected_total_stay_time = 0 self.assertEqual(expected_total_stay_time, solution.get_total_stay_time()) expected_total_travel_time = 0 self.assertEqual(expected_total_travel_time, solution.get_total_travel_time()) expected_total_trip_time = expected_total_stay_time + expected_total_travel_time self.assertEqual(expected_total_trip_time, solution.get_total_trip_time()) self.assertTrue(solution.is_valid_required_city()) self.assertTrue(solution.is_valid_knapsack_time()) self.assertTrue(solution.is_valid_total_trip_time()) self.assertTrue(solution.is_valid())
def test_solution_valid_with_required_cities(self): required_cities = [self.possible_cities["Cordoba"]] max_trip_time = 14 route = [ self.possible_cities["Cordoba"], self.possible_cities["Rosario"], self.possible_cities["Ushuaia"] ] solution = Solution(origin_city=self.origin_city, cities=route, required_cities=required_cities, max_trip_time=max_trip_time) expected_total_stay_time = 6 self.assertEqual(expected_total_stay_time, solution.get_total_stay_time()) expected_total_travel_time = 1 + 1 + 3 + 3 self.assertEqual(expected_total_travel_time, solution.get_total_travel_time()) expected_total_trip_time = expected_total_stay_time + expected_total_travel_time self.assertEqual(expected_total_trip_time, solution.get_total_trip_time()) self.assertTrue(solution.is_valid_required_city()) self.assertTrue(solution.is_valid_knapsack_time()) self.assertTrue(solution.is_valid_total_trip_time()) self.assertTrue(solution.is_valid())
def is_valid(self, origin_city, required_cities, max_trip_time): if len(required_cities) == 0: return True solution = Solution(origin_city, required_cities, required_cities, max_trip_time) optimizer = TSPOptimizerClosestCityStrategy(origin_city, solution.cities) solution.cities = optimizer.optimize() if not solution.is_valid(): solution.print() print() print("NOT VALID SOLUTION WITH ONLY REQUIRED CITIES") return False return True
def test_solution_invalid_with_two_required_city_both_not_present(self): required_cities = [ self.possible_cities["Cordoba"], self.possible_cities["Rosario"] ] max_trip_time = 999999 route = [self.possible_cities["Ushuaia"]] solution = Solution(origin_city=self.origin_city, cities=route, required_cities=required_cities, max_trip_time=max_trip_time) self.assertFalse(solution.is_valid_required_city()) self.assertTrue(solution.is_valid_knapsack_time()) self.assertTrue(solution.is_valid_total_trip_time()) self.assertFalse(solution.is_valid())