现代科学运算-matlab语言与应用
东北大学 http://www.icourses.cn/home/ (薛定宇)
《高等应用数学问题的MATLAB求解(第四版)》
代码可在matlab r2016b 运行。
代数方程的图解法
一元方程的图解法
一元方程的标准形式 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对复数根
多项式方程的准解析解法
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
更高此带有参数的方程没有解析解
准解析解方法的优势和劣势
优势:可以求出解析解或高精度数值解,可以指定初值,可以同时求出方程的实数根和复数根
劣势:使用于多项式方程,求解其他类型方程没有优势,相比后面介绍的数值解方法速度较慢
一般非线性方程数值解
求多元方程的一个实数根
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)
所期望的精度可能过于严苛,无法达到,但能尽可能精确
可以得到双精度下的最好结果
求解多解方程的全部解
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
无约束最优化问题的数学描述
无约束最小化问题的数学描述 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)
全局最优解与局部最优解
最小值存在的必要条件是 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)
有约束最优化问题的计算机求解
约束条件与可行解区域
有约束非线性最优化问题的一般描述
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)
线性规划问题的计算机求解
线性规划(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
一般非线性规划问题
一般非线性规划问题
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 & f1end %如果找到的解优于现有的最好解,存储该解
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
混合整数规划问题的计算机求解
非线性规划包括了单目标规划的绝大多数最优化类型,在实际应用中还可能有其它要求,比如某决策变量为人数,则需要为整数,这样就引入了整数规划问题
整数规划问题的穷举方法
所谓穷举方法,就是将决策变量取值所有的可能都衡量一番,从满足条件的决策变量可能中找出目标函数值最小的组合,这样的解即为原始问题的全局最优解。
如果已知自变量所在区间,理论上可以考虑用穷举方法举出区间内所有的变量组合
不能用于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−x