蚁群算法(ACO)解决旅行商(TSP)问题的python实现

发布时间:2024年01月13日

TSP问题

旅行商问题(Travelling Salesman Problem, 简记TSP,亦称货郎担问题):设有n个城市和距离矩阵D = [dij],其中dij表示城市i到城市j的距离,i, j = 1, 2 … n,则问题是要找出遍访每个城市恰好一次的一条回路并使其路径长度为最短。说明:
回路:从某个城市出发,最后回到这个城市。

蚁群算法

蚁群算法(Ant Colony Optimization, ACO)是一种基于蚂蚁觅食行为的模拟优化算法,由意大利学者Marco Dorigo于1990年代初期提出。它是一种用来寻找优化路径的概率型算法,广泛应用于解决各种组合优化问题,如旅行商问题(TSP)、车辆路径问题(VRP)等。

基本原理
蚁群算法的灵感来源于蚂蚁在寻找食物过程中的行为模式。蚂蚁在移动时会在路径上留下信息素,而其他蚂蚁会倾向于选择信息素较浓的路径,因此这种行为形成了一种正反馈机制。在这个过程中,最短的路径上的信息素浓度增长最快,最终导致更多的蚂蚁选择这条路径。

关键概念
信息素(Pheromone):蚂蚁在路径上留下的信息素是蚁群算法的核心。蚂蚁在选择路径时会考虑信息素的浓度,信息素浓度高的路径更有可能被选择。
启发式信息(Heuristic Information):反映问题本身特征的信息,如在TSP中,两城市间距离的倒数可以作为启发式信息。
信息素更新:路径上的信息素会随着时间而挥发,同时每次迭代后根据蚂蚁走过的路径更新信息素的浓度。

蚁群算法解决TSP问题原理

启发式信息(Heuristic Information):这通常是问题本身的某些先验知识,例如在TSP中,两个城市间的距离的倒数可以作为启发式信息。
信息素(Pheromone):蚁群算法中的关键部分,模拟蚂蚁在路径上留下的信息素,以指导后来的蚂蚁选择路径。
正反馈机制:蚂蚁倾向于选择含有较多信息素的路径,而这条路径上的蚂蚁越多,留下的信息素就越多,从而吸引更多蚂蚁。
随机性:蚂蚁在选择路径时还会有一定的随机性,以避免过早地陷入局部最优解。

过程

1 初始化:随机放置一定数量的蚂蚁在不同的城市上,并初始化信息素浓度。
2 构建解决方案:每只蚂蚁根据信息素浓度和启发式信息来选择下一个访问的城市,直到构建出一个完整的路径(即访问所有城市一次)。
3 更新信息素:根据蚂蚁走过的路径和所得的解(如总路径长度)来更新路径上的信息素浓度。一般来说,路径越短,更新的信息素越多。
4 迭代循环:重复构建解决方案和更新信息素的过程,直到达到预设的迭代次数或其他停止条件。
5 输出最优解:选择在迭代过程中找到的最短路径作为TSP问题的解。
蚁群算法在求解TSP问题时特别有效,因为它能够在大规模搜索空间中有效地找到近似最优解,同时具有很好的

代码实现

我们这里代码给出了自定义数据集和dantzig42 数据集的代码

import random
import math
import numpy as np
# 读取 .tsp 文件以获取元数据
def read_tsp_file(filename):
    metadata = {}
    with open(filename, 'r') as file:
        lines = file.readlines()
        for line in lines:
            if line.startswith("DIMENSION"):
                metadata["num_cities"] = int(line.split(":")[1])
            # 可以根据需要解析其他元数据
            
    return metadata

# 读取距离矩阵文件 .d
def read_distance_matrix(filename, num_cities):
    with open(filename, 'r') as file:
        lines = file.readlines()
    
    # 解析距离矩阵
    distance_matrix = []
    for line in lines:
        row = [int(dist) for dist in line.strip().split()]
        distance_matrix.append(row)
    
    return distance_matrix

# 计算路径长度
def calculate_path_length(path, distance_matrix):
    total_distance = 0
    for i in range(len(path) - 1):
        total_distance += distance_matrix[path[i]][path[i + 1]]
    total_distance += distance_matrix[path[-1]][path[0]]  # 回到起始城市
    return total_distance

# 蚁群算法
def ant_colony_optimization(distance_matrix, num_ants, num_iterations, alpha, beta, rho):
    num_cities = len(distance_matrix)
    pheromone_matrix = [[1.0 for _ in range(num_cities)] for _ in range(num_cities)]
    best_path = None
    best_distance = float('inf')

    for _ in range(num_iterations):
        for ant in range(num_ants):
            current_city = random.randint(0, num_cities - 1)
            unvisited_cities = set(range(num_cities))
            unvisited_cities.remove(current_city)
            path = [current_city]

            while unvisited_cities:
                probabilities = []
                total_prob = 0

                for city in unvisited_cities:
                    pheromone = pheromone_matrix[current_city][city]
                    distance = distance_matrix[current_city][city]
                    prob = (pheromone ** alpha) * ((1 / distance) ** beta)
                    probabilities.append((city, prob))
                    total_prob += prob

                # 选择下一个城市
                chosen_city = None
                if total_prob > 0:
                    prob_values = [prob / total_prob for _, prob in probabilities]
                    chosen_city = random.choices(
                        [city for city, _ in probabilities],
                        prob_values
                    )[0]
                else:
                    chosen_city = random.choice(list(unvisited_cities))

                path.append(chosen_city)
                unvisited_cities.remove(chosen_city)
                current_city = chosen_city

            # 计算路径长度
            path_length = calculate_path_length(path, distance_matrix)

            # 更新最佳路径
            if path_length < best_distance:
                best_distance = path_length
                best_path = path

            # 更新信息素
            for i in range(len(path) - 1):
                pheromone_matrix[path[i]][path[i + 1]] = (1 - rho) * pheromone_matrix[path[i]][path[i + 1]] + rho
                pheromone_matrix[path[i + 1]][path[i]] = (1 - rho) * pheromone_matrix[path[i + 1]][path[i]] + rho

    return best_path, best_distance

# 主程序
if __name__ == "__main__":
    num_ants = 20
    num_iterations = 100
    alpha = 1.0
    beta = 3.0
    rho = 0.5
    #tsp_metadata = read_tsp_file("dantzig42.tsp")
    #distance_matrix = read_distance_matrix("dantzig42_d.txt", tsp_metadata["num_cities"])
    distance_matrix = np.array([
    [0, 10, 20, 15, 30],   # 城市0到其他城市的距离
    [10, 0, 25, 20, 35],   # 城市1到其他城市的距离
    [20, 25, 0, 12, 28],   # 城市2到其他城市的距离
    [15, 20, 12, 0, 22],   # 城市3到其他城市的距离
    [30, 35, 28, 22, 0]    # 城市4到其他城市的距离
     ])

    best_path, best_distance = ant_colony_optimization(distance_matrix, num_ants, num_iterations, alpha, beta, rho)

    print("最短路径:", best_path)
    print("最短距离:", best_distance)

结果展示

在这里插入图片描述

总结

蚁群算法在组合优化问题中表现出色,尤其是在动态变化的问题环境中。它已被应用于各种实际问题,如物流配送、网络路由优化、图像处理等领域。
优势与局限性
优势:蚁群算法具有强大的全局搜索能力,能够在大规模搜索空间中有效找到解决方案;同时具备良好的并行性和适应性。
局限性:蚁群算法可能需要较多的迭代次数才能收敛,且有可能陷入局部最优解。此外,算法参数的设置对结果影响较大,需要根据具体问题仔细调整。

文章来源:https://blog.csdn.net/qq_49370210/article/details/135564618
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。