072. 编写一个函数,实现简单的蚁群算法

蚁群算法(Ant Colony Optimization, ACO)是一种模拟蚂蚁觅食行为的优化算法,常用于解决组合优化问题,如旅行商问题(TSP)。

示例

假设我们有一个旅行商问题(TSP),需要找到访问多个城市并返回起点的最短路径。

蚁群算法的基本步骤

  1. 初始化:初始化信息素浓度。
  2. 蚂蚁移动:每只蚂蚁根据信息素浓度选择路径。
  3. 更新信息素:根据蚂蚁走过的路径更新信息素浓度。
  4. 迭代:重复上述步骤,直到满足终止条件(如达到最大迭代次数)。

代码

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

注意事项

  1. 参数调整:蚂蚁数量、迭代次数、信息素衰减率、信息素重要性参数(alpha)和启发式信息重要性参数(beta)等参数对算法性能有重要影响,需要根据具体问题进行调整。
  2. 启发式信息:在选择路径时,启发式信息通常是距离的倒数,也可以根据具体问题选择其他启发式信息。
  3. 信息素更新:信息素更新可以采用全局更新或局部更新策略,具体取决于问题的复杂性。
  4. 性能优化:对于大规模问题,可以使用并行计算或优化数据结构来提高算法性能。

视频讲解

BiliBili: 视睿网络-哔哩哔哩视频 (bilibili.com)