072. 编写一个函数,实现简单的蚁群算法
蚁群算法(Ant Colony Optimization, ACO)是一种模拟蚂蚁觅食行为的优化算法,常用于解决组合优化问题,如旅行商问题(TSP)。
示例
假设我们有一个旅行商问题(TSP),需要找到访问多个城市并返回起点的最短路径。
蚁群算法的基本步骤
- 初始化:初始化信息素浓度。
- 蚂蚁移动:每只蚂蚁根据信息素浓度选择路径。
- 更新信息素:根据蚂蚁走过的路径更新信息素浓度。
- 迭代:重复上述步骤,直到满足终止条件(如达到最大迭代次数)。
代码
import numpy as np
import random
# 计算城市之间的距离矩阵
def calculate_distance_matrix(cities):
num_cities = len(cities)
distance_matrix = np.zeros((num_cities, num_cities))
for i in range(num_cities):
for j in range(i + 1, num_cities):
distance = np.linalg.norm(cities[i] - cities[j])
distance_matrix[i][j] = distance
distance_matrix[j][i] = distance
return distance_matrix
# 蚁群算法
def ant_colony_optimization(cities, num_ants, num_iterations, decay, alpha=1, beta=2):
"""
蚁群算法解决 TSP 问题
:param cities: 城市坐标列表
:param num_ants: 蚂蚁数量
:param num_iterations: 迭代次数
:param decay: 信息素衰减率
:param alpha: 信息素重要性参数
:param beta: 启发式信息重要性参数
:return: 最短路径和路径长度
"""
num_cities = len(cities)
distance_matrix = calculate_distance_matrix(cities)
pheromone_matrix = np.ones((num_cities, num_cities))
best_path = None
best_path_length = float('inf')
for iteration in range(num_iterations):
all_paths = []
all_path_lengths = []
for ant in range(num_ants):
path = [random.randint(0, num_cities - 1)] # 随机选择起始城市
visited = set(path)
while len(visited) < num_cities:
current_city = path[-1]
probabilities = np.zeros(num_cities)
for next_city in range(num_cities):
if next_city not in visited:
probabilities[next_city] = (pheromone_matrix[current_city][next_city] ** alpha) * \
((1.0 / distance_matrix[current_city][next_city]) ** beta)
probabilities /= np.sum(probabilities)
next_city = np.random.choice(range(num_cities), p=probabilities)
path.append(next_city)
visited.add(next_city)
path_length = sum(distance_matrix[path[i]][path[i + 1]] for i in range(num_cities - 1)) + \
distance_matrix[path[-1]][path[0]]
all_paths.append(path)
all_path_lengths.append(path_length)
if path_length < best_path_length:
best_path = path
best_path_length = path_length
# 更新信息素
pheromone_matrix *= decay
for path, path_length in zip(all_paths, all_path_lengths):
for i in range(num_cities - 1):
pheromone_matrix[path[i]][path[i + 1]] += 1.0 / path_length
pheromone_matrix[path[-1]][path[0]] += 1.0 / path_length
print(f"Iteration {iteration + 1}: Best Path Length = {best_path_length:.2f}")
return best_path, best_path_length
# 示例用法
if __name__ == "__main__":
# 城市坐标
cities = 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_ants = 10
num_iterations = 100
decay = 0.8
alpha = 1
beta = 2
best_path, best_path_length = ant_colony_optimization(cities, num_ants, num_iterations, decay, alpha, beta)
print(f"Best Path: {best_path}")
print(f"Best Path Length: {best_path_length:.2f}")
代码说明
城市坐标:定义了城市坐标,每个城市是一个二维坐标点。
距离矩阵:计算城市之间的欧几里得距离矩阵。
信息素矩阵:初始化信息素浓度矩阵,初始值为 1。
蚂蚁移动:
-
每只蚂蚁根据信息素浓度和启发式信息(距离的倒数)选择路径。
-
使用轮盘赌选择法选择下一个城市。
信息素更新:
-
每次迭代后,根据蚂蚁走过的路径更新信息素浓度。
-
信息素浓度会逐渐衰减,以避免算法过早收敛。
迭代:重复上述步骤,直到达到最大迭代次数。
示例输出
Iteration 1: Best Path Length = 1234.56
Iteration 2: Best Path Length = 1123.45
...
Iteration 100: Best Path Length = 987.65
Best Path: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
Best Path Length: 987.65
注意事项
- 参数调整:蚂蚁数量、迭代次数、信息素衰减率、信息素重要性参数(alpha)和启发式信息重要性参数(beta)等参数对算法性能有重要影响,需要根据具体问题进行调整。
- 启发式信息:在选择路径时,启发式信息通常是距离的倒数,也可以根据具体问题选择其他启发式信息。
- 信息素更新:信息素更新可以采用全局更新或局部更新策略,具体取决于问题的复杂性。
- 性能优化:对于大规模问题,可以使用并行计算或优化数据结构来提高算法性能。
视频讲解
BiliBili: 视睿网络-哔哩哔哩视频 (bilibili.com)