離散型遺傳演算法求解組合優化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
***************************************************************************************************************************************