蚁群算法(Ant Colony Optimization,ACO)讲解+代码实现

1.蚁群算法来源

蚁群算法(Ant Colony Optimization,简称ACO)是一种模拟自然界中蚂蚁寻找食物路径行为的优化算法,主要用于解决组合优化问题。它的灵感来源于意大利学者Marco Dorigo在1992年提出的蚂蚁系统模型

蚁群算法的灵感来源于自然界中蚂蚁寻找食物的行为。蚂蚁在寻找食物的过程中会释放一种称为信息素的化学物质,这种物质会在蚂蚁走过的路径上留下痕迹,后续的蚂蚁会根据这些信息素的浓度来选择路径,从而形成一条从蚁巢到食物源的最短路径。蚂蚁觅食的过程是一个正反馈的过程,该路段经过的蚂蚁越多,信息素留下的就越多,浓度越高,更多的蚂蚁都会选择这个路段。

这种行为模式启发了科学家们设计出蚁群算法,用于解决复杂的优化问题。

2.蚁群算法基本原理

蚁群算法的基本原理可以概括为以下几个步骤:

(1)初始化:设定每个解(相当于蚂蚁可能行走的路径)的信息素初始值,通常设置为一个较小的正数。
(2)蚂蚁构建解:每只蚂蚁根据当前的信息素浓度和启发式信息(如距离的倒数)来选择下一步要走的路径。这个过程是概率性的,信息素浓度越高,被选中的概率越大。
(3)信息素更新:一轮搜索结束后,根据蚂蚁找到的解的质量来更新信息素。通常情况下,较优的解对应的路径上的信息素会被加强,而较差解对应的信息素则会减少或蒸发。
(4)循环迭代:重复上述过程,直到满足停止条件(如达到最大迭代次数或解的质量不再明显提高)。
通过这样的机制,蚁群算法能够在解空间中逐渐逼近最优解。需要注意的是,蚁群算法是一种
随机优化算法,每次运行可能会得到不同的结果,但多次运行后往往能够找到接近最优的解。

数学原理:

3.蚁群算法的应用

蚁群算法的应用非常广泛,包括旅行商问题(TSP)图着色问题网络路由优化调度问题等。它特别适合于解决大规模的复杂的优化问题,尤其是那些难以用传统数学方法求解的问题。

下面简单介绍一些经典的应用

(1)旅行商问题(TSP):最初被用于解决TSP问题,即在给定一组城市中找到最短的巡回路径。

(2)物流和交通:用于优化物流配送路径、车辆路径规划和交通信号控制等问题。

(3)网络路由:在计算机网络和通信网络中,用于动态路由选择以提高网络效率。

(4)生产调度:在制造业中,用于优化生产计划和调度,减少生产成本和时间。

(5)图像处理:用于图像分割、边缘检测等图像处理任务。

(6)图着色问题

4.蚁群算法解决TSP问题

旅行商问题(Traveling saleman problem, TSP)是物流配送的典型问题,其求解有十分重要的理论和现实意义。

旅行商问题传统的解决方法都是遗传算法,但是遗传算法的收敛速度慢,具有一定的缺陷。

在求解TSP蚁群算法中,每只蚂蚁相互独立,用于构造不同的路线,蚂蚁之间通过信息素进行交流,合作求解。

动图展示TSP问题求解过程:

下面介绍一下具体流程:

(1)初始化参数:epochs表示迭代次数,ants表示蚂蚁数量,alphabeta是信息素重要程度的参数,rho是信息素挥发速度,Q是信息素强度常数。

(2)计算城市之间的距离矩阵:使用numpy的linalg.norm函数计算每对城市之间的欧几里得距离,并将结果存储在Distance矩阵中。

(3)初始化信息素矩阵Tau:将所有元素设置为1.0。

(4)初始化每只蚂蚁的路线图Route:创建一个ants x cities的零矩阵,表示每只蚂蚁访问过的城市。

(5)进行迭代:对于每次迭代,首先为每只蚂蚁随机选择一个起始城市,然后根据概率选择下一个要访问的城市。概率由信息素浓度和启发式信息共同决定。

(6)计算每只蚂蚁的总距离:遍历每只蚂蚁的路线,累加经过的城市之间的距离。

(7)更新最优解:如果当前迭代中找到了一条更短的路径,就更新最优距离和最优路线。

(8)更新信息素:根据蚂蚁走过的路径,更新信息素矩阵Tau。

(9)输出结果:打印出找到的最短路径和对应的距离。

程序中各符号说明如下表格:

变量/矩阵名称

维度

描述

position

(cities, 2)

城市坐标数组,每行代表一个城市的x和y坐标。

Distance

(cities, cities)

城市之间的距离矩阵,存储每两个城市之间的欧几里得距离。

Eta

(cities, cities)

启发式信息矩阵,是Distance矩阵的倒数,用于指导蚂蚁选择路径。

Tau

(cities, cities)

信息素矩阵,表示在每两个城市之间的路径上的信息素浓度。

Route

(ants, cities)

蚂蚁路径矩阵,存储每一只蚂蚁在当前迭代中的路径。

best_distance

1

变量,存储迄今为止找到的最短路径的长度。

best_route

(cities,)

数组,存储迄今为止找到的最短路径的城市顺序。

epochs

1

算法运行的迭代次数。

ants

1

蚁群中蚂蚁的数量。

alpha

1

信息素重要性的影响因子。

beta

1

启发式信息重要性的影响因子。

rho

1

信息素蒸发率。

Q

1

信息素强度,用于在每次迭代后更新信息素矩阵。

最终结果展示:

完整python代码如下:

import numpy as np
import random

# 城市坐标
x = np.array([51, 27, 56, 21, 4, 6, 58, 71, 54, 40, 94, 18, 89, 33, 12, 25, 24, 58, 71, 94, 17, 38, 13, 82, 12, 58, 45, 11, 47, 4])
y = np.array([14, 81, 67, 92, 64, 19, 98, 18, 62, 69, 30, 54, 10, 46, 34, 18, 42, 69, 61, 78, 16, 40, 10, 7, 32, 17, 21, 26, 35, 90])
position = np.column_stack((x, y))

epochs = 50
ants = 50
alpha = 1.4
beta = 2.2
rho = 0.15
Q = 10**6
cities = position.shape[0]

# 城市之间的距离矩阵
Distance = np.ones((cities, cities))
for i in range(cities):
    for j in range(cities):
        if i != j:
            Distance[i, j] = np.linalg.norm(position[i] - position[j])
        else:
            Distance[i, j] = np.finfo(float).eps

Eta = 1.0 / Distance
Tau = np.ones((cities, cities))

# 每只蚂蚁的路线图
Route = np.zeros((ants, cities))
best_distance = np.inf
best_route = np.zeros(cities)

for epoch in range(epochs):
    # 为每只蚂蚁随机选择一个唯一的起始城市
    start_cities = np.random.permutation(cities).tolist()
    for i in range(ants):
        Route[i, 0] = start_cities[i % cities]

    for j in range(1, cities):
        for i in range(ants):
            Visited = Route[i, :j]
            NoVisited = np.setdiff1d(np.arange(cities), Visited)
            P = np.zeros(len(NoVisited))
            for k in range(len(NoVisited)):
                P[k] = (Tau[int(Visited[-1]), int(NoVisited[k])] ** alpha) * (Eta[int(Visited[-1]), int(NoVisited[k])] ** beta)
            P = P / P.sum()
            Pcum = np.cumsum(P)
            select = np.where(Pcum >= random.random())[0][0]
            to_visit = NoVisited[select]
            Route[i, j] = to_visit

    Distance_epoch = np.zeros(ants)
    for i in range(ants):
        R = Route[i, :]
        for j in range(cities - 1):
            Distance_epoch[i] += Distance[int(R[j]), int(R[j + 1])]
        Distance_epoch[i] += Distance[int(R[0]), int(R[-1])]

    best_distance_epoch = np.min(Distance_epoch)
    best_index_epoch = np.argmin(Distance_epoch)
    if best_distance_epoch < best_distance:
        best_distance = best_distance_epoch
        best_route = Route[best_index_epoch, :]

    Delta_Tau = np.zeros((cities, cities))
    for i in range(ants):
        for j in range(cities - 1):
            Delta_Tau[int(Route[i, j]), int(Route[i, j + 1])] += Q / Distance_epoch[i]
        Delta_Tau[int(Route[i, 0]), int(Route[i, -1])] += Q / Distance_epoch[i]

    Tau = (1 - rho) * Tau + Delta_Tau

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

MATLAB代码如下:

动图显示路径部分

function DrawRoute(C, R)
N = length(R);
scatter(C(:, 1), C(:, 2));
hold on
plot([C(R(1), 1), C(R(N), 1)], [C(R(1), 2), C(R(N), 2)], 'g');
for ii = 2: N
    hold on
    plot([C(R(ii - 1), 1), C(R(ii), 1)], [C(R(ii - 1), 2), C(R(ii), 2)], 'g');
    pause(0.1)
    frame = getframe(gcf);
    imind = frame2im(frame);
    [imind, cm] = rgb2ind(imind, 256);
    if ii == 2
        imwrite(imind, cm, 'test.gif', 'gif', 'Loopcount', inf, 'DelayTime', 1e-4);
    else
        imwrite(imind, cm, 'test.gif', 'gif', 'WriteMode', 'append', 'DelayTime', 1e-4);
    end
end
title('旅行商规划');

蚁群算法部分:

clear;
clc;
x=[51 27 56 21 4 6 58 71 54 40 94 18 89 33 12 25 24 58 71 94 17 38 13 82 12 58 45 11 47 4]';
y=[14 81 67 92 64 19 98 18 62 69 30 54 10 46 34 18 42 69 61 78 16 40 10 7 32 17 21 26 35 90]';
position = 100 * randn(40, 2);
% position = [x, y];
epochs = 50;
ants = 50;
alpha = 1.4;
beta = 2.2;
rho = 0.15;Q = 10^6;
cities = size(position, 1);
% 城市之间的距离矩阵
Distance = ones(cities, cities);
for i = 1: cities
    for j = 1: cities
        if i ~= j
            Distance(i, j) = ((position(i, 1) - position(j, 1))^2 + (position(i, 2) - position(j, 2))^2)^0.5;
        else
            Distance(i, j) = eps;
        end
        Distance(j, i) = Distance(i, j);
    end
end
Eta = 1./Distance;
Tau = ones(cities, cities);
% 每只蚂蚁的路线图
Route = zeros(ants, cities);
epoch = 1;
% 记录每回合最优城市
R_best = zeros(epochs, cities);
L_best = inf .* ones(epochs, 1);
L_ave = zeros(epochs, 1);
% 开始迭代
while epoch <= epochs
    % 随机位置
    RandPos = [];
    for i = 1: ceil(ants / cities)
        RandPos = [RandPos, randperm(cities)];
    end
    Route(:, 1) = (RandPos(1, 1:ants))';
    for j = 2:cities
        for i = 1: ants
            Visited = Route(i, 1:j-1);
            NoVisited = zeros(1, (cities - j + 1));
            P = NoVisited;
            num = 1;
            for k = 1: cities
                if length(find(Visited == k)) == 0
                    NoVisited(num) = k;
                    num = num + 1;
                end
            end
            for k = 1: length(NoVisited)
                P(k) = (Tau(Visited(end), NoVisited(k))^alpha) * (Eta(Visited(end), NoVisited(k))^beta);
            end
            P = P / sum(P);
            Pcum = cumsum(P);
            select = find(Pcum >= rand);
            to_visit = NoVisited(select(1));
            Route(i, j) = to_visit;
        end
    end
    if epoch >= 2
        Route(1, :) = R_best(epoch - 1, :);
    end
    Distance_epoch = zeros(ants, 1);
    for i = 1: ants
        R = Route(i, :);
        for j = 1: cities - 1
            Distance_epoch(i) = Distance_epoch(i) + Distance(R(j), R(j + 1));
        end
        Distance_epoch(i) = Distance_epoch(i) + Distance(R(1), R(cities));
    end
    L_best(epoch) = min(Distance_epoch);
    pos = find(Distance_epoch == L_best(epoch));
    R_best(epoch, :) = Route(pos(1), :);
    L_ave(epoch) = mean(Distance_epoch);
    epoch = epoch + 1;
    
    Delta_Tau = zeros(cities, cities);
    for i = 1: ants
        for j = 1: (cities - 1)
            Delta_Tau(Route(i, j), Route(i, j + 1)) = Delta_Tau(Route(i, j), Route(i, j + 1)) + Q / Distance_epoch(i);
        end
        Delta_Tau(Route(i, 1), Route(i, cities)) = Delta_Tau(Route(i, 1), Route(i, cities)) + Q / Distance_epoch(i);
    end
    Tau = (1 - rho) .* Tau + Delta_Tau;
    Route = zeros(ants, cities);
end
%% 结果展示
Pos = find(L_best == min(L_best));
Short_Route = R_best(Pos(1), :);
Short_Length = L_best(Pos(1), :);
figure
% subplot(121);
DrawRoute(position, Short_Route);
% subplot(122);
% plot(L_best);
% hold on
% plot(L_ave, 'r');
% title('平均距离和最短距离');

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

应急响应——勒索病毒

先上搜索引擎上搜 也可以用360来杀 但是都无法解密 可以解密的&#xff1a; linux

LeNet原理及代码实现

目录 1.原理及介绍 2.代码实现 2.1model.py 2.2model_train.py 2.3model.test.py 1.原理及介绍 2.代码实现 2.1model.py import torch from torch import nn from torchsummary import summaryclass LeNet(nn.Module):def __init__(self):super(LeNet, self).__init__…

uniapp 去掉小数末尾多余的0

文章目录 在uniapp或者一般的JavaScript环境中&#xff0c;要去掉小数末尾的0&#xff0c;可以使用以下几种方法&#xff1a; 使用parseFloat()函数 let num 123.4500; let result parseFloat(num); console.log(result); // 输出: 123.45字符串处理 将数字转换为字符串&am…

02day-C++学习(const 指针与引用的关系 inline nullptr)

02day-C学习 1. 使用const注意事项 注意事项 • 可以引⽤⼀个const对象&#xff0c;但是必须⽤const引⽤。const引⽤也可以引⽤普通对象&#xff0c;因为对象的访 问权限在引⽤过程中可以缩⼩&#xff0c;但是不能放⼤。 • 不需要注意的是类似 int& rb a3; double d 1…

代码随想录——合并区间(Leecode LCR74)

题目链接 贪心 排序 class Solution {public int[][] merge(int[][] intervals) {ArrayList<int[]> res new ArrayList<>();// 先将数组按照左区间排序Arrays.sort(intervals, new Comparator<int[]>() {public int compare(int[] intervals1, int[] in…

模板语法之插值语法{{}}——01

<主要研究&#xff1a;{{ 这里可以写什么}} 1.在data中声明的变量函数都可以 2.常量 3.只要是合法的JavaScript的表达式&#xff0c;都可以 4. 模板表达式都被放在沙盒中&#xff0c;只能访问全局变量的一个白名单&#xff0c;如 Math 和 Date <body> <div i…

STM32智能仓库管理系统教程

目录 引言环境准备智能仓库管理系统基础代码实现&#xff1a;实现智能仓库管理系统 4.1 数据采集模块 4.2 数据处理与控制算法 4.3 通信与网络系统实现 4.4 用户界面与数据可视化应用场景&#xff1a;仓库管理与优化问题解决方案与优化收尾与总结 1. 引言 智能仓库管理系统通…

深入理解循环神经网络(RNN)

深入理解循环神经网络&#xff08;RNN&#xff09; 循环神经网络&#xff08;Recurrent Neural Network, RNN&#xff09;是一类专门处理序列数据的神经网络&#xff0c;广泛应用于自然语言处理、时间序列预测、语音识别等领域。本文将详细解释RNN的基本结构、工作原理以及其优…

国际网课平台Udemy上的亚马逊云科技AWS免费高分课程和创建、维护EC2动手实践

亚马逊云科技(AWS)是全球云行业最&#x1f525;火的云平台&#xff0c;在全球经济形势不好的大背景下&#xff0c;通过网课学习亚马逊云科技AWS基础备考亚马逊云科技AWS证书&#xff0c;对于找工作或者无背景转行做AWS帮助巨大。欢迎大家关注小李哥&#xff0c;及时了解世界最前…

香橙派AIpro初体验:搭建无线随身NAS

文章目录 1.引言2. 香橙派 AIPro概述3. 开发准备3.0 烧录镜像3.1 需要准备的硬件3.2 需要准备的软件3.3 启动并连接香橙派 AIPro3.3.1 初始化启动香橙派 AIPro3.3.2 无线连接香橙派 AIPro3.3.3.3 VNC连接香橙派 AIPro 3.4 设置固定ip3.4.1 设置开机自动连接WIFI3.4.1 设置香橙派…

遍历请求后端数据引出的数组forEach异步操作的坑

有一个列表数据&#xff0c;每项数据里有一个额外的字段需要去调另外一个接口才能拿到&#xff0c;后端有现有的这2个接口&#xff0c;现在临时需要前端显示出来&#xff0c;所以这里需要前端先去调列表数据的接口拿到列表数据&#xff0c;然后再遍历请求另外一个接口去拿到对应…

springboot封装请求参数json的源码解析

源码位置&#xff1a; org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver#readWithMessageConverters(org.springframework.http.HttpInputMessage, org.springframework.core.MethodParameter, java.lang.reflect.Type…

Java PKI Programmer‘s Guide

一、PKI程序员指南概述 PKI Programmer’s Guide Overview Java认证路径API由一系列类和接口组成&#xff0c;用于创建、构建和验证认证路径。这些路径也被称作认证链。实现可以通过基于提供者的接口插入。 这个API基于密码服务提供者架构&#xff0c;这在《Java密码架构参考指…

c++入门基础篇(上)

目录 前言&#xff1a; 1.c&#xff0b;&#xff0b;的第一个程序 2.命名空间 2.1 namespace的定义 2.2 命名空间使用 3.c&#xff0b;&#xff0b;输入&输出 4.缺省参数 5.函数重载 前言&#xff1a; 我们在之前学完了c语言的大部分语法知识&#xff0c;是不是意…

springboot驾校管理系统-计算机毕业设计源码49777

驾校管理系统 摘 要 驾校管理系统是一个基于Spring Boot框架开发的系统&#xff0c;旨在帮助驾校提高管理效率和服务水平。该系统主要实现了用户管理、年月类型管理、区域信息管理、驾校信息管理、车辆信息管理、报名信息管理、缴费信息管理、财务信息管理、教练分配管理、更换…

微搭低代码从入门到实战01创建数据源

目录 1 创建数据源2 创建字段总结 很多零基础的想学习低代码开发&#xff0c;苦于没有编程的经验感觉入门困难。本次教程就按照我们日常开发的思路&#xff0c;从浅入深逐步拆解一下低代码该如何学习。 开发软件&#xff0c;不管是管理后台还是小程序&#xff0c;先需要规划好数…

忘记Apple ID密码怎么退出苹果ID账号?

忘记Apple ID密码怎么退出账号&#xff1f;Apple ID对每个苹果用户来说都是必不可少的&#xff0c;没有它&#xff0c;用户就不能享受iCloud、App Store、iTunes等服务。苹果手机软件下载、丢失解锁、恢复出厂设置等都需要使用Apple ID。如果忘记Apple ID 密码&#xff0c;这会…

C语言 结构体和共用体——结构体和数组的嵌套

目录 结构体和数组的相互嵌套​编辑 嵌套的结构体 嵌套结构体变量的初始化 结构体数组的定义和初始化 结构体和数组的相互嵌套 嵌套的结构体 在一个结构体内包含了另一个结构体作为其成员 嵌套结构体变量的初始化 STUDENT stu1 {100310121, " 王刚 ", M, {1991…

【Java 的四大引用详解】

首先分别介绍一下这几种引用 强引用&#xff1a; 只要能通过GC ROOT根对象引用链找到就不会被垃圾回收器回收&#xff0c;当所有的GC Root都不通过强引用引用该对象时&#xff0c;才能被垃圾回收器回收。 软引用&#xff08;SoftReference&#xff09;&#xff1a; 当只有软引…

打开ps提示dll文件丢失如何解决?教你几种靠谱的方法

在日常使用电脑过程中&#xff0c;由于不当操作&#xff0c;dll文件丢失是一种常见现象。当dll文件丢失时&#xff0c;程序将无法正常运行&#xff0c;比如ps&#xff0c;pr等待软件。此时&#xff0c;我们需要对其进行修复以恢复其功能&#xff0c;下面我们一起来了解一下出现…