-
Notifications
You must be signed in to change notification settings - Fork 256
Expand file tree
/
Copy pathtraveling_salesman_problem.py
More file actions
67 lines (54 loc) · 3.15 KB
/
traveling_salesman_problem.py
File metadata and controls
67 lines (54 loc) · 3.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#!/usr/bin/env python
# Created by "Thieu" at 13:57, 07/11/2023 ----------%
# Email: nguyenthieu2102@gmail.com %
# Github: https://github.com/thieu1995 %
# --------------------------------------------------%
# In the context of the Mealpy for the Traveling Salesman Problem (TSP), a solution is a possible route that
# represents a tour of visiting all the cities exactly once and returning to the starting city. The solution is typically
# represented as a permutation of the cities, where each city appears exactly once in the permutation.
# For example, let's consider a TSP instance with 5 cities labeled as A, B, C, D, and E. A possible solution could be
# represented as the permutation [A, B, D, E, C], which indicates the order in which the cities are visited. This solution
# suggests that the tour starts at city A, then moves to city B, then D, E, and finally C before returning to city A.
import numpy as np
from mealpy import PermutationVar, WOA, Problem
# Define the positions of the cities
city_positions = np.array([[60, 200], [180, 200], [80, 180], [140, 180], [20, 160],
[100, 160], [200, 160], [140, 140], [40, 120], [100, 120],
[180, 100], [60, 80], [120, 80], [180, 60], [20, 40],
[100, 40], [200, 40], [20, 20], [60, 20], [160, 20]])
num_cities = len(city_positions)
data = {
"city_positions": city_positions,
"num_cities": num_cities,
}
class TspProblem(Problem):
def __init__(self, bounds=None, minmax="min", data=None, **kwargs):
super().__init__(bounds, minmax, **kwargs)
self.data = data
@staticmethod
def calculate_distance(city_a, city_b):
# Calculate Euclidean distance between two cities
return np.linalg.norm(city_a - city_b)
@staticmethod
def calculate_total_distance(route, city_positions):
# Calculate total distance of a route
total_distance = 0
num_cities = len(route)
for idx in range(num_cities):
current_city = route[idx]
next_city = route[(idx + 1) % num_cities] # Wrap around to the first city
total_distance += TspProblem.calculate_distance(city_positions[current_city], city_positions[next_city])
return total_distance
def obj_func(self, x):
x_decoded = self.decode_solution(x)
route = x_decoded["per_var"]
fitness = self.calculate_total_distance(route, self.data["city_positions"])
return fitness
bounds = PermutationVar(valid_set=list(range(0, num_cities)), name="per_var")
problem = TspProblem(bounds=bounds, minmax="min", data=data)
model = WOA.OriginalWOA(epoch=100, pop_size=20)
model.solve(problem)
print(f"Best agent: {model.g_best}") # Encoded solution
print(f"Best solution: {model.g_best.solution}") # Encoded solution
print(f"Best fitness: {model.g_best.target.fitness}")
print(f"Best real scheduling: {model.problem.decode_solution(model.g_best.solution)}") # Decoded (Real) solution