现代科学运算-matlab语言与应用
东北大学 http://www.icourses.cn/home/ (薛定宇)
《高等应用数学问题的MATLAB求解(第四版)》
代码可在matlab r2016b 运行。
06 代数方程与最优化问题的计算机求解
06.01 代数方程的图解法
代数方程的图解法
一元方程的图解法
一元方程的标准形式 f(x) = 0
ezplot()函数可以绘制函数曲线,其解为与实轴交点
二元方程的图解法
联立方程f(x, y) = 0 与 g(x, y) = 0
用 ezplot函数在同一坐标系下绘制出两个隐函数方程的曲线,其交点为联立方程的解
例6-1 图解法解一元方程
用图解法求解方程
e−3tsin(4t+2)+4e−0.5tcos2t=0.5
e
−
3
t
sin
(
4
t
+
2
)
+
4
e
−
0.5
t
cos
2
t
=
0.5
ezplot('exp(-3*t)*sin(4*t+2)+4*exp(-0.5*t)*cos(2*t)-0.5', [0 5])
line([0, 5], [0, 0])
% 验证 t = 0.6738
t = 0.6738
exp(-3*t)*sin(4*t+2)+4*exp(-0.5*t)*cos(2*t)-0.5
% ans = -2.9852e-04
例6-2 图解法解二元方程
用图解法求解联立方程:
{x2e−xy2/2+e−x/2sin(xy)=0y2cos(y+x2)+x2ex+y=0
{
x
2
e
−
x
y
2
/
2
+
e
−
x
/
2
sin
(
x
y
)
=
0
y
2
cos
(
y
+
x
2
)
+
x
2
e
x
+
y
=
0
% 画第一个函数:
ezplot('x^2*exp(-x*y^2/2) + exp(-x/2)*sin(x*y)')
% 画第二个函数:
hold on;
ezplot('y^2*cos(y+x^2) + x^2*exp(x+y)')
hold off;
例6-3 图解法解方法
试用图解法求解二元方程
{x2+y2−1=00.75x3−y+0.9=0
{
x
2
+
y
2
−
1
=
0
0.75
x
3
−
y
+
0.9
=
0
ezplot('x^2 + y^2 - 1');
hold on;
ezplot('0.75*x^3 - y + 0.9')
hold off;
% 丢掉了2对复数根
06.02 多项式方程准解析解法
多项式方程的准解析解法
Abel-Ruffini定理说明:5阶及以上的多项式型方程没有解析解方法
特殊的高阶方程如多项式方程,可以用solve函数直接解出,必要时用vpasolve函数求准解析解
传统的数值算法得出的解不精确,这里只考虑多项式型方程的高精度求解问题
方程求解的matlab函数
求解多项式型方程的函数调用格式
最简调用方式 S = solve(eqn1, eqn2, …, eqnn)
直接得出根: [x,y, …] = solve(eqn1, eqn2, …, eqnn)
指定变量:[x, y, …] = solve(eqn1, eqn2, …, eqnn, ‘x, y, …’)
例6-4 鸡兔同笼问题
鸡兔同笼问题可以列出线性联立方程
{x+y=352x+4y=94
{
x
+
y
=
35
2
x
+
4
y
=
94
syms x y;
[x0 y0] = solve(x+y == 35, 2*x+4*y==94)
二元方程问题 {x2+y2−1=00.75x3−y+0.9=0 { x 2 + y 2 − 1 = 0 0.75 x 3 − y + 0.9 = 0
[x1, y1] = vpasolve(x^2+y^2-1==0, 0.75*x^3-y+0.9==0)
例6-6 三元方程解析解
⎧⎩⎨⎪⎪x+3y3+2z2=1/2x2+3y+z3=2x3+2z+2y2=2/4
{
x
+
3
y
3
+
2
z
2
=
1
/
2
x
2
+
3
y
+
z
3
=
2
x
3
+
2
z
+
2
y
2
=
2
/
4
syms x y z;
F = [x+3*y^3+2*z^2-1/2, x^2+3*y+z^3-2, x^3+2*z+2*y^2-2/4];
[x0, y0, z0] = vpasolve(F, [x, y, z])
size(x0)
% 检验
norm(subs(F, {x, y, z}, {x0, y0, z0}))
例6-7 复杂方程的准解析解
⎧⎩⎨⎪⎪⎪⎪⎪⎪12x2+x+32+21y+52y2+31x3=0y2+32x+1x4+5y4=0
{
1
2
x
2
+
x
+
3
2
+
2
1
y
+
5
2
y
2
+
3
1
x
3
=
0
y
2
+
3
2
x
+
1
x
4
+
5
y
4
=
0
syms x y;
F = [x^2/2 + x + 3/2 + 2/y + 5/(2*y^2)+3/x^3;y/2+3/(2*x)+1/x^4+5*y^4];
[x0, y0] = vpasolve(F),
size(x0),
%检验
e = norm(subs(F, {x, y}, {x0, y0}))
例6-8 含有参数的方程
{x2+ax2+6b+3y2=0y=a+x+3
{
x
2
+
a
x
2
+
6
b
+
3
y
2
=
0
y
=
a
+
x
+
3
syms x y;
syms a b;
[x1, y1] = solve(x^2+a*x^2 + 6*b + 3*y^2 == 0, y==a + x + 3, [x, y])
% [x, y] 指明要求的变量是x, y,而不是a, b
更高此带有参数的方程没有解析解
准解析解方法的优势和劣势
优势:可以求出解析解或高精度数值解,可以指定初值,可以同时求出方程的实数根和复数根
劣势:使用于多项式方程,求解其他类型方程没有优势,相比后面介绍的数值解方法速度较慢
06.03 非线性方程的数值解法
一般非线性方程数值解
求多元方程的一个实数根
s = fsolve(fun, x0)
[x, f, flag, out] = fsolve(fun, x0, opt)
[x, f, flag,out] = fsolve(fun, x0, opt, p1, p2, …)
求解代数方程组的步骤
设置变量,使等式变成如下形式
y = f(x) = 0
按如下方程描述等式
M-函数
匿名函数
inline函数,不推荐
求解方程组
验证解的正确性
例6-9 方程的数值解
{x2+y2−1=00.75x3−y+0.9=0
{
x
2
+
y
2
−
1
=
0
0.75
x
3
−
y
+
0.9
=
0
选择变量
x1=x,x2=y
x
1
=
x
,
x
2
=
y
把原始方程组变为
{x21+x22−1=00.75x31−x2+0.9=0
{
x
1
2
+
x
2
2
−
1
=
0
0.75
x
1
3
−
x
2
+
0.9
=
0
变成矩阵形式
y=f(x)y=[x21+x22−10.75x31−x2+0.9]=0
y
=
f
(
x
)
y
=
[
x
1
2
+
x
2
2
−
1
0.75
x
1
3
−
x
2
+
0.9
]
=
0
% m-函数
function y = myfun(x)
y = [x(1)*x(1) + x(2)*x(2) - 1; ...
0.75*x(1)^3 - x(2) + 0.9];
% 匿名函数
f = @(x) [x(1)*x(1) + x(2)*x(2) - 1; ...
0.75*x(1)^3 - x(2) + 0.9];
% inline函数
f = inline('[x(1)*x(1) + x(2)*x(2) - 1; ...
0.75*x(1)^3 - x(2) + 0.9];', 'x');
在初值下搜索根
当初值选为
x0=[1,2]T
x
0
=
[
1
,
2
]
T
f = @(x) [x(1)*x(1) + x(2)*x(2) - 1; ...
0.75*x(1)^3 - x(2) + 0.9];
OPT = optimset;
OPT.LargeScale = 'off';
[x, Y, c, d] = fsolve(f, [1; 2], OPT)
当使用另一个搜索初始点 x0=[−1,0]T x 0 = [ − 1 , 0 ] T
[x, Y, c, d] = fsolve(f, [-1, 0]', OPT);
x, norm(Y), kk = d.funcCount
注意:选择不同的初值可能得出不同的结果
求解方程的控制参数
选择方法和修改控制精度的函数调用格式
获得默认的常用变量
opt = optimset;
设置控制参数
直接修改: opt.TolX = 1e-10
或 set(opt, ‘TolX’, 1e-10)
其它重要参数: TolFun, MaxIter, MaxFcnEvals等
控制求解精度
重新设置相关精度的控制变量
ff = optimset;
ff.TolX = 1e-16;
ff.TolFun = 1e-30;
[x, Y, c, d] = fsolve(f, [1; 2], ff)
所期望的精度可能过于严苛,无法达到,但能尽可能精确
可以得到双精度下的最好结果
06.04 多解矩阵方程通用解法
求解多解方程的全部解
Riccati方程(第四章)
ATX+XA−XBX+C=0
A
T
X
+
X
A
−
X
B
X
+
C
=
0
更多的非线性矩阵方程,例如,
广义Riccati方程
AX+XD−XBX+C=0
A
X
+
X
D
−
X
B
X
+
C
=
0
类Riccati方程
AX+XD−XBXT+C=0
A
X
+
X
D
−
X
B
X
T
+
C
=
0
还有很多其它矩阵方程
一种简单但很使用的思路
已知:选择了初值,则fsolve函数可以求解方程,一般能得出方程的数值解
如果初值选择为复数则有可能得出复数解
可以建立一个循环,甚至是死循环
随机选择初值,调用fsolve求解
若得出的解已被记录,则放弃该解,否则记录该解
如果一段时间没有找到新的解,则终止程序
用户可以用Ctrl+C键随时终端程序
函数调用:more_sols(f,
X0
X
0
, A,
ϵ
ϵ
,
tlim
t
lim
)
function more_sols(f,X0,varargin)
[A,tol,tlim]=default_vals({1000,eps,30},varargin{:}); [n,m,i]=size(X0);
if length(A)==1, a=-0.5*A; b=0.5*A; else, a=A(1); b=A(2); end
ar=real(a); br=real(b); ai=imag(a); bi=imag(b);
ff=optimset; ff.Display='off'; ff1=ff; ff.TolX=tol; ff.TolFun=tol; X=X0;
try, err=evalin('base','err'); catch, err=0; end, if i<=1; err=0; end, tic
while (1)
x0=ar+(br-ar)*rand(n,m);
if abs(imag(A))>1e-5, x0=x0+(ai+(bi-ai)*rand(n,m))*1i; end
[x,aa,key]=fsolve(f,x0,ff1);
t=toc; if t>tlim, break; end
if key>0, N=size(X,3);
for j=1:N, if norm(X(:,:,j)-x)<1e-5; key=0; break; end, end
if key>0, [x1,aa,key]=fsolve(f,x,ff);
if norm(x-x1)<1e-5 & key>0; X(:,:,i+1)=x1; assignin('base','X',X);
err=max([norm(aa),err]); assignin('base','err',err); i=i+1, tic
end, end, end, end
例6-11 求Riccati方程全部的根
求解下列Riccati方程组:
ATX+XA−XBX+C=0
A
T
X
+
X
A
−
X
B
X
+
C
=
0
其中
A=⎡⎣⎢−2−1010−1−3−2−2⎤⎦⎥,B=⎡⎣⎢2−1−1251−2−22⎤⎦⎥,C=⎡⎣⎢511−40−1445⎤⎦⎥
A
=
[
−
2
1
−
3
−
1
0
−
2
0
−
1
−
2
]
,
B
=
[
2
2
−
2
−
1
5
−
2
−
1
1
2
]
,
C
=
[
5
−
4
4
1
0
4
1
−
1
5
]
A = [-2, 1, -3; -1, 0, -2; 0, -1, -2];
B = [2, 2, -2; -1, 5, -2; -1, 1, 2];
C = [5, -4, 4; 1, 0, 4; 1, -1, 5];
f = @(X)A'*X+X*A-X*B*X+C;
more_sols(f, zeros(3, 3, 0));
X, err
原方程有8个实根,Ctrl+C中断求解或等几分钟自动停止
求复数根
more_sols(f, X, 1000+1000i);
X, err
例6-12 变形Riccati方程求解
变形Riccati方程
AX+XD−XBXT+C=0
A
X
+
X
D
−
X
B
X
T
+
C
=
0
A=⎡⎣⎢296175993⎤⎦⎥,B=⎡⎣⎢088322608⎤⎦⎥,C=⎡⎣⎢751064344⎤⎦⎥,D=⎡⎣⎢313923590⎤⎦⎥
A
=
[
2
1
9
9
7
9
6
5
3
]
,
B
=
[
0
3
6
8
2
0
8
2
8
]
,
C
=
[
7
0
3
5
6
4
1
4
4
]
,
D
=
[
3
9
5
1
2
9
3
3
0
]
求出并检验全部根
A = [2, 1, 9; 9, 7, 9; 6, 5, 3];
B = [0, 3, 6; 8, 2, 0; 8, 2, 8];
C = [7, 0, 3; 5, 6, 4; 1, 4, 4];
D = [3, 9, 5; 1, 2, 9; 3, 3, 0];
f = @(X) A*X + X*D - X*B*X.' + C;
more_sols(f, zeros(3, 3, 0));
X, err
more_sols(f, X, 1000+1000i);
X, err
原方程有16个实根,还可以求出复数根,共40个根
例6-13 联立方程求解
求非线性方程组全部根
{x2e−xy2/2+e−x/2sin(xy)=0y2cos(y+x2)+x2ex+y=0
{
x
2
e
−
x
y
2
/
2
+
e
−
x
/
2
sin
(
x
y
)
=
0
y
2
cos
(
y
+
x
2
)
+
x
2
e
x
+
y
=
0
感兴趣区域
−2π≤x,y≤2π
−
2
π
≤
x
,
y
≤
2
π
% 图解法
ezplot('x^2*exp(-x*y^2/2) + exp(-x/2)*sin(x*y)')
hold on;
ezplot('y^2*cos(y+x^2) + x^2*exp(x+y)')
hold off;
f = @(x) [x(1)^2*exp(-x(1)*x(2)^2/2) + ...
exp(-x(1)/2)*sin(x(1)*x(2));
x(2)^2*cos(x(2)+x(1)^2) + ...
x(1)^2 * exp(x(1) + x(2))];
more_sols(f, [0; 0], [-2*pi, 2*pi]);
err
用图解法显示找出的全部根
x = X(1, 1, :);
x = x(:);
y = X(2, 1, :);
y = y(:);
plot(x, y, 'o')
高精度求解函数
将more_sols中的fsolve用vpasolve取代
function more_vpasols(f,X0,varargin)
[A,tlim]=default_vals({1000,60},varargin{:}); X=X0;
if length(A)==1, a=-0.5*A; b=0.5*A; else, a=A(1); b=A(2); end
ar=real(a); br=real(b); ai=imag(a); bi=imag(b); [i,n]=size(X0); tic
while (1),
x0=ar+(br-ar)*rand(1,n);
if abs(imag(A))>1e-5, x0=x0+(ai+(bi-ai)*rand(1,n))*1i; end
V=vpasolve(f,x0); N=size(X,1); key=1; x=sol2vec(V);
if length(x)>0
t=toc; if t>tlim, break; end
for j=1:N, if norm(X(j,:)-x)<1e-5; key=0; break; end, end
if key>0, i=i+1;
X=[X; x]; disp(['i=',int2str(i)]); assignin('base','X',X); tic
end, end, end
function v=sol2vec(A)
v=[]; A=struct2cell(A); for i=1:length(A), v=[v, A{i}]; end
06.05 无约束最优化问题
无约束最优化问题的数学描述
无约束最小化问题的数学描述
minxf(x)
min
x
f
(
x
)
目标函数是一个标量函数 f(.)
向量
x=[x1,x2,⋯,xn]T
x
=
[
x
1
,
x
2
,
⋯
,
x
n
]
T
决策变量,或优化变量
物理意义:求取一组x向量,使得最优化目标函数f(x)为最小
最大化问题:
maxxf(x)=minx−f(x)
max
x
f
(
x
)
=
min
x
−
f
(
x
)
解析解法和图解法
无约束最优化问题的必要条件:
∂f∂x1|x=x∗=0,∂f∂x2|x−x∗=0,⋯,∂f∂xn|x=x∗=0
∂
f
∂
x
1
|
x
=
x
∗
=
0
,
∂
f
∂
x
2
|
x
−
x
∗
=
0
,
⋯
,
∂
f
∂
x
n
|
x
=
x
∗
=
0
其中,
x∗
x
∗
是最优点
方程的求解可能比解方程更麻烦,有时可能需要二阶导数运算
基于matlab的数值解法
数值最优化函数调用格式
x = fminunc(fun, x0)
x = fminsearch(fun, x0)
[x, f, flag, out] = fminsearch(fun, x0, opt, p1, p2, …)
[x, f, flag, out] = fminunc(fun, x0, opt, p1, p2, …)
目标函数的三种描述方法
M-函数(入口)
function y = fun(x)
function y = fun(x, p1, p2, …)
匿名函数
f = @(x) …
f = @(x) (x, p1, p2, …) …
inline函数(不推荐使用)
在匿名函数或inline函数中无法使用中间变量
例6-21 简单最优化问题举例
目标函数:
z=(x2−2x)e−x2−y2−xy
z
=
(
x
2
−
2
x
)
e
−
x
2
−
y
2
−
x
y
变量替换:
x1=x,x2=y
x
1
=
x
,
x
2
=
y
新目标函数:
f(x)=(x21−2x1)e−x21−x22−x1x2
f
(
x
)
=
(
x
1
2
−
2
x
1
)
e
−
x
1
2
−
x
2
2
−
x
1
x
2
f = @(x) (x(1)^2-2*x(1))*exp(-x(1)^2-x(2)^2-x(1)*x(2));
x0 = [0; 0];
[x, b, c, d] = fminsearch(f, x0)
% 使用fminunc()
[x, b, c, d] = fminunc(f, x0)
中间过程提取
编写一个提取、绘制中间点的函数myout,将属性Output设置成@myout
function stop = myout(x, optimValues, state)
stop = false;
switch state
case 'init', hold on;
case 'iter', plot(x(1), x(2), 'o');
text(x(1)+0.1, x(2), int2str(optimValues.interation));
case 'done', hold off;
end;
搜索中间结果:
绘制三维等高线获得并叠印中间结果
f = @(x) (x(1)^2-2*x(1))*exp(-x(1)^2-x(2)^2-x(1)*x(2));
[x, y] = meshgrid(-3: .1: 3, -2: .1: 2);
z = (x.^2-2*x).*exp(-x.^2-y.^2-x.*y);
contour(x, y, z, 30);
ff = optimset;
ff.OutputFcn = @myout;
x0 = [2 1];
x = fminunc(f, x0, ff)
最优化求解函数的另一种调用方法
建立最优化问题的“结构体”模型
例6-22 用结构体模型求解
problem.solver = 'fminunc';
problem.options = optimset;
problem.objective = @(x)(x(1)^2-2*x(1))*exp(-x(1)^2-x(2)^2-x(1)*x(2));
problem.x0 = [2; 1];
[x, b, c, d] = fminunc(problem)
06.06 全局最优解
全局最优解与局部最优解
最小值存在的必要条件是
df(x)dx=0
d
f
(
x
)
d
x
=
0
使用搜索方法,从初始值出发,可能找到一个这样的点,它是局部最小值
局部极小值中目标函数最小的为全局最小
整个目标函数可能存在多个局部最小值
搜索算法不一定能求出全局最小值
例6-23 基准测试函数 – Rastrigin函数
目标函数:
f(x1,x2)=20+x21+x22−10(cosπx1+cosπx2)
f
(
x
1
,
x
2
)
=
20
+
x
1
2
+
x
2
2
−
10
(
cos
π
x
1
+
cos
π
x
2
)
目标函数曲面绘制:
ezsurf('20 + x1^2+x2^2 - 10*(cos(pi*x1) + cos(pi*x2))')
% view(0, 90), shading flat % 俯视图
% view(0, 0), shading flat % 侧视图
选择不同初值,得出不同结果
一个全局最优解搜索函数
[x,
fmin
f
min
] = fminunc_global(fun, a, b, n, N)
function [x, f0] = fminunc_global(f, a, b, n, N, varargin)
k0 = 0;
f0 = Inf;
if strcmp(class(f), 'struct')
k0 = 1;
end;
for i = 1: N
x0 = a+(b-a)*rand(n, 1);
if k0 == 1
f.x0 = x0;
[x1 f1 key] = fminunc(f);
else
[x1 f1 key] = fminunc(f, x0, varargin{:});
end;
if key > 0 & f1 < f0
x = x1;
f0 = f1;
end;
end;
例6-25 改进的Rastrigin函数
将全局最优值做一个偏移
f(x1,x2)=20+(x1/30−1)2+(x2/20−1)2−10[cos(x1/30−1)π+cos(x2/20−1)π]
f
(
x
1
,
x
2
)
=
20
+
(
x
1
/
30
−
1
)
2
+
(
x
2
/
20
−
1
)
2
−
10
[
cos
(
x
1
/
30
−
1
)
π
+
cos
(
x
2
/
20
−
1
)
π
]
搜索100次,97%都能找到全局最优解,耗时1分钟
f = @(x) 20 + (x(1)/30 -1)^2 + (x(2)/20-1)^2 - ...
10*(cos(pi*(x(1)/30-1)) + cos(pi*(x(2)/20-1)));
F = [];
tic,
for i = 1:100
[x, f0] = fminunc_global(f, -100, 100, 2, 50);
F = [F, f0];
end;
toc
利用梯度求解最优化问题
有时,仅利用目标函数提供信息,很难得到精确的最优解。这是由于求解某些最优化问题收敛速度一般较慢,尤其是变量较多的最优化问题
可以利用梯度信息解决上述问题
例6-26 Rosenbrock函数
求Rosenbrock函数的无约束最优化问题
人造函数:
f(x1,x2)=100(x2−x21)2+(1−x1)2
f
(
x
1
,
x
2
)
=
100
(
x
2
−
x
1
2
)
2
+
(
1
−
x
1
)
2
% 绘制三维等高线图(香蕉函数)
[x, y] = meshgrid(0.5: 0.01: 1.5);
z = 100*(y - x.^2).^2 +(1-x).^2;
contour3(x, y, z, 100),
zlim([0, 310])
% 不用梯度信息
f = @(x)100*(x(2)-x(1)^2)^2 +(1-x(1))^2;
ff = optimset;
ff.TolX = 1e-10;
ff.TolFun = 1e-20;
x = fminunc(f, [0; 0], ff)
采用梯度信息求解
求梯度矩阵
syms x1 x2;
f = 100*(x2-x1^2)^2 + (1 - x1)^2;
J = jacobian(f, [x1, x2])
自包含梯度的目标函数
function [y, Gy] = c6fun3(x)
y = 100*(x(2)-x(1)^2)^2 + (1-x(1))^2;
Gy = [-400*(x(2)-x(1)^2)*x(1)-2+2*x(1);
200*x(2)-200*x(1)^2];
求解
ff.GradObj = 'on';
x = fminunc(@c6fun3, [0, 0], ff)
06.07 可行解区域
有约束最优化问题的计算机求解
约束条件与可行解区域
有约束非线性最优化问题的一般描述
minxs.t.G(x)≤0f(x)
min
x
s
.
t
.
G
(
x
)
≤
0
f
(
x
)
决策变量:
x=[x1,x2,⋯,xn]T
x
=
[
x
1
,
x
2
,
⋯
,
x
n
]
T
约束条件:
G(x)≤0
G
(
x
)
≤
0
满足约束条件的所有x称为可行解区域
在满足约束条件(
G(x≤0
G
(
x
≤
0
)的前提下最优
例6-28 图解法求最优化
图解法
maxxs.t.{9≥x21+x22x1+x2≤1(−x21−x2)
max
x
s
.
t
.
{
9
≥
x
1
2
+
x
2
2
x
1
+
x
2
≤
1
(
−
x
1
2
−
x
2
)
目标函数描述:
[x1, x2] = meshgrid(-3: .1: 3);
z = -x1.^2 - x2;
可行解区域描述
i = find(x1.^2 + x2.^2 > 9);
z(i) = NaN;
i = find(x1 + x2 > 1);
z(i) = NaN;
surf(x1, x2, z);
shading interp;
带有变量边界约束的最优化问题求解
带有变量边界约束的最优化问题的数学描述
minxs.t.xm≤x≤xMf(x)
min
x
s
.
t
.
x
m
≤
x
≤
x
M
f
(
x
)
其中,符号s.t.表示subject to
fminsearchbnd()函数在本书程序包中给出或从Mathworks的File Exchange下载
function [x,fval,exitflag,output]=fminsearchbnd3(fun,x0,LB,UB,options,varargin)
xsize = size(x0);
x0 = x0(:);
n=length(x0);
if (nargin<3) || isempty(LB)
LB = repmat(-inf,n,1);
else
LB = LB(:);
end
if (nargin<4) || isempty(UB)
UB = repmat(inf,n,1);
else
UB = UB(:);
end
if (n~=length(LB)) || (n~=length(UB))
error 'x0 is incompatible in size with either LB or UB.'
end
% set default options if necessary
if (nargin<5) || isempty(options)
options = optimset('fminsearch');
end
% stuff into a struct to pass around
params.args = varargin;
params.LB = LB;
params.UB = UB;
params.fun = fun;
params.n = n;
params.OutputFcn = [];
params.BoundClass = zeros(n,1);
for i=1:n
k = isfinite(LB(i)) + 2*isfinite(UB(i));
params.BoundClass(i) = k;
if (k==3) && (LB(i)==UB(i))
params.BoundClass(i) = 4;
end
end
x0u = x0;
k=1;
for i = 1:n
switch params.BoundClass(i)
case 1
% lower bound only
if x0(i)<=LB(i)
% infeasible starting value. Use bound.
x0u(k) = 0;
else
x0u(k) = sqrt(x0(i) - LB(i));
end
% increment k
k=k+1;
case 2
% upper bound only
if x0(i)>=UB(i)
% infeasible starting value. use bound.
x0u(k) = 0;
else
x0u(k) = sqrt(UB(i) - x0(i));
end
% increment k
k=k+1;
case 3
% lower and upper bounds
if x0(i)<=LB(i)
% infeasible starting value
x0u(k) = -pi/2;
elseif x0(i)>=UB(i)
% infeasible starting value
x0u(k) = pi/2;
else
x0u(k) = 2*(x0(i) - LB(i))/(UB(i)-LB(i)) - 1;
% shift by 2*pi to avoid problems at zero in fminsearch
% otherwise, the initial simplex is vanishingly small
x0u(k) = 2*pi+asin(max(-1,min(1,x0u(k))));
end
% increment k
k=k+1;
case 0
% unconstrained variable. x0u(i) is set.
x0u(k) = x0(i);
% increment k
k=k+1;
case 4
% fixed variable. drop it before fminsearch sees it.
% k is not incremented for this variable.
end
end
% if any of the unknowns were fixed, then we need to shorten
% x0u now.
if k<=n
x0u(k:n) = [];
end
% were all the variables fixed?
if isempty(x0u)
% All variables were fixed. quit immediately, setting the
% appropriate parameters, then return.
% undo the variable transformations into the original space
x = xtransform(x0u,params);
% final reshape
x = reshape(x,xsize);
% stuff fval with the final value
fval = feval(params.fun,x,params.args{:});
% fminsearchbnd was not called
exitflag = 0;
output.iterations = 0;
output.funcount = 1;
output.algorithm = 'fminsearch';
output.message = 'All variables were held fixed by the applied bounds';
% return with no call at all to fminsearch
return
end
% Check for an outputfcn. If there is any, then substitute my
% own wrapper function.
if ~isempty(options.OutputFcn)
params.OutputFcn = options.OutputFcn;
options.OutputFcn = @outfun_wrapper;
end
% now we can call fminsearch, but with our own
% intra-objective function.
[xu,fval,exitflag,output] = fminsearch(@intrafun,x0u,options,params);
% undo the variable transformations into the original space
x = xtransform(xu,params);
% final reshape
x = reshape(x,xsize);
% Use a nested function as the OutputFcn wrapper
function stop = outfun_wrapper(x,varargin);
% we need to transform x first
xtrans = xtransform(x,params);
% then call the user supplied OutputFcn
stop = params.OutputFcn(xtrans,varargin{1:(end-1)});
end
end % mainline end
% ======================================
% ========= begin subfunctions =========
% ======================================
function fval = intrafun(x,params)
% transform variables, then call original function
% transform
xtrans = xtransform(x,params);
% and call fun
fval = feval(params.fun,xtrans,params.args{:});
end % sub function intrafun end
% ======================================
function xtrans = xtransform(x,params)
% converts unconstrained variables into their original domains
xtrans = zeros(1,params.n);
% k allows some variables to be fixed, thus dropped from the
% optimization.
k=1;
for i = 1:params.n
switch params.BoundClass(i)
case 1
% lower bound only
xtrans(i) = params.LB(i) + x(k).^2;
k=k+1;
case 2
% upper bound only
xtrans(i) = params.UB(i) - x(k).^2;
k=k+1;
case 3
% lower and upper bounds
xtrans(i) = (sin(x(k))+1)/2;
xtrans(i) = xtrans(i)*(params.UB(i) - params.LB(i)) + params.LB(i);
% just in case of any floating point problems
xtrans(i) = max(params.LB(i),min(params.UB(i),xtrans(i)));
k=k+1;
case 4
% fixed variable, bounds are equal, set it at either bound
xtrans(i) = params.LB(i);
case 0
% unconstrained variable.
xtrans(i) = x(k);
k=k+1;
end
end
end % sub function xtransform end
matlab求解方法
变量边界约束的最优化问题求解的语句调用格式
x = fminsearchbnd(fun, x0, xm, xM)
[x, f, flag, out] = fminsearchbnd(fun, x0, xm, xM, opt, p1, p2, …)
例6-29 边界约束问题求解
求解 Resenbrock问题
f(x1,x2)=100(x2−x21)2+(1−x1)2
f
(
x
1
,
x
2
)
=
100
(
x
2
−
x
1
2
)
2
+
(
1
−
x
1
)
2
其中,
x1∈(2,4)
x
1
∈
(
2
,
4
)
和
x2∈(3,6)
x
2
∈
(
3
,
6
)
f = @(x)[100*(x(2)-x(1)^2)^2 + (1-x(1))^2];
xm = [2, 3];
xM = [4, 6];
x = fminsearchbnd3(f, [0, 0], xm, xM)
06.08 线性规划与二次型规划
线性规划问题的计算机求解
线性规划(LP)问题的一般数学描述为:
minxs.t.⎧⎩⎨⎪⎪⎪⎪Ax≤BAeqx=Beqxm≤x≤xMfTx
min
x
s
.
t
.
{
A
x
≤
B
A
e
q
x
=
B
e
q
x
m
≤
x
≤
x
M
f
T
x
目标函数和约束条件都是线性的
注意,约束的标准形式是
≤
≤
线性规划是凸问题,与初值无关
求解线性规划问题的函数调用:
x = linrog(f, A, B)
x = linprog(f, A, B,
Aeq
A
e
q
,
Beq
B
e
q
)
x = linprog(f, A, B,
Aeq,Beq,xm,xM,x0
A
e
q
,
B
e
q
,
x
m
,
x
M
,
x
0
)
[x,
fopt
f
o
p
t
, flag, c] = linprog(f, A, B,
Aeq,Beq,xm,xM,x0
A
e
q
,
B
e
q
,
x
m
,
x
M
,
x
0
, OPT)
x = linprog(problem)
[x,
fopt
f
o
p
t
, flag, c] = linprog(problem)
例6-29 线性规划问题求解
试求解下面线性规划问题
minxs.t.⎧⎩⎨⎪⎪2x2+x3+4x4+2x5≤543x1+4x2+5x3−x4−x5≤64x1,x2≥0,x3≥3.32,x4≥0.678,x5≥2.57(−2x1−x2−4x3−3x4−x5)
min
x
s
.
t
.
{
2
x
2
+
x
3
+
4
x
4
+
2
x
5
≤
54
3
x
1
+
4
x
2
+
5
x
3
−
x
4
−
x
5
≤
64
x
1
,
x
2
≥
0
,
x
3
≥
3.32
,
x
4
≥
0.678
,
x
5
≥
2.57
(
−
2
x
1
−
x
2
−
4
x
3
−
3
x
4
−
x
5
)
约束条件的矩阵表示:
f=[−2,−1,−4,−3,−1]T
f
=
[
−
2
,
−
1
,
−
4
,
−
3
,
−
1
]
T
A=[0324154−12−1],B=[5462]
A
=
[
0
2
1
4
2
3
4
5
−
1
−
1
]
,
B
=
[
54
62
]
f = -[2, 1, 4, 3, 1]';
Ae = [];
Be = [];
A = [0, 2, 1, 4, 2; 3,4,5, -1, -1];
B = [54; 62];
xm = [0, 0, 3.32, 0.678, 2.57];
[x, f_opt, key, c] = linprog(f, A, B, Ae, Be, xm, [], [])
例 6-30 结构体求解
clear P;
P.f = f;
P.Aineq = A;
P.Bineq = B;
P.lb = xm;
P.solver = 'linprog';
P.options = optimset;
[x, f_opt, key, c] = linprog(P)
例6-31 线性规划问题求解
求解线性规划问题
maxxs.t.⎧⎩⎨⎪⎪⎪⎪x1/4−60x2−x3/50+9x4≤0−x1/2+90x2+x5/50−3x4≥0x3≤1,x1≥−5,x2≥−5,x3≥−5,x4≥−5[34x1−150x2+150x3−6x4]
max
x
s
.
t
.
{
x
1
/
4
−
60
x
2
−
x
3
/
50
+
9
x
4
≤
0
−
x
1
/
2
+
90
x
2
+
x
5
/
50
−
3
x
4
≥
0
x
3
≤
1
,
x
1
≥
−
5
,
x
2
≥
−
5
,
x
3
≥
−
5
,
x
4
≥
−
5
[
3
4
x
1
−
150
x
2
+
1
50
x
3
−
6
x
4
]
先将原问题转换为标准问题
f=[−34150−1506]
f
=
[
−
3
4
150
−
1
50
6
]
A=⎡⎣⎢⎢0.250.5−60−90−150−15093⎤⎦⎥⎥,B=[00],xM=⎡⎣⎢⎢⎢∞∞1∞⎤⎦⎥⎥⎥
A
=
[
0.25
−
60
−
1
50
9
0.5
−
90
−
1
50
3
]
,
B
=
[
0
0
]
,
x
M
=
[
∞
∞
1
∞
]
f = [-3/4, 150, -1/50, 6];
Aeq = [];
Beq = [];
A = [1/4, -60, -1/50, 9; 1/2, -90, -1/50, 3];
B = [0, 0];
xm = [-5; -5; -5; -5];
xM = [Inf; Inf; 1; Inf];
[x, f_opt, key, c] = linprog(f, A, B, Aeq, Beq, xm, xM, [0; 0; 0; 0])
% 结构体求解
clear P;
P.f = f;
P.Aineq = A;
P.Bineq = B;
P.solver = 'linprog';
P.lb = xm;
P.ub = xM;
P.options = optimset;
[x, f_opt, key, c] = linprog(P)
例6-32 双下标问题
求解双下标线性规划问题
min2800(x11+x21+x31+x41)+4500(x12+x22+x32)+6000(x13+x23)+7300x14
min
2800
(
x
11
+
x
21
+
x
31
+
x
41
)
+
4500
(
x
12
+
x
22
+
x
32
)
+
6000
(
x
13
+
x
23
)
+
7300
x
14
xs.t.⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪x11+x12+x13+x14≥15x12+x13+x14+x21+x22+x23≥10x13+x14+x22+x23+x31+x32≥20x14+x23+x32+x41≥12xij≥0,(i=1,2,3,4,j=1,2,3,4)
x
s
.
t
.
{
x
11
+
x
12
+
x
13
+
x
14
≥
15
x
12
+
x
13
+
x
14
+
x
21
+
x
22
+
x
23
≥
10
x
13
+
x
14
+
x
22
+
x
23
+
x
31
+
x
32
≥
20
x
14
+
x
23
+
x
32
+
x
41
≥
12
x
i
j
≥
0
,
(
i
=
1
,
2
,
3
,
4
,
j
=
1
,
2
,
3
,
4
)
变成标准型,定义为单下标变量
x1=x11,x2=x12,x3=x13,x4=x14,x5=x21,
x
1
=
x
11
,
x
2
=
x
12
,
x
3
=
x
13
,
x
4
=
x
14
,
x
5
=
x
21
,
x6=x22,x7=x23,x8=x31,x9=x32,x10=x41
x
6
=
x
22
,
x
7
=
x
23
,
x
8
=
x
31
,
x
9
=
x
32
,
x
1
0
=
x
41
原问题改为:
min2800(x1+x5+x8+x10)+4500(x2+x6+x9)+6000(x3+x7)+7300x4
min
2800
(
x
1
+
x
5
+
x
8
+
x
10
)
+
4500
(
x
2
+
x
6
+
x
9
)
+
6000
(
x
3
+
x
7
)
+
7300
x
4
xs.t.⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪−(x1+x2+x3+x4)≤15−(x2+x3+x4+x5+x6+x7)≤10−(x3+x4+x6+x7+x8+x9)≤20−(x4+x7+x9+x10)≤12xi≥0,(i=1,2,3,⋯,10)
x
s
.
t
.
{
−
(
x
1
+
x
2
+
x
3
+
x
4
)
≤
15
−
(
x
2
+
x
3
+
x
4
+
x
5
+
x
6
+
x
7
)
≤
10
−
(
x
3
+
x
4
+
x
6
+
x
7
+
x
8
+
x
9
)
≤
20
−
(
x
4
+
x
7
+
x
9
+
x
10
)
≤
12
x
i
≥
0
,
(
i
=
1
,
2
,
3
,
⋯
,
10
)
f = 2800*[1 0 0 0 1 0 0 1 0 1] + ...
4500*[0 1 0 0 0 1 0 0 1 0] + ...
6000*[0 0 1 0 0 0 1 0 0 0] + ...
7300*[0 0 0 1 0 0 0 0 0 0];
A = -[1 1 1 1 0 0 0 0 0 0; 0 1 1 1 1 1 1 0 0 0;
0 0 1 1 0 1 1 1 1 0; 0 0 0 1 0 0 1 0 1 1];
B = -[15; 10; 20; 12];
xm = [0 0 0 0 0 0 0 0 0 0];
Aeq = [];
Beq = [];
x = linprog(f, A, B, Aeq, Beq, xm)
得出的结果再反代回双下标自变量
二次型规划求解
一般二次型绘画问题的数学表示
minxs.t.⎧⎩⎨⎪⎪⎪⎪Ax≤BAeqx=Beqxm≤x≤xM(12xTHx+fTx)
min
x
s
.
t
.
{
A
x
≤
B
A
e
q
x
=
B
e
q
x
m
≤
x
≤
x
M
(
1
2
x
T
H
x
+
f
T
x
)
二次型规划问题也是凸问题,其解与初值选择无关
x = quadprog(H, f, A, B)
x = quadprog(H, f, A, B,
Aeq,Beq
A
e
q
,
B
e
q
)
x = quadprog(H, f, A, B,
Aeq,Beq,xm,xM
A
e
q
,
B
e
q
,
x
m
,
x
M
)
[x,
fopt
f
o
p
t
, flag, c] = quadprog(H, f, A, B,
Aeq,Beq,xm,xM,x0
A
e
q
,
B
e
q
,
x
m
,
x
M
,
x
0
, OPT)
x = quadprog(progblem)
[x,
fopt
f
o
p
t
, flag, c] = quadprog(progblem)
构造H矩阵注意标准型系数1/2
06.09 非线性规划
一般非线性规划问题
一般非线性规划问题
minxs.t.G(x)≤0f(x)
min
x
s
.
t
.
G
(
x
)
≤
0
f
(
x
)
其中:
x=[x1,x2,⋯,xn]T
x
=
[
x
1
,
x
2
,
⋯
,
x
n
]
T
物理解释:在给出的约束条件下,找出向量x,使目标函数达到最小值
决策变量
可行解
更具体描述
minxs.t.⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪Ax≤BAeqx=Beqxm≤x≤xMC(x)≤0Ceq(x)=0f(x)
min
x
s
.
t
.
{
A
x
≤
B
A
e
q
x
=
B
e
q
x
m
≤
x
≤
x
M
C
(
x
)
≤
0
C
e
q
(
x
)
=
0
f
(
x
)
求解出非线性规划问题:
[x,
fopt
f
o
p
t
, flag, c] = fmincon(fun,
x0,A,B,Aeq,Beq,xm,xM,CFun,OPT,p1,p2,⋯
x
0
,
A
,
B
,
A
e
q
,
B
e
q
,
x
m
,
x
M
,
C
F
u
n
,
O
P
T
,
p
1
,
p
2
,
⋯
)
CFun返回两个输出变量,不等式约束C和等式约束
Ceq
C
e
q
,不能用匿名函数来描述,需要使用
.m文件
例6-34 非线性规划
试求解下面非线性规划问题
min1000−x21−2x22−x23−x1x2−x1x3
min
1000
−
x
1
2
−
2
x
2
2
−
x
3
2
−
x
1
x
2
−
x
1
x
3
xs.t.⎧⎩⎨⎪⎪x21+x22+x23−25=08x1+14x2+7x3−56=0x1,x2,x3≥0
x
s
.
t
.
{
x
1
2
+
x
2
2
+
x
3
2
−
25
=
0
8
x
1
+
14
x
2
+
7
x
3
−
56
=
0
x
1
,
x
2
,
x
3
≥
0
为目标函数和约束函数编写M-函数
目标函数
% 非线性约束函数(返回两个变量)
function [c, ceq] = opt_con1(x)
ceq = [x(1)*x(1) + x(2)*x(2)+x(3)*x(3)-25;
8*x(1) + 14*x(2) + 7*x(3) - 56];
c = [];
% 目标函数
f = @(x) 1000-x(1)*x(1) - 2*x(2)*x(2) - x(3)*x(3) - x(1)*x(2) -x(1)*x(3);
% 问题求解
ff = optimset;
ff.LargeScale = 'off';
ff.TolFun = 1e-30;
ff.TolX = 1e-15;
ff.TolCon = 1e-20;
x0 = [1;1;1];
xm = [0; 0; 0];
xM = [];
A = [];
B = [];
Aeq = [];
Beq = [];
[x, f_opt, c, d] = fmincon(f, x0, A, B, Aeq, Beq, xm, xM, @opt_con1, ff)
% 使用结构体描述
clear P;
P.objective = f;
P.nonlcon = @opt_con1;
P.x0 = x0;
P.lb = xm;
P.options = ff;
P.solver = 'fmincon';
[x, f_opt, c, d] = fmincon(P)
分离掉线性约束条件
function [c, ceq] = opt_con2(x)
c = [];
ceq = x(1)*x(1) + x(2)*x(2) + x(3)*x(3) - 25;
求出结果:
x0 = [1;1;1];
Aeq = [8, 14, 7];
Beq = 56;
[x, f_opt, c, d] = fmincon(f, x0, A, B, Aeq, Beq, xm, xM, @opt_con2, ff)
例6-38 复杂优化问题
求解最优化问题
mink
min
k
q,w,ks.t.⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪q3+9.625q1w+16q2w+16w2+12−4q1−q2−78w=016q1w+44−19q1−8q2−q3−24w=02.25−0.25k≤q1≤2.25+0.25k1.5−0.5k≤q2≤1.5+0.5k1.5−1.5k≤q3≤1.5+1.5k
q
,
w
,
k
s
.
t
.
{
q
3
+
9.625
q
1
w
+
16
q
2
w
+
16
w
2
+
12
−
4
q
1
−
q
2
−
78
w
=
0
16
q
1
w
+
44
−
19
q
1
−
8
q
2
−
q
3
−
24
w
=
0
2.25
−
0.25
k
≤
q
1
≤
2.25
+
0.25
k
1.5
−
0.5
k
≤
q
2
≤
1.5
+
0.5
k
1.5
−
1.5
k
≤
q
3
≤
1.5
+
1.5
k
选择决策变量
x1=q1,x2=q2,x3=q3,x4=w,x5=k
x
1
=
q
1
,
x
2
=
q
2
,
x
3
=
q
3
,
x
4
=
w
,
x
5
=
k
将原问题修改为标准型
minx5
min
x
5
xs.t.⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪x3+9.625x1x4+16x2x4+16x24+12−4x1−x2−78x4=016x1x4+44−19x1−8x2−x3−24x4=0−0.25x5−x1≤−2.25x1−0.25x5≤2.25−0.5x5−x2≤−1.5x2−0.5x5≤1.5−1.5x5−x3≤−1.5x3−1.5x5≤1.5
x
s
.
t
.
{
x
3
+
9.625
x
1
x
4
+
16
x
2
x
4
+
16
x
4
2
+
12
−
4
x
1
−
x
2
−
78
x
4
=
0
16
x
1
x
4
+
44
−
19
x
1
−
8
x
2
−
x
3
−
24
x
4
=
0
−
0.25
x
5
−
x
1
≤
−
2.25
x
1
−
0.25
x
5
≤
2.25
−
0.5
x
5
−
x
2
≤
−
1.5
x
2
−
0.5
x
5
≤
1.5
−
1.5
x
5
−
x
3
≤
−
1.5
x
3
−
1.5
x
5
≤
1.5
例6-39 全局最优解
例6-38 容易陷入局部最优解
function [c,ceq] = c6exnls(x)
c = [];
ceq = [x(3)+9.625*x(1)*x(4)+16*x(2)*x(4)+16*x(4)^2+12-4*x(1)-x(2)-78*x(4);
16*x(1)*x(4)+44-19*x(1)-8*x(2)-x(3)-24*x(4)];
% 全局最优化求解函数
function [x,f0] = fmincon_global(f, a, b, n, N, varargin)
x0 = rand(n,1);
k0 = 0;
if strcmp(class(f), 'struct')
k0 = 1;
end %处理结构体
if k0 == 1
f.x0 = x0;
[x f0] = fmincon(f); %如果是结构体描述的问题,直接求解
else
[x f0] = fmincon(f, x0, varargin{:});
end %如果不是结构体描述的,直接求解
for i = 1:N
x0 = a+(b-a)*rand(n,1); %用循环结构尝试不同的随机搜索初值
if k0 == 1
f.x0 = x0;
[x1 f1 key] = fmincon(f); %结构体问题求解
else
[x1 f1 key] = fmincon(f, x0, varargin{:});
end %非结构体问题求解
if key>0 & f1<f0
x = x1;
f0 = f1;
end %如果找到的解优于现有的最好解,存储该解
end
clear P;
P.objective = @(x)x(5);
P.nonlcon = @c6exnls;
P.solver = 'fmincon';
P.Aineq = [-1, 0, 0, 0, -0.25; 1, 0, 0, 0, -0.25; 0, -1, 0, 0, -0.5;
0, 1, 0, 0, -0.5; 0, 0, -1, 0, -1.5; 0, 0, 1, 0, -1.5];
P.Bineq = [-2.25; 2.25; -1.5; 1.5; -1.5; 1.5];
P.options = optimset;
P.x0 = rand(5, 1);
[x, f0] = fmincon_global(P, 0, 5, 5, 50)
% 运行100次,成功率100%,耗时4分钟
tic, X=[];
for i = 1:100
[x, f0] = fmincon_global(P, 0, 5, 5, 50);
X = [X; x'];
end;
toc
06.10 整数规划的穷举方法
混合整数规划问题的计算机求解
非线性规划包括了单目标规划的绝大多数最优化类型,在实际应用中还可能有其它要求,比如某决策变量为人数,则需要为整数,这样就引入了整数规划问题
整数规划问题的穷举方法
所谓穷举方法,就是将决策变量取值所有的可能都衡量一番,从满足条件的决策变量可能中找出目标函数值最小的组合,这样的解即为原始问题的全局最优解。
如果已知自变量所在区间,理论上可以考虑用穷举方法举出区间内所有的变量组合
不能用于NP问题,穷举方法只适合于极有限的小规模问题
混合整数规划问题不能采用穷举方法
例6-40 线性整数规划
求解下列线性整数规划问题,其中,各个变量全为整数
minxs.t.⎧⎩⎨⎪⎪2x2+x3+4x4+2x3≤543x1+4x2+5x3−x4−x5≤62x1,x2≥0,x3≥3.32,x4≥0.678,x5≥2.57(−2x1−x2−4x3−3x4−x5)
min
x
s
.
t
.
{
2
x
2
+
x
3
+
4
x
4
+
2
x
3
≤
54
3
x
1
+
4
x
2
+
5
x
3
−
x
4
−
x
5
≤
62
x
1
,
x
2
≥
0
,
x
3
≥
3.32
,
x
4
≥
0.678
,
x
5
≥
2.57
(
−
2
x
1
−
x
2
−
4
x
3
−
3
x
4
−
x
5
)
穷举法思路
认为假定取值范围[0.25]
用 ndgrid 函数可以生成所有可能
对可行解排序,得出最优解和次优解
穷举求解
N = 25;
[x1, x2, x3, x4, x5] = ndgrid(0:N, 0:N, 4:N, 1:N, 3:N);
i = find((2*x2+x3+4*x4+2*x5 <= 54) & ...
(3*x1 + 4*x2 + 5*x3 - x4 - x5 <= 62));
x1 = x1(i);
x2 = x2(i);
x3 = x3(i);
x4 = x4(i);
x5 = x5(i);
f = -2*x1 - x2 -4*x3 - 3*x4 -x5;
[fmin, ii] = sort(f);
in = ii(1);
x = [x1(in), x2(in), x3(in), x4(in), x5(in)]
% size(x1)
% 最优解与次最优解
L = 10;
f1 = f(1:L)';
in = ii(1:L);
x = [x1(in), x2(in), x3(in), x4(in), x5(in), f1']
穷举法的优劣
限定的区间[0, 15],不能随意拓展到此区间外,如想将25变为30,在一般的计算机配置下都实现不了,因为需要内除过大,5个变量的存储量为
315×5×8/220=1092.1MB
31
5
×
5
×
8
/
2
20
=
1092.1
M
B
除了得出最优解外,事实上还可以得出若干组合,为次最优解
例6-41 穷举方法求解
用穷举法求解非线性整数规划问题
minx21+x22+2x23+x24−5x1−5x2−21x3+7x4
min
x
1
2
+
x
2
2
+
2
x
3
2
+
x
4
2
−
5
x
1
−
5
x
2
−
21
x
3
+
7
x
4
xs.t.⎧⎩⎨⎪⎪⎪⎪−x21−x22−x23−x24−x1+x2−x3+x4+8≥0−x21−2x22−x23−2x24+x1+x4+10≥0−2x21−x22−x23−2x24+x2+x4+5≥0
x
s
.
t
.
{
−
x
1
2
−
x
2
2
−
x
3
2
−
x
4
2
−
x
1
+
x
2
−
x
3
+
x
4
+
8
≥
0
−
x
1
2
−
2
x
2
2
−
x
3
2
−
2
x
4
2
+
x
1
+
x
4
+
10
≥
0
−
2
x
1
2
−
x
2
2
−
x
3
2
−
2
x
4
2
+
x
2
+
x
4
+
5
≥
0
N = 30;
[x1 x2 x3 x4] = ndgrid(-N:N);
ii = find((-x1.^2 -x2.^2 -x3.^2 -x4.^2 -x1 +x2 -x3 +x4 + 8 >= 0) & ...
(-x1.^2 -2*x2.^2 -x3.^2 -2*x4.^2 + x1 + x4 + 10 >= 0) & ...
(-2*x1.^2 -x2.^2 -x3.^2 -2*x4.^2 +x2 + x4 + 5 >= 0));
x1 = x1(ii);
x2 = x2(ii);
x3 = x3(ii);
x4 = x4(ii);
ff = x1.^2 + x2.^2 + 2*x3.^2 +x4.^2 -5*x1 - 5*x2 - 21*x3 +7*x4;
[fm, ii] = sort(ff);
k = ii(1:5);
X = [x1(k), x2(k), x3(k), x4(k)],
fm(1:5)
例6-42 离散规划问题求解
离散最优化问题
min2x21+x22−16x1−10x2
min
2
x
1
2
+
x
2
2
−
16
x
1
−
10
x
2
xs.t.{x21−6x1+x2−11≤0−x1x2+3x2+ex1−3−1≤0
x
s
.
t
.
{
x
1
2
−
6
x
1
+
x
2
−
11
≤
0
−
x
1
x
2
+
3
x
2
+
e
x
1
−
3
−
1
≤
0
x1是0.25的整数倍,x2是0.1的整数倍
x
1
是
0.25
的
整
数
倍
,
x
2
是
0.1
的
整
数
倍
[x1 x2] = meshgrid(-20:0.25:20, 3:0.1:20);
ii = find(x1.^2 - 6*x1 + x2 - 11 <= 0 & ...
-x1.*x2 + 3*x2 + exp(x1 -3) - 1 <= 0);
x1 = x1(ii);
x2 = x2(ii);
ff = 2*x1.^2 + x2.^2 - 16*x1 - 10*x2;
[fm, ij] = sort(ff);
k = ij(1:5);
X = [x1(k) x2(k)],
fm(1:5)
06.11 混合整数规划问题
整数线性规划问题求解
整数线性规划的一般数学描述
minxs.t.⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪Ax≤BAeqx=Beqxm≤x≤xMx^integersfTx
min
x
s
.
t
.
{
A
x
≤
B
A
e
q
x
=
B
e
q
x
m
≤
x
≤
x
M
x
^
i
n
t
e
g
e
r
s
f
T
x
其中,x^为变量x的子集
其
中
,
x
^
为
变
量
x
的
子
集
整数规划与混合整数规划
混合整数线性规划的求解函数
混合线性整数规划的求解函数
[x, f_m, key, c] = intlinprog(problem)
[x, f_m, key, c] = intlinprog(
f,intcon,A,b,Aeq,beq,xm,xM
f
,
i
n
t
c
o
n
,
A
,
b
,
A
e
q
,
b
e
q
,
x
m
,
x
M
, pars)
结构体设置
problem.solver = ‘intlinprog’;
problem.options = optimoptions(‘intlinprog’)
结果精调
x(intcon) = round(x(intcon))
例6-42 混合整数线性规划
混合整数线性规划, 1, 4, 5变量要求为整数
min(−2x1−x2−4x3−3x4−x5)
min
(
−
2
x
1
−
x
2
−
4
x
3
−
3
x
4
−
x
5
)
xs.t.⎧⎩⎨⎪⎪2x2+x3+4x4+2x5≤543x1+4x2+5x3−x4−x5≤62x1,x2≥0,x3≥3.32,x4≥0.678,x5≥2.57
x
s
.
t
.
{
2
x
2
+
x
3
+
4
x
4
+
2
x
5
≤
54
3
x
1
+
4
x
2
+
5
x
3
−
x
4
−
x
5
≤
62
x
1
,
x
2
≥
0
,
x
3
≥
3.32
,
x
4
≥
0.678
,
x
5
≥
2.57
clear P;
P.solver = 'intlinprog';
P.options = optimoptions('intlinprog');
P.lb = [0; 0; 3.32; 0.678; 2.57];
P.f = [-2, -1, -4, -3, -1];
I = [1, 4, 5];
P.Aineq = [0, 2, 1, 4, 2; 3, 4, 5, -1, -1];
P.Bineq = [54; 62];
P.intcon = [1, 4, 5];
[x, f, a, b] = intlinprog(P);
x(I) = round(x(I))
一般非线性整数规划问题与求解
分枝定界算法是一种最常用的处理非线性整数规划或混合规划问题的算法
免费工具箱由 Mr.Keort Kuipers 提供
数学描述
minf(x)
min
f
(
x
)
xs.t.⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪Ax≤BAeqx=Beqxm≤x≤xMC(x)≤0Ceq(x)=0x^integers
x
s
.
t
.
{
A
x
≤
B
A
e
q
x
=
B
e
q
x
m
≤
x
≤
x
M
C
(
x
)
≤
0
C
e
q
(
x
)
=
0
x
^
i
n
t
e
g
e
r
s
求解语句:
[err, f, x] = bnb20_new(fun,
x0,intcon,xm,xM,A,B,Aeq,Beq
x
0
,
i
n
t
c
o
n
,
x
m
,
x
M
,
A
,
B
,
A
e
q
,
B
e
q
, CFun)
例6-46 非线性整数规划
整数规划
minx31+x22−4x1+4+x43
min
x
1
3
+
x
2
2
−
4
x
1
+
4
+
x
3
4
xs.t.⎧⎩⎨⎪⎪x1−2x2+12+x3≥0−x21+3x2−8−x3≥0x1≥0,x2≥0,x3≥0
x
s
.
t
.
{
x
1
−
2
x
2
+
12
+
x
3
≥
0
−
x
1
2
+
3
x
2
−
8
−
x
3
≥
0
x
1
≥
0
,
x
2
≥
0
,
x
3
≥
0
非线性约束条件
function [c, ce] = c6exinl(x)
ce = [];
c = [-x(1) + 2*x(2) - 12 - x(3);
x(1)^2-3*x(2)+8+x(3)];
clear P;
in = [1:3];
P.objective = @(x)x(1)^3+x(2)^2-4*x(1) + 4 + x(3)^4;
P.intcon = in;
P.nonlcon = @c6exinl;
P.lb = [0; 0; 0];
P.ub = 100*[1;1;1];
P.x0 = P.ub;
[err, fm x] = BNB20_new(P);
x(in) = round(x(in))
例6-47 离散规划问题求解
离散最优化问题
min2x21+x22−16x1−10x2
min
2
x
1
2
+
x
2
2
−
16
x
1
−
10
x
2
xs.t.{x21−6x1+x2−11≤0−x1x2+3x2+ex1−3−1≤0
x
s
.
t
.
{
x
1
2
−
6
x
1
+
x
2
−
11
≤
0
−
x
1
x
2
+
3
x
2
+
e
x
1
−
3
−
1
≤
0
x1是0.25的整数倍,x2是0.1的整数倍
x
1
是
0.25
的
整
数
倍
,
x
2
是
0.1
的
整
数
倍
引入
y1=4x1,y2=10x2,
y
1
=
4
x
1
,
y
2
=
10
x
2
,
整数规划
min2y21/16+y22/100−4y1−y2
min
2
y
1
2
/
16
+
y
2
2
/
100
−
4
y
1
−
y
2
ys.t.⎧⎩⎨⎪⎪y21/1y−6y1/4+y2/10−11≤0−y1y2/40+3y2/10+ey1/4−3−1≤0y2≥30
y
s
.
t
.
{
y
1
2
/
1
y
−
6
y
1
/
4
+
y
2
/
10
−
11
≤
0
−
y
1
y
2
/
40
+
3
y
2
/
10
+
e
y
1
/
4
−
3
−
1
≤
0
y
2
≥
30
约束条件
function [c, ceq] = c6mdisp(y)
ceq = [];
c = [y(1)^2/10-6*y(1)/4+y(2)/10-11;
-y(1)*y(2)/40+3*y(2)/10+exp(y(1)/4-3)-1];
clear P;
P.objective = @(y)2*y(1)^2/16+y(2)^2/100 - ...
4*y(1) - y(2);
P.nonlcon = @c6mdisp;
P.lb = [-200; 30];
P.ub = [200; 200];
P.intcon = [1; 2];
P.x0 = [12; 30];
[errmsg, ym, y] = BNB20_new(P);
x = [y(1)/4, y(2)/10]
0-1规划问题求解
没有现成的函数可以直接求解0-1规划
可以利用前面介绍的整数规划问题求解函数
线性规划问题:intlinprog
非线性规划问题: BNB20_new
使用技巧:
将下界定义一个全为0的向量
将上界定义一个全为1的向量
例6-50 混合非线性0-1规划
混合0-1规划问题
min5y1+6y2+8y3+10x1−7x3−18ln(x2+1)−19.2ln(x1−x2+1)+10
min
5
y
1
+
6
y
2
+
8
y
3
+
10
x
1
−
7
x
3
−
18
ln
(
x
2
+
1
)
−
19.2
ln
(
x
1
−
x
2
+
1
)
+
10
xs.t.⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪0.8ln(x2+1)+0.96ln(x1−x2+1)−0.8x3≤0ln(x2+1)+1.2ln(x1−x2+1)−x3−2y3≥−2x2−x1≤0x2−2y1≤0x1−x2−2y2≤0y1+y2≤10≤x≤[2,2,1]T,y∈{0,1}
x
s
.
t
.
{
0.8
ln
(
x
2
+
1
)
+
0.96
ln
(
x
1
−
x
2
+
1
)
−
0.8
x
3
≤
0
ln
(
x
2
+
1
)
+
1.2
ln
(
x
1
−
x
2
+
1
)
−
x
3
−
2
y
3
≥
−
2
x
2
−
x
1
≤
0
x
2
−
2
y
1
≤
0
x
1
−
x
2
−
2
y
2
≤
0
y
1
+
y
2
≤
1
0
≤
x
≤
[
2
,
2
,
1
]
T
,
y
∈
{
0
,
1
}
变量替换,保留前三个x
令x4=y1,x5=y2,x6=y3
令
x
4
=
y
1
,
x
5
=
y
2
,
x
6
=
y
3
min5x4+6x5+8x6+10x1−7x3−18ln(x2+1)−19.2ln(x1−x2+1)+10
min
5
x
4
+
6
x
5
+
8
x
6
+
10
x
1
−
7
x
3
−
18
ln
(
x
2
+
1
)
−
19.2
ln
(
x
1
−
x
2
+
1
)
+
10
xs.t.⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪0.8ln(x2+1)+0.96ln(x1−x2+1)−0.8x3≤0ln(x2+1)+1.2ln(x1−x2+1)−x3−2x6≥−2x2−x1≤0x2−2x4≤0x1−x2−2x5≤0x4+x5≤10≤x≤[2,2,1,1,1,1]T
x
s
.
t
.
{
0.8
ln
(
x
2
+
1
)
+
0.96
ln
(
x
1
−
x
2
+
1
)
−
0.8
x
3
≤
0
ln
(
x
2
+
1
)
+
1.2
ln
(
x
1
−
x
2
+
1
)
−
x
3
−
2
x
6
≥
−
2
x
2
−
x
1
≤
0
x
2
−
2
x
4
≤
0
x
1
−
x
2
−
2
x
5
≤
0
x
4
+
x
5
≤
1
0
≤
x
≤
[
2
,
2
,
1
,
1
,
1
,
1
]
T
function [c, ceq] = c6mmibp(x)
ceq = [];
c = [-0.8*log(x(2)+1)-0.96*log(x(1)-x(2)+1)+0.8*x(3);
-log(x(2)+1)-1.2*log(x(1)-x(2)+1)+x(3)+2*x(6)-2];
clear P;
P.intcon = 4:6;
P.x0 = [0 0 0 0 0 0]';
P.objective = @(x)5*x(4)+6*x(5)+8*x(6)+10*x(1) ...
-7*x(3)-18*log(x(2)+1)-19.2*log(x(1)-x(2)+1)+10;
P.ub = [2 2 1 1 1 1 ]';
P.lb = [0 0 0 0 0 0]';
P.Aineq = [-1 1 0 0 0 0; 0 1 0 -2 0 0; 1 -1 0 0 -2 0; 0 0 0 1 1 0];
P.nonlcon = @c6mmibp;
P.Bineq = [0; 0; 0; 1];
[errmsg, fm, x] = BNB20_new(P)
06.12 动态规划与最优路径问题
多阶段目标–目标函数随着实际完成情况动态地改变
图的矩阵表示方法
有向图的路径寻优
无向图的路径最优搜索
例6-57 最短路径问题
有向图:节点、边、权值
倒叙求解
问题:
繁琐、易出错、难以求解大规模问题
图的矩阵表示方法
图是由节点和边构成的。边是连接两个节点的直接路径。如果边是又向的,则图称为有向图,否则称为无向图
在计算机中,图用矩阵表示,即关联矩阵
matlab语言支持关联矩阵的稀疏矩阵表示方法
例5-58 有向图的矩阵描述
关联矩阵表示
构造关联矩阵的稀疏矩阵函数调用格式
a=[a1,a2,⋯,am,n];
a
=
[
a
1
,
a
2
,
⋯
,
a
m
,
n
]
;
b=[b1,b2,⋯,bm,n];
b
=
[
b
1
,
b
2
,
⋯
,
b
m
,
n
]
;
w=[w1,w2,⋯,2m,0];
w
=
[
w
1
,
w
2
,
⋯
,
2
m
,
0
]
;
R = sparse(a, b, w);
其中,ai为起始节点向量,bi为终止节点向量,wi为边权值向量,这里i=1,2,⋯,m
其
中
,
a
i
为
起
始
节
点
向
量
,
b
i
为
终
止
节
点
向
量
,
w
i
为
边
权
值
向
量
,
这
里
i
=
1
,
2
,
⋯
,
m
各个向量最后的一个值使得关联矩阵为方阵
% 建立关联矩阵并显示图
ab = [1 1 2 2 3 3 4 4 4 4 5 6 6 7 8];
bb = [2 3 5 4 4 6 5 7 8 6 7 8 9 9 9];
w = [1 2 12 6 3 4 4 15 7 2 7 7 15 3 10];
R = sparse(ab, bb, w);
R(9, 9) = 0;
h = view(biograph(R, [], 'ShowWeights', 'on'))
% 搜索最短路径
[d, p] = graphshortestpath(R, 1, 9)
set(h.Nodes(p), 'Color', [1, 0.4 0.4])
edges = getedgesbynodeid(h, get(h.Nodes(p), 'ID'));
set(edges, 'LineColor', [1 0 0])
无向图的路径最优搜索
无向图的关联矩阵构造方法
先按照有向图的方式构造关联矩阵R
无向图的关联矩阵为
R1=R+RT
R
1
=
R
+
R
T
如果无向图中,某些边是有向的,则手工修改该矩阵
若由节点i到节点j与由节点j到i的边权值是不同的,用手工方法重新定义和修改