一、关于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 all
figure
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