13
13
7 : [6 , 2 ],
14
14
}
15
15
16
+
16
17
def euclidean_distance (city1 : list [int ], city2 : list [int ]) -> float :
17
18
"""
18
19
Calculate the Euclidean distance between two cities (points).
19
20
"""
20
21
return math .sqrt ((city1 [0 ] - city2 [0 ]) ** 2 + (city1 [1 ] - city2 [1 ]) ** 2 )
21
22
23
+
22
24
def initialize_pheromone_matrix (size : int ) -> list [list [float ]]:
23
25
"""
24
26
Initialize the pheromone matrix with 1.0 values.
25
27
"""
26
28
return [[1.0 for _ in range (size )] for _ in range (size )]
27
29
30
+
28
31
def compute_distance_matrix (cities : dict [int , list [int ]]) -> list [list [float ]]:
29
32
"""
30
33
Precompute the distance between all cities and store them in a matrix.
@@ -38,13 +41,14 @@ def compute_distance_matrix(cities: dict[int, list[int]]) -> list[list[float]]:
38
41
dist_matrix [j ][i ] = dist
39
42
return dist_matrix
40
43
44
+
41
45
def select_next_city (
42
46
current_city : int ,
43
47
unvisited : list [int ],
44
48
pheromone : list [list [float ]],
45
49
distances : list [list [float ]],
46
50
alpha : float ,
47
- beta : float
51
+ beta : float ,
48
52
) -> int :
49
53
"""
50
54
Select the next city to visit based on pheromone levels and distances.
@@ -62,14 +66,15 @@ def select_next_city(
62
66
# Randomly select next city based on the probabilities
63
67
return random .choices (unvisited , weights = probabilities )[0 ]
64
68
69
+
65
70
def update_pheromones (
66
71
pheromone : list [list [float ]],
67
72
ants_paths : list [list [int ]],
68
73
distances : list [list [float ]],
69
74
q : float ,
70
75
evaporation_rate : float ,
71
76
best_path : list [int ],
72
- best_distance : float
77
+ best_distance : float ,
73
78
) -> tuple [list [list [float ]], list [int ], float ]:
74
79
"""
75
80
Update pheromone levels on the paths chosen by ants.
@@ -79,11 +84,13 @@ def update_pheromones(
79
84
# Evaporate pheromones
80
85
for i in range (size ):
81
86
for j in range (size ):
82
- pheromone [i ][j ] *= ( 1 - evaporation_rate )
87
+ pheromone [i ][j ] *= 1 - evaporation_rate
83
88
84
89
# Update pheromones based on ants' paths
85
90
for path in ants_paths :
86
- total_distance = sum (distances [path [i ]][path [i + 1 ]] for i in range (len (path ) - 1 ))
91
+ total_distance = sum (
92
+ distances [path [i ]][path [i + 1 ]] for i in range (len (path ) - 1 )
93
+ )
87
94
pheromone_deposit = q / total_distance
88
95
89
96
for i in range (len (path ) - 1 ):
@@ -97,28 +104,29 @@ def update_pheromones(
97
104
98
105
return pheromone , best_path , best_distance
99
106
107
+
100
108
def ant_colony_optimization (
101
109
cities : dict [int , list [int ]],
102
110
ants_num : int ,
103
111
iterations : int ,
104
112
alpha : float ,
105
113
beta : float ,
106
114
evaporation_rate : float ,
107
- q : float
115
+ q : float ,
108
116
) -> tuple [list [int ], float ]:
109
117
"""
110
118
Solve the TSP using Ant Colony Optimization (ACO).
111
119
"""
112
120
cities_num = len (cities )
113
121
if cities_num == 0 :
114
- return [], float (' inf' ) # No cities to visit
122
+ return [], float (" inf" ) # No cities to visit
115
123
116
124
# Initialize pheromone and distance matrices
117
125
pheromone = initialize_pheromone_matrix (cities_num )
118
126
distances = compute_distance_matrix (cities )
119
127
120
128
best_path = []
121
- best_distance = float (' inf' )
129
+ best_distance = float (" inf" )
122
130
123
131
for _ in range (iterations ):
124
132
all_paths = []
@@ -129,7 +137,9 @@ def ant_colony_optimization(
129
137
# Construct path for the ant
130
138
current_city = 0
131
139
while unvisited :
132
- next_city = select_next_city (current_city , unvisited , pheromone , distances , alpha , beta )
140
+ next_city = select_next_city (
141
+ current_city , unvisited , pheromone , distances , alpha , beta
142
+ )
133
143
path .append (next_city )
134
144
unvisited .remove (next_city )
135
145
current_city = next_city
@@ -139,11 +149,18 @@ def ant_colony_optimization(
139
149
140
150
# Update pheromones and track the best path found
141
151
pheromone , best_path , best_distance = update_pheromones (
142
- pheromone , all_paths , distances , q , evaporation_rate , best_path , best_distance
152
+ pheromone ,
153
+ all_paths ,
154
+ distances ,
155
+ q ,
156
+ evaporation_rate ,
157
+ best_path ,
158
+ best_distance ,
143
159
)
144
160
145
161
return best_path , best_distance
146
162
163
+
147
164
if __name__ == "__main__" :
148
165
# Example usage
149
166
best_path , best_distance = ant_colony_optimization (
@@ -153,7 +170,7 @@ def ant_colony_optimization(
153
170
alpha = 1.0 ,
154
171
beta = 5.0 ,
155
172
evaporation_rate = 0.7 ,
156
- q = 10
173
+ q = 10 ,
157
174
)
158
175
159
176
print (f"Best path: { best_path } " )
0 commit comments