在實際的工作和生活過程中,優(yōu)化問題無處不在,比如資源如何分配效益最高,擬合問題,最小最大值問題等等。優(yōu)化問題一般分為局部最優(yōu)和全局最優(yōu),局部最優(yōu),就是在函數(shù)值空間的一個有限區(qū)域內(nèi)尋找最小值;而全局最優(yōu),是在函數(shù)值空間整個區(qū)域?qū)ふ易钚≈祮栴}。
函數(shù)局部最小點是那種它的函數(shù)值小于或等于附近點的點。但是有可能大于較遠(yuǎn)距離的點。
-
全局最小點是那種它的函數(shù)值小于或等于所有的可行點。
全局優(yōu)化和局部優(yōu)化區(qū)別示意圖
matlab中的提供的傳統(tǒng)優(yōu)化工具箱(Optimization Tool),能實現(xiàn)局部最優(yōu),但要得全局最優(yōu),則要用全局最優(yōu)化算法(Global Optimization Tool),主要包括:
GlobalSearch 全局搜索和MultiStart多起點方法產(chǎn)生若干起始點,然后它們用局部求解器去找到起始點吸引盆處的最優(yōu)點。
ga 遺傳算法用一組起始點(稱為種群),通過迭代從種群中產(chǎn)生更好的點,只要初始種群覆蓋幾個盆,GA就能檢查幾個盆。
simulannealbnd模擬退火完成一個隨機搜索,通常,模擬退火算法接受一個點,只要這個點比前面那個好,它也偶而接受一個比較糟的點,目的是轉(zhuǎn)向不同的盆。
patternsearch模式搜索算法在接受一個點之前要看看其附近的一組點。假如附近的某些點屬于不同的盆,模式搜索算法本質(zhì)上時同時搜索若干個盆。
下面我就一些具體例子,來說明各種優(yōu)化方法:
- 先看一個求最小值的普通優(yōu)化問題
%%目標(biāo)函數(shù)
f = @(x) x.*sin(x) + x.*cos(2.*x);
%% 的取值范圍
lb = 0;
ub = 10;
%% 尋找最小值和繪圖
x0 = [0 1 3 6 8 10];
hf = figure;
for i=1:6
x(i) = fmincon(f,x0(i),[],[],[],[],lb,ub,[],...
optimset('Algorithm','SQP','Disp','none'));
subplot(2,3,i)
ezplot(f,[lb ub]);
hold on
plot(x0(i),f(x0(i)),'k+')
plot(x(i),f(x(i)),'ro')
hold off
title(['Starting at ',num2str(x0(i))])
if i == 1 || i == 4
ylabel('x sin(x) + x cos(2 x)')
end
end
可以看出,初值x0不同,得到的結(jié)果截然不同,這說明這種求解器,能尋找局部最優(yōu),但不一定是全局最優(yōu),在起點為8時,取得全局最優(yōu)。
我們換一種求解器:fminbound,這種求解器不需要給點初值。
x2 = fminbnd(f,lb,ub);
figure
ezplot(f,[lb ub]);
hold on
plot(x2,f(x2),'ro')
hold off
ylabel('x sin(x) + x cos(2 x)')
title({'Solution using fminbnd.','Required no starting point!'})
- 現(xiàn)在我們嘗試全局最優(yōu)的方法:GlobalSearch
% Leason Learned: Use the appropriate solver for your problem type!
%% But what if |fmincon| was the only choice?
% Use globalSearch or MultiStart
problem = createOptimProblem('fmincon','objective',f,'x0',x0(1),'lb',lb,...
'ub',ub,'options',optimset('Algorithm','SQP','Disp','none'));
gs = GlobalSearch;
xgs = run(gs,problem);
figure
ezplot(f,[lb ub]);
hold on
plot(xgs,f(xgs),'ro')
hold off
ylabel('x sin(x) + x cos(2 x)')
title('Solution using globalSearch.')
因此全局最優(yōu)的方法能夠獲取全局最優(yōu)。
- 再看一個線性擬合的問題:
close all, clear all, clc
%% Pharmacokinetic Data
t = [ 3.92, 7.93, 11.89, 23.90, 47.87, 71.91, 93.85, 117.84 ] %#ok<*NOPTS>
c = [0.163, 0.679, 0.679, 0.388, 0.183, 0.125, 0.086, 0.0624 ]
plot(t,c,'o'), xlabel('t'), ylabel('c')
%% 3 Compartment Model
model = @(b,t) b(1)*exp(-b(4)*t) + b(2)*exp(-b(5)*t) + b(3)*exp(-b(6)*t)
%% Define Optimization Problem
problem = createOptimProblem('lsqcurvefit', ...
'objective', model, ...
'xdata', t, 'ydata', c, ...
'x0',ones(1,6),...
'lb', [-10 -10 -10 0 0 0 ],...
'ub', [ 10 10 10 0.5 0.5 0.5], ...
'options',optimset('OutputFcn',...
@curvefittingPlotIterates))
%% solve
b = lsqcurvefit(problem)
結(jié)果:最小二乘擬合結(jié)果誤差較大
- 現(xiàn)在我們嘗試全局最優(yōu)方法:MultiStart
%% Multistart
ms = MultiStart
[b,fval,exitflag,output,solutions] = run(ms, problem, 50) %#ok<*NASGU,*ASGLU>
%%
curvefittingPlotIterates(solutions)
%%
problem.options.OutputFcn = {};
tic, [b,fval,exitflag,output,solutions] = run(ms, problem, 100), toc %計算算法的時間
可以看出全局優(yōu)化結(jié)果較好,誤差較小。
這種算法的運行時間:Elapsed time is 6.139324 seconds.
使用并行計算的方式解決
%% Parallel Version
matlabpool open 2 %開啟兩個matlab并行計算
ms.UseParallel = 'always' %開啟并行計算
tic, [bp,fvalp,exitflagp,outputp,solutionsp] = run(ms, problem, 100); toc
matlabpool close
結(jié)果:14 out of 100 local solver runs converged with a positive local solver exit flag.
Elapsed time is 4.358762 seconds.Sending a stop signal to all the labs ... stopped.可以看出,運行時間減少,提高了效率。
- 再看一個尋找最小值的問題
%% Objective Function
% We wish find the minimum of the |peaks| function
clear all, close all, clc
peaks
%% Nonlinear Constraint Function
% Subject to a nonlinear constraint defined by a circular region of radius
% three around the origin
type circularConstraint
%% Define Optimization Problem
problem = createOptimProblem('fmincon',...
'objective',@(x) peaks(x(1),x(2)), ...
'nonlcon',@circularConstraint,...
'x0',[-1 -1],...
'lb',[-3 -3],...
'ub',[3 3],...
'options',optimset('OutputFcn',...
@peaksPlotIterates))
%% Run the solver |fmincon| from the inital point
% We can see the solution is not the global minimum
[x,f] = fmincon(problem)
這種方法只能尋找局部最優(yōu)。
現(xiàn)在用全局優(yōu)化算法:
%% Use |MultiStart| to Find the Global Minimum
% Define the multistart solver
close all
ms = MultiStart %這里可以換成GlobalSearch
%% Run |Multistart|
% Well use 5 starting points
[x,f,exitflag,output,solutions] = run(ms, problem, 5)
- 再舉一個模擬退火即模式搜索的算法 :
[x fval] = simulannealbnd(@objfun,x0,lb,ub,options)
%% Objective Function
% We wish find the minimum of the |peaks| function
clear all, close all, clc
peaks
%% Nonlinear Constraint Function
% Subject to a nonlinear constraint defined by a circular region of radius
% three around the origin
type circularConstraint
%% Define Optimization Problem
problem = createOptimProblem('fmincon',...
'objective',@(x) peaks(x(1),x(2)), ...
'nonlcon',@circularConstraint,...
'x0',[-1 -1],...
'lb',[-3 -3],...
'ub',[3 3],...
'options',optimset('OutputFcn',...
@peaksPlotIterates))
%% Run the solver |fmincon| from the inital point
% We can see the solution is not the global minimum
[x,f] = fmincon(problem)
%% Use Simmulated Annealing to Find the Global Minimum
% Solve the problem using simmulated annealing. Note that simmulated
% annealing does not support nonlinear so we need to account for this in
% the objective function.
problem.solver = 'simulannealbnd';
problem.objective = @(x) peaks(x(1),x(2)) + (x(1)^2 + x(2)^2 - 9);
problem.options = saoptimset('OutputFcn',@peaksPlotIterates,...
'Display','iter',...
'InitialTemperature',10,...
'MaxIter',300)
[x,f] = simulannealbnd(problem)
f = peaks(x(1),x(2))
- Use Pattern Search to Find the Global Minimum
%% Use Pattern Search to Find the Global Minimum
% Solve the problem using pattern search.
problem.solver = 'patternsearch';
problem.options = psoptimset('OutputFcn',@peaksPlotIterates,...
'Display','iter',...
'SearchMethod',{@searchlhs})
[x,f] = patternsearch(problem)