文章目录
- 一、关于matlab的fmincon函数
- 二、使用匿名函数句柄传入额外参数或数据例子
一、关于matlab的fmincon函数
fmincon是matlab的带约束的非线性优化模型的求解函数,可以求解优化模型的局部最优解。带约束的非线性优化模型可以描述为:
fmincon函数完整的调用格式为:
[x,fval,exitflag,output,lambda,grad,hessian] = fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon,options)
可以在命令行窗口敲doc fmincon,查看其具体用法。
上述调用格式中,fun为目标函数,通常为关于变量 x x x的函数,如 f ( x ) = x 2 + 1 f(x)=x^2+1 f(x)=x2+1。在一些场合下,你的目标函数可能是带参数的,如 f ( x ) = a x 2 + 1 f(x)=ax^2+1 f(x)=ax2+1,然后 a a a的取值可能是一系列的值,如 a = 1 , 2 , 3 , . . . a=1,2,3,... a=1,2,3,...。当然,此时你可以在编写目标函数fun的function文件时,将 a a a定义为全局变量,将 a a a的值传给目标函数。但是,这种做法不够好,全局变量导致程序间耦合。那么,有什么方法可以解决该问题吗?有,可以使用匿名函数句柄传入参数!
类似的,对于非线性约束nonlcon函数,有时候你可能需要传入一些已知的数据,这时可以使用匿名函数句柄传入数据。
下面是非线性约束nonlcon函数,使用匿名函数句柄传入数据的例子。
二、使用匿名函数句柄传入额外参数或数据例子
最小覆盖圆算法比较高效的解法可以参考博文:最小覆盖圆(附完整代码)。这里通过建立非线性优化模型来求解最小覆盖圆问题。
设平面圆的方程为:
( x − x 0 ) 2 + ( y − y 0 ) 2 = R 2 (1) (x-x_0)^2+(y-y_0)^2=R^2\tag 1 (x−x0)2+(y−y0)2=R2(1)
其中, ( x 0 , y 0 ) (x_0,y_0) (x0,y0)为圆心, R R R为半径。
最小覆盖圆的非线性优化数学模型非常简单,如下:
m i n R ( x i − x 0 ) 2 + ( y i − y 0 ) 2 ≤ R 2 (2) min R \\ \tag 2 (x_i-x_0)^2+(y_i-y_0)^2\le R^2 minR(xi−x0)2+(yi−y0)2≤R2(2)
其中, ( x i , y i ) (x_i,y_i) (xi,yi)为已知数据点, i = 1 , 2 , 3 , . . . , n i=1,2,3,...,n i=1,2,3,...,n。
求解模型(2)的完整matlab代码:
function f = fun( var )
x0 = var(1);
y0 = var(2);
R = var(3);f = R;
end
function [c, ceq] = nonlcon(var, x, y)
x0 =var(1);
y0 =var(2);
R = var(3);c = (x - x0).^2 + (y - y0).^2 - R^2; %非线性不等式约束
ceq = []; %非线性等式约束
end
clc
clear
close allfigure
axis([0 10 0 10])
[x, y] = ginput(); %左键取点,回车键结束 var0 = [5; 5; 5]; %迭代初值
A = [];
b = [];
Aeq = [];
beq = [];
lb = [];
ub = [];
[var,fval,exitflag,output] = fmincon(@fun, var0, A, b, Aeq, beq, lb, ub,@(var)nonlcon(var, x, y)) %使用匿名函数句柄, 关键所在@(var)nonlcon(var, x, y)x0 = var(1);
y0 = var(2);
R = var(3);
theta = 0: 0.01 : 2 * pi;
X = x0 + cos(theta) * R;
Y = y0 + sin(theta) * R;plot(x, y, '+')
hold on
plot(X, Y,'-')
axis equal