【路徑規劃】基於蟻群的多無人機攻擊排程

天天matlab發表於2020-11-08

 

 

t=[4 5;16 25.8;10 45;20 55;30 65;35 55;29 31;37 26;47 27;30 31.3;31 17;14 7;35.6 13.8;26.7 22.5;21 39;38 42;5 26;28 53;20 13;10 60;26 31;54 38;7 58;12 36;30 2] %24個點,第25個點事origin
save t.mat t
load t.mat
value=[1 1 1 2 3 2 1 3 3 2 2 2 2 2 1 2 3 3 1 1 2 1 1 1]; %24個目標的價值
value=value/100;
time=zeros(1,25); %偵察UAV時間陣列,裡面放的是飛機走的航程,除以速度便是時間,設速度為‘1’
attacktime=zeros(1,25); %打擊UAV時間陣列
%把偵察過的任務對應無人機走過的航程存到該任務的一個矩陣裡,當做時間,然後打擊任務如果選定某任務,check一下時間是否合格,合格的話,可以打擊,並存入禁忌表,不合格的話,選次概率的

%注:目的是把所有目標執行完所有任務,所以每次迭代最後所有無人機收穫的總價值都一樣,都是所有目標的價值之和;所以本程式考慮優先執行價值大的目標,防止無人機飛很久、打很久後攻打效率變低
%的情況出現

%%計算城市間相互距離
n=size(t,1);
D=zeros(n,n);
for i=1:n
    for j=1:n
        if i~=j
            D(i,j)=sqrt(sum((t(i,:)-t(j,:)).^2));
        else
            D(i,j)=1e-2;
        end
    end
end
%%初始化引數
m=10;         %螞蟻個數
alpha=1;      %資訊素重要程度因子
beta=1;       %啟發函式重要程度因子
gama=2;
rho=0.3;      %資訊素揮發因子
Q=1.0;          %總量
eta=1./D;     %啟發函式
tau=ones(n,n)+7.1192e-005;%資訊素矩陣
iter=1;       %迭代次數初始值
iter_max=80;  %迭代次數最大值
length_best=zeros(iter_max,1);%每次迭代最佳路徑長度(應該是一次比一次小)
length_ave=zeros(iter_max,1); %每次迭代路徑平均長度 
%%迭代尋找最佳路徑
while iter<=iter_max
    whta=cell(8,1);
    lieend=zeros(8,1);
    for zu=1:8
    city_index=1:25;       %城市來標號 
    table=[];
    start=zeros(4,1);
        temp=randperm(24);
        for i=1:4
        start(i)=temp(i);
        end
    table(:,1)=start;
    j=2;
 while (j<=30)
        for i=1:4
            if i==1 %UAV1只負責“偵察”任務
                if table(1,(j-1))~=25
                    table1=table(1,:);
                    table1=[table1;table(3:4,:)];
                    tabu1=table1(:); %UAV1的禁忌表出來了 %25如果也在tabu1裡的話,那麼
            allow_index1=~ismember(city_index,tabu1);  %【走過的變成0,能走的為1】【若tabu=(1 4)則allow_index=(0 1 1 0 1 1 1...)】【注意:allow_index與city_index同維】
            allow1=city_index(allow_index1);  %把還能走的序號摘出來了(待訪問的城市集合)
            P1=allow1;
            %計算城市的轉移概率
            if numel(allow1)~=0
              for k=1:max(size(allow1))-1
               P1(k)=(tau(table(1,(j-1)),allow1(k))^alpha)*(eta(table(1,(j-1)),allow1(k))^beta)*10000+7.1192e-004;
              end
            P1(max(size(allow1)))=7.1192e-005;
            P1=P1/sum(P1);
            [d1,ind1]=sort(P1,2,'descend');%從大到小排序是d1,對應的原序號是ind1
            target1=allow1(ind1(1));
            %輪盤賭法選擇下一個城市
            %pc1=cumsum(P1);  % (p1 p1+p2 p1+p2+p3 p1+p2+p3+p4 ....)【p1<->allow(1)  p2<->allow(2) ...】
            %target_index1=find(pc1>=rand); 
            %target1=allow1(target_index1(1));  %這次返回的是allow陣列中城市的真正序號
            table(1,j)=target1;  %把選好這個點放到路徑表裡面
            rr=D(25,table(1,1));
            time(table(1,1))=rr;
            if j>2
            for c=2:(j-1)
                rr=rr+D(table(1,c-1),table(1,c));
            end 
            end
            rrr=rr+D(table(1,j-1),target1);%rrr就是UAV1到該點時走過的航程
            time(target1)=rrr;
            else
                table(1,j)=25;
            end
                end
                 if table(1,(j-1))==25
                    table(1,j)=25;
                 end
            end          
            if i==2 %UAV2只負責“打擊”任務
                if (table(2,(j-1))~=25)
                table(2,1)=table(1,1); %設定它第一次打擊的是UAV1偵察過的目標
                ta2=table(1:(4*(j-1)+1)); %當前元素之前所有的元素
                tabu21=[];
                tabu22=[];
                tabu2=[];
                for y=1:24
                    if sum(ta2==y)==2
                        tabu21=[tabu21;y];
                    end
                end                       %出現過兩次的放在tabu21裡
                tabu22=setdiff(1:24,ta2); %一次都沒出現的放在tabu22裡
                tabu2=[tabu21',tabu22];   %tabu2出來了
            allow_index2=~ismember(city_index,tabu2);  %【走過的變成0,能走的為1】【若tabu=(1 4)則allow_index=(0 1 1 0 1 1 1...)】【注意:allow_index與city_index同維】
            allow2=city_index(allow_index2);  %把還能走的序號摘出來了(待訪問的城市集合)
            P2=allow2;
            %計算城市的轉移概率
           for k=1:(length(allow2)-1)
               P2(k)=tau(table(2,(j-1)),allow2(k))*eta(table(2,(j-1)),allow2(k))*value(allow2(k))*10000;
           end
           P2(max(size(allow2)))=7.1192e-005;
            P2=P2/sum(P2);
            [d2,ind2]=sort(P2,2,'descend');%從大到小排序是d1,對應的原序號是ind1
            target2=allow2(ind2(1)); %target2=d1(1);
            %輪盤賭法選擇下一個城市
            %pc2=cumsum(P2);  % (p1 p1+p2 p1+p2+p3 p1+p2+p3+p4 ....)【p1<->allow(1)  p2<->allow(2) ...】
            %target_index2=find(pc2>=rand);  %選中那個概率較大的選中的點,返回的是allow陣列中的序號
            %target2=allow2(target_index2(1));  %這次返回的是allow陣列中城市的真正序號
            %table(2,j)=target2;  %把選好這個點放到路徑表裡面
            oo=D(25,table(2,1));
            attacktime(table(2,1))=oo;
            if j>2
            for c=2:(j-1)
                oo=oo+D(table(2,c-1),table(2,c));
            end 
            end
            ooo=oo+D(table(2,j-1),target2);%ooo就是UAV2到該點時走過的航程
            if numel(d2)>5
            u=2;
            while (ooo>time(target2)+20 & u<6)
                 target2=allow2(ind2(u));
                 ooo=oo+D(table(2,(j-1)),target2);
                 u=u+1;
            end
            end
            table(2,j)=target2;
            attacktime(target2)=ooo;
                end
                if table(2,(j-1))==25
                    table(2,j)=25;
                end
            end
            if i==3 %UAV3是“察打”任務
                if table(3,(j-1))~=25
                    ta3=table(1:(4*(j-1)+2));
                    tabu3=[];
                    tabu3c=[];
                for y=1:24
                    if sum(ta3==y)==2
                        tabu3=[tabu3;y];
                    end
                end    %出現兩次的放在tabu3裡   
                  for y=1:24
                    if sum(ta3==y)==1
                        tabu3c=[tabu3c;y];
                    end
                end %tabu3c是待打的任務,已偵查完的任務
            allow_index3=~ismember(city_index,tabu3);  %【走過的變成0,能走的為1】【若tabu=(1 4)則allow_index=(0 1 1 0 1 1 1...)】【注意:allow_index與city_index同維】
            allow3=city_index(allow_index3);  %把還能走的序號摘出來了(待訪問的城市集合)
            P3=allow3;
            %計算城市的轉移概率
           for k=1:(length(allow3)-1)
               %if ismember(allow3(k),tabu3c)==1     
               h=table(3,(j-1))
               P3(k)=(tau(table(3,j-1),allow3(k))^alpha)*(eta(table(3,(j-1)),allow3(k))^beta)*value(allow3(k))*10000+7.1192e-005;%這是要打的,需要價值
               %else
               %P3(k)=(tau(table(3,(j-1)),allow3(k))^alpha)*(eta(table(3,(j-1)),allow3(k))^beta)*100+7.1192e-005;%這些是待偵察的,沒有價值
               %end
           end
            P3(max(size(allow3)))=7.1192e-009;
            P3=P3/sum(P3);
            [d3,ind3]=sort(P3,2,'descend');%從大到小排序是d1,對應的原序號是ind1
            target3=allow3(ind3(1));
            %輪盤賭法選擇下一個城市
            %pc3=cumsum(P3);  % (p1 p1+p2 p1+p2+p3 p1+p2+p3+p4 ....)【p1<->allow(1)  p2<->allow(2) ...】
            %target_index3=find(pc3>=rand);  %選中那個概率較大的選中的點,返回的是allow陣列中的序號
            %target3=allow3(target_index3(1));  %這次返回的是allow陣列中城市的真正序號
            %table(3,j)=target3;  %把選好這個點放到路徑表裡面
            ww=D(25,table(3,1));
            time(table(3,1))=ww;
            if j>2
            for c=2:(j-1)
                ww=ww+D(table(3,c-1),table(3,c));
            end 
            end
            www=ww+D(table(3,j-1),target3);%www就是UAV3到該點時走過的航程
            if ismember(target3,tabu3c)==0 %偵察任務
                time(target3)=www;
                table(3,j)=target3;
            else %打擊任務
                attacktime(target3)=www;
                if numel(d3)>5
                u=2;
            while (www>time(target3)+20 & u<6)
                 target3=allow3(ind3(u));
                 www=ww+D(table(3,(j-1)),target3);
                 u=u+1;
            end
                end
            attacktime(target3)=www;
            table(3,j)=target3;%www<time(target3)+10 說明此打擊任務合理
            end 
                end
                if table(3,(j-1))==25
                    table(3,j)=25;
                end
            end
            if i==4 %UAV4是“察打”任務
                if table(4,(j-1))~=25
                    ta4=table(1:(4*(j-1)+3));
                    tabu4=[];
                    tabu4c=[];
                for y=1:24
                    if sum(ta4==y)==2
                        tabu4=[tabu4;y];
                    end
                end    %出現兩次的放在tabu4裡、、可以把已經偵察過的放在tabu4c中,(即出現過一次的),如果選到的是在tabu4'中的說明是要打擊的然後算一下它的航程,再和偵察路徑比較 
                for y=1:24
                    if sum(ta4==y)==1
                        tabu4c=[tabu4c;y];
                    end
                end 
            allow_index4=~ismember(city_index,tabu4);  %【走過的變成0,能走的為1】【若tabu=(1 4)則allow_index=(0 1 1 0 1 1 1...)】【注意:allow_index與city_index同維】
            allow4=city_index(allow_index4);  %把還能走的序號摘出來了(待訪問的城市集合)
            P4=allow4;
            %計算城市的轉移概率
           for k=1:(max(size(allow4))-1)
               %if ismember(allow4(k),tabu4c)==1
               sxx=table(4,(j-1))
               P4(k)=(tau(table(4,(j-1)),allow4(k))^alpha)*(eta(table(4,(j-1)),allow4(k))^beta)*value(allow4(k))*10000+7.1192e-005;
               %else
               %P4(k)=(tau(table(4,(j-1)),allow4(k))^alpha)*(eta(table(4,(j-1)),allow4(k))^beta)*100+7.1192e-005;
               %end
           end
           P4(max(size(allow4)))=7.1192e-009;
            P4=P4/sum(P4);
            [d4,ind4]=sort(P4,2,'descend');%從大到小排序是d1,對應的原序號是ind1
            target4=allow4(ind4(1));
            %輪盤賭法選擇下一個城市
            %pc4=cumsum(P4);  % (p1 p1+p2 p1+p2+p3 p1+p2+p3+p4 ....)【p1<->allow(1)  p2<->allow(2) ...】
            %target_index4=find(pc4>=rand);  %選中那個概率較大的選中的點,返回的是allow陣列中的序號
            %target4=allow4(target_index4(1));  %這次返回的是allow陣列中城市的真正序號
            %table(4,j)=target4;  %把選好這個點放到路徑表裡面
            qq=D(25,table(4,1));
            time(table(4,1))=qq;
            if j>2
            for c=2:(j-1)
                qq=qq+D(table(4,c-1),table(4,c));
            end 
            end
            qqq=qq+D(table(4,j-1),target4);%www就是UAV3到該點時走過的航程
            if ismember(target4,tabu4c)==0 %偵察任務
                time(target4)=qqq;
                table(4,j)=target4;
            else %打擊任務
                attacktime(target4)=qqq;
                if numel(d4)>5
                u=2;
            while (qqq>time(target4)+20 & u<6)
                 target4=allow4(ind4(u));
                 qqq=qq+D(table(4,j-1),target4);
                 u=u+1;
            end
                end
            attacktime(target4)=qqq;
            table(4,j)=target4;%www<time(target4)+10 說明此打擊任務合理
            end                
                end
                if table(4,(j-1))==25
                    table(4,j)=25;
                end
              end
        end %一列結束
           

完整程式碼或者代寫新增QQ1575304183

相關文章