如果目标函数或约束条件中包含非线性函数,就称这种规划问题为非线性规划问题。一般来说,解非线性规划要比线性规划问题困难得多。而且也不像线性规划有单纯形法这一通用方法,非线性规划目前还没有适用于各种问题的一般算法,各个方法都有自己特定的适用范围。
例1 投资决策问题
某企业有 n \text n n个项目可供选择投资,并且至少要对其中一个项目投资。已知该企业拥有总资金 A \text A A元,投资于第 i ( i = 1 , 2 , ⋯ , n ) \text i(\text i=1,2,\cdots,\text n) i(i=1,2,⋯,n)个项目需要花资金 a i a_\text i ai元,并预计可收益 b i \text b_\text i bi元。式选择最佳投资方案。
解:设投资决策变量为:
x i = { 1 决定会投资第i个项目 0 决定不投资第i个项目 x_\text i= \begin{cases} 1&决定会投资第\text i个项目\\ 0&决定不投资第\text i个项目\\ \end{cases} xi={10决定会投资第i个项目决定不投资第i个项目
则投资总额为 ∑ i = 1 n a i x i \sum\limits_{\text i=1}^\text na_\text ix_\text i i=1∑naixi,投资总收益为 ∑ i = 1 n b i x i \sum\limits_{\text i=1}^\text n\text b_\text ix_\text i i=1∑nbixi。
因为该公司至少要对一个项目投资,并且总的投资金额不能超过总资金 A \text A A,固有限制条件:
0 < ∑ i = 1 n a i x i ≤ A 0<\sum\limits_{\text i=1}^\text na_\text ix_\text i\le\text A 0<i=1∑naixi≤A
另外由于 x i x_\text i xi只能取0或1,所以还有:
x i ( 1 − x i ) = 0 i = 1 , 2 , ⋯ , n x_\text i(1-x_\text i)=0\quad \text i=1,2,\cdots,\text n xi(1−xi)=0i=1,2,⋯,n
最佳方案应是投资额最小而总收益最大的方案,所以这个最佳投资决策问题归结为总资金以及决策变量的限制条件下,极大化总收益和总投资之比。因此,其数学模型为:
max z = ∑ i = 1 n b i x i ∑ i = 1 n a i x i \max\quad z=\dfrac{\sum\limits_{\text i=1}^\text n\text b_\text ix_\text i}{\sum\limits_{\text i=1}^\text na_\text ix_\text i} maxz=i=1∑naixii=1∑nbixi
s.t. { 0 < ∑ i = 1 n a i x i ≤ A x i ( 1 − x i ) = 0 i = 1 , 2 , ⋯ , n \text {s.t.}\quad \begin{cases} 0<\sum\limits_{\text i=1}^\text na_\text ix_\text i\le\text A\\ x_\text i(1-x_\text i)=0\quad \text i=1,2,\cdots,\text n \end{cases} s.t.⎩ ⎨ ⎧0<i=1∑naixi≤Axi(1−xi)=0i=1,2,⋯,n
非线性数学规划的数学模型一般形式:
min f ( x ) \min\quad f(x) minf(x)
s.t. { h j ( x ) ≤ 0 j = 1 , 2 , ⋯ , q g i ( x ) = 0 i = 1 , 2 , ⋯ , p \text{s.t.}\quad \begin{cases} h_\text j(x)\le0&\text j=1,2,\cdots,\text q\\ g_\text i(x)=0&\text i=1,2,\cdots,\text p\\ \end{cases} s.t.{hj(x)≤0gi(x)=0j=1,2,⋯,qi=1,2,⋯,p
在一组等式或不等式的约束下,求一个函数的最大值(或最小值)问题,其中至少有一个非线性函数,这类问题称之为非线性规划问题。
min f ( x ) \min\quad f(x) minf(x)
s.t. { A x ≤ b c ( x ) ≤ 0 ceq ( x ) = 0 lb ≤ x ≤ ub \text{s.t.}\quad \begin{cases} \begin{aligned} \text Ax\le\text b\\ \text c(x)\le0\\ \text{ceq}(x)=0\\ \text{lb}\le x\le\text{ub} \end{aligned} \end{cases} s.t.⎩ ⎨ ⎧Ax≤bc(x)≤0ceq(x)=0lb≤x≤ub
其中 f ( x ) f(x) f(x)是标量函数, A , b , Aeq , beq , lb , ub \text A,\text b,\text{Aeq},\text{beq},\text{lb},\text{ub} A,b,Aeq,beq,lb,ub是相应维数的矩阵和向量, c ( x ) , ceq ( x ) \text c(x),\text{ceq}(x) c(x),ceq(x)是非线性向量函数。
[x,fval]=fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nolcon,options);
x
的返回值是决策向量 X \bf X X的取值,fval
返回的是目标函数的取值,其中fun
是用 M \text M M文件定义的函数;x0
是 X \bf X X的初始值(初始值不同,则最优解可能不同);A,b,Aeq,beq
定义了线性约束 A x ≤ b , A e q ⋅ x = b e q \bf \text Ax\le\text b,\text Aeq\cdot x=\text beq Ax≤b,Aeq⋅x=beq,如果没有线性约束,则A=[],b=[],Aeq=[],beq=[]
;lb
和ub
是变量 x x x的下界和上界,如果上界和下界没有约束,即 x x x无下界也无上界,则lb=[],ub=[]
,也可以写成lb
的各分量都是-inf
,ub
的各分量都为inf
;nonlcon
是用 M \text M M文件定义的非线性向量函数 c ( x ) , ceq ( x ) \text c(x),\text{ceq}(x) c(x),ceq(x);options
定义了优化参数,可以使用 MATLAB \text{MATLAB} MATLAB缺省参数设置。
例2 求下列非线性规划
min f ( x ) = x 1 2 + x 2 2 + x 3 2 + 8 \min\quad f(x)=x_1^2+x_2^2+x_3^2+8 minf(x)=x12+x22+x32+8
s.t. { x 1 2 − x 2 + x 3 2 ≥ 0 x 1 + x 2 2 + x 3 ≤ 20 − x 1 − x 2 + 2 = 0 x 2 + 2 x 3 2 = 3 x 1 , x 2 , x 3 ≥ 0 \text{s.t.}\quad \begin{cases} \begin{aligned} x_1^2-x_2+x_3^2\ge0\\ x_1+x_2^2+x_3\le20\\ -x_1-x_2+2=0\\ x_2+2x_3^2=3\\ x_1,x_2,x_3\ge0 \end{aligned} \end{cases} s.t.⎩ ⎨ ⎧x12−x2+x32≥0x1+x22+x3≤20−x1−x2+2=0x2+2x32=3x1,x2,x3≥0
解:
function f=fun1(x)%定义目标函数
f=sum(x.^2)+8;
end
function [g,h]=fun2(x);%定义非线性约束条件
g=[-x(1)^2+x(2)-x(3)^2%回车换行,第一个不等式约束
x(1)+x(2)^2+x(3)^3-20];%第二个不等式约束
h=[-x(1)-x(2)^2+2%回车换行,第一个等式约束
x(2)+2*x(3)^2-3];%非线性等式约束,第二个等式约束
end
[x,y]=fmincon('fun1',rand(3,1),[],[],[],[],zeros(3,1),[],'fun2');
求得当 x 1 = 0.5522 , x 2 = 1.2033 , x 3 = 0.9478 x_1=0.5522,x_2=1.2033,x_3=0.9478 x1=0.5522,x2=1.2033,x3=0.9478时,最小值 y = 10.6511 y=10.6511 y=10.6511。这里的初始值是用了一组随机数,但是此题初始值不论是什么都不影响最终的结果。
若某非线性规划的目标函数为自变量的二次函数,约束条件又全是线性的,就称这种规划为二次规划。
min 1 2 x T H x + f T x \min\quad\frac{1}{2}{\bf x}^\text T{\bf H}{\bf x}+\bf f^\text T\bf x min21xTHx+fTx
s.t. { A x ≤ b A e q ⋅ x = b e q l b ≤ x ≤ u b \text{s.t.}\quad \begin{cases} \begin{aligned} {\bf Ax}\le\bf b\\ \bf Aeq\cdot x=beq\\ \bf lb\le x\le ub \end{aligned} \end{cases} s.t.⎩ ⎨ ⎧Ax≤bAeq⋅x=beqlb≤x≤ub
这里 H \bf H H是实对称矩阵, f , b , b e q , l b , u b \bf f,b,beq,lb,ub f,b,beq,lb,ub是列向量, A , A e q \bf A,Aeq A,Aeq是相应维数的矩阵。
[x,fval]=quadporg(H,f,A,b,Aeq,beq,lb,ub,x0,options);
返回值 x \bf x x是决策向量 x \bf x x的值,返回值 fval \text{fval} fval是目标函数在 x \bf x x处的值。
例3 求解二次规划
min f ( x ) = 2 x 1 2 − 4 x 1 x 2 + 4 x 2 2 − 6 x 1 − 3 x 2 \min\quad f(x)=2x_1^2-4x_1x_2+4x_2^2-6x_1-3x_2 minf(x)=2x12−4x1x2+4x22−6x1−3x2
s.t. { x 1 + x 2 ≤ 3 4 x 1 + x 2 ≤ 9 x 1 , x 2 ≥ 0 \text{s.t.}\quad \begin{cases} \begin{aligned} x_1+x_2\le3\\ 4x_1+x_2\le9\\ x_1,x_2\ge0 \end{aligned} \end{cases} s.t.⎩ ⎨ ⎧x1+x2≤34x1+x2≤9x1,x2≥0
解:编写如下程序:
H=[4,-4;-4,8];
f=[-6;-3];
A=[1,1;4,1];
b=[3;9];
lb=zeros(2,1);
[x,fval]=quadprog(H,f,A,b,[],[],lb,[],rand(2,1));
求得 x 1 = 1.9500 , x 2 = 1.0500 , min f ( x ) = − 11.0250 x_1=1.9500,x_2=1.0500,\min f(x)=-11.0250 x1=1.9500,x2=1.0500,minf(x)=−11.0250,本题的最优解也与初始值无关。
例4 供应与选址
某公司有6个建筑工地要开工,每个工地的位置(用平面坐标系 a , b a,\text b a,b表示,距离单位:千米)及水泥日用量 d \text d d由下表给出。目前有两个临时料场位于 A ( 5 , 1 ) , B ( 2 , 7 ) \text A(5,1),\text B(2,7) A(5,1),B(2,7),日储量各有20吨。假设从料场到工地之间均有直线道路相连。
1 | 2 | 3 | 4 | 5 | 6 | |
---|---|---|---|---|---|---|
a a a | 1.25 | 8.75 | 0.5 | 5.75 | 3 | 7.25 |
b | 1.25 | 0.75 | 4.75 | 5 | 6.5 | 7.25 |
d | 3 | 5 | 4 | 7 | 6 | 11 |
X ij X_\text{ij} Xij | 从料场 j \text j j向工地 i \text i i的运送量 |
---|---|
( a i , b i ) (a_\text i,\text b_\text i) (ai,bi) | 工地 i \text i i的位置, i = 1 , 2 , ⋯ , 6 \text i=1,2,\cdots,6 i=1,2,⋯,6 |
d i \text d_\text i di | 工地 i \text i i水泥的日用量, i = 1 , 2 , ⋯ , 6 \text i=1,2,\cdots,6 i=1,2,⋯,6 |
( x j , y j ) (x_\text j,y_\text j) (xj,yj) | 料场 j \text j j的位置, j = 1 , 2 \text j=1,2 j=1,2 |
e j \text e_\text j ej | 料场 j \text j j的日储量, j = 1 , 2 \text j=1,2 j=1,2 |
使用两个临时料场 A ( 5 , 1 ) , B ( 2 , 7 ) \text A(5,1),\text B(2,7) A(5,1),B(2,7)。在各工地用量必须满足和各料场不超过日储量的条件下,使总的吨千米数最小,这是线性规划问题,线性规划模型为:
min f = ∑ j = 1 2 ∑ i = 1 6 a a ( i , j ) X ij \min\quad f=\sum_{\text j=1}^2\sum_{\text i=1}^6aa(\text i,\text j)X_{\text {ij}} minf=j=1∑2i=1∑6aa(i,j)Xij
s.t. { ∑ j = 1 2 X ij = d i i = 1 , 2 , ⋯ , 6 ∑ i = 1 6 X ij ≤ e i j = 1 , 2 \text{s.t.}\quad \begin{cases} \sum\limits_{\text j=1}^2X_{\text{ij}}=\text d_\text i&\text i=1,2,\cdots,6\\ \sum\limits_{\text i=1}^6X_{\text{ij}}\le\text e_\text i&\text j=1,2 \end{cases} s.t.⎩ ⎨ ⎧j=1∑2Xij=dii=1∑6Xij≤eii=1,2,⋯,6j=1,2
其中 a a ( i , j ) = ( x j − a i ) + ( y j − b i ) ) , i = 1 , 2 , ⋯ , 6 , j = 1 , 2 aa(\text i,\text j)=\sqrt{(x_\text j-a_\text i)+(y_\text j-\text b_\text i)}),\text i=1,2,\cdots,6,\text j=1,2 aa(i,j)=(xj−ai)+(yj−bi)),i=1,2,⋯,6,j=1,2,为常数。
由于料场的位置也是我们要求的决策变量,所以料场到各工地的距离不是常数了。这是非线性规划问题,但不是二次规划。
min f = ∑ j = 1 2 ∑ i = 1 6 X ij ( x j − a i ) + ( y j − b i ) ) \min\quad f=\sum_{\text j=1}^2\sum_{\text i=1}^6X_{\text {ij}}\sqrt{(x_\text j-a_\text i)+(y_\text j-\text b_\text i)}) minf=j=1∑2i=1∑6Xij(xj−ai)+(yj−bi))
s.t. { ∑ j = 1 2 X ij = d i i = 1 , 2 , ⋯ , 6 ∑ i = 1 6 X ij ≤ e i j = 1 , 2 \text{s.t.}\quad \begin{cases} \sum\limits_{\text j=1}^2X_{\text{ij}}=\text d_\text i&\text i=1,2,\cdots,6\\ \sum\limits_{\text i=1}^6X_{\text{ij}}\le\text e_\text i&\text j=1,2 \end{cases} s.t.⎩ ⎨ ⎧j=1∑2Xij=dii=1∑6Xij≤eii=1,2,⋯,6j=1,2
设:
X 11 = X 1 , X 21 = X 2 , X 31 = X 3 , X 41 = X 4 X 51 = X 5 , X 61 = X 6 , X 12 = X 7 , X 22 = X 8 X 32 = X 9 , X 42 = X 10 , X 52 = X 11 , X 62 = X 12 X_{11}=X_1,X_{21}=X_2,X_{31}=X_3,X_{41}=X_4\\ X_{51}=X_5,X_{61}=X_6,X_{12}=X_7,X_{22}=X_8\\ X_{32}=X_9,X_{42}=X_{10},X_{52}=X_{11},X_{62}=X_{12} X11=X1,X21=X2,X31=X3,X41=X4X51=X5,X61=X6,X12=X7,X22=X8X32=X9,X42=X10,X52=X11,X62=X12
MATLAB \text{MATLAB} MATLAB程序如下:
a=[1.25 8.75 0.5 5.75 3 7.25];%工厂的横坐标
b=[1.25 0.75 4.75 5 6.5 7.75];%工厂的纵坐标
d=[3 5 4 7 6 11];%工厂的水泥日用量
x=[5 2];%临时料场的横坐标
y=[1 7];%临时料场的纵坐标
e=[20 20];%临时料场的日存储量
for i=1:6%计算每个工地到两个临时料场的距离
for j=1:2
aa(i,j)=sqrt((x(j)-a(i))^2+(y(j)-b(i))^2);
end
end
c=[aa(:,1);aa(:,2)];%把aa矩阵拼接成列向量
A=[1 1 1 1 1 1 0 0 0 0 0 0;0 0 0 0 0 0 1 1 1 1 1 1];
B=[20;20];
Aeq=[1 0 0 0 0 0 1 0 0 0 0 0
0 1 0 0 0 0 0 1 0 0 0 0
0 0 1 0 0 0 0 0 1 0 0 0
0 0 0 1 0 0 0 0 0 1 0 0
0 0 0 0 1 0 0 0 0 0 1 0
0 0 0 0 0 1 0 0 0 0 0 1];
beq=d';
lb=zeros(12,1);
ub=[];
[x,fval]=linprog(c,A,B,Aeq,beq,lb,ub);
计算结果为:
x=[3,5,0,7,0,1,0,0,4,0,6,10];
fval=136.2275;
即由料场A、B向6个工地运料方案为:
1 | 2 | 3 | 4 | 5 | 6 | |
---|---|---|---|---|---|---|
料场A | 3 | 5 | 0 | 7 | 0 | 1 |
料场B | 0 | 0 | 4 | 0 | 6 | 10 |
总的吨千米数为136.2275。
设:
X 11 = X 1 , X 21 = X 2 , X 31 = X 3 , X 41 = X 4 X 51 = X 5 , X 61 = X 6 , X 12 = X 7 , X 22 = X 8 X 32 = X 9 , X 42 = X 10 , X 52 = X 11 , X 62 = X 12 x 1 = X 13 , y 1 = X 14 , x 2 = X 15 , y 2 = X 16 X_{11}=X_1,X_{21}=X_2,X_{31}=X_3,X_{41}=X_4\\ X_{51}=X_5,X_{61}=X_6,X_{12}=X_7,X_{22}=X_8\\ X_{32}=X_9,X_{42}=X_{10},X_{52}=X_{11},X_{62}=X_{12}\\ x_1=X_{13},y_1=X_{14},x_2=X_{15},y_2=X_{16} X11=X1,X21=X2,X31=X3,X41=X4X51=X5,X61=X6,X12=X7,X22=X8X32=X9,X42=X10,X52=X11,X62=X12x1=X13,y1=X14,x2=X15,y2=X16
MATLAB \text{MATLAB} MATLAB程序如下:
function f=liaoch(x)
a=[1.25 8.75 0.5 5.75 3 7.25];
b=[1.25 0.75 4.75 5 6.5 7.75];
f1=0;%料场1到各工厂的吨千米数
for i=1:6
s(i)=sqrt((x(13)-a(i))^2+(x(14)-b(i))^2);
f1=s(i)*x(i)+f1;
end
f2=0;%料场2到各工厂的吨千米数
for i=7:12
s(i)=sqrt((x(15)-a(i-6))^2+(x(16)-b(i-6))^2);
f2=s(i)*x(i)+f2;
end
f=f1+f2;
end
d=[3 5 4 7 6 11];%工厂的水泥日用量
x0=[3,5,0,7,0,1,0,0,4,0,6,10,5,1,2,7];%使用第一小题的解作为初始值
A=[1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0;0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0];
B=[20;20];
Aeq=[1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0];
beq=d';
lb=[zeros(12,1);-inf;-inf;-inf;-inf];
ub=[];
[x,fval]=fmincon('liaoch',x0,A,B,Aeq,beq,lb,ub)
x=[2.9410 4.8405 3.8779 6.9431 1.3033 0.0221 0.0590 0.1595 0.1221 0.0569 4.6967 10.9779 5.7297 4.9757 7.2500 7.7500];
fval=90.4920;
exitflag=2;
即两个新料场的坐标分别为 ( 5.7297 , 4.9757 ) , ( 7.2500 , 7.7500 ) (5.7297,4.9757),(7.2500,7.7500) (5.7297,4.9757),(7.2500,7.7500),由料场A、B向6个工地运料方案为:
1 | 2 | 3 | 4 | 5 | 6 | |
---|---|---|---|---|---|---|
料场A | 2.9410 | 4.8405 | 3.8779 | 6.9431 | 1.3033 | 0.0221 |
料场B | 0.0590 | 0.1595 | 0.1221 | 0.0569 | 4.6967 | 10.9779 |
总的吨千米数为90.4920。比用临时料场节省了45.7355吨千米。
x0=[2.9410 4.8405 3.8779 6.9431 1.3033 0.0221 0.0590 0.1595 0.1221 0.0569 4.6967 10.9779 5.7297 4.9757 7.2500 7.7500];
得计算结果如下:
x=[2.9410 4.8404 3.8779 6.9431 1.3034 0.0221 0.0590 0.1596 0.1221 0.0569 4.6966 10.9779 5.7298 4.9757 7.2500 7.7500];
fval=90.4921;
exitflag=2;
此次计算结果与上次的结果不同,说明结果与初始值有关,初始值不同,则结果不同。并且此次的最优解要劣于上次的最优解。按照视频讲的是把一次结果的最优解作为初始值再求解一次,得到的最优解会变得更优,然后反复将最优解带入初始值,最优解会逐渐逼近唯一的最优解。但是这次最优解解要略差一些,个人认为这是因为精度的问题,因为每一次求解得到的决策变量都会保留很多位小数,而我带入的初始值舍弃了一部分小数,不过这两次的初始值得到的解相差不是很多,在误差的允许范围之内,可以接受。
数学建模老哥