35.利用fminsearch解 多元变量无约束条件下的函数最小值(matlab程序)

1. 简述

1.fminsearch函数基本语法

函数功能:使用无导数法计算无约束多变量函数的最小值

语法
x = fminsearch(fun,x0)
x = fminsearch(fun,x0,options)
x = fminsearch(problem)
[x,fval] = fminsearch(___)
[x,fval,exitflag] = fminsearch(___)
[x,fval,exitflag,output] = fminsearch(___)
说明
非线性规划求解器。搜索由以下公式指定的问题的最小值:
min f(x)
f(x) 是返回标量的函数,x 是向量或矩阵;请参阅矩阵参数。
x = fminsearch(fun,x0) 在点 x0 处开始并尝试求 fun 中描述的函数的局部最小值 x。
x = fminsearch(fun,x0,options) 使用 options 所指定的优化选项执行最小化。使用 optimset 可设置这些选项。
x = fminsearch(problem) 求 problem 的最小值,它是 problem 中所述的一个结构体。
[x,fval] = fminsearch(___),对任何上述输入语法,在 fval 中返回目标函数 fun 在解 x 处的值。
[x,fval,exitflag] = fminsearch(___) 还返回描述退出条件的值 exitflag。
[x,fval,exitflag,output] = fminsearch(___) 还会返回结构体 output 以及有关优化过程的信息。

2. 代码

主程序:

% 通过绘图确定一个初始值;然后进行迭代找到真正的最小值;

clc

clear

[x,y]=meshgrid(-6:.5:6);

f= 8*x-4*y +x.^2+3*y.^2;

surfc(x,y,f)

x0=[0,0];

%[x,fval,exitflag]=fminunc(@(x)(8*x(1)-4*x(2) +x(1).^2+3*x(2).^2),x0)

options=optimset('display','iter','Tolx',1e-8);

[x,fval,exitflag]=fminunc(@(x)(8*x(1)-4*x(2) +x(1).^2+3*x(2).^2),x0,options)

[x_fminsearch,fval_fminsearch,exitflag]=fminsearch(@(x)(8*x(1)-4*x(2) +x(1).^2+3*x(2).^2),x0,options)

子程序:

function [x,fval,exitflag,output] = fminsearch(funfcn,x,options,varargin)

%FMINSEARCH Multidimensional unconstrained nonlinear minimization (Nelder-Mead).

% X = FMINSEARCH(FUN,X0) starts at X0 and attempts to find a local minimizer

% X of the function FUN. FUN is a function handle. FUN accepts input X and

% returns a scalar function value F evaluated at X. X0 can be a scalar, vector

% or matrix.

%

% X = FMINSEARCH(FUN,X0,OPTIONS) minimizes with the default optimization

% parameters replaced by values in the structure OPTIONS, created

% with the OPTIMSET function. See OPTIMSET for details. FMINSEARCH uses

% these options: Display, TolX, TolFun, MaxFunEvals, MaxIter, FunValCheck,

% PlotFcns, and OutputFcn.

%

% X = FMINSEARCH(PROBLEM) finds the minimum for PROBLEM. PROBLEM is a

% structure with the function FUN in PROBLEM.objective, the start point

% in PROBLEM.x0, the options structure in PROBLEM.options, and solver

% name 'fminsearch' in PROBLEM.solver.

%

% [X,FVAL]= FMINSEARCH(...) returns the value of the objective function,

% described in FUN, at X.

%

% [X,FVAL,EXITFLAG] = FMINSEARCH(...) returns an EXITFLAG that describes

% the exit condition. Possible values of EXITFLAG and the corresponding

% exit conditions are

%

% 1 Maximum coordinate difference between current best point and other

% points in simplex is less than or equal to TolX, and corresponding

% difference in function values is less than or equal to TolFun.

% 0 Maximum number of function evaluations or iterations reached.

% -1 Algorithm terminated by the output function.

%

% [X,FVAL,EXITFLAG,OUTPUT] = FMINSEARCH(...) returns a structure

% OUTPUT with the number of iterations taken in OUTPUT.iterations, the

% number of function evaluations in OUTPUT.funcCount, the algorithm name

% in OUTPUT.algorithm, and the exit message in OUTPUT.message.

%

% Examples

% FUN can be specified using @:

% X = fminsearch(@sin,3)

% finds a minimum of the SIN function near 3.

% In this case, SIN is a function that returns a scalar function value

% SIN evaluated at X.

%

% FUN can be an anonymous function:

% X = fminsearch(@(x) norm(x),[1;2;3])

% returns a point near the minimizer [0;0;0].

%

% FUN can be a parameterized function. Use an anonymous function to

% capture the problem-dependent parameters:

% f = @(x,c) x(1).^2+c.*x(2).^2; % The parameterized function.

% c = 1.5; % The parameter.

% X = fminsearch(@(x) f(x,c),[0.3;1])

%

% FMINSEARCH uses the Nelder-Mead simplex (direct search) method.

%

% See also OPTIMSET, FMINBND, FUNCTION_HANDLE.

% Reference: Jeffrey C. Lagarias, James A. Reeds, Margaret H. Wright,

% Paul E. Wright, "Convergence Properties of the Nelder-Mead Simplex

% Method in Low Dimensions", SIAM Journal of Optimization, 9(1):

% p.112-147, 1998.

% Copyright 1984-2018 The MathWorks, Inc.

defaultopt = struct('Display','notify','MaxIter','200*numberOfVariables',...

'MaxFunEvals','200*numberOfVariables','TolX',1e-4,'TolFun',1e-4, ...

'FunValCheck','off','OutputFcn',[],'PlotFcns',[]);

% If just 'defaults' passed in, return the default options in X

if nargin == 1 && nargout <= 1 && strcmpi(funfcn,'defaults')

x = defaultopt;

return

end

if nargin < 3, options = []; end

% Detect problem structure input

if nargin == 1

if isa(funfcn,'struct')

[funfcn,x,options] = separateOptimStruct(funfcn);

else % Single input and non-structure

error('MATLAB:fminsearch:InputArg',...

getString(message('MATLAB:optimfun:fminsearch:InputArg')));

end

end

if nargin == 0

error('MATLAB:fminsearch:NotEnoughInputs',...

getString(message('MATLAB:optimfun:fminsearch:NotEnoughInputs')));

end

% Check for non-double inputs

if ~isa(x,'double')

error('MATLAB:fminsearch:NonDoubleInput',...

getString(message('MATLAB:optimfun:fminsearch:NonDoubleInput')));

end

n = numel(x);

numberOfVariables = n;

% Check that options is a struct

if ~isempty(options) && ~isa(options,'struct')

error('MATLAB:fminsearch:ArgNotStruct',...

getString(message('MATLAB:optimfun:commonMessages:ArgNotStruct', 3)));

end

printtype = optimget(options,'Display',defaultopt,'fast');

tolx = optimget(options,'TolX',defaultopt,'fast');

tolf = optimget(options,'TolFun',defaultopt,'fast');

maxfun = optimget(options,'MaxFunEvals',defaultopt,'fast');

maxiter = optimget(options,'MaxIter',defaultopt,'fast');

funValCheck = strcmp(optimget(options,'FunValCheck',defaultopt,'fast'),'on');

% In case the defaults were gathered from calling: optimset('fminsearch'):

if ischar(maxfun) || isstring(maxfun)

if strcmpi(maxfun,'200*numberofvariables')

maxfun = 200*numberOfVariables;

else

error('MATLAB:fminsearch:OptMaxFunEvalsNotInteger',...

getString(message('MATLAB:optimfun:fminsearch:OptMaxFunEvalsNotInteger')));

end

end

if ischar(maxiter) || isstring(maxiter)

if strcmpi(maxiter,'200*numberofvariables')

maxiter = 200*numberOfVariables;

else

error('MATLAB:fminsearch:OptMaxIterNotInteger',...

getString(message('MATLAB:optimfun:fminsearch:OptMaxIterNotInteger')));

end

end

switch printtype

case {'notify','notify-detailed'}

prnt = 1;

case {'none','off'}

prnt = 0;

case {'iter','iter-detailed'}

prnt = 3;

case {'final','final-detailed'}

prnt = 2;

case 'simplex'

prnt = 4;

otherwise

prnt = 1;

end

% Handle the output

outputfcn = optimget(options,'OutputFcn',defaultopt,'fast');

if isempty(outputfcn)

haveoutputfcn = false;

else

haveoutputfcn = true;

xOutputfcn = x; % Last x passed to outputfcn; has the input x's shape

% Parse OutputFcn which is needed to support cell array syntax for OutputFcn.

outputfcn = createCellArrayOfFunctions(outputfcn,'OutputFcn');

end

% Handle the plot

plotfcns = optimget(options,'PlotFcns',defaultopt,'fast');

if isempty(plotfcns)

haveplotfcn = false;

else

haveplotfcn = true;

xOutputfcn = x; % Last x passed to plotfcns; has the input x's shape

% Parse PlotFcns which is needed to support cell array syntax for PlotFcns.

plotfcns = createCellArrayOfFunctions(plotfcns,'PlotFcns');

end

header = ' Iteration Func-count min f(x) Procedure';

% Convert to function handle as needed.

funfcn = fcnchk(funfcn,length(varargin));

% Add a wrapper function to check for Inf/NaN/complex values

if funValCheck

% Add a wrapper function, CHECKFUN, to check for NaN/complex values without

% having to change the calls that look like this:

% f = funfcn(x,varargin{:});

% x is the first argument to CHECKFUN, then the user's function,

% then the elements of varargin. To accomplish this we need to add the

% user's function to the beginning of varargin, and change funfcn to be

% CHECKFUN.

varargin = [{funfcn}, varargin];

funfcn = @checkfun;

end

n = numel(x);

% Initialize parameters

rho = 1; chi = 2; psi = 0.5; sigma = 0.5;

onesn = ones(1,n);

two2np1 = 2:n+1;

one2n = 1:n;

% Set up a simplex near the initial guess.

xin = x(:); % Force xin to be a column vector

v = zeros(n,n+1); fv = zeros(1,n+1);

v(:,1) = xin; % Place input guess in the simplex! (credit L.Pfeffer at Stanford)

x(:) = xin; % Change x to the form expected by funfcn

fv(:,1) = funfcn(x,varargin{:});

func_evals = 1;

itercount = 0;

how = '';

% Initial simplex setup continues later

% Initialize the output and plot functions.

if haveoutputfcn || haveplotfcn

[xOutputfcn, optimValues, stop] = callOutputAndPlotFcns(outputfcn,plotfcns,v(:,1),xOutputfcn,'init',itercount, ...

func_evals, how, fv(:,1),varargin{:});

if stop

[x,fval,exitflag,output] = cleanUpInterrupt(xOutputfcn,optimValues);

if prnt > 0

disp(output.message)

end

return;

end

end

% Print out initial f(x) as 0th iteration

if prnt == 3

disp(' ')

disp(header)

fprintf(' %5.0f %5.0f %12.6g %s\n', itercount, func_evals, fv(1), how);

elseif prnt == 4

formatsave.format = get(0,'format');

formatsave.formatspacing = get(0,'formatspacing');

% reset format when done

oc1 = onCleanup(@()set(0,'format',formatsave.format));

oc2 = onCleanup(@()set(0,'formatspacing',formatsave.formatspacing));

format compact

format short e

disp(' ')

disp(how)

disp('v = ')

disp(v)

disp('fv = ')

disp(fv)

disp('func_evals = ')

disp(func_evals)

end

% OutputFcn and PlotFcns call

if haveoutputfcn || haveplotfcn

[xOutputfcn, optimValues, stop] = callOutputAndPlotFcns(outputfcn,plotfcns,v(:,1),xOutputfcn,'iter',itercount, ...

func_evals, how, fv(:,1),varargin{:});

if stop % Stop per user request.

[x,fval,exitflag,output] = cleanUpInterrupt(xOutputfcn,optimValues);

if prnt > 0

disp(output.message)

end

return;

end

end

% Continue setting up the initial simplex.

% Following improvement suggested by L.Pfeffer at Stanford

usual_delta = 0.05; % 5 percent deltas for non-zero terms

zero_term_delta = 0.00025; % Even smaller delta for zero elements of x

for j = 1:n

y = xin;

if y(j) ~= 0

y(j) = (1 + usual_delta)*y(j);

else

y(j) = zero_term_delta;

end

v(:,j+1) = y;

x(:) = y; f = funfcn(x,varargin{:});

fv(1,j+1) = f;

end

% sort so v(1,:) has the lowest function value

[fv,j] = sort(fv);

v = v(:,j);

how = 'initial simplex';

itercount = itercount + 1;

func_evals = n+1;

if prnt == 3

fprintf(' %5.0f %5.0f %12.6g %s\n', itercount, func_evals, fv(1), how)

elseif prnt == 4

disp(' ')

disp(how)

disp('v = ')

disp(v)

disp('fv = ')

disp(fv)

disp('func_evals = ')

disp(func_evals)

end

% OutputFcn and PlotFcns call

if haveoutputfcn || haveplotfcn

[xOutputfcn, optimValues, stop] = callOutputAndPlotFcns(outputfcn,plotfcns,v(:,1),xOutputfcn,'iter',itercount, ...

func_evals, how, fv(:,1),varargin{:});

if stop % Stop per user request.

[x,fval,exitflag,output] = cleanUpInterrupt(xOutputfcn,optimValues);

if prnt > 0

disp(output.message)

end

return;

end

end

exitflag = 1;

% Main algorithm: iterate until

% (a) the maximum coordinate difference between the current best point and the

% other points in the simplex is less than or equal to TolX. Specifically,

% until max(||v2-v1||,||v3-v1||,...,||v(n+1)-v1||) <= TolX,

% where ||.|| is the infinity-norm, and v1 holds the

% vertex with the current lowest value; AND

% (b) the corresponding difference in function values is less than or equal

% to TolFun. (Cannot use OR instead of AND.)

% The iteration stops if the maximum number of iterations or function evaluations

% are exceeded

while func_evals < maxfun && itercount < maxiter

if max(abs(fv(1)-fv(two2np1))) <= max(tolf,10*eps(fv(1))) && ...

max(max(abs(v(:,two2np1)-v(:,onesn)))) <= max(tolx,10*eps(max(v(:,1))))

break

end

% Compute the reflection point

% xbar = average of the n (NOT n+1) best points

xbar = sum(v(:,one2n), 2)/n;

xr = (1 + rho)*xbar - rho*v(:,end);

x(:) = xr; fxr = funfcn(x,varargin{:});

func_evals = func_evals+1;

if fxr < fv(:,1)

% Calculate the expansion point

xe = (1 + rho*chi)*xbar - rho*chi*v(:,end);

x(:) = xe; fxe = funfcn(x,varargin{:});

func_evals = func_evals+1;

if fxe < fxr

v(:,end) = xe;

fv(:,end) = fxe;

how = 'expand';

else

v(:,end) = xr;

fv(:,end) = fxr;

how = 'reflect';

end

else % fv(:,1) <= fxr

if fxr < fv(:,n)

v(:,end) = xr;

fv(:,end) = fxr;

how = 'reflect';

else % fxr >= fv(:,n)

% Perform contraction

if fxr < fv(:,end)

% Perform an outside contraction

xc = (1 + psi*rho)*xbar - psi*rho*v(:,end);

x(:) = xc; fxc = funfcn(x,varargin{:});

func_evals = func_evals+1;

if fxc <= fxr

v(:,end) = xc;

fv(:,end) = fxc;

how = 'contract outside';

else

% perform a shrink

how = 'shrink';

end

else

% Perform an inside contraction

xcc = (1-psi)*xbar + psi*v(:,end);

x(:) = xcc; fxcc = funfcn(x,varargin{:});

func_evals = func_evals+1;

if fxcc < fv(:,end)

v(:,end) = xcc;

fv(:,end) = fxcc;

how = 'contract inside';

else

% perform a shrink

how = 'shrink';

end

end

if strcmp(how,'shrink')

for j=two2np1

v(:,j)=v(:,1)+sigma*(v(:,j) - v(:,1));

x(:) = v(:,j); fv(:,j) = funfcn(x,varargin{:});

end

func_evals = func_evals + n;

end

end

end

[fv,j] = sort(fv);

v = v(:,j);

itercount = itercount + 1;

if prnt == 3

fprintf(' %5.0f %5.0f %12.6g %s\n', itercount, func_evals, fv(1), how)

elseif prnt == 4

disp(' ')

disp(how)

disp('v = ')

disp(v)

disp('fv = ')

disp(fv)

disp('func_evals = ')

disp(func_evals)

end

% OutputFcn and PlotFcns call

if haveoutputfcn || haveplotfcn

[xOutputfcn, optimValues, stop] = callOutputAndPlotFcns(outputfcn,plotfcns,v(:,1),xOutputfcn,'iter',itercount, ...

func_evals, how, fv(:,1),varargin{:});

if stop % Stop per user request.

[x,fval,exitflag,output] = cleanUpInterrupt(xOutputfcn,optimValues);

if prnt > 0

disp(output.message)

end

return;

end

end

end % while

x(:) = v(:,1);

fval = fv(:,1);

output.iterations = itercount;

output.funcCount = func_evals;

output.algorithm = 'Nelder-Mead simplex direct search';

% OutputFcn and PlotFcns call

if haveoutputfcn || haveplotfcn

callOutputAndPlotFcns(outputfcn,plotfcns,x,xOutputfcn,'done',itercount, func_evals, how, fval, varargin{:});

end

if func_evals >= maxfun

msg = getString(message('MATLAB:optimfun:fminsearch:ExitingMaxFunctionEvals', sprintf('%f',fval)));

if prnt > 0

disp(' ')

disp(msg)

end

exitflag = 0;

elseif itercount >= maxiter

msg = getString(message('MATLAB:optimfun:fminsearch:ExitingMaxIterations', sprintf('%f',fval)));

if prnt > 0

disp(' ')

disp(msg)

end

exitflag = 0;

else

msg = ...

getString(message('MATLAB:optimfun:fminsearch:OptimizationTerminatedXSatisfiesCriteria', ...

sprintf('%e',tolx), sprintf('%e',tolf)));

if prnt > 1

disp(' ')

disp(msg)

end

exitflag = 1;

end

output.message = msg;

%--------------------------------------------------------------------------

function [xOutputfcn, optimValues, stop] = callOutputAndPlotFcns(outputfcn,plotfcns,x,xOutputfcn,state,iter,...

numf,how,f,varargin)

% CALLOUTPUTANDPLOTFCNS assigns values to the struct OptimValues and then calls the

% outputfcn/plotfcns.

%

% state - can have the values 'init','iter', or 'done'.

% For the 'done' state we do not check the value of 'stop' because the

% optimization is already done.

optimValues.iteration = iter;

optimValues.funccount = numf;

optimValues.fval = f;

optimValues.procedure = how;

xOutputfcn(:) = x; % Set x to have user expected size

stop = false;

state = char(state);

% Call output functions

if ~isempty(outputfcn)

switch state

case {'iter','init'}

stop = callAllOptimOutputFcns(outputfcn,xOutputfcn,optimValues,state,varargin{:}) || stop;

case 'done'

callAllOptimOutputFcns(outputfcn,xOutputfcn,optimValues,state,varargin{:});

end

end

% Call plot functions

if ~isempty(plotfcns)

switch state

case {'iter','init'}

stop = callAllOptimPlotFcns(plotfcns,xOutputfcn,optimValues,state,varargin{:}) || stop;

case 'done'

callAllOptimPlotFcns(plotfcns,xOutputfcn,optimValues,state,varargin{:});

end

end

%--------------------------------------------------------------------------

function [x,FVAL,EXITFLAG,OUTPUT] = cleanUpInterrupt(xOutputfcn,optimValues)

% CLEANUPINTERRUPT updates or sets all the output arguments of FMINBND when the optimization

% is interrupted.

% Call plot function driver to finalize the plot function figure window. If

% no plot functions have been specified or the plot function figure no

% longer exists, this call just returns.

callAllOptimPlotFcns('cleanuponstopsignal');

x = xOutputfcn;

FVAL = optimValues.fval;

EXITFLAG = -1;

OUTPUT.iterations = optimValues.iteration;

OUTPUT.funcCount = optimValues.funccount;

OUTPUT.algorithm = 'Nelder-Mead simplex direct search';

OUTPUT.message = getString(message('MATLAB:optimfun:fminsearch:OptimizationTerminatedPrematurelyByUser'));

%--------------------------------------------------------------------------

function f = checkfun(x,userfcn,varargin)

% CHECKFUN checks for complex or NaN results from userfcn.

f = userfcn(x,varargin{:});

% Note: we do not check for Inf as FMINSEARCH handles it naturally.

if isnan(f)

error('MATLAB:fminsearch:checkfun:NaNFval',...

getString(message('MATLAB:optimfun:fminsearch:checkfun:NaNFval', localChar( userfcn ))));

elseif ~isreal(f)

error('MATLAB:fminsearch:checkfun:ComplexFval',...

getString(message('MATLAB:optimfun:fminsearch:checkfun:ComplexFval', localChar( userfcn ))));

end

%--------------------------------------------------------------------------

function strfcn = localChar(fcn)

% Convert the fcn to a character array for printing

if ischar(fcn)

strfcn = fcn;

elseif isstring(fcn) || isa(fcn,'inline')

strfcn = char(fcn);

elseif isa(fcn,'function_handle')

strfcn = func2str(fcn);

else

try

strfcn = char(fcn);

catch

strfcn = getString(message('MATLAB:optimfun:fminsearch:NameNotPrintable'));

end

end

3. 运行结果

相关推荐
Chris _data10 分钟前
如何提升编程能力第二篇
开发语言·青少年编程
遇到困难睡大觉哈哈10 分钟前
JavaScript面向对象
开发语言·javascript·ecmascript
十五年专注C++开发12 分钟前
C++中的链式操作原理与应用(一)
开发语言·c++·设计模式
我是Superman丶15 分钟前
【前端】js vue 屏蔽BackSpace键删除键导致页面后退的方法
开发语言·前端·javascript
qq_4856689930 分钟前
算法习题--蓝桥杯
算法·职场和发展·蓝桥杯
就是有点傻31 分钟前
C#中面试的常见问题006
开发语言·面试·c#·wpf
waves浪游33 分钟前
类和对象(中)
c语言·开发语言·数据结构·c++·算法·链表
做人不要太理性37 分钟前
【算法一周目】滑动窗口(2)
c++·算法·leetcode·哈希算法·散列表·滑动窗口
青い月の魔女37 分钟前
数据结构初阶---复杂度
c语言·数据结构·笔记·学习·算法
汤姆和杰瑞在瑞士吃糯米粑粑37 分钟前
【优先算法学习】双指针--结合题目讲解学习
c++·学习·算法