?? mysf.m
字號:
%2008-07-11 13:02%這是免疫算法。這個算法幾乎與遺傳算法一樣,只是多用了一個免疫函數
%免疫算法是遺傳算法的變體,它不用雜交,而是采用注入疫苗的方法。
%疫苗是優秀染色體中的一段基因,把疫苗接種到其它染色體中
%注意:標準遺傳算法的一個重要概念是,染色體是可能解的2進制順序號,由這個序號在可能解的集合(解空間)中找到可能解
%這是免疫算法的主程序,它需要調用的函數如下。
%接種疫苗函數:
%function inoculateChromosome=immunity(chromosomeGroup,bacterinChromosome,parameter)
%parameter:1,隨機制取染色體接種。2,每個染色體都接種。3,每個染色體都接種,但接種的位置是隨機的
%這個函數實現對染色體的疫苗接種
%由染色體(可能解的2進制)順序號找到可能解:
%x=chromosome_x(fatherChromosomeGroup,oneDimensionSet,solutionSum);
%把解代入非線性方程組計算誤差函數:functionError=nonLinearSumError1(x);
%判定程是否得解函數:[solution,isTrue]=isSolution(x,funtionError,solutionSumError);
%選擇最優染色體函數:
%[bestChromosome,leastFunctionError]=best_worstChromosome(fatherChromosomeGroup,functionError);
%誤差比較函數:從兩個染色體中,選出誤差較小的染色體
%[holdBestChromosome,holdLeastFunctionError]...
% =compareBestChromosome(holdBestChromosome,holdLeastFunctionError,...
% bestChromosome,leastFuntionError)
%為染色體定義概率函數,好的染色體概率高,壞染色體概率低
%p=chromosomeProbability(functionError);
%按概率選擇染色體函數:
%slecteChromosomeGroup=selecteChromome(fatherChromosomeGroup,p);
%父代染色體雜交產生子代染色體函數
%sonChrmosomeGroup=crossChromosome(slecteChromosomeGroup,2);
%防止染色體超出解空間的函數
%chromosomeGroup=checkSequence(chromosomeGroup,solutionSum)
%變異函數
%fatherChromosomeGroup=varianceCh(sonChromosomeGroup,0.8,solutionN);
%通過實驗有如下結果:
%1。染色體應當多一些
%2。通過概率選擇染色體,在迭代早期會有效選出優秀的染色體,使解的誤差迅速降低,
%但隨著迭代的進行,概率選擇也會導致某種染色體在基因池中迅速增加,使染色體趨同,
%這就減少了物種的多樣性,反而難以逼近解
%3。不用概率選擇,僅采用染色體雜交,采用保留優秀染色體,也可以得到解
%4。單純免疫效果不好,雜交+免疫效果比較好
%%%%%%%%%%%%%%%%%%%%%%%%程序開始運行
clear,clc;%清理內存,清屏
circleN=200;%迭代次數
format long
%%%%%%%%%%%%%%%構造可能解的空間,確定染色體的個數、長度
solutionSum=4;
leftBoundary=-10;
rightBoundary=10;
distance=1;
chromosomeSum=500;
solutionSumError=0.1;
%solutionSum:非線性方程組的元數(待解變量的個數);leftBoundary:可能解的左邊界;
%rightBoundary:可能解的右邊界;distance:可能解的間隔,也是解的精度
%chromosomeSum:染色體的個數;solveSumError:解的誤差
oneDimensionSet=leftBoundary:distance:rightBoundary;
%oneDimensionSet:可能解在一個數軸(維)上的集合
oneDimensionSetN=size(oneDimensionSet,2); %返回oneDimensionSet中的元素個數
solutionN=oneDimensionSetN^solutionSum; %解空間(解集合)中可能解的總數
binSolutionN=dec2bin(solutionN); %把可能解的總數轉換成二進制數,dec2bin()為轉換函數
chromosomeLength=size(binSolutionN,2); %由解空間中可能解的總數(二進制數)計算染色體的長度
%%%%%%%%%%%%%%%%程序初始化
%隨機生成初始可能解的順序號,+1是為了防止出現0順序號
solutionSequence=fix(rand(chromosomeSum,1)*solutionN)+1;
for i=1:chromosomeSum%防止解的順序號超出解的個數
if solutionSequence(i)>solutionN;
solutionSequence(i)=solutionN;
end
end
%染色體是解集合中的序號,它對應一個可能解
%把解的十進制序號轉成二進制序號,解碼dec2bin()
fatherChromosomeGroup=dec2bin(solutionSequence,chromosomeLength);
holdLeastFunctionError=Inf;%可能解的最小誤差的初值
holdBestChromosome=0;%對應最小誤差的染色體的初值
%%%%%%%%%%%%%%%%%%開始計算
compute=1;
circle=0;
while compute%開始迭代求解
%%%%%%%%%%%%%1:由可能解的序號尋找解本身(關鍵步驟)
x=chromosome_x(fatherChromosomeGroup,oneDimensionSet,solutionSum);
%%%%%%%%%%%%%2:把解代入非線性方程計算誤差
functionError=nonLinearSumError1(x);%把解代入方程計算誤差
[solution,minError,isTrue]=isSolution(x,functionError,solutionSumError);
%isSolution函數根據誤差functionError判定方程是否已經解開,isTrue=1,方程得解。solution是方程的解
if isTrue==1
'方程得解'
solution
minError
return%結束程序
end
%%%%%%%%%%%%%3:選擇最好解對應的最優染色體
[bestChromosome,leastFunctionError]=best_worstChromosome(fatherChromosomeGroup,functionError);
%%%%%%%%%%%%%4:保留每次迭代產生的最好的染色體
%本次最好解與上次最好解進行比較,如果上次最好解優于本次最好解,保留上次最好解;
%反之,保留本次最好解。保留的最好染色體放在holdBestChromosome中
[holdBestChromosome,holdLeastFunctionError]...
=compareBestChromosome(holdBestChromosome,holdLeastFunctionError,...
bestChromosome,leastFunctionError);
circle=circle+1
%minError
%solution
holdLeastFunctionError
if circle>circleN
return
end
%%%%%%%%%%%%%%5:把保留的最好的染色體holdBestChromosome加入到染色體群中
order=round(rand(1)*chromosomeSum);
if order==0
order=1;
end
fatherChromosomeGroup(order,:)=holdBestChromosome;
functionError(order)=holdLeastFunctionError;
%%%%%%%%%%%%%%%6:為每一條染色體(即可能解的序號)定義一個概率(關鍵步驟)
%%%%%%%%%%%%%%%好的染色體概率高,壞的概率低。依據誤差functionError計算概率
[p,trueP]=chromosomeProbability(functionError);
if trueP =='Fail'
'可能解嚴重不適應方程,請重新開始'
return%結束程序
end
%%%%%%%%%%%%%%%7:按照概率篩選染色體(關鍵步驟)
%fa=bin2dec(fatherChromosomeGroup)%顯示父染色體
%從父染體中選擇優秀染色體
%selecteChromosomeGroup=selecteChromosome(fatherChromosomeGroup,p);
%%%%%%%%%%%%%%%8:染色體雜交(關鍵步驟)
%sle=bin2dec(selecteChromosomeGroup)%顯示選擇出來的解的序號(染色體)
%用概率篩選出的染色體selecteChromosomeGroup進行雜交,產生子代染色體
%sonChromosomeGroup=crossChromosome(selecteChromosomeGroup,2);
%不用概率篩選出的染色體selecteChromosomeGroup進行雜交,而直接用上一代(父代)的
sonChromosomeGroup=crossChromosome(fatherChromosomeGroup,2);
%sonChromosomeGroup=immunity(fatherChromosomeGroup,holdBestChromosome,3);
%把疫苗接種到其它染色體中
sonChromosomeGroup=immunity(sonChromosomeGroup,holdBestChromosome,3);
%cro=bin2dec(sonChromosomeGroup)%顯示雜交后的子代染色體
sonChromosomeGroup=checkSequence(sonChromosomeGroup,solutionN);%檢查雜交后的染色體是否越界
%%%%%%%%%%%%%%%9:變異
%不雜交直接變異
%fatherChromosomeGroup=varianceCh(fatherChromosomeGroup,0.1,solutionN);
%雜交后變異
fatherChromosomeGroup=varianceCh(sonChromosomeGroup,0.5,solutionN);
fatherChromosomeGroup=checkSequence(fatherChromosomeGroup,solutionN);%檢查變異后的染色體是否越界
end
%接種疫苗函數,這是和遺傳算法唯一不同的函數,可以用它代替染色體的交叉操作。
%chromosomeGroup:染色體組
%bachterinChromosome:疫苗染色體,即最好的染色體。從這個染色體上取疫苗
%parameter:接種疫苗的參數,即用什么方法接種
%inoculateChromosome:接種疫苗后的染色體
function inoculateChromosome=immunity(chromosomeGroup,bacterinChromosome,parameter)
[chromosomeGroupSum,chromosomeLength]=size(chromosomeGroup);
[row,bacterinChromosomeLength]=size(bacterinChromosome);
%chromosomeGroupSum:染色體的條數;chromosomeLength:染色體的長度
switch parameter
case 1 %隨機選擇染色體進行接種
for i=1:chromosomeGroupSum
%%%%%%%%%%%%從疫苗染色體上定位疫苗
headDot=fix(rand(1)*bacterinChromosomeLength);
%疫苗在染色體上左邊的點位
if headDot==0%防止出現0點位
headDot=1;
end
tailDot=fix(rand(1)*bacterinChromosomeLength);
%疫苗在染色體上右邊的點位
if tailDot==0%防止出現0點位
tailDot=1;
end
if tailDot>headDot%防止右邊的點位大于左邊的點位
dot=headDot;
headDot=tailDot;
tailDot=dot;
end
%%%%%%%%%%%%%接種
randChromosomeSequence=round(rand(1)*chromosomeGroupSum);
%隨機產生1條染色體的序號,對這條染色體進行接種
if randChromosomeSequence==0%防止產生0序號
randChromosomeSequence=1;
end
inoculateChromosome(i,:)...%先把輸入染色體傳給輸出
=chromosomeGroup(randChromosomeSequence,:);
%執行免疫,即從疫苗染色體上取出一段基因做疫苗,再注入到其它染色體中
inoculateChromosome(i,headDot:tailDot)...
=bacterinChromosome(1,headDot:tailDot);
end
case 2 %所有染色體挨個接種
for i=1:chromosomeGroupSum
%%%%%%%%%%%%從疫苗染色體上定位疫苗
headDot=fix(rand(1)*bacterinChromosomeLength);
%疫苗在染色體上左邊的點位
if headDot==0%防止出現0點位
headDot=1;
end
tailDot=fix(rand(1)*bacterinChromosomeLength);
%疫苗在染色體上右邊的點位
if tailDot==0%防止出現0點位
tailDot=1;
end
if tailDot>headDot%防止右邊的點位大于左邊的點位
dot=headDot;
headDot=tailDot;
tailDot=dot;
end
%%%%%%%%%%%%%接種
inoculateChromosome(i,:)=chromosomeGroup(i,:);%先把輸入染色體傳給輸出
%執行免疫,即從疫苗染色體上取出一段基因做疫苗,再注入到其它染色體中
inoculateChromosome(i,headDot:tailDot)...
=bacterinChromosome(1,headDot:tailDot);
end
case 3 %接種位置是隨機的
for i=1:chromosomeGroupSum
%%%%%%%%%%%%從疫苗染色體上定位疫苗
headDot=fix(rand(1)*bacterinChromosomeLength);
%疫苗在染色體上左邊的點位
if headDot==0%防止出現0點位
headDot=1;
end
tailDot=fix(rand(1)*bacterinChromosomeLength);
%疫苗在染色體上右邊的點位
if tailDot==0%防止出現0點位
tailDot=1;
end
if tailDot>headDot%防止右邊的點位大于左邊的點位
dot=headDot;
headDot=tailDot;
tailDot=dot;
end
%%%%%%%%%%%%%在染色體上隨機定位接種位置
inoculateDot=fix(rand(1)*chromosomeLength);%隨機選擇染色體的接種點位
if inoculateDot==0
inoculateDot=1;
inoculateChromosome(i,:)=chromosomeGroup(i,:);
inoculateChromosome(i,inoculateDot:tailDot-headDot+1)...
=bacterinChromosome(1,headDot:tailDot);
elseif inoculateDot<=headDot
inoculateChromosome(i,:)=chromosomeGroup(i,:);
inoculateChromosome(i,inoculateDot:inoculateDot+tailDot-headDot)...
=bacterinChromosome(1,headDot:tailDot);
elseif (chromosomeLength-inoculateDot)>=(tailDot-headDot)
inoculateChromosome(i,:)=chromosomeGroup(i,:);
inoculateChromosome(i,inoculateDot:inoculateDot+tailDot-headDot)...
=bacterinChromosome(1,headDot:tailDot);
else
inoculateChromosome(i,:)=chromosomeGroup(i,:);
inoculateChromosome(i,headDot:tailDot)...
=bacterinChromosome(1,headDot:tailDot);
end
end
end
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -