Кирсанов М.Н. Графы в Maple M.: Физматлит 2007
> | #Программа 36 c.148 |
Муравьиный алгоритм
> | restart; |
> | with(LinearAlgebra):with(plots): |
> | n:=7: Q:=5*n: Lmin:=1000: |
> | a:=9: b:=5: p:=0.7:# |
> | DWt:=Matrix(n): |
> | Wt:= Matrix(1..n,1..n,0.1):#След |
> | m:=rand(0..20): |
> | for i to n do #Координаты вершин |
> | x[i]:=m():y[i]:=m(): |
> | od: |
> | W:=Matrix(n,shape=symmetric): |
> | for i to n do # Расстояния |
> | for j from i to n do |
> | W[i,j]:=evalf(sqrt((x[i]-x[j])^2+(y[i]-y[j])^2)); |
> | od; |
> | od; |
> | for i to n do W[i,i]:=infinity: od: |
Процедура выбора наиболее вероятного направления
> | P:=proc(x) |
> | local n,sm,i,Beg,End,c,s,m,j; |
> | n:=nops(x): |
> | sm:=0: for i to n do sm:=sm+x[i]: od: |
> | c:=0: |
> | for i to n do |
> | Beg[i]:=c: End[i]:=c+x[i]/sm; c:=End[i]: |
> | od: |
> | m:=rand(0..100): |
> | s:=m()/101: |
> | for i to n do |
> | if (Beg[i]<=s) and (End[i]>=s) |
> | then j:=i: fi: |
> | od: |
> | return j; |
> | end proc: |
> |
> | for k0 to 100 do# Основной цикл |
> | for ant to n do# Цикл по муравьям |
> | s:={$1..n}: # Список непосещенных вершин |
> | j:=ant: # начальная вершина для муравья ant |
> | for j1 to n-1 do |
> | s:=s minus {j};# Tabu list увеличился |
> | sp:=[]:k1:=0: |
> | for i in s do # Каждой вершине - свой вес |
> | sp:=[op(sp),1/W[j,i]^b*Wt[j,i]^a]: k1:=k1+1: nn[k1]:=i; |
> | od: |
> | j0:=nn[P(sp)];#Выбор направления |
> | v[j1]:=j0; |
> | r[j1]:=W[j,j0]; |
> | j:=j0:# Начало следующей дуги - конец предыдущей |
> | od:#Цикл j1 по всем вершинам для ant муравья |
> | L:=add(r[i],i=1..n-1)+W[op(s),ant];#Добавляем последнюю дугу |
> | v[0]:=ant; v[n]:=ant; #Начало и конец пути |
> | v1:=seq([v[m],v[m+1]],m=0..n-1): #Дуги |
> | for i to n do #Пометка дуг феромоном |
> | DWt[op(v1[i])]:=DWt[op(v1[i])]+Q/L; |
> | od: |
> | if L<Lmin then Lmin:=L:fi:# Выбор min |
> | od:#ant |
> | Wt:=Wt+DWt*p:# Добавление новых следов |
> | Wt:=Wt*(1-p):# Испарение феромона |
> | od:# k0 |
> | Lmin; |
> | z:=i ->[x[i],y[i]]: |
> | ris:=seq(seq(PLOT(CURVES([z(i),z(j)]), THICKNESS(round((Wt[i,j]+Wt[j,i])/15))),i=1..n),j=1..n): |
> | Ver:=PLOT(seq(TEXT(map(`+`,z(i),0.5),convert(i,symbol)),i=1..n),FONT(TIMES,BOLD,14)): |
> | display(ris,Ver); |
> |