1.編寫框架的目的
在優化算法筆記(一)優化算法的介紹中,已經介紹過了優化算法的基本結構。大多數優化算法的結構都是十分相似的。
實現單個算法時,我們可能不需要什么框架。但是我們需要算法之間的對比,免不了需要實現多個算法。
由于優化算法之間的結構大致相同,所以我們可以將其相同的部分或者模塊抽離出來,形成公共的部分,我們只需要關注每一個算法自身獨特的部分即可。
為了實現公共部分的抽離,我們需要用到面向對象的思想。在matlab中使用類(classdef)來定義一個基礎類,其中編寫公共代碼,在其他類中只需繼承基礎類并實現自身獨有的方法即可。
2.優化算法公共部分
將優化算法進行抽象可以得到三個部分:種群(個體),規則,環境。
其中種群即優化算法中個體組成的種群,規則則是各個優化算法中的算子,環境為我們需要求解的適應度環境。優化算法也可以描述成:在種群中求解在一定規則下最適應目標環境的個體。
描述 | |
---|---|
種群 | 由個體組成的群體(列表) |
規則 | 優化算法結構及算子 |
環境 | 待解適應度函數(外部輸入) |
具體實現時,我們需要實現的是
(1)個體(種群為個體的列表)
(2)規則(優化算法流程)
2.1個體
各算法中個體的差異其實還是挺大的,不過個體的公共屬性比較簡單只有兩個
(1)位置:適應度函數的輸入。
(2)值:適應度函數的值。
2.2 規則
規則其實就是算法的主題,算法的執行過程。每個算法的執行過程必然不一樣(一樣那就是同一個算法了)。但是算法的執行流程還是有很多相同的部分的。
(1)初始化:初始化個體,一般是在解空間內隨機初始化。
(2)循環迭代:在最大迭代次數內執行指定步驟
(3)記錄:記錄每代的最優解,最優值
3.實現
下面是完整的代碼,需要自己動手組成框架。
總目錄:../optimization algorithm
框架目錄:../optimization algorithm/frame
框架文件:
文件名 | 描述 |
---|---|
../optimization algorithm/frame/Unit.m | 個體 |
../optimization algorithm/frame/Algorithm_Impl.m | 算法主體 |
文件內容:
Unit.m
% 個體基類
classdef Unit
properties
% 個體的位置
position
% 個體的適應度值
value
end
methods
function self = Unit()
end
end
end
Algorithm_Impl.m
% 優化算法基類
classdef Algorithm_Impl < handle
properties
%當前最優位置
position_best;
%當前最優適應度
value_best;
%歷史最優適應度
value_best_history;
%歷史最優位置
position_best_history;
%是否為求最大值,默認為是
is_cal_max;
%適應度函數,需要單獨傳入
fitfunction;
% 調用適應度函數次數
cal_fit_num = 0;
end
properties(Access = protected)
%維度
dim;
%種群中個體的數量
size;
%最大迭代次數
iter_max;
%解空間下界
range_min_list;
%解空間上界
range_max_list;
%種群列表
unit_list;
end
methods
% 運行,調用入口
function run(self)
tic
self.init()
self.iteration()
toc
disp(['運行時間: ',num2str(toc)]);
end
end
methods (Access = protected)
% 構造函數
function self = Algorithm_Impl(dim,size,iter_max,range_min_list,range_max_list)
self.dim =dim;
self.size = size;
self.iter_max = iter_max;
self.range_min_list = range_min_list;
self.range_max_list = range_max_list;
%默認為求最大值
self.is_cal_max = true;
end
% 初始化
function init(self)
self.position_best=zeros(1,self.dim);
self.value_best_history=[];
self.position_best_history=[];
%設置初始最優值,由于是求最大值,所以設置了最大浮點數的負值
self.value_best = -realmax('double');
end
% 開始迭代
function iteration(self)
for iter = 1:self.iter_max
self.update(iter)
end
end
% 處理一次迭代
function update(self,iter)
% 記錄最優值
for i = 1:self.size
if(self.unit_list(i).value>self.value_best)
self.value_best = self.unit_list(i).value;
self.position_best = self.unit_list(i).position;
end
end
disp(['第' num2str(iter) '代']);
if(self.is_cal_max)
self.value_best_history(end+1) = self.value_best;
disp(['最優值=' num2str(self.value_best)]);
else
self.value_best_history(end+1) = -self.value_best;
disp(['最優值=' num2str(-self.value_best)]);
end
self.position_best_history = [self.position_best_history;self.position_best];
disp(['最優解=' num2str(self.position_best)]);
end
function value = cal_fitfunction(self,position)
if(isempty(self.fitfunction))
value = 0;
else
% 如果適應度函數不為空則返回適應度值
if(self.is_cal_max)
value = self.fitfunction(position);
else
value = -self.fitfunction(position);
end
end
self.cal_fit_num = self.cal_fit_num+1;
end
% 越界檢查,超出邊界則停留在邊界上
function s=get_out_bound_value(self,position,min_list,max_list)
if(~exist('min_list','var'))
min_list = self.range_min_list;
end
if(~exist('max_list','var'))
max_list = self.range_max_list;
end
% Apply the lower bound vector
position_tmp=position;
I=position_tmp<min_list;
position_tmp(I)=min_list(I);
% Apply the upper bound vector
J=position_tmp>max_list;
position_tmp(J)=max_list(J);
% Update this new move
s=position_tmp;
end
% 越界檢查,超出邊界則在解空間內隨機初始化
function s=get_out_bound_value_rand(self,position,min_list,max_list)
if(~exist('min_list','var'))
min_list = self.range_min_list;
end
if(~exist('max_list','var'))
max_list = self.range_max_list;
end
position_rand = unifrnd(self.range_min_list,self.range_max_list);
% Apply the lower bound vector
position_tmp=position;
I=position_tmp<min_list;
position_tmp(I)=position_rand(I);
% Apply the upper bound vector
J=position_tmp>max_list;
position_tmp(J)=position_rand(J);
% Update this new move
s=position_tmp;
end
end
events
end
end
注意:此代碼實現的是求目標函數最大值,求最小值可將適應度函數乘以-1(框架代碼已實現)。
注意:此代碼實現的是求目標函數最大值,求最小值可將適應度函數乘以-1(框架代碼已實現)。
注意:此代碼實現的是求目標函數最大值,求最小值可將適應度函數乘以-1(框架代碼已實現)。
4.測試(bushi)
這里只是實現了優化算法框架的公共部分,這還不是一個完整的優化算法,我們無法使用它來求解,在下一篇,在框架的基礎上實現 粒子群算法。