1. 程式人生 > >離散型遺傳演算法求解組合優化matlab實現

離散型遺傳演算法求解組合優化matlab實現

問題描述: 103個50維的節點中,選出n個節點進行組合,使其獲得較好的適應度值

注意點:首先在原始資料檔案(txt)中,將相應的節點進行編號,編成1-103,放在第一列,之後再將編號對映到相應的真實節點上。

需要資料檔案的小夥伴,可以到:https://download.csdn.net/download/qq_37188465/10314985 下載

%%%實現個體的交叉變異matlab程式碼:

*****************************************************************************************************************

%從橋樑感測器103*50模態資料中,共103個點中,選出zh個點進行組合,每一個個體的每一維是離散的,因此
%為103條記錄進行編號
function ga_main(zh)
%匯入模態檔案
format long
file='C:\Users\my_pc_2017_1_2\Desktop\node_trans.txt';
mt=load(file);
m=mt;
[rows,cols]=size(mt);%獲得模態矩陣的行和列,第一列表示為節點編的編號,方便找到對應的節點,第二列表示實際節
%定義目標函式,目標函式為r=obj_val()
%節點組合個數
n=zh;
%遺傳代數
ge=100;
%種群規模
gm=50;
%種群代溝
gg=0.7;
%種群變異概率
gb=0.0125;
%交叉概率
gj=0.7;
%重插入概率
gc=1;
%尋優結果的初始
%設定初始化隨機數發生器
rand('state',sum(clock));
for k=1:gm %通過改良圈演算法選取初始種群
    cl=randperm(103,103);%生成20個1-103的隨機且不重複的資料,即生成初始解
  %儲存種群所有的組合
  J(k,1:103)=cl;
end
 %disp(J);
 %計算初始種群的適應度值
 j1=J(:,1:n);
 objvalue=obj_val(j1,m);
 J=J/103;%把整數序列轉換成[0,1]區間上的實數,即轉換成染色體編碼
 for k=1:ge%該層迴圈進行遺傳演算法的操作
     A=J;%交配產生子代A的初始染色體
     if rand<gj
     c=randperm(gm);%產生下面交叉操作的染色體對
    % disp(c);
     for i=1:2:gm
         F=1+floor((n-1)*rand(1));%產生交叉操作的的地址
         temp=A(c(i),[F:n]);%中間變數的儲存值
         A(c(i),[F:n])=A(c(i+1),[F:n]);%交叉操作
         A(c(i+1),F:n)=temp;
     end
     end
      B=[];
      if rand<gb
     by=[];%為了防止下面產生空地址,這裡先初始化
     while ~length(by)
         by=find(rand(1,gm)<0.1);%產生變異操作的地址
     end
     B=A(by,:);%產生變異操作的初始染色體
     for j=1:length(by)
         bw=sort(1+floor((n-1)*rand(1,3)));%產生變異操作的3個地址
         B(j,:)=B(j,[1:bw(1)-1,bw(2)+1:bw(3),bw(1):bw(2),bw(3)+1:end]);%交換位置
     end
      end
     G=[J;A;B];%父代和子代種群和在一起
     %disp(G);
     [SG,ind1]=sort(G,2);%把染色體翻譯成1...20的序列ind1,此處需要修改
     num=size(G,1);
     long=zeros(1,num);
     g1=ind1(:,1:n);
     %fprintf('交叉變異後的種群:\n');
     %disp(g1);
     objvalue=obj_val(g1,m);
     long=objvalue;
     [slong,ind2]=sort(long);%對路徑長度從小到大排序
     J=G(ind2((end+1)-gm:end),:);%精選前m個較大的組合對應的染色體
 end
 [SG1,ind3]=sort(J,2);
  fprintf('最終的索引:\n');
 disp(ind3);
 path=ind3(gm,:),
 path=path(:,1:n),
 objvalue=obj_val(path,m);
 pp=zeros(1,n);
 for k1=1:n
  pp(k1)=m(path(k1),2);
 end
 fprintf('最終的橋樑節點組合:\n');
 pp=sort(pp);
 max=objvalue;
 disp(pp)
end

********************************************************************************************************************************

%%計算適應度值

*******************************************************************************************************************************

%定義最佳組合節點的適應度求解函式
function [objvalue] =obj_val(obj,m)%obj表示傳進來的目標矩陣,m表示總共的節點資料,輸出為適應度值
     [rows,cols]=size(obj);
     [rs,cs]=size(m);
     %將對應節點的模態值放進一個矩陣裡
     val=zeros(rows);
     for i=1:rows
         sum2=0;%儲存
         for j=1:cols %獲得一個個體對應的目標模態矩陣
             temp(j,:)=m(obj(i,j),3:end);% 
         end
       %獲得儲存個體對應的模態矩陣的行數和列數
       [rt,ct]=size(temp);
   %計算目標模態矩陣的累積和
   for k1=1:ct
       for k2=1:ct
          sum2=sum2+abs(temp(:,k1)'*temp(:,k2));
       end  
   end
      a(i)=sum2;
     end
      objvalue=a,

end

********************************************************************************************************************************

主函式部分

*******************************************************************************************************************************

%改變n的個數,指定生成的目標節點個數
clc;
clear;
n=10;%需要組合的節點的個數
for i=1:10
fprintf('節點個數=%d時第%d次試驗結果為\n',n,i);
    ga_main(n)%呼叫遺傳演算法,求得目標節點

end

***************************************************************************************************************************************