非线性规划模型

  • 目标函数或约束条件中包含非线性函数的数学规划问题称为非线性规划问题

非线性规划 - 图1

  • Matlab求解非线性规划问题的函数

[x,fval]=fmincon(@fun,x0,A,b,Aeq,beq,lb,ub,@nonlfun,option)
fun:目标函数的M文件名
nonlfun:非线性约束条件函数的M文件名
option:可以给定求解的算法,可以使用默认参数设置

  • 注意
  1. 非线性规划问题对于初始值x0的选取很重要,因为费霞凝规划的算法求解出来的是一个局部最优解
  2. “全局最优解”的两种思路:

①给定不同的初值,在里面找到一个最优解
②先用蒙特卡洛模拟得到一个解,然后将这个解作为初始值来求最优解(推荐)

  1. option选项有四种算法:interior-point(内点法)、sqp(序列二次规划法)、action-set(有效集法)、trust-region-reflective(信赖域反射算法),不同的算法有各自的优缺点,我们可以该边求解的算法来看求解的结果是否更优

    例题并求解

非线性规划 - 图2

  • Matlab求解 ```matlab %% fun2.m定义目标函数 function f = fun2(x) f=sum(x.^2)+8; end

%% nonlfun2.m定义非线性约束 function [g,h]=nonlfun2(x) %g 非线性不等式约束;h 非线性等式约束 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

%% 主程序 clc;clear; %% 用蒙特卡罗方法找初始值 f_min=+inf; x0=[0 ;0 ;0]; x1=unifrnd(0,2,10^6,1); x2=unifrnd(0,1.5,10^6,1); x3=unifrnd(0,1.3,10^6,1); tic for i=1:10^6 x=[x1(i),x2(i),x3(i)]; f=fun2(x); [g,h]=nonlfun2(x); if isempty(find(g>0)) & abs(h(1))<0.01 & abs(h(2))<0.01 if f<f_min x0=x;f_min=f; end end end x0 f_min toc %% 代入求得的初值求解 [x,fval]=fmincon(@fun2,[0.3471,1.2852,0.9278],[],[],[],[],zeros(3,1),[],@nonlfun2)

  1. 结果为:x = 0.4011 1.2645 0.9315 fval = 10.6275<br />对比《数学建模算法与应用》上的结果,此结果更优
  2. - python求解
  3. ```python
  4. #目标函数
  5. fun=lambda x:x[0]**2+x[1]**2+x[2]**2+8
  6. # 'eq'表示表达式等于0,'ineq'表示表达式大于等于0
  7. constraints=[{'type': 'ineq', 'fun': lambda x:x[0]**2 - x[1] + x[2]**2},
  8. {'type': 'ineq', 'fun': lambda x: 20 - x[0] - x[1]**2 - x[2]**3},
  9. {'type': 'eq', 'fun': lambda x: -x[0] - x[1]**2 +2},
  10. {'type': 'eq', 'fun': lambda x: x[1] + 2*x[2]**2 - 3}]
  11. #上下界
  12. bounds = [(0,None)]*3
  13. #蒙特卡洛法设置初始值
  14. f_min=float('inf')
  15. x0=[0 ,0 ,0]
  16. x1=2*np.random.rand(10**6,1)
  17. x2=1.5*np.random.rand(10**6,1)
  18. x3=1.3*np.random.rand(10**6,1)
  19. for i in range(10**6):
  20. x=[x1[i],x2[i],x3[i]]
  21. x=[x[0][0],x[1][0],x[2][0]]
  22. f=fun(x)
  23. g=np.array([constraints[0]['fun'](x),constraints[1]['fun'](x)])
  24. h=np.array([constraints[2]['fun'](x),constraints[3]['fun'](x)])
  25. if all(g)>=0 & all(abs(h))<0.00001:
  26. x0=x
  27. f_min=f
  28. print(x0)
  29. print(f_min)
  30. #求解
  31. res = minimize(fun, x0, method='SLSQP',constraints=constraints)
  32. res

结果:fun: 10.651091840570237
x: array([0.55216734, 1.20325918, 0.94782404])

非线性规划的典型例题——选址问题

  • 题目:临时料场A(5,1),B(2,7),日储量各20吨。 | 工地位置坐标及日需求量 | | | | | | | | —- | —- | —- | —- | —- | —- | —- | | | 1 | 2 | 3 | 4 | 5 | 6 | | 横坐标 | 1.25 | 8.75 | 0.5 | 5.75 | 3 | 7.25 | | 纵坐标 | 1.25 | 0.75 | 4.75 | 5 | 6.5 | 7.25 | | 日需求量 | 3 | 5 | 4 | 7 | 6 | 11 |

(1)试制定每天的供应计划,即从两料场分别向各工地运送多少吨水泥,使总的吨千米数最小。
(2)为了进一步减少吨千米数,打算舍弃两个临时料场,改建两个新的,日储量各为20吨,问应建在何处,节省的吨千米数有多大?

  • 问分析

记工地非线性规划 - 图3的坐标为非线性规划 - 图4水泥日用量为非线性规划 - 图5
记料场非线性规划 - 图6的坐标为非线性规划 - 图7,日储量为20
记从料场非线性规划 - 图8往工地非线性规划 - 图9运送的水泥为非线性规划 - 图10

非线性规划 - 图11
(1)问非线性规划 - 图12是已知的,故共有12个变量,(2)问有16个变量
决策变量双下下标改为单下表:

非线性规划 - 图13 非线性规划 - 图14 …… 非线性规划 - 图15 非线性规划 - 图16 非线性规划 - 图17 …… 非线性规划 - 图18 非线性规划 - 图19 非线性规划 - 图20 非线性规划 - 图21 非线性规划 - 图22
非线性规划 - 图23 非线性规划 - 图24 …… 非线性规划 - 图25 非线性规划 - 图26 非线性规划 - 图27 …… 非线性规划 - 图28 非线性规划 - 图29 非线性规划 - 图30 非线性规划 - 图31 非线性规划 - 图32
  1. function f = fun5(xx) % 注意为了避免和下面的x同号,我们把决策变量的向量符号用xx表示(注意xx的长度为16
  2. a=[1.25 8.75 0.5 5.75 3 7.25]; % 工地的横坐标
  3. b=[1.25 0.75 4.75 5 6.5 7.25]; % 工地的纵坐标
  4. x = [xx(13) xx(15)]; % 新料场的横坐标
  5. y = [xx(14) xx(16)]; % 新料场的纵坐标
  6. c = []; % 初始化用来保存工地和料场距离的向量 (这个向量就是我们的系数向量)
  7. for j =1:2
  8. for i = 1:6
  9. c = [c; sqrt( (a(i)-x(j))^2 + (b(i)-y(j))^2)]; % 每循环一次就在c的末尾插入新的元素
  10. end
  11. end
  12. % 下面我们要求吨千米数,注意c是列向量,我们计算非线性规划时给定的初始值x0是行向量
  13. f = xx(1:12) * c;
  14. end
  15. clear;clc
  16. format long g
  17. % (1) 不等式约束
  18. A =zeros(2,16); % 注意这里要改成16
  19. A(1,1:6) = 1;
  20. A(2,7:12) = 1;
  21. b = [20,20]';
  22. % (2) 等式约束
  23. Aeq = zeros(6,16); % 注意这里要改成16
  24. for i = 1:6
  25. Aeq(i,i) = 1; Aeq(i,i+6) = 1;
  26. end
  27. beq = [3 5 4 7 6 11]'; % 每个工地的日需求量
  28. %(3)上下界
  29. lb = zeros(16,1);
  30. % lb = [zeros(12,1); -inf*ones(4,1)]; 两个新料场坐标的下界可以设为-inf
  31. % 进行求解
  32. x0 = [3 5 0 7 0 1 0 0 4 0 6 10 5 1 2 7]; % 用第一问的结果作为初始值
  33. [x,fval] = fmincon(@fun5,x0,A,b,Aeq,beq,lb) % 注意没有非线性约束,所以这里可以用[]替代,或者干脆不写

x =

1 至 4 列

  1. 2.93079373691722 4.62098894690306 3.86630967073392 6.9323464081422

5 至 8 列

  1. 1.54452626271135 0.025293774364618 0.0692062630827831 0.379011053096942

9 至 12 列

  1. 0.133690329266078 0.0676535918578045 4.45547373728865 10.9747062256354

13 至 16 列

  1. 5.74190837844137 4.99144031310414 7.24999993630655 7.24999999514472<br />fval =
  2. 89.9232875546202