蚁群算法求解TSP问题的源程序及简要说明

蚁群算法求解TSP问题的源程序及简要说明,第1张

该程序试图对具有31个城市的VRP进行求解,已知的最优解为784.1,我用该程序只能优化到810左右,返茄应该是陷入局部最优,但我不知问题出在什么地方。请用过蚁群算法的高手指教。

蚁群算法的matlab源码,同时请指出为何不能优化漏庆察到已知的最好解

%

%

%the procedure of ant colony algorithm for VRP

%

%%%%%%%%%%%

%initialize the parameters of ant colony algorithms

load data.txt

d=data(:,2:3)

g=data(:,4)

m=31% 蚂蚁

alpha=1

belta=4% 决定tao和miu重要性的参数

lmda=0

rou=0.9%衰减系数

q0=0.95

% 概率

tao0=1/(31*841.04)%初始信息

Q=1% 蚂蚁循环一周所释放的信息素

defined_phrm=15.0 % initial pheromone level value

QV=100 % 车辆容量

vehicle_best=round(sum(g)/QV)+1%所完成任务所需的最少车数

V=40

% 计算两点的距离

for i=1:32

for j=1:32

dist(i,j)=sqrt((d(i,1)-d(j,1))^2+(d(i,2)-d(j,2))^2)

end

end

%给tao miu赋初值

for i=1:32

for j=1:32

if i~=j

%s(i,j)=dist(i,1)+dist(1,j)-dist(i,j)

tao(i,j)=defined_phrm

miu(i,j)=1/dist(i,j)

end

end

end

for k=1:32

for k=1:32

deltao(i,j)=0

end

end

best_cost=10000

for n_gen=1:50

print_head(n_gen)

for i=1:m

%best_solution=[]

print_head2(i)

sumload=0

cur_pos(i)=1

rn=randperm(32)

n=1

nn=1

part_sol(nn)=1

%cost(n_gen,i)=0.0

n_sol=0 % 由蚂蚁产生的路径数量

M_vehicle=500

t=0 %最佳路径数组的元素数为0

while sumload<=QV

for k=1:length(rn)

if sumload+g(rn(k))<=QV

gama(cur_pos(i),rn(k))=(sumload+g(rn(k)))/QV

A(n)=rn(k)

n=n+1

end

end

fid=fopen('out_customer.txt','a+')

fprintf(fid,'%s %i\t','the current position is:',cur_pos(i))

fprintf(fid,'\n%s','the possible customer set is:')

fprintf(fid,'\t%i\n',A)

fprintf(fid,'差辩------------------------------\n')

fclose(fid)

p=compute_prob(A,cur_pos(i),tao,miu,alpha,belta,gama,lmda,i)

maxp=1e-8

na=length(A)

for j=1:na

if p(j)>maxp

maxp=p(j)

index_max=j

end

end

old_pos=cur_pos(i)

if rand(1)<q0

cur_pos(i)=A(index_max)

else

krnd=randperm(na)

cur_pos(i)=A(krnd(1))

bbb=[old_pos cur_pos(i)]

ccc=[1 1]

if bbb==ccc

cur_pos(i)=A(krnd(2))

end

end

tao(old_pos,cur_pos(i))=taolocalupdate(tao(old_pos,cur_pos(i)),rou,tao0)%对所经弧进行局部更新

sumload=sumload+g(cur_pos(i))

nn=nn+1

part_sol(nn)=cur_pos(i)

temp_load=sumload

if cur_pos(i)~=1

rn=setdiff(rn,cur_pos(i))

n=1

A=[]

end

if cur_pos(i)==1 % 如果当前点为车场,将当前路径中的已访问用户去掉后,开始产生新路径

if setdiff(part_sol,1)~=[]

n_sol=n_sol+1 % 表示产生的路径数,n_sol=1,2,3,..5,6...,超过5条对其费用加上车辆的派遣费用

fid=fopen('out_solution.txt','a+')

fprintf(fid,'%s%i%s','NO.',n_sol,'条路径是:')

fprintf(fid,'%i ',part_sol)

fprintf(fid,'\n')

fprintf(fid,'%s','当前的用户需求量是:')

fprintf(fid,'%i\n',temp_load)

fprintf(fid,'------------------------------\n')

fclose(fid)

% 对所得路径进行路径内3-opt优化

final_sol=exchange(part_sol)

for nt=1:length(final_sol)% 将所有产生的路径传给一个数组

temp(t+nt)=final_sol(nt)

end

t=t+length(final_sol)-1

sumload=0

final_sol=setdiff(final_sol,1)

rn=setdiff(rn,final_sol)

part_sol=[]

final_sol=[]

nn=1

part_sol(nn)=cur_pos(i)

A=[]

n=1

end

end

if setdiff(rn,1)==[]% 产生最后一条终点不为1的路径

n_sol=n_sol+1

nl=length(part_sol)

part_sol(nl+1)=1%将路径的最后1位补1

% 对所得路径进行路径内3-opt优化

final_sol=exchange(part_sol)

for nt=1:length(final_sol)% 将所有产生的路径传给一个数组

temp(t+nt)=final_sol(nt)

end

cost(n_gen,i)=cost_sol(temp,dist)+M_vehicle*(n_sol-vehicle_best) %计算由蚂蚁i产生的路径总长度

for ki=1:length(temp)-1

deltao(temp(ki),temp(ki+1))=deltao(temp(ki),temp(ki+1))+Q/cost(n_gen,i)

end

if cost(n_gen,i)<best_cost

best_cost=cost(n_gen,i)

old_cost=best_cost

best_gen=n_gen % 产生最小费用的代数

best_ant=i%产生最小费用的蚂蚁

best_solution=temp

end

if i==m %如果所有蚂蚁均完成一次循环,,则用最佳费用所对应的路径对弧进行整体更新

for ii=1:32

for jj=1:32

tao(ii,jj)=(1-rou)*tao(ii,jj)

end

end

for kk=1:length(best_solution)-1

tao(best_solution(kk),best_solution(kk+1))=tao(best_solution(kk),best_solution(kk+1))+deltao(best_solution(kk),best_solution(kk+1))

end

end

fid=fopen('out_solution.txt','a+')

fprintf(fid,'%s%i%s','NO.',n_sol,'路径是:')

fprintf(fid,'%i ',part_sol)

fprintf(fid,'\n')

fprintf(fid,'%s %i\n','当前的用户需求量是:',temp_load)

fprintf(fid,'%s %f\n','总费用是:',cost(n_gen,i))

fprintf(fid,'------------------------------\n')

fprintf(fid,'%s\n','最终路径是:')

fprintf(fid,'%i-',temp)

fprintf(fid,'\n')

fclose(fid)

temp=[]

break

end

end

end

end

我现在也在研究它,希望能共同进步.建义可以看一下段海滨的关于蚁群算法的书.讲的不错,李士勇的也可以,还有一本我在图书馆见过,记不得名字了.

蚁群算法(ant colony optimization, ACO),又称蚂蚁算法,是一种用来在图中寻找优化路径的机率型技术。它由岁没茄Marco Dorigo于1992年在他的博士论文中引入,其灵感来源于蚂蚁在寻找食物过程中发现路径的行为。

为什么小小的蚂蚁能够找到食物?他们具有智能么?设想,如果我们要为蚂蚁设计一个人工智能的程序,那么这个程序要多么复杂呢?首先,你要让蚂蚁能够避开障碍物,就必须根据适当的地形给它编进指令让他们能够巧妙的避开障碍物,其次,要让蚂蚁找到食物,就需要让他们遍历空间上的所有点;再次,如果要让蚂蚁找到最短的路径,那么需要计算所有可能的路径并且比较它们的大小,而且更重要的是,你要小心翼翼的编程,因为程序的错误也许会让你前功尽弃。这是多么不可思议的程序!太复杂了,恐怕没人能够完成这样繁琐冗余的程序。

然而,事实并没有你想得那么复杂,上面这个程序每个蚂蚁的核心程序编码不过100多行!为什么这么简单的程序会让蚂蚁干这样复杂的事情?答案是:简单规则的涌现。事实上,每只蚂蚁并不是像我们想象的需要知道整个世界的信息,他们其实只关心很小范围内的眼前信息,而且根据这些局部信息利用几条简单的规则进行决策,这样,在蚁群这个集体里,复杂性的行为就会凸现出来。这就乎察是人工生命、复杂性科学解释的规律!那么,这些简单规则是什么呢?下面详细说明:

1、范围:

蚂蚁观察到的范围是一个方格世界,蚂蚁有一个参数为速度半径(一般是3),那么它能观察到的范围就是3*3个方格世界,并且能移动的距离也在这个范围之内。

2、环境:

蚂蚁所在的环境是一个虚拟的世界,其中有障碍物,有别的蚂蚁,还有信息素,信息素有两种,一种是找到食物的蚂蚁洒下的食物信息素,一种是找到窝的蚂蚁洒下的窝的信息素。每个蚂蚁都仅仅能感知它范围内的环境信息。环境以一定的速率让信息素消失。

3、觅食规则:

在每只蚂蚁能感知的范围内寻找是否有食物,如果有就直接过去。否则看是否有信息素,并且比较在能感知的范围内哪一点的信息素最多,这样,它就朝信息素多的地方走,并且每只蚂蚁多会以小概率犯错误,从而并不是往信息素最多的点移动。蚂蚁找窝的规则和上面一样,只不过它对窝的信息素做出反应,而对食物信息素没反应。

4、移动规则:

每只蚂蚁都朝向信息素最多的方向移,并且,当周围没有信息素指引的时候,蚂蚁会按照自己原来运动的方向惯性的运动下去,并且,在运动的方向有一个随机的小的扰动。为了防止蚂蚁原地转圈,它会记住最近刚走过了哪些点,如果发现要走的下一点已经在最近走过了,它就会尽量避开。

5、避障规则:

如果蚂蚁要移动的方向有障碍物挡住,它会随机的选择另一个方向,并且有信息素指引的话,它会按照觅食的规则行为。

7、播撒信息素规则:

每只蚂蚁在刚找到食物或者窝的时候撒发的信息素最多,并随着它走远的距离,播撒的信息素越来越少。

根据这几条规则,蚂蚁之间并没有直接的关系,但是每只蚂蚁都和环境发生交互,而通过信息素这个纽带,实际上把各个蚂蚁之间关联起来了。比如,当一只蚂蚁找到了食物,它并没有直接告诉其它蚂蚁这儿有食物,而是向环境播撒信息素,当其它的蚂蚁经过它附近的时候,就会感觉到信息素的存在,进而根据信息素的指引找到了食物。

说了这么多,蚂蚁究竟是怎么找到食物的呢?

在没有蚂蚁找到食物的时候,环境没有有用的信息素,那么蚂蚁为什么会相对有效的找到食物呢?这要归功于蚂蚁的移动规则,尤其是在没有信息素时候的移动规则。首先,它要能尽量保持某种惯性,这样使得蚂蚁尽量向前方移动(开始,这个前方是随机固定的一个方向),而不是原地无谓的打转或者震动;其次,蚂蚁要有一定的随机性,虽然有了固定的方向,但它也不能像粒子一样直线运动下去,而是有一个随机的干扰。这样就使得蚂蚁运动起来具有了一定的目的性,尽量保持原来的方向,但又有新的试探,尤其当碰到障碍物的时候它会察迅立即改变方向,这可以看成一种选择的过程,也就是环境的障碍物让蚂蚁的某个方向正确,而其他方向则不对。这就解释了为什么单个蚂蚁在复杂的诸如迷宫的地图中仍然能找到隐蔽得很好的食物。

当然,在有一只蚂蚁找到了食物的时候,其他蚂蚁会沿着信息素很快找到食物的。

蚂蚁如何找到最短路径的?这一是要归功于信息素,另外要归功于环境,具体说是计算机时钟。信息素多的地方显然经过这里的蚂蚁会多,因而会有更多的蚂蚁聚集过来。假设有两条路从窝通向食物,开始的时候,走这两条路的蚂蚁数量同样多(或者较长的路上蚂蚁多,这也无关紧要)。当蚂蚁沿着一条路到达终点以后会马上返回来,这样,短的路蚂蚁来回一次的时间就短,这也意味着重复的频率就快,因而在单位时间里走过的蚂蚁数目就多,洒下的信息素自然也会多,自然会有更多的蚂蚁被吸引过来,从而洒下更多的信息素……;而长的路正相反,因此,越来越多地蚂蚁聚集到较短的路径上来,最短的路径就近似找到了。也许有人会问局部最短路径和全局最短路的问题,实际上蚂蚁逐渐接近全局最短路的,为什么呢?这源于蚂蚁会犯错误,也就是它会按照一定的概率不往信息素高的地方走而另辟蹊径,这可以理解为一种创新,这种创新如果能缩短路途,那么根据刚才叙述的原理,更多的蚂蚁会被吸引过来。

引申:

跟着蚂蚁的踪迹,你找到了什么?通过上面的原理叙述和实际 *** 作,我们不难发现蚂蚁之所以具有智能行为,完全归功于它的简单行为规则,而这些规则综合起来具有下面两个方面的特点:

1、多样性

2、正反馈

多样性保证了蚂蚁在觅食的时候不置走进死胡同而无限循环,正反馈机制则保证了相对优良的信息能够被保存下来。我们可以把多样性看成是一种创造能力,而正反馈是一种学习强化能力。正反馈的力量也可以比喻成权威的意见,而多样性是打破权威体现的创造性,正是这两点小心翼翼的巧妙结合才使得智能行为涌现出来了。

引申来讲,大自然的进化,社会的进步、人类的创新实际上都离不开这两样东西,多样性保证了系统的创新能力,正反馈保证了优良特性能够得到强化,两者要恰到好处的结合。如果多样性过剩,也就是系统过于活跃,这相当于蚂蚁会过多的随机运动,它就会陷入混沌状态;而相反,多样性不够,正反馈机制过强,那么系统就好比一潭死水。这在蚁群中来讲就表现为,蚂蚁的行为过于僵硬,当环境变化了,蚂蚁群仍然不能适当的调整。

既然复杂性、智能行为是根据底层规则涌现的,既然底层规则具有多样性和正反馈特点,那么也许你会问这些规则是哪里来的?多样性和正反馈又是哪里来的?我本人的意见:规则来源于大自然的进化。而大自然的进化根据刚才讲的也体现为多样性和正反馈的巧妙结合。而这样的巧妙结合又是为什么呢?为什么在你眼前呈现的世界是如此栩栩如生呢?答案在于环境造就了这一切,之所以你看到栩栩如生的世界,是因为那些不能够适应环境的多样性与正反馈的结合都已经死掉了,被环境淘汰了!

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"><HEAD>

<meta http-equiv="Content-Type" content="text/htmlcharset=gb2312" />

<style>

.ant{

position:absolute

background-color:#000000

overflow:hidden

width:2px

height:2px

}

.food{

position:absolute

background-color:#0000ff

overflow:hidden

width:2px

height:2px

}

.nest{

position:absolute

background-color:#ff0000

overflow:hidden

width:2px

height:2px

}

</style>

<script type="text/JavaScript">

//============================

//系统参数初始化

//----------------------------

//生命体数量与轨迹长度

Unit=10Path=30

//生命体速度上下限

v0=2vM=10

//生命体加速度变化范围

Kr=0.1Kv=0.1*(vM-v0)

//生命体运动范围

x0=0xM=document.documentElement.clientWidth

y0=0yM=document.documentElement.clientHeight

//生命体出生地(巢穴)

xi0=x0+(xM-x0)*Math.random()

yi0=y0+(yM-y0)*Math.random()

str0='<div class="ant" style="left:'+xi0+'top:'+yi0+'"></div>'

//食物所在地

xf=x0+(xM-x0)*Math.random()

yf=y0+(yM-y0)*Math.random()

//气味感知范围

R_2=5*5

//============================

var r=new Array()

var v=new Array()

var dr=new Array()

var dv=new Array()

var x=new Array()

var y=new Array()

var life=new Array()

//单击暂停

var xi0,yi0,xf,yf

var Time0,str0

window.status='pause'

function document.onclick(){

if(window.status=='pause'){

window.status=0

nest.style.left=xi0

nest.style.top=yi0

food.style.left=xf

food.style.top=yf

//测试初始化时间用

Time0=(new Date()).getTime()

init(0)

}else{

window.status='pause'

}

}

//窗口大小调整后刷新页面以调整系统参数

function window.onresize(){

//window.location.href=document.location

}

//初始化函数

function init(i){

if(window.status!='pause'&&i<Unit){

if(!life){

document.body.appendChild(life=document.createElement(str0))

x=xi0

y=yi0

r=Math.random()

v=1/Math.random()

dr=Kr*Math.random()

dv=Kv*Math.random()

}

Move(i)

window.status=i+1

setTimeout('init('+(i+1)+')',i)

//}else{

//alert('生成耗时:'+((new Date()).getTime()-Time0)+'ms')

}

}

//运动函数

Total=Unit*Path

P2=2*Math.PI

function Move(i){

if(window.status!='pause'){

k=i%Unit

X=x[k]

Y=y[k]

R=r[k]

V=v[k]

if(!life){

str='<div class="ant" style="left:'+X+'top:'+Y+'"></div>'

document.body.appendChild(life=document.createElement(str))

}

obj=life

R+=dr[k]*(2*Math.random()-1)

V+=dv[k]*(2*Math.random()-1)

X+=Math.sin(P2*R)*V

Y+=Math.cos(P2*R)*V

//遇到食物原路返回并减小角度变化

distance=(X-xf)*(X-xf)+(Y-yf)*(Y-yf)

if(distance<R_2){

R+=0.5

r/=2

v*=2

}

distance=(X-xi0)*(X-xi0)+(Y-yi0)*(Y-yi0)

if(distance<R_2){

R+=0.5

r/=2

v*=2

}

/*----------------------------------

/*================================*/

//碰撞边界反d

R=(X<x0||X>xM)?-R:R

R=(Y<y0||Y>yM)?0.5-R:R

X=x[k]+Math.sin(P2*R)*V

Y=y[k]+Math.cos(P2*R)*V

/*================================*/

//溢出边界重生(类似流星效果)

if(X<x0||X>xM||Y<y0||Y>yM){

X=xi0

Y=yi0

}

/*----------------------------------

/*================================*/

//边界限制

x[k]=X=(X<x0)?x0:(X>xM)?xM-2:X

y[k]=Y=(Y<y0)?y0:(Y>yM)?yM-2:Y

r[k]=R>1?R-1:R<0?R+1:R

v[k]=V=(V<v0)?v0:((V<vM)?V:vM)

/*================================*/

obj.style.left=x[k]=X

obj.style.top=y[k]=Y

setTimeout('Move('+(i+Unit)%Total+')',Unit)

}

}

//根据浏览器自动加载动画

switch(navigator.appName.toLowerCase()){

case "netscape":

window.addEventListener("load",document.onclick,false)

break

case "microsoft internet explorer":

default:

window.attachEvent("onload",document.onclick)

break

}

</script>

</head>

<body scroll="no">

<div id="food" class="food"></div>

<div id="nest" class="nest"></div>

</body>

</html>

这里使用蚁群算法求函数的最大值,函数是:

步骤如下:

下面是主函数:

程序运行结果绘图如下,其中歼锋晌蓝色点为第一代蚁群,基笑红色为最后一代蚁群:

函数说明如下:

下面计算函数的状态转氏锋移概率,进行局部搜索和全局搜索:

之后约束边界:

最后进行选择:

初始化蚁群函数:

计算目标函数值函数:

绘制函数图像函数:


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12455238.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存