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 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_notequal3(self):
        route = [self.possible_cities["Cordoba"]]
        solution1 = Solution(origin_city=self.origin_city,
                             cities=route,
                             required_cities=[],
                             max_trip_time=0)
        route = [self.possible_cities["Rosario"]]
        solution2 = Solution(origin_city=self.origin_city,
                             cities=route,
                             required_cities=[],
                             max_trip_time=0)

        self.assertNotEqual(solution1, solution2)
Exemple #4
0
    def create_random_individual(self):
        cities = []
        cities += self.required_cities
        random.shuffle(self.not_required_possible_cities)
        for random_city in self.not_required_possible_cities:
            if random_city not in cities:
                backup = list(cities)
                cities.append(random_city)
                solution = Solution(self.origin_city, cities, self.required_cities,
                                    self.max_trip_time)
                if not solution.is_valid_knapsack_time():
                    cities = backup
                    continue

                optimizer = TSPOptimizerClosestCityStrategy(self.origin_city, cities)
                cities = optimizer.optimize()
                solution.cities = cities
                if not solution.is_valid_total_trip_time():
                    cities = backup
                    continue

        solution = Solution(self.origin_city, cities, self.required_cities, self.max_trip_time)
        optimizer = TSPOptimizerClosestCityStrategy(self.origin_city, cities)
        solution.cities = optimizer.optimize()
        return solution
Exemple #5
0
    def __get_child(self, other):
        child_solution_cities = []
        # Add required cities
        child_solution_cities += self.required_cities
        # Add cities present in both parents
        for city_parent_1 in self.solution.cities:
            if city_parent_1 in other.solution.cities:
                if city_parent_1 not in child_solution_cities:
                    child_solution_cities.append(city_parent_1)

        # Get random sample of cities from parent 1 and add them to child if not already present
        parent_solution_cities = []
        if len(self.solution.cities) > 0:
            parent_solution_cities = random.sample(
                self.solution.cities,
                random.randint(1, len(self.solution.cities)))
            random.shuffle(parent_solution_cities)
        for parent_solution_city in parent_solution_cities:
            if parent_solution_city in child_solution_cities:
                continue
            child_solution_cities.append(parent_solution_city)

        # Get random sample of cities from parent 2 and add them to child if not already present
        parent_solution_cities = []
        if len(other.solution.cities) > 0:
            parent_solution_cities = random.sample(
                other.solution.cities,
                random.randint(1, len(other.solution.cities)))
            random.shuffle(parent_solution_cities)
        for parent_solution_city in parent_solution_cities:
            if parent_solution_city in child_solution_cities:
                continue
            child_solution_cities.append(parent_solution_city)

        # Get child solution
        child_solution = Solution(self.origin_city, child_solution_cities,
                                  self.required_cities, self.max_trip_time)

        # Optimize tsp
        optimizer = TSPOptimizerClosestCityStrategy(self.origin_city,
                                                    child_solution.cities)
        child_solution.cities = optimizer.optimize()

        # Delete random cities until solution is valid
        while not child_solution.is_valid_total_trip_time():
            self.solution_delete_city(child_solution)
            # Optimize the tsp part of the solution
            optimizer = TSPOptimizerClosestCityStrategy(
                self.origin_city, child_solution.cities)
            child_solution.cities = optimizer.optimize()
        child_solution.update_fitness()
        child_individual = Individual(self.origin_city, self.possible_cities,
                                      self.required_cities, self.max_trip_time,
                                      child_solution)
        return child_individual
    def solve(self):
        best_solution_fitness = 0
        best_solution_trip_time = 0
        if self.should_print_stats():
            self.print_stats()
        for x in range(1, len(self.possible_trip_cities) + 1):
            for cities in combinations(self.possible_trip_cities, x):
                self.current_iteration += 1
                if self.should_print_stats():
                    self.print_stats()

                solution = Solution(self.origin_city, cities, self.required_cities,
                                    self.max_trip_time)
                if not solution.is_valid_knapsack_time() or not solution.is_valid_required_city():
                    continue

                # Apply construction heuristic
                optimizer = TSPOptimizerClosestCityStrategy(self.origin_city, solution.cities)
                solution.cities = optimizer.optimize()

                if not solution.is_valid_total_trip_time():
                    continue

                if solution.fitness > best_solution_fitness:
                    # Update best_solution as first objective fitness is better
                    best_solution = solution
                    self.set_best_solution(best_solution)
                    best_solution_fitness = solution.fitness
                    best_solution_trip_time = solution.get_total_travel_time()
                elif solution.fitness == best_solution_fitness:
                    if solution.get_total_travel_time() < best_solution_trip_time:
                        # Update best_solution as first objective fitness is same but
                        # second objective travel time is better
                        best_solution = solution
                        self.set_best_solution(best_solution)
                        best_solution_fitness = solution.fitness
                        best_solution_trip_time = solution.get_total_travel_time()
                # self.add_good_solution(solution)
        self.improve_solutions()
        # return self.best_solution, self.good_solutions
        return self.best_solution
Exemple #7
0
    def test_add_good_solution_with_good_solutions_list_not_full(self):
        self.strategy.max_good_solution_length = 5

        route = [self.possible_cities["2"], self.possible_cities["8"]]
        best_solution = Solution(self.origin_city, route, [], 0)
        best_solution.fitness = 100
        self.strategy.best_solution = best_solution

        good_solutions = []
        route = [self.possible_cities["2"]]
        s1 = Solution(self.origin_city, route, [], 0)
        good_solutions.append(s1)

        route = [self.possible_cities["2"], self.possible_cities["4"], self.possible_cities["8"]]
        s2 = Solution(self.origin_city, route, [], 0)
        good_solutions.append(s2)

        route = [self.possible_cities["2"], self.possible_cities["5"]]
        s3 = Solution(self.origin_city, route, [], 0)
        good_solutions.append(s3)

        route = [self.possible_cities["6"], self.possible_cities["7"]]
        s4 = Solution(self.origin_city, route, [], 0)
        good_solutions.append(s4)

        route = [self.possible_cities["6"], self.possible_cities["5"]]
        s5 = Solution(self.origin_city, route, [], 0)
        good_solutions.append(s5)

        for s in good_solutions:
            s.fitness = 100

        self.strategy.add_good_solution(s1)
        self.assertEqual(self.strategy.good_solutions[0], s1)

        self.strategy.add_good_solution(s2)
        self.assertEqual(self.strategy.good_solutions[1], s2)

        self.strategy.add_good_solution(s3)
        self.assertEqual(self.strategy.good_solutions[2], s3)

        self.strategy.add_good_solution(s4)
        self.assertEqual(self.strategy.good_solutions[3], s4)

        self.strategy.add_good_solution(s5)
        self.assertEqual(self.strategy.good_solutions[4], s5)
 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())
Exemple #10
0
    def crossover(self, parent1, parent2):
        child_solution_cities = []
        # Add required cities
        child_solution_cities += self.required_cities
        # Add cities present in both parents
        for city_parent_1 in parent1.cities:
            if city_parent_1 in parent2.cities:
                if city_parent_1 not in child_solution_cities:
                    child_solution_cities.append(city_parent_1)

        # Get random sample of cities from parent 1 and add them to child if not already present
        parent_solution_cities = []
        if len(parent1.cities) > 0:
            parent_solution_cities = random.sample(parent1.cities,
                                                   random.randint(1, len(parent1.cities)))
            random.shuffle(parent_solution_cities)
        for parent_solution_city in parent_solution_cities:
            if parent_solution_city in child_solution_cities:
                continue
            child_solution_cities.append(parent_solution_city)

        # Get random sample of cities from parent 2 and add them to child if not already present
        parent_solution_cities = []
        if len(parent2.cities) > 0:
            parent_solution_cities = random.sample(parent2.cities,
                                                   random.randint(1, len(parent2.cities)))
            random.shuffle(parent_solution_cities)
        for parent_solution_city in parent_solution_cities:
            if parent_solution_city in child_solution_cities:
                continue
            child_solution_cities.append(parent_solution_city)

        # Get child solution
        child_solution = Solution(self.origin_city, child_solution_cities, self.required_cities,
                                  self.max_trip_time)
        return child_solution
Exemple #11
0
    def get_valid_solution(self):
        while True:
            cities = random.sample(
                self.possible_trip_cities,
                random.randint(1, len(self.possible_trip_cities)))
            random.shuffle(cities)
            solution = Solution(self.origin_city, cities, self.required_cities,
                                self.max_trip_time)

            if not solution.is_valid_knapsack_time(
            ) or not solution.is_valid_required_city():
                continue

            optimizer = TSPOptimizerClosestCityStrategy(
                self.origin_city, solution.cities)
            solution.cities = optimizer.optimize()

            if solution.is_valid_total_trip_time():
                return solution
Exemple #12
0
    def create_random_solution(self):
        while True:
            cities = []
            cities += self.required_cities
            sample_size = random.randint(1, len(self.possible_cities))
            random_sample_cities = random.sample(self.possible_cities,
                                                 sample_size)
            for random_city in random_sample_cities:
                if random_city not in cities:
                    cities.append(random_city)
            random.shuffle(cities)
            solution = Solution(self.origin_city, cities, self.required_cities,
                                self.max_trip_time)

            if not solution.is_valid_knapsack_time(
            ) or not solution.is_valid_required_city():
                continue

            optimizer = TSPOptimizerClosestCityStrategy(
                self.origin_city, solution.cities)
            solution.cities = optimizer.optimize()

            if solution.is_valid_total_trip_time():
                return solution
Exemple #13
0
    def test_add_good_solution(self):
        self.strategy.max_good_solution_length = 5
        self.strategy.good_solution_fitness_threshold = 0.8

        route = [self.possible_cities["2"], self.possible_cities["8"]]
        best_solution = Solution(self.origin_city, route, [], 0)
        best_solution.fitness = 100
        self.strategy.best_solution = best_solution

        good_solutions = []
        route = [self.possible_cities["2"]]
        s1 = Solution(self.origin_city, route, [], 0)
        good_solutions.append(s1)

        route = [self.possible_cities["2"], self.possible_cities["4"], self.possible_cities["8"]]
        s2 = Solution(self.origin_city, route, [], 0)
        good_solutions.append(s2)

        route = [self.possible_cities["2"], self.possible_cities["5"]]
        s3 = Solution(self.origin_city, route, [], 0)
        good_solutions.append(s3)

        route = [self.possible_cities["6"], self.possible_cities["7"]]
        s4 = Solution(self.origin_city, route, [], 0)
        good_solutions.append(s4)

        route = [self.possible_cities["6"], self.possible_cities["5"]]
        s5 = Solution(self.origin_city, route, [], 0)
        good_solutions.append(s5)

        for s in good_solutions:
            s.fitness = 100

        self.strategy.good_solutions = good_solutions

        route = [self.possible_cities["3"]]
        s6 = Solution(self.origin_city, route, [], 0)
        s6.fitness = 100

        self.strategy.add_good_solution(s6)
        self.assertEqual(self.strategy.good_solutions[0], s6)
        self.assertEqual(self.strategy.good_solutions[1], s4)
        self.assertEqual(self.strategy.good_solutions[2], s5)
        self.assertEqual(self.strategy.good_solutions[3], s1)
        self.assertEqual(self.strategy.good_solutions[4], s2)
    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_similarity(self):
        route = [self.possible_cities["Cordoba"]]
        solution1 = Solution(origin_city=self.origin_city,
                             cities=route,
                             required_cities=[],
                             max_trip_time=0)
        route = [self.possible_cities["Rosario"]]
        solution2 = Solution(origin_city=self.origin_city,
                             cities=route,
                             required_cities=[],
                             max_trip_time=0)

        route = [
            self.possible_cities["Cordoba"], self.possible_cities["Rosario"]
        ]
        solution3 = Solution(origin_city=self.origin_city,
                             cities=route,
                             required_cities=[],
                             max_trip_time=0)

        route = [
            self.possible_cities["Ushuaia"], self.possible_cities["Rosario"]
        ]
        solution4 = Solution(origin_city=self.origin_city,
                             cities=route,
                             required_cities=[],
                             max_trip_time=0)

        expected_similarity = 1
        self.assertEqual(solution1.get_similarity(solution1),
                         expected_similarity)

        expected_similarity = 1
        self.assertEqual(solution2.get_similarity(solution2),
                         expected_similarity)

        expected_similarity = 2
        self.assertEqual(solution3.get_similarity(solution3),
                         expected_similarity)

        expected_similarity = 2
        self.assertEqual(solution4.get_similarity(solution4),
                         expected_similarity)

        expected_similarity = 0
        self.assertEqual(solution1.get_similarity(solution2),
                         expected_similarity)
        self.assertEqual(solution2.get_similarity(solution1),
                         expected_similarity)

        expected_similarity = 1
        self.assertEqual(solution1.get_similarity(solution3),
                         expected_similarity)
        self.assertEqual(solution3.get_similarity(solution1),
                         expected_similarity)

        expected_similarity = 0
        self.assertEqual(solution1.get_similarity(solution4),
                         expected_similarity)
        self.assertEqual(solution4.get_similarity(solution1),
                         expected_similarity)

        expected_similarity = 1
        self.assertEqual(solution2.get_similarity(solution3),
                         expected_similarity)
        self.assertEqual(solution3.get_similarity(solution2),
                         expected_similarity)

        expected_similarity = 1
        self.assertEqual(solution2.get_similarity(solution4),
                         expected_similarity)
        self.assertEqual(solution4.get_similarity(solution2),
                         expected_similarity)

        expected_similarity = 1
        self.assertEqual(solution3.get_similarity(solution4),
                         expected_similarity)
        self.assertEqual(solution4.get_similarity(solution3),
                         expected_similarity)
 def get_travel_time(self, cities):
     solution = Solution(self.origin_city, cities, required_cities=[], max_trip_time=0)
     return solution.get_total_travel_time()
Exemple #17
0
    def test_add_good_solution_with_fitness_not_good_enough(self):
        self.strategy.max_good_solution_length = 5
        self.strategy.good_solution_fitness_threshold = 0.8

        route = [self.possible_cities["2"], self.possible_cities["8"]]
        best_solution = Solution(self.origin_city, route, [], 0)
        best_solution.fitness = 100
        self.strategy.best_solution = best_solution

        route = [self.possible_cities["2"]]
        s1 = Solution(self.origin_city, route, [], 0)
        s1.fitness = 79

        route = [self.possible_cities["2"], self.possible_cities["4"], self.possible_cities["8"]]
        s2 = Solution(self.origin_city, route, [], 0)
        s2.fitness = 70

        route = [self.possible_cities["2"], self.possible_cities["5"]]
        s3 = Solution(self.origin_city, route, [], 0)
        s3.fitness = 60

        route = [self.possible_cities["6"], self.possible_cities["7"]]
        s4 = Solution(self.origin_city, route, [], 0)
        s4.fitness = 50

        route = [self.possible_cities["6"], self.possible_cities["5"]]
        s5 = Solution(self.origin_city, route, [], 0)
        s5.fitness = 0

        self.strategy.add_good_solution(s1)
        self.assertEqual(len(self.strategy.good_solutions), 0)

        self.strategy.add_good_solution(s2)
        self.assertEqual(len(self.strategy.good_solutions), 0)

        self.strategy.add_good_solution(s3)
        self.assertEqual(len(self.strategy.good_solutions), 0)

        self.strategy.add_good_solution(s4)
        self.assertEqual(len(self.strategy.good_solutions), 0)

        self.strategy.add_good_solution(s5)
        self.assertEqual(len(self.strategy.good_solutions), 0)