Exemple #1
0
    def mutate_add_city(self):
        # Get a copy and shuffle
        possible_cities = list(self.possible_cities)
        random.shuffle(possible_cities)
        backup = list(self.solution.cities)
        for possible_city in possible_cities:
            if possible_city in self.solution.cities:
                # City already in solution. Try another one
                continue
            # City not in solution. See if adding it gives a valid solution
            self.solution.cities.append(possible_city)
            if not self.solution.is_valid_knapsack_time():
                # Not knapsack valid. Roll back and try another one
                self.solution.cities = list(backup)
                self.solution.update_fitness()
                continue
            # Optimize the tsp and see if it's valid
            optimizer = TSPOptimizerClosestCityStrategy(
                self.solution.origin_city, self.solution.cities)
            self.solution.cities = optimizer.optimize()
            if not self.solution.is_valid_total_trip_time():
                # Not tsp valid. Roll back and try another one
                self.solution.cities = list(backup)
                self.solution.update_fitness()
                continue

            # Mutation done.
            return True
        return False
    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
Exemple #3
0
 def mutate_delete_city(self):
     self.solution_delete_city(self.solution)
     # Optimize the tsp. As we are just deleting a city we know the resulting solution
     # it's tsp valid
     optimizer = TSPOptimizerClosestCityStrategy(self.solution.origin_city,
                                                 self.solution.cities)
     self.solution.cities = optimizer.optimize()
 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
Exemple #5
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
    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 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 #8
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 #9
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
Exemple #10
0
    def repair(self, solution):

        # If already valid return
        if solution.is_valid_total_trip_time():
            return

        # Delete process
        for city_to_delete in self.not_required_possible_cities_asc:
            if city_to_delete not in solution.cities:
                continue
            for i, solution_city in enumerate(solution.cities):
                if solution_city == city_to_delete:
                    break
            solution.cities.pop(i)

            if not solution.is_valid_knapsack_time():
                continue

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

            if not solution.is_valid_total_trip_time():
                continue

            break

        # Add process
        for city_to_add in self.not_required_possible_cities_desc:
            if city_to_add in solution.cities:
                continue
            backup = list(solution.cities)
            solution.cities.append(city_to_add)
            if not solution.is_valid_knapsack_time():
                solution.cities = backup
                continue
            optimizer = TSPOptimizerClosestCityStrategy(self.origin_city, solution.cities)
            solution.cities = optimizer.optimize()
            if not solution.is_valid_total_trip_time():
                solution.cities = backup
                continue
Exemple #11
0
 def setUp(self):
     travel_times = {
         "A": {
             "B": 1,
             "C": 3,
             "D": 3,
             "E": 6,
             "F": 6,
             "G": 6
         },
         "B": {
             "A": 1,
             "C": 1,
             "D": 2,
             "E": 5,
             "F": 6,
             "G": 4
         },
         "C": {
             "A": 3,
             "B": 1,
             "D": 2,
             "E": 4,
             "F": 5,
             "G": 5
         },
         "D": {
             "A": 3,
             "B": 2,
             "C": 2,
             "E": 3,
             "F": 4,
             "G": 4
         },
         "E": {
             "A": 6,
             "B": 5,
             "C": 4,
             "D": 3,
             "F": 4,
             "G": 5
         },
         "F": {
             "A": 6,
             "B": 6,
             "C": 5,
             "D": 4,
             "E": 4,
             "G": 6
         },
         "G": {
             "A": 6,
             "B": 4,
             "C": 5,
             "D": 4,
             "E": 5,
             "F": 6
         },
     }
     self.cities = [
         City('G', 3, 10, travel_times['G']),
         City('F', 2, 10, travel_times['F']),
         City('E', 2, 10, travel_times['E']),
         City('D', 2, 10, travel_times['D']),
         City('C', 2, 10, travel_times['C']),
         City('B', 2, 10, travel_times['B']),
     ]
     self.origin_city = City('A', 0, 0, travel_times['A'])
     self.optimizer = TSPOptimizerClosestCityStrategy(
         self.origin_city, self.cities)
Exemple #12
0
class TestSolution(unittest.TestCase):
    def setUp(self):
        travel_times = {
            "A": {
                "B": 1,
                "C": 3,
                "D": 3,
                "E": 6,
                "F": 6,
                "G": 6
            },
            "B": {
                "A": 1,
                "C": 1,
                "D": 2,
                "E": 5,
                "F": 6,
                "G": 4
            },
            "C": {
                "A": 3,
                "B": 1,
                "D": 2,
                "E": 4,
                "F": 5,
                "G": 5
            },
            "D": {
                "A": 3,
                "B": 2,
                "C": 2,
                "E": 3,
                "F": 4,
                "G": 4
            },
            "E": {
                "A": 6,
                "B": 5,
                "C": 4,
                "D": 3,
                "F": 4,
                "G": 5
            },
            "F": {
                "A": 6,
                "B": 6,
                "C": 5,
                "D": 4,
                "E": 4,
                "G": 6
            },
            "G": {
                "A": 6,
                "B": 4,
                "C": 5,
                "D": 4,
                "E": 5,
                "F": 6
            },
        }
        self.cities = [
            City('G', 3, 10, travel_times['G']),
            City('F', 2, 10, travel_times['F']),
            City('E', 2, 10, travel_times['E']),
            City('D', 2, 10, travel_times['D']),
            City('C', 2, 10, travel_times['C']),
            City('B', 2, 10, travel_times['B']),
        ]
        self.origin_city = City('A', 0, 0, travel_times['A'])
        self.optimizer = TSPOptimizerClosestCityStrategy(
            self.origin_city, self.cities)

    def test_get_closest_city_not_visited(self):
        closest_city = self.optimizer.get_closest_city_not_visited(
            self.origin_city)
        self.assertEqual(closest_city.name, 'B')

    def test_get_closest_city_not_visited_with_one_visited(self):
        self.optimizer.visited_cities['B'] = True
        closest_city = self.optimizer.get_closest_city_not_visited(
            self.cities[5])
        self.assertEqual(closest_city.name, 'C')

    def test_optimize(self):
        route = self.optimizer.optimize()
        self.assertEqual(route[0].name, 'B')
        self.assertEqual(route[1].name, 'C')
        self.assertEqual(route[2].name, 'D')
        self.assertEqual(route[3].name, 'E')
        self.assertEqual(route[4].name, 'F')
        self.assertEqual(route[5].name, 'G')