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

news2024/9/30 1:30:19

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)

结果展示

在这里插入图片描述

总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1378919.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c#多线程中使用SemaphoreSlim

SemaphoreSlim是一个用于同步和限制并发访问的类&#xff0c;和它类似的还有Semaphore&#xff0c;只是SemaphoreSlim更加的轻量、高效、好用。今天说说它&#xff0c;以及如何使用&#xff0c;在什么时候去使用&#xff0c;使用它将会带来什么优势。 代码的业务是&#xff1a…

InseRF: 文字驱动的神经3D场景中的生成对象插入

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

UE5 简易MC教程学习心得

https://www.bilibili.com/video/BV12G411J7hV?p13&spm_id_frompageDriver&vd_sourceab35b4ab4f3968642ce6c3f773f85138 ———— 目录 0.摧毁逻辑学习 1.发光材质灯方块 2.封装。想让子类 不更改父类的变量。 3.材质命名习惯。 0.摧毁逻辑学习 达到摧毁的条件…

多国管理中心多语言区块链源码一元夺宝程序仿趣步奕跑/原生计步器/原生人脸识别

前后台分开的&#xff0c;后台是TP3.2的框架了。 目前把整体UI 改版黄色系风格&#xff0c;集成了一元夺宝程序&#xff0c;用户数据同步趣步&#xff0c;效果看起来很棒&#xff0c;另外加入股票走势图&#xff08;K线图&#xff09;&#xff0c;目前已经继承人脸识别&#xf…

数据结构——二叉树(先序、中序、后序及层次四种遍历(C语言版))超详细~ (✧∇✧) Q_Q

目录 ​​​​​​​ 二叉树的定义&#xff1a; *特殊的二叉树&#xff1a; 二叉树的性质&#xff1a; 二叉树的声明&#xff1a; 二叉树的先序遍历&#xff1a; 二叉树的中序遍历&#xff1a; 二叉树的后序遍历&#xff1a; 二叉树的层序遍历&#xff1a; 二叉树的节…

【工具使用-A2B】32通道24bit传输的配置方法

一&#xff0c;简介 本文记录A2B总线上压缩为24bit的方法和如何计算是否超带宽的方法。 二&#xff0c;具体操作 2.1 计算是否超带宽的方法 确认传输带宽占比 2.2 32通道24bit配置 Downstream Compression选择Disable。 三&#xff0c;总结 本文主要介绍&#xff0c;如…

如何在Spring Boot中使用EhCache缓存

1、EhCache介绍 在查询数据的时候&#xff0c;数据大多来自于数据库&#xff0c;我们会基于SQL语句与数据库交互&#xff0c;数据库一般会基于本地磁盘IO将数据读取到内存&#xff0c;返回给Java服务端&#xff0c;我们再将数据响应给前端&#xff0c;做数据展示。 但是MySQL…

红队专题-Golang工具ChYing

Golang工具ChYing 招募六边形战士队员原chying工具代码分析并发访问控制并发 原子 写入读取 通道嵌套映射结构初始化启动代理服务器重启代理服务器 招募六边形战士队员 一起学习 代码审计、安全开发、web攻防、逆向等。。。 私信联系 原chying工具代码分析 前有 Chying 后有…

什么是云服务器,阿里云优势如何?

阿里云服务器ECS英文全程Elastic Compute Service&#xff0c;云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务&#xff0c;阿里云提供多种云服务器ECS实例规格&#xff0c;如经济型e实例、通用算力型u1、ECS计算型c7、通用型g7、GPU实例等&#xff0c;阿里云百科aliyunbai…

C++|44.智能指针

文章目录 智能指针unique_ptr特点一——无法进行复制 shared_ptr特点一——可复制特点二——计数器&#xff08;用于确定删除的时机&#xff09; 其他 智能指针 通常的指针是需要特殊地去申请对应的空间&#xff0c;并在不使用的时候还需要人工去销毁。 而智能指针相对普通的指…

2024 1.6~1.12 周报

一、上周工作 论文研读 二、本周计划 思考毕业论文要用到的方法或者思想&#xff0c;多查多看积累可取之处。学习ppt和上周组会内容、卷积神经网络。 三、完成情况 1. 数据训练的方式 1.1 迁移学习 迁移学习是一种机器学习方法&#xff0c;把任务 A 训练出的模型作为初始模…

Java8常用新特性

目录 简介 1.默认方法 2..Lambda表达式 3.Stream API 4.方法引用 5.Optional类 简介 Java 8是Java编程语言的一个重要版本&#xff0c;引入了许多令人兴奋和强大的新特性。这些特性使得Java程序更加现代化、灵活和高效。让我们一起来探索一些Java 8的常用新特性吧&#…

css3基础语法与盒模型

css3基础语法与盒模型 前言CSS3基础入门css3的书写位置内嵌式外链式导入式&#xff08;工作中几乎不用&#xff09;行内式 css3基本语法css3选择器标签选择器id选择器class类名原子类复合选择器伪类元素关系选择器序号选择器属性选择器css3新增伪类![在这里插入图片描述](https…

【Java SE语法篇】6.数组

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ 文章目录 1.数组的基本概念1.1 为什么使用数组&#xff1f;1.…

如何一键添加引号和英文逗号,然后可以放入SQL中使用 → WHERE USER_NAME IN (‘张三‘,‘李四‘,‘王五‘)

如何一键添加引号和英文逗号&#xff0c;然后可以放入SQL中使用 → WHERE USER_NAME IN&#xff08;张三,李四,王五&#xff09; 一、背景二、解决方法三、一键添加引号和英文逗号的教程 一、背景 在日常开发中&#xff0c;当处理VARCHAR或VARCHAR2类型的字段时&#xff0c;很…

【Linux实用篇】Linux常用命令(1)

目录 1.1 Linux命令初体验 1.1.1 常用命令演示 1.1.2 Linux命令使用技巧 1.1.3 Linux命令格式 1.2 文件目录操作命令 1.2.1 ls 1.2.2 cd 1.2.3 cat 1.2.4 more 1.2.5 tail 1.2.6 mkdir 1.2.7 rmdir 1.2.8 rm 1.1 Linux命令初体验 1.1.1 常用命令演示 在这一部分中…

关于鸿蒙的ArkUI的自我理解

先不说好不好上手 一些软件必要的基础概念了解 ①瓦片地图 --无或未找到 ②视频播放功能 --未找到能播放直播流&#xff08;找到个 ohos/ijkplayer不知如何&#xff09; ③支付功能 微信无 支付宝的是java代码写得&#xff0c;AskUI中如何调用 ④推送 --自己应该有吧 ⑤长…

influxdb: 元数据操作

一、写语法 https://docs.influxdata.com/influxdb/v1.7/write_protocols/line_protocol_tutorial/ 二、字段类型 https://docs.influxdata.com/influxdb/v1.7/write_protocols/line_protocol_reference/ 获取库下的表列表 SHOW MEASUREMENTS [ON <database_name>]…

MySQL的Windows系统安装

一、MySQL的Windows系统安装 1、下载MySQL安装包 打开如下链接地址&#xff0c;下载安装包 2、安装并配置 双击下载好的安装包进行安装&#xff0c;出现如下界面&#xff1a; 选择【 Full 】选项&#xff0c;然后单击【 Next 】按钮。 出现如下界面&#xff0c;单击【 Execute…

HCIA的交换机(单臂路由)

实现单臂路由的IP自动分配 实验素材&#xff1a; 实现思路&#xff1a; 交换机&#xff1a;创建VLAN10&#xff0c;VLAN20&#xff0c;将0/0/1&#xff0c;2划入相应VLAN&#xff0c;接口使用access模式&#xff0c; 要实现两个交换机之间的通信&#xff0c;须在0/0/3口使用t…