实验6 蚁群算法求解tsp问题

传送门(所有的实验都使用python实现)

实验1 BP神经网络实验

实验2 som网实验

实验3 hopfield实现八皇后问题

实验4 模糊搜索算法预测薄冰厚度

实验5 遗传算法求解tsp问题

实验6 蚁群算法求解tsp问题

实验7 粒子群优化算法求解tsp问题

实验8 分布估计算法求解背包问题

实验9 模拟退火算法求解背包问题

实验10 禁忌搜索算法求解tsp问题

一、实验目的

理解并使用蚁群算法

二、实验内容

实现基于蚁群算法的旅行商路线寻找

三、实验环境

使用Python3.0 在 eclipse进行编辑

四、实验步骤

1、输入介绍:

    城市总数目为30,每个城市的坐标以(x,y)表示,x,y的取值均为0~30的随机数。

2、初始群体设定:

随机产生n条长度为m的数组。n代表个体数目,m代表城市个数。在本次实验中设定n=10,m=30。且同一个体中的m个数互不相同,因为每个城市只经过一次。

3、信息素强度初始化:

根据使用贪心算法所得到的路径len,初始化每条边信息素含量为m/len;本次实验计算可得len=300,m=30,故初始化每条边信息素含量为0.1;

   

4、路线寻找:

    每只蚂蚁随机选择一个出发点,根据下面公式计算下个点的概率,并采用轮盘赌方式决定。决定的过程中不断更新禁忌表。

5.  信息素更新:

当所有蚂蚁成功行走出路线后,采用下列公式对于每条边进行信息素更新。为使得信息素更新明显,设置信息素强度Q=10000,挥发率p=0.1;

6.终止条件

    分别进行5,20,50,100次迭代后终止。

运行截图:

5次迭代总距离:193.52

20次迭代总距离:143.708

50次迭代总距离:150.60

100次迭代总距离:140.136

五、总结

信息素强度的设置会直接影响到算法的迭代次数与效率,若强度设置的过低就会导致挥发速度比蚂蚁更新速度还快,最后导致最优路线上的信息素丢失,失去最优解。若强度设置过高,会影响启发式信息的比重,找到的解并非较优解。经过多次实验,我设置信息素强度为1万。

    与遗传算法比较,个人觉得蚁群算法的效率高于遗传算法,遗传算法中的随机因素太多,导致最优解的寻找比较久,蚁群算法对于路径的寻找虽然有轮盘赌的随机因素,但是信息素和启发式信息的影响有起到一定的纠正作用。

python源码

#coding:gbk
import random
import math
import matplotlib.pyplot as plt
global n,m,best,Q;
global br;
best = 10000;           #best记录最优距离,初始化无限大
n=10;m=30;          #n:样本个数    m:城市个数
road = [[0]*(m) for i in range(n)]   #开辟n*m的数组记录每个只蚂蚁行走的路线
tau = [[0]*(m) for i in range(n)]   #禁忌表
con = [[0]*(m) for i in range(m)]     #记录信息素浓度
dis =  [[0]*(m) for i in range(m)]     #邻接矩阵记录两点间的距离
game = [0.0]*m;                        #轮盘赌的概率
value = [0.0]*n;                        #value数组记录每只蚂蚁的路线长度
way =[0]*m;                          #way数组记录最优解路线
class no:                       #该类表示每个点的坐标
    def __init__(self,x,y):
        self.x=x;
        self.y=y;
p=[];
def draw(t):              #该函数用于描绘路线图
    x=[0]*(m+1);y=[0]*(m+1);
    for i in range(m):
        x[i] =p[t[i]].x;
        y[i] =p[t[i]].y;
    x[m] =p[t[0]].x;
    y[m] =p[t[0]].y;
    plt.plot(x,y,color='r',marker='*' ); 
    plt.show();
def  mycol():                           #城市坐标输入
        p.append(no( 8 , 20 ));
        p.append(no( 28 , 6 )); p.append(no( 27 , 24 )); p.append(no( 25 , 20 )); p.append(no( 5 , 14 )); p.append(no( 18 , 4 )); p.append(no( 21 , 22 ));
        p.append(no( 19 , 17 )); p.append(no( 28 , 22 )); p.append(no( 16 , 18 )); p.append(no( 28 , 28 )); p.append(no( 11 , 28 )); p.append(no( 29 , 28 ));
        p.append(no( 15 , 22 )); p.append(no( 25 , 24 )); p.append(no( 9 , 22 )); p.append(no( 17 , 16 )); p.append(no( 12 , 16 )); p.append(no( 5 , 21 ));
        p.append(no( 6 , 6 )); p.append(no( 12 , 21 )); p.append(no( 11 , 28 )); p.append(no( 20 , 22 )); p.append(no( 17 , 10 )); p.append(no( 18 , 6 ));
        p.append(no( 18 , 9 )); p.append(no( 25 , 24 )); p.append(no( 24 , 11 )); p.append(no( 25 , 12 )); p.append(no( 0 , 28 ));
def  get_dis(a,b):       #返回a,b两城市的距离
    return   math.sqrt((p[a].x-p[b].x) *(p[a].x-p[b].x) +(p[a].y-p[b].y) *(p[a].y-p[b].y));
def get_value(t):        #计算蚂蚁t的路线长度
    ans = 0.0;
    for i in range(1,m):     #两点距离公式
        ans += math.sqrt((p[t[i]].x-p[t[i-1]].x) *(p[t[i]].x-p[t[i-1]].x)  +(p[t[i]].y-p[t[i-1]].y) *(p[t[i]].y-p[t[i-1]].y));
    ans +=  math.sqrt((p[t[0]].x-p[t[m-1]].x) * (p[t[0]].x-p[t[m-1]].x)  +(p[t[0]].y-p[t[m-1]].y) *(p[t[0]].y-p[t[m-1]].y));
    return ans;
def init():            #初始化函数
    for i in range(m):
        for j in range(m):
            con[i][j] = 0.1;             #初始化所有信息素为0.03
            dis[i][j]=get_dis(i,j);
def rws():                                      #轮盘赌函数
    num = random.random();
    r = 0.0;
    for i in range(m):
        r += game[i];
        if(r >= num): return i;
    return m-1;
def move(x,loc):              #蚂蚁x从loc位置爬行到下一个点
    tol=0.0
    pk = [0.0]*m;
    for i in range(m):
        if(tau[x][i] != 1and dis[loc][i] !=0):    #概率计算
                pk[i] = con[loc][i]*(1/dis[loc][i])*(1/dis[loc][i]);
        else:
            pk[i]=0;
        tol += pk[i];
    if(tol == 0):           #启发式信息的总和为0,br标记迭代结束
        tol=1;br=0;       
    for i in range(m):    #分配轮盘赌的概率
        game[i] =pk[i]/tol;
    return rws();       #返回轮盘赌的选择
def slove():
    global best,br;
    for i in range(n):
        for j in range(m):
            tau[i][j] = 0;       #初始化禁忌表
    for i in range(n):
        num = random.randint(0,m-1);    #随机选择出发地点
        tau[i][num]=1;   road[i][0] = num;
    for k in range(m-1):
        for i in range(n):
            ob = move(i,road[i][k]);      #向前移动一步
            tau[i][ob]=1;road[i][k+1] = ob;     #更新禁忌表
    if(br == 0):          #br=0说明迭代已经到达终点,函数结束
        return;
    for i in range(n):               #计算每只蚂蚁路径长度
        value[i]=get_value(road[i]);
        if(value[i] < best):       #更新记录最优解
            best = value[i];
            for j in range(m):
                way[j]= road[i][j];     
            
    for i in range(m):               #挥发过程,每次挥发0.1
        for j in range(m):
            con[i][j]*=0.9;
    for i in range(n):               #信息素更新
        for j in range(m-1):
            a=road[i][j];  b=road[i][j+1];
            con[a][b] += Q/value[i];                #Q为信息素强度
    for i in range(m-1):
            a=road[i][m-1];  b=road[i][0];
            con[a][b] += Q/value[i];
        
mycol();            #数据输入    
init();                 #数据初始化
Q=10000;        #信息素强度设置
br = 1;             #迭代开始标记
for i in range(100):      #控制迭代次数
    if(br == 0):
        break;
    slove();
print(round(best,3));       #打印最优解距离,保留三位小数
draw(way);                      #画图描绘路线
print(way);                     #打印路线,以序列表示
        
  • 8
    点赞
  • 121
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Blaze Jack

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

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

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

打赏作者

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

抵扣说明:

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

余额充值