查看: 123|回復: 3|關注: 0
打印 上一主題 下一主題

[已解決] 蟻群算法MMAS的相關求教

[復制鏈接]

新手

9 麥片

財富積分


050


2

主題

8

帖子

0

最佳答案
可以說這篇代碼是在論壇上一別的大神的基礎上修改的 先貼代碼如下:

clear all;
clc
t0 = clock;%開始計時
citys=xlsread('POI信息表.xls','Sheet1');
[m2]=size(citys,1);
D=zeros(m2,m2);
IV=0;
for i=1:m2
    for j=1:m2
        IV=abs(citys(i,8)-(citys(i,9)+citys(i,10)))*log(citys(i,8)/(citys(i,9)+citys(i,10)));
    end
end
for i=1:m2
    for j=1:m2
        if citys(i,8)==1
            citys(i,8)=0.99;
            citys(i,10)=0.01;
        end
    end
end
for i=1:m2
    for j=1:m2
        if i~=j
            D(i,j)=sqrt((1-(abs(citys(i,8)-(citys(i,9)+citys(i,10)))*log(citys(i,8)/(citys(i,9)+citys(i,10)))+ abs(citys(j,8)-(citys(j,9)+citys(j,10)))*log(citys(j,8)/(citys(j,9)+citys(j,10)))/IV))*((citys(i,1)-citys(j,1))^2+(citys(i,2)-citys(j,2)).^2)+(abs(citys(i,8)-(citys(i,9)+citys(i,10)))*log(citys(i,8)/(citys(i,9)+citys(i,10)))+ abs(citys(j,8)-(citys(j,9)+citys(j,10)))*log(citys(j,8)/(citys(j,9)+citys(j,10)))/IV)*(citys(i,11)-citys(j,11))^2+(citys(i,12)-citys(j,12))^2+(citys(i,13)-citys(j,13))^2+(citys(i,14)-citys(j,14))^2+(citys(i,15)-citys(j,15))^2);
        else
            D(i,j)=1e-4;
        end
    end
end
ratings=xlsread('用戶評分表.xls','Sheet1');
[m1,n1]=size(ratings);
% 注意,svd算法當中要求不能是稀疏矩陣 [U,S,V]=svd(ratings)
item_Sim=zeros(n1,n1);
u1=xlsread('用戶評分平均值表.xls','Sheet2');


for i=1:n1
    for k=i+1:n1
        for j=1:m1
            if ~isnan(ratings(j,i))&&~isnan(ratings(j,k))
                current_sum=0;
                current_sum=current_sum+(ratings(j,i)-u1(1,i))*(ratings(j,k)-u1(1,k));
                for i1=1:n1
                    for j1=1:n1
                        item_Sim(i1,j1)=current_sum;
                    end
                end
            end
        end
    end
end
item_Sim1=zeros(n1,n1);



for i=1:n1
    for k=i+1:n1
        for j=1:m1
            if ~isnan(ratings(j,i))&&~isnan(ratings(j,k))
                current_sum1=0;
                current_sum2=0;
               current_sum1=current_sum1+(ratings(j,i)-u1(1,i))^2;
               current_sum2=current_sum2+(ratings(j,k)-u1(1,k))^2;
               for i2=1:n1
                   for j2=1:n1
                       item_Sim1(i2,j2)=sqrt(current_sum1*current_sum2);
                   end
               end
            end
        end
    end
end
for i3=1:n1
    for j3=1:n1
        item_Sim(i3,j3)=item_Sim(i3,j3)/item_Sim1(i3,j3);
    end
end   
Sim=zeros(n1,n1);
for i=1:n1
    for j=1:n1
        Sim(i,j)=item_Sim(i,j)/(1+D(i,j));
    end
end
% for i=1:n
%     for j=1:n
%         if i~=j
%             D(i,j)=sqrt(sum((citys(i,:)-citys(j,:)).^2));
%     
%             else
%             D(i,j)=1e-4;%用很小的值代替0 公式需要
%         end
%     end

%end

%3.初始化參數
m=16;%螞蟻數量
alpha=1;%信息素重要程度因子
beta=2;%啟發函數重要程度因子
rho=0.1;%信息素揮發因子
Q=1;%常系數
Eta=1./Sim;%啟發函數
Tau=1000*ones(n1,n1);%信息素矩陣
Table=zeros(m,n1);%路徑記錄表 M個螞蟻走過的路徑
iter=1;%迭代次數初值
iter_max=2000;
Route_best=zeros(iter_max,n1);%各代最佳路徑
Length_best=zeros(iter_max,1);%各代最佳路徑的長度
Length_ave=zeros(iter_max,1);%各代路徑的平均長度
q0=rand(1,1);
current_max=0;

%4.迭代尋找最佳路徑
while iter<=iter_max
    %隨機產生各個螞蟻的起點城市
    start=zeros(m,1);
    for i=1:m %50個螞蟻隨機產生的起始城市位置
        temp=randperm(n1);
        start(i)=temp(1);
    end
    Table(:,1)=start;%初始位置
    citys_index=1:n1;%城市索引取出來
    %逐個螞蟻路徑選擇
    for i=1:m
        %逐個城市路徑選擇
        for j=2:n1  %第一只螞蟻第一次已經隨機選擇了一個城市,因此從2開始
            tabu=Table(i,1:(j-1));%已訪問的城市集合(禁忌表)
            allow_index=~ismember(citys_index,tabu);%沒有訪問過的城市取出來
            allow=citys_index(allow_index);%待訪問的城市集合
            P=allow;
            %計算城市間轉移概率
%          if q0>0.95
              for ii=1:length(allow)
                    P(ii)=Tau(tabu(end),allow(ii))^alpha*Eta(tabu(end),allow(ii))^beta;%end代表最后一個元素,對應公式
              end
              P=P/sum(P);
            %輪盤賭法選擇下一個訪問城市
              Pc=cumsum(P);
              target_index=find(Pc>=rand);
              target=allow(target_index(1));
              Table(i,j)=target;%記錄下來,添加新訪問的城市
%             else
%                 for iii=1:length(allow)
%                     P(iii)=Tau(tabu(end),allow(iii))*Eta(tabu(end),allow(iii))^beta;%end代表最后一個元素,對應公式
%                     current_max=P(iii);
%                     if current_max>P(iii)
%                         P(iii)=current_max;
%                     end
%                 end
%             end
        end
    end
    if iter>=2
        Table(1,:)=Route_best(iter-1,:);        
    end
    %計算各個螞蟻的距離路徑
    Length=zeros(m,1);
    for i=1:m
        Route=Table(i,:);%每一個螞蟻的路徑取出來
        for j=1:(n1-1)
            Length(i)=Length(i)+Sim(Route(j),Route(j+1));
        end
            Length(i)=Length(i)+Sim(Route(n1),Route(1));
    end
    %計算最短距離及平均距離
    if iter==1
        [min_Length,min_index]=min(Length);
        Length_best(iter)=min_Length;
        Length_ave(iter)=mean(Length);
        Route_best(iter,:)=Table(min_index,:);
    else
        [min_Length,min_index]=min(Length);
         Length_best(iter)=min(Length_best(iter-1),min_Length);
         Length_ave(iter)=mean(Length);
         if Length_best(iter)==min_Length
             Route_best(iter,:)=Table(min_index,:);
         else
             Route_best(iter,:)=Route_best((iter-1),:);
         end
    end

    gb_length=min(Length_best);
    TauMax=1/(rho*gb_length);
    pbest=0.05;                       %%pbest設置為0.05  
    pbest=power(pbest,1/n1);
    TauMin=TauMax*(1-pbest)/((n1/2-1)*pbest);


    %更新信息素
    Delta_Tau=zeros(n1,n1);
    %逐個螞蟻計算
     for i=1:m
        %逐個城市計算
        for j=1:(n1-1)
            Delta_Tau(Table(i,j),Table(i,j+1))=Delta_Tau(Table(i,j),Table(i,j+1))+Q/Length(i);
        end
            Delta_Tau(Table(i,n1),Table(i,1))=Delta_Tau(Table(i,n1),Table(i,1))+Q/Length(i);
     end
     Tau=(1-rho).*Tau+Delta_Tau;

   for i=1:n1
    for j=1:n1
        if Tau(i,j)>TauMax
            Tau(i,j)=TauMax;
        else if Tau(i,j)<TauMin
                Tau(i,j)=TauMin;
            end
        end
    end
   end

    %迭代次數加一,清空路徑記錄表
    Table=zeros(m,n1);
    iter=iter+1;

end
%5結果顯示
[ Shortest_Length,index]=min(Length_best);
Shortest_Route=Route_best(index,:);
Time_Cost=etime(clock,t0);
disp(['最優路徑距離:' num2str(Shortest_Length)]);
disp(['最優路徑:' num2str([Shortest_Route Shortest_Route(1)])]);
disp(['程序執行時間:' num2str(Time_Cost) '秒']);

%6.繪圖
figure(1)
plot([citys(Shortest_Route,1);citys(Shortest_Route(1),1)],...
    [citys(Shortest_Route,2);citys(Shortest_Route(1),2)],'o-');
grid on
for i=1:size(citys,1)
    text(citys(i,1),citys(i,2),['' num2str(i) ]);
end
text(citys(Shortest_Route(1),1),citys(Shortest_Route(1),2),' 起點');
text(citys(Shortest_Route(end),1),citys(Shortest_Route(end),2),' 終點');
xlabel('故宮poi位置橫坐標');
ylabel('故宮poi位置縱坐標');
title(['蟻群算法優化路徑(最優路徑距離:' num2str(Shortest_Length) ')']);
figure(2)
plot(1:iter_max,Length_best,'b',1:iter_max,Length_ave,'r:');
legend('最優路徑距離','平均距離');
xlabel('迭代次數');
ylabel('距離');
title('各代最優距離與平均距離對比');

新手

9 麥片

財富積分


050


2

主題

8

帖子

0

最佳答案
2#
 樓主| 發表于 7 天前 | 只看該作者
然后注釋掉一下的代碼,
  for i=1:n1
    for j=1:n1
        if Tau(i,j)>TauMax
            Tau(i,j)=TauMax;
        else if Tau(i,j)<TauMin
                Tau(i,j)=TauMin;
            end
        end
    end
   end
沒有任何問題 代碼也能運行出來
但一旦注釋掉 就出現索引超出維度的錯誤 不知道怎么解決

新手

9 麥片

財富積分


050


2

主題

8

帖子

0

最佳答案
3#
 樓主| 發表于 7 天前 | 只看該作者
順便說一下 我的數據預處理是沒有問題的

MATLAB 基礎討論
版塊優秀回答者

入門

403 麥片

財富積分


50500


0

主題

176

帖子

28

最佳答案
  • 關注者: 2
4#
發表于 7 天前 | 只看該作者 |此回復為最佳答案
szq1234 發表于 2019-10-24 22:02
順便說一下 我的數據預處理是沒有問題的

你好,如果不介意,可以把POI信息表.xls,用戶評分表.xls等數據私下發一份嗎,要不后面無法修改程序
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規則

關閉

站長推薦上一條 /3 下一條

快速回復 返回頂部 返回列表
哪一款德州扑克还能玩