蚁群算法(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('平均距离和最短距离');

蚁群算法Ant Colony OptimizationACO)是一种模拟蚂蚁寻找食物的行为进行优化的算法。下面是一个在C#中实现蚁群算法的示例代码: ```csharp using System; using System.Collections.Generic; class AntColonyOptimization { private int numAnts; // 蚂蚁数量 private int numCities; // 城市数量 private double[,] distanceMatrix; // 城市间距离矩阵 private double[,] pheromoneMatrix; // 信息素矩阵 private double alpha; // 信息素重要程度因子 private double beta; // 启发式因子 private double evaporationRate; // 信息素挥发率 private double initialPheromone; // 初始信息素浓度 private int maxIterations; // 最大迭代次数 public AntColonyOptimization(int numAnts, int numCities, double[,] distanceMatrix, double alpha, double beta, double evaporationRate, double initialPheromone, int maxIterations) { this.numAnts = numAnts; this.numCities = numCities; this.distanceMatrix = distanceMatrix; this.alpha = alpha; this.beta = beta; this.evaporationRate = evaporationRate; this.initialPheromone = initialPheromone; this.maxIterations = maxIterations; InitializePheromoneMatrix(); } private void InitializePheromoneMatrix() { pheromoneMatrix = new double[numCities, numCities]; for (int i = 0; i < numCities; i++) { for (int j = 0; j < numCities; j++) { pheromoneMatrix[i, j] = initialPheromone; } } } public List<int> FindShortestPath() { List<int> shortestPath = null; double shortestDistance = double.MaxValue; for (int iteration = 0; iteration < maxIterations; iteration++) { List<List<int>> antPaths = ConstructAntPaths(); UpdatePheromoneMatrix(antPaths); foreach (var path in antPaths) { double distance = CalculatePathDistance(path); if (distance < shortestDistance) { shortestDistance = distance; shortestPath = path; } } EvaporatePheromoneMatrix(); } return shortestPath; } private List<List<int>> ConstructAntPaths() { List<List<int>> antPaths = new List<List<int>>(); for (int ant = 0; ant < numAnts; ant++) { List<int> path = new List<int>(); bool[] visited = new bool[numCities]; int currentCity = new Random().Next(numCities); path.Add(currentCity); visited[currentCity] = true; while (path.Count < numCities) { int nextCity = ChooseNextCity(currentCity, visited); path.Add(nextCity); visited[nextCity] = true; currentCity = nextCity; } antPaths.Add(path); } return antPaths; } private int ChooseNextCity(int currentCity, bool[] visited) { double[] probabilities = new double[numCities]; double totalProbability = 0; for (int city = 0; city < numCities; city++) { if (!visited[city]) { probabilities[city] = Math.Pow(pheromoneMatrix[currentCity, city], alpha) * Math.Pow(1.0 / distanceMatrix[currentCity, city], beta); totalProbability += probabilities[city]; } } double randomValue = new Random().NextDouble(); for (int city = 0; city < numCities; city++) { if (!visited[city]) { probabilities[city] /= totalProbability; if (randomValue <= probabilities[city]) { return city; } randomValue -= probabilities[city]; } } return -1; } private void UpdatePheromoneMatrix(List<List<int>> antPaths) { for (int i = 0; i < numCities; i++) { for (int j = 0; j < numCities; j++) { if (i != j) { pheromoneMatrix[i, j] *= (1 - evaporationRate); foreach (var path in antPaths) { if (path.Contains(i) && path.Contains(j)) { pheromoneMatrix[i, j] += 1.0 / CalculatePathDistance(path); } } } } } } private void EvaporatePheromoneMatrix() { for (int i = 0; i < numCities; i++) { for (int j = 0; j < numCities; j++) { pheromoneMatrix[i, j] *= (1 - evaporationRate); } } } private double CalculatePathDistance(List<int> path) { double distance = 0; for (int i = 0; i < path.Count - 1; i++) { distance += distanceMatrix[path[i], path[i + 1]]; } return distance; } } ``` 上述代码实现了一个AntColonyOptimization类,可以用于解决旅行商问题。其中numAnts表示蚂蚁数量,numCities表示城市数量,distanceMatrix表示城市间距离矩阵,alpha和beta分别表示信息素重要程度因子和启发式因子,evaporationRate表示信息素挥发率,initialPheromone表示初始信息素浓度,maxIterations表示最大迭代次数。 你可以根据需要修改以上代码,并使用以下示例进行测试: ```csharp class Program { static void Main(string[] args) { int numAnts = 10; int numCities = 5; double[,] distanceMatrix = new double[,] { { 0, 2, 1, 3, 4 }, { 2, 0, 4, 1, 2 }, { 1, 4, 0, 5, 2 }, { 3, 1, 5, 0, 3 }, { 4, 2, 2, 3, 0 } }; double alpha = 1.0; double beta = 2.0; double evaporationRate = 0.5; double initialPheromone = 1.0; int maxIterations = 100; AntColonyOptimization aco = new AntColonyOptimization(numAnts, numCities, distanceMatrix, alpha, beta, evaporationRate, initialPheromone, maxIterations); List<int> shortestPath = aco.FindShortestPath(); Console.WriteLine("Shortest Path: " + string.Join(" -> ", shortestPath)); Console.WriteLine("Shortest Distance: " + aco.CalculatePathDistance(shortestPath)); } } ``` 希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小梁不秃捏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值