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. 运行结果

相关推荐
封步宇AIGC4 分钟前
量化交易系统开发-实时行情自动化交易-3.4.1.2.A股交易数据
人工智能·python·机器学习·数据挖掘
何曾参静谧4 分钟前
「Py」Python基础篇 之 Python都可以做哪些自动化?
开发语言·python·自动化
m0_523674215 分钟前
技术前沿:从强化学习到Prompt Engineering,业务流程管理的创新之路
人工智能·深度学习·目标检测·机器学习·语言模型·自然语言处理·数据挖掘
Prejudices8 分钟前
C++如何调用Python脚本
开发语言·c++·python
HappyAcmen15 分钟前
IDEA部署AI代写插件
java·人工智能·intellij-idea
SoraLuna18 分钟前
「Mac玩转仓颉内测版7」入门篇7 - Cangjie控制结构(下)
算法·macos·动态规划·cangjie
我狠狠地刷刷刷刷刷21 分钟前
中文分词模拟器
开发语言·python·算法
鸽鸽程序猿21 分钟前
【算法】【优选算法】前缀和(上)
java·算法·前缀和
wyh要好好学习24 分钟前
C# WPF 记录DataGrid的表头顺序,下次打开界面时应用到表格中
开发语言·c#·wpf
AitTech25 分钟前
C#实现:电脑系统信息的全面获取与监控
开发语言·c#