广告位联系
返回顶部
分享到

Python&Matlab实现蚂蚁群算法求解最短路径问题

python 来源:互联网 作者:秩名 发布时间:2022-03-04 22:02:56 人浏览
摘要

1 知识点 详细知识点见:智能优化算法蚁群算法(Python实现) 我们这一节知识点只讲蚁群算法求解最短路径步骤及流程。 1.1蚁群算法步骤 设蚂蚁的数量为m,地点的数量为n,地点i与地

1 知识点

详细知识点见:智能优化算法—蚁群算法(Python实现)

我们这一节知识点只讲蚁群算法求解最短路径步骤及流程。

 1.1 蚁群算法步骤

     设蚂蚁的数量为m,地点的数量为n,地点i与地点j之间相距Dij,t时刻地点i与地点j连接的路径上的信息素浓度为Sij,初始时刻每个地点间路径上的信息素浓度相等。

   蚂蚁k根据各个地点间连接路径上的信息素决定下一个目标地点,Pijk表示t时刻蚂蚁k从地点i转移的概率,概率计算公式如下:

上式中,为启发函数,,表示蚂蚁从地点i转移到地点j的期望程度;为蚂蚁k即将访问地点的集合,开始时中有n-1个元素(除出发地点),随时间的推移,蚂蚁每到达下一个地点,中的元素便减少一个,直至空集,即表示所有地点均访问完毕;a为信息素重要程度因子,值越大,表明信息素的浓度在转移中起到的作用越大,也就是说蚂蚁选择距离近的下一个地点的概率更大,β为启发函数重要程度因子。

 蚂蚁在释放信息素的同时,每个地点间连接路径上的信息素逐渐消失,用参数

 表示信息素的挥发程度。因此,当所有蚂蚁完成一次循环后,每个地点间连接路径上的信息素浓度需更新,也就是有蚂蚁路过并且留下信息素,有公式表示为:

其中,表示第k只蚂蚁在地点i与j连接路径上释放的信息素浓度;表示所有蚂蚁在地点i与j连接路径上释放的信息素浓度之和;Q为常数,表示蚂蚁循环一次所释放的信息素总量;Lk表示第k只蚂蚁经过路径的长度,总的来说,蚂蚁经过的路径越短,释放的信息素浓度越高,最终选出最短路径。 

1.2 蚁群算法程序

(1)参数初始化

在寻最短路钱,需对程序各个参数进行初始化,蚁群规模m、信息素重要程度因子α、启发函数重要程度因子β、信息素会发因子、最大迭代次数ddcs_max,初始迭代值为ddcs=1。

(2)构建解空间

将每只蚂蚁随机放置在不同的出发地点,对蚂蚁访问行为按照公式计算下一个访问的地点,直到所有蚂蚁访问完所有地点。

(3)更新信息素

计算每只蚂蚁经过的路径总长Lk,记录当前循环中的最优路径,同时根据公式对各个地点间连接路径上的信息素浓度进行更新。

(4)判断终止

迭代次数达到最大值前,清空蚂蚁经过的记录,并返回步骤(2)。

2 蚂蚁算法求解最短路径问题——Python实现

2.1 源码实现

智能优化算法—蚁群算法(Python实现)

2.2  ACA_TSP实现

补充知识点:scipy.spatial.distance.cdist

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

#============导入相关库=================

import numpy as np

from scipy import spatial

import pandas as pd

import matplotlib.pyplot as plt

from sko.ACA import ACA_TSP

  

num_points = 25

  

points_coordinate = np.random.rand(num_points, 2)  # 生成点的坐标

distance_matrix = spatial.distance.cdist(points_coordinate, points_coordinate, metric='euclidean')#函数用于计算两个输入集合的距离

  

  

def cal_total_distance(routine):

    num_points, = routine.shape

    return sum([distance_matrix[routine[i % num_points], routine[(i + 1) % num_points]] for i in range(num_points)])

  

  

#=============ACA_TSP解决==================================

  

aca = ACA_TSP(func=cal_total_distance, n_dim=num_points,

              size_pop=50, max_iter=200,

              distance_matrix=distance_matrix)

  

best_x, best_y = aca.run()

  

#=============可视化=======================

  

fig, ax = plt.subplots(1, 2)

best_points_ = np.concatenate([best_x, [best_x[0]]])

best_points_coordinate = points_coordinate[best_points_, :]

ax[0].plot(best_points_coordinate[:, 0], best_points_coordinate[:, 1], 'o-r')

pd.DataFrame(aca.y_best_history).cummin().plot(ax=ax[1])

plt.show()

3 蚂蚁算法求解最短路径问题——Matlab实现

3.1 流程图

3.2 代码实现 

下表为一些坐标点,找出最短路线:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

%蚁群算法寻找最短路径程序

%% 清空环境变量

clear

clc

%% 导入数据,导入方式,看个人习惯

zuobiao=[1304  2312

3639  1315

4177  2244

3712  1399

3488  1535

3326  1556

3238  1229

4196  1004

4312  790

4386  570

3007  1970

2562  1756

2788  1491

2381  1676

1332  695

3715  1678

3918  2179

4061  2370

3780  2212

3676  2578

4029  2838

4263  2931

3429  1908

3507  2367

3394  2643

3439  3201

2935  3240

3140  3550

2545  2357

2778  2826

2370  2975];

%% 计算城市间相互距离

n = size(zuobiao,1);%城市个数

jl = zeros(n,n);%首先求得各个坐标点的距离,这里是矩阵初始化

for i = 1:n

    for j = 1:n

        if i ~= j  %~=是不等于的意思,zuobiao矩阵中每行都有个坐标,坐标相减用i和j区分不同的坐标点,然后求两点距离

            jl(i,j) = sqrt(sum((zuobiao(i,:) - zuobiao(j,:)).^2));

%上式运算如a=[2,2;1,1]=>a(1,:)-a(2,:)=>ans =1 1,然后1?+1?=2,最后开根号

        else

            jl(i,j) = 1e-4;%相等的点相减准确说是等于0的,这里设置成了一个很小的数,是为了避免后面程序运算出错

        end

    end   

end

%% 初始化参数

m = 50;         % 蚂蚁数量,视情况而定,坐标点多的话可以适当增加蚂蚁数量

a= 1;           % 信息素重要程度因子

b= 5;           % 启发函数重要程度因子

r = 0.1;        % 信息素挥发因子

Q = 1;          % 常数

qfhs = 1./jl;    % 启发函数,将jl矩阵中每个元素转化为倒数

xxsjz = ones(n,n);       % 信息素矩阵初始化

ljjl = zeros(m,n);       % 路径记录表矩阵初始化

ddcs = 1;                % 迭代次数初值

ddcs_max = 200;          % 最大迭代次数

Lujin_best = zeros(ddcs_max,n);      % 各代最佳路径      

L_best = zeros(ddcs_max,1);     % 各代最佳路径的长度 

L_ave = zeros(ddcs_max,1);      % 各代路径的平均长度 

%% 迭代寻找最佳路径

while ddcs <= ddcs_max%在ddcs小于ddcs_max前,一直循环

%% 随机产生各个蚂蚁的起点

      start = zeros(m,1);

      for i = 1:m

          temp = randperm(n);%功能是随机打乱一个数字序列,也就是现将坐标点排号再打乱,相当于将蚂蚁随机分布在各个地点

          start(i) = temp(1);

      end

      ljjl(:,1) = start;

%% 构建解空间

      zuobiao_index = 1:n;

      % 逐个蚂蚁路径选择

      for i = 1:m

          % 逐个地点路径选择

         for j = 2:n

             yfw = ljjl(i,1:(j - 1));           % 已访问的地点集合(禁忌表)

             allow_index = ~ismember(zuobiao_index,yfw);%ismember用于判断矩阵某个元素是否存在,用法详见后文函数讲解

             allow = zuobiao_index(allow_index);  % 待访问的城市集合

             P = allow;

             % 计算城市间转移概率

             for k = 1:length(allow)

                 P(k) = xxsjz(yfw(end),allow(k))^a * qfhs(yfw(end),allow(k))^b;%见文中公式

             end

             P = P/sum(P);

             % 选择下一个访问城市

             Plj = cumsum(P);     %cumsum函数用于累加,具体用法详见后文函数讲解

             yidong_index = find(Plj >= rand);

             yidong = allow(yidong_index(1));

             ljjl(i,j) = yidong;

         end

      end

      % 计算各个蚂蚁的路径距离

      L = zeros(m,1);

      for i = 1:m

          Lujin = ljjl(i,:);

          for j = 1:(n - 1)

              L(i) = L(i) + jl(Lujin(j),Lujin(j + 1));

          end

          L(i) = L(i) + jl(Lujin(n),Lujin(1));

      end

      % 计算最短路径距离及平均距离

      if ddcs == 1

          [min_L,min_index] = min(L);

          L_best(ddcs) = min_L; 

          L_ave(ddcs) = mean(L);

          Lujin_best(ddcs,:) = ljjl(min_index,:);

      else

          [min_L,min_index] = min(L);

          L_best(ddcs) = min(L_best(ddcs - 1),min_L);

          L_ave(ddcs) = mean(L);

          if L_best(ddcs) == min_L

              Lujin_best(ddcs,:) = ljjl(min_index,:);

          else

              Lujin_best(ddcs,:) = Lujin_best((ddcs-1),:);

          end

      end

%% 更新信息素

      S = zeros(n,n);

      % 逐个蚂蚁计算

      for i = 1:m

          % 逐个城市计算

          for j = 1:(n - 1)

              S(ljjl(i,j),ljjl(i,j+1)) = S(ljjl(i,j),ljjl(i,j+1)) + Q/L(i);

          end

          S(ljjl(i,n),ljjl(i,1)) = S(ljjl(i,n),ljjl(i,1)) + Q/L(i);

      end

      xxsjz = (1-r) * xxsjz + S;

    % 迭代次数加1,清空路径记录表

    ddcs = ddcs + 1;

    ljjl = zeros(m,n);

end

%% 结果显示

[Shortest_L,index] = min(L_best);

Shortest_Lujin = Lujin_best(index,:);

disp(['最短距离:' num2str(Shortest_L)]);

disp(['最短路径:' num2str([Shortest_Lujin Shortest_Lujin(1)])]);

%% 绘图

figure(1)

plot([zuobiao(Shortest_Lujin,1);zuobiao(Shortest_Lujin(1),1)],...

     [zuobiao(Shortest_Lujin,2);zuobiao(Shortest_Lujin(1),2)],'o-');

grid on

for i = 1:size(zuobiao,1)

    text(zuobiao(i,1),zuobiao(i,2),['   ' num2str(i)]);

end

text(zuobiao(Shortest_Lujin(1),1),zuobiao(Shortest_Lujin(1),2),'       起点');

text(zuobiao(Shortest_Lujin(end),1),zuobiao(Shortest_Lujin(end),2),'       终点');

xlabel('城市位置横坐标')

ylabel('城市位置纵坐标')

title(['蚁群算法优化路径(最短距离:' num2str(Shortest_L) ')'])

figure(2)

plot(1:ddcs_max,L_best,'b',1:ddcs_max,L_ave,'r')

legend('最短距离','平均距离')

xlabel('迭代次数')

ylabel('距离')

title('各代最短距离与平均距离对比')

3.3 结果 


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://blog.csdn.net/weixin_46039719/article/details/123036600
相关文章
  • Python Django教程之实现新闻应用程序

    Python Django教程之实现新闻应用程序
    Django是一个用Python编写的高级框架,它允许我们创建服务器端Web应用程序。在本文中,我们将了解如何使用Django创建新闻应用程序。 我们将
  • 书写Python代码的一种更优雅方式(推荐!)

    书写Python代码的一种更优雅方式(推荐!)
    一些比较熟悉pandas的读者朋友应该经常会使用query()、eval()、pipe()、assign()等pandas的常用方法,书写可读性很高的「链式」数据分析处理代码
  • Python灰度变换中伽马变换分析实现

    Python灰度变换中伽马变换分析实现
    1. 介绍 伽马变换主要目的是对比度拉伸,将图像灰度较低的部分进行修正 伽马变换针对的是对单个像素点的变换,也就是点对点的映射 形
  • 使用OpenCV实现迷宫解密的全过程

    使用OpenCV实现迷宫解密的全过程
    一、你能自己走出迷宫吗? 如下图所示,可以看到是一张较为复杂的迷宫图,相信也有人尝试过自己一点一点的找出口,但我们肉眼来解谜
  • Python中的数据精度问题的介绍

    Python中的数据精度问题的介绍
    一、python运算时精度问题 1.运行时精度问题 在Python中(其他语言中也存在这个问题,这是计算机采用二进制导致的),有时候由于二进制和
  • Python随机值生成的常用方法

    Python随机值生成的常用方法
    一、随机整数 1.包含上下限:[a, b] 1 2 3 4 import random #1、随机整数:包含上下限:[a, b] for i in range(10): print(random.randint(0,5),end= | ) 查看运行结
  • Python字典高级用法深入分析讲解
    一、 collections 中 defaultdict 的使用 1.字典的键映射多个值 将下面的列表转成字典 l = [(a,2),(b,3),(a,1),(b,4),(a,3),(a,1),(b,3)] 一个字典就是一个键对
  • Python浅析多态与鸭子类型使用实例
    什么多态:同一事物有多种形态 为何要有多态=》多态会带来什么样的特性,多态性 多态性指的是可以在不考虑对象具体类型的情况下而直
  • Python字典高级用法深入分析介绍
    一、 collections 中 defaultdict 的使用 1.字典的键映射多个值 将下面的列表转成字典 l = [(a,2),(b,3),(a,1),(b,4),(a,3),(a,1),(b,3)] 一个字典就是一个键对
  • Python淘宝或京东等秒杀抢购脚本实现(秒杀脚本

    Python淘宝或京东等秒杀抢购脚本实现(秒杀脚本
    我们的目标是秒杀淘宝或京东等的订单,这里面有几个关键点,首先需要登录淘宝或京东,其次你需要准备好订单,最后要在指定时间快速
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计