数学建模社区-数学中国
标题:
2-7、规划问题的Lingo解法
[打印本页]
作者:
杨利霞
时间:
2019-4-25 16:16
标题:
2-7、规划问题的Lingo解法
2-7、规划问题的Lingo解法
5 V5 T% I. p' f8 K
一、 从规划问题引入
) t! `# B1 r- |8 t3 K
- d( p( {; g" @. {5 y+ U) Q
在我们学习探索的各个领域,规划问题都是无处不在的。通过列出约束条件及目标函数,再画出约束条件所表示的可行域,就能在可行域内求得目标函数的最优解以及最优值。当然我们在高中就已经学习过线性规划的相关知识,对于理科同学来说,大多数同学应该感觉难度不大,或者说是送分考点。然而到了大学阶段,一些规划问题的求解已经不是人力可以轻松算出来的了,必须借助于计算机来进行计算。那么对于规划问题的软件选择,又应当如何进行呢?
. X' I- O7 W+ e0 `
* A: D& l4 S' C1 R
二、 软件分析与选择
' S% d* t0 C4 `, B. w5 x' Y" T u8 Q
" h6 w' B5 C* y4 @% d
Matlab相比之下是一个面面俱到的编程软件,也可用于求解规划问题。但是如果一定要去和某些“针对特定功能而开发的软件”去比的话,Matlab有时也会稍显逊色。就好比一款顶级的耳机能通吃高中低音,但是去和另一款顶级的为高音而设计的耳机去比较的话,也难免会被比下去。这也就是为什么在规划问题上,很多人会去使用Lingo进行求解。
9 R# h5 t( i3 G. m
+ e: C8 a, ?: D, O
首先我们来区分一下Lindo和Lingo这两款软件。Lingo是在Lindo基础之上做成的软件,处理解线性规划问题之外还加了非线性的求解器,更关键的是还追加了集的概念。可以更方便的解决复杂的问题。所以本文只对Lingo进行讲解。
9 @7 ~' _! J, Q" z) b Y& y% H
而对于Matlab与Lingo的区别,就好比手动挡与自动挡的区别,有针对性的专业软件会对用户做很多的优化。这里引用知乎上大佬 花开花落 的回答
% n1 [% F# @ J7 M: n( D
https://www.zhihu.com/question/49319704/answer/165923451
4 m* v! T" ~4 N# N
8 U% [. k( F/ ]" E" ?" k( a
用MATLAB求解线性规划和整数规划问题,需要先将问题转化成如下标准型,其中X只能是向量,也就是单下标变量,然后用向量和矩阵来表达目标函数和约束条件。
0 V' ]7 V, W. \: G7 k
然而,许多问题(如指派问题和运输问题)由于参数和决策变量是双下标变量,必须在基本的数学模型的基础上进行变换才能求解,这样得到的等式约束和不等式约束的系数矩阵规模就非常庞大,当然由MATLAB计算问题不大,但转换工作完全要由人工完成,工作量大而且容易出错,因此在这一块效率不高。
4 Y8 b& u' |. S& a4 s. }) I
而LINGO有自己的建模语言,在建立了集合的基础上,能够高效表达目标函数和各种约束条件。所写的模型基本上可以看作是对数学模型的翻译,不需要太多的转换。
3 w2 I) C0 |' A/ H8 s- |
1 \) Y' l2 ^7 Q- b9 n! J# c
那么现在我们基本上对LINGO和MATLAB对规划问题的处理方面有了初步认识与了解,至于是执着于MATLAB还是选择开辟LINGO这片新的领域,取决于队伍自身了。
4 x- i' R; J( H e6 E
; _$ q0 k* H9 r/ l
三、 如何上手Lingo
6 e2 S, |3 v- D* _& X
, v q0 K# D* b& H# [
有很多人对于Lingo的评价都是,非常简单的软件,很好上手。
; N" r) }$ a( V
“简单”一词我觉得还比较恰当。Lingo的各种版本几乎全部都是免安装版本的,界面很简单,功能用法很简单,处理问题的方式简单快捷。确实是跟“简单”一词挂钩的。但是任何一款软件想要精通,都是有一定难度的。如果你只需要用Lingo处理一些简单的线性问题,那么2个小时不到,0编程基础的朋友就能上手。如果你认准了Lingo就是你处理各类规划问题的御用软件,那么还是有很长一段路要走的。当然这也取决于用户的编程基础。如果学习过面向对象的程序设计课程的朋友,对于类与对象概念有所了解,那么对于集这一概念也能快速理解上手,学习起来更加轻松。
" Z+ ]' M4 x) d% J. |( Q1 G
5 ?. q- ^" z: _' [
四、 Lingo的基本语法规则
* f5 A- Y$ a1 W6 A' m
+ \, h% Y" m/ C0 M, I- E
1、求目标函数的最大最小值用 MAX=MAX= 和 MIN=MIN= 来表示;
( X& d1 F8 ^( w
2、每个语句必须用分号“;”结束,每行可以有许多语句,一个语句可以跨行;
1 X1 \: m5 U3 ^- q. w4 d8 ]
3、变量名必须以字母A-Z开头,由字母、数字0-9和下划线组成,长度不超过32个字符,不区分大小写;
4 W% S: V( z! N3 T* H5 i
4、可以给语句加上标号;
H, b' q3 u2 O
5、注释以“!”开头以“;”结束;
6 l0 h4 t5 Q/ K4 T% _
6、默认所有的决策变量为非负数;
9 R, I- b" F C6 c
7、Lingo模型以“MODEL”开头以“END”结束。
/ `5 c1 G8 p$ p, Z% \, H
8、Lingo把相联系的对象聚合成集,借助集,就能够用一个单一的长的简明的公式表示一系列相应的约束。
1 t) y" ]# [: Z! i( u
9、Lingo程序会包含集合段,数据输入段,优化目标和约束段,初始段和数据预处理部分。
4 c% K& ?3 b7 l# i
10、Lingo函数包括有数学函数,金融函数,概率函数,变量界定义函数,集操作函数,集循环函数,输入输出函数,辅助函数等等。
+ ?. I# q9 ~6 G7 ~; o) }
1 W+ p' F' T4 M! F* ?1 N9 r
五、 谈一谈例子
* \" V+ j/ J o4 K9 d5 K+ W; j
/ W' Z9 e3 t% I3 G+ o, p
那么Lingo用起来到底有多简单呢,我们来看一个例子。
9 m9 Y$ P7 E3 i1 u) y: G
~3 D2 i) S" s+ K. p
例1:某家公诉制造书桌、餐桌和椅子,所用的资源有三种:木料、木工和漆工。生产数据如下表所示:
* O$ S0 d. z2 ^8 T x
( w5 l4 W5 H% P2 P8 u& d/ ]/ v; J8 \
每个书桌 每个餐桌 每个椅子 现有资源总数
* | ~8 T: t$ _: z' E
木料 8个单位 6个单位 1个单位 48个单位
! I: ?; ~% G. O4 @6 `" T7 N6 ^
漆工 4个单位 2个单位 1.5个单位 20个单位
4 K' E f6 y+ \- \
木工 2个单位 1.5个单位 0.5个单位 8个单位
, K0 i% m' d: T. y
成品单价 60个单位 30个单位 20个单位
) T, l% J0 Q8 h2 [0 Z. R
若要求桌子的生产量不超过5件,如何安排三种产品的生产可使利润最大?
4 F( u+ L5 B j2 e6 \* K: \
" q0 d8 [( e: n4 }& ^( ?
解:代码
; {$ |% t0 W" ^
$ `$ c ?+ B, M; G7 G N
max = 60 * desks + 30 * tables + 20 * chairs;
& z% b1 d# S8 n! ^/ c+ f: ]- y$ h
8 * desks + 6 * tables + chairs <= 48;
- {0 e; _, m/ F. ?* E
4 * desks + 2 * tables + 1.5 * chairs <= 20;
* q2 Z+ {! {1 i$ }( L7 S
2 * desks + 1.5 * tables + .5 * chairs <= 8;
. ~8 w3 r% m+ k% o* Z
tables <= 5;
- x% P* ~- Z6 P8 E4 S
1
% p* Z3 g8 h) ]8 p
2
" h4 a, B% f) L+ I3 j
3
/ _5 ]* @/ e- ~( Q) o W' P: `
4
( `# y k7 y% x0 v. A' I+ s: K
5
3 g" H3 [2 k3 T( t/ q6 \# K( `0 Y! n
可以得到结果:
+ h7 p- m( O. y, d
! @- H& L$ P/ j' I4 T
这里的 Total solver iteration 表示一共迭代2次得到最优解。
3 y9 J0 }- f6 _9 c: B) P8 Z* Q
Objective value 表示最优值为280,而取280的时候各个变量取多少呢,底下的表格给出了答案。
, V+ K# K5 o1 E4 N" y% @0 p9 q
可以看到,没有定义变量,简简单单一个函数一个约束条件,迅速计算出了答案。Lingo看上去就像是为了非编程人员量身定制的一样。
1 F, N- G. G! [6 k- z# P
- \" S4 K# O5 [5 v
例2:给定一个直角三角形,求包含该三角形的最小正方形。
6 A, Z+ k0 ~' N0 j! h4 I7 W
% N9 Y. S4 Y; N: P" ?$ m S
我们可以作出如下正方形:
. A& c2 H2 _0 Z( H7 F" m% C
e- c7 V% L' O R* Z: T6 p. d5 Q9 Z
5 J* ^) W; U- ?" T# m
CE=asinx,AD=bcosx,DE=acosx+bsinxCE=asinx,AD=bcosx,DE=acosx+bsinx
2 y" {' g. s- i7 i, L5 @9 U
转化为了规划问题那么正方形面积最小的时候即为最优解。
# S2 d- |7 @4 ?0 N s( @# P' ^
代码:
* Z1 z+ o: a; @1 p
2 S5 w5 P% d h" @# k
model:
% @* n6 ]% G: `1 X
sets:
% h/ T+ O, c$ T$ m4 ~$ T2 i
object/1..3/:f;
( Y9 C* v' T! h1 N# ]+ Q& ?# M" W
endsets
" `0 m2 a& ^' s* @
data:
% o% A# j1 z2 K! {4 G5 Q+ H1 X3 K
a, b = 3, 4;
% Z6 z$ c8 `# [& {" A( g# n5 a
enddata
3 \& P) B5 }5 N. A- B& n S& ?
f(1) = a * @sin(x);
; Y0 `1 z6 ]- _; ~6 G
f(2) = b * @cos(x);
+ b ^' r p* K0 u j4 j
f(3) = a * @cos(x) + b * @sin(x);
0 O+ P" n, f) f9 @+ Y: m
min = @smax(f(1), f(2), f(3));
$ R( m3 X' y7 j6 x
@bnd(0, x, 1.57);
' q# {( ?. b$ D ^2 g
end
) ?) H7 v+ G8 ^" _% p0 L. n
1
" e/ O4 { {8 { C. P
2
- A' Z+ b4 f, G& e1 C1 a
3
$ m) g2 j$ j% U9 A
4
- {2 _$ Y! l; U+ S
5
# V1 e( E8 U7 Y# l7 } A9 L
6
' o5 s5 R% }! Z3 }: Y4 \
7
% k. Z( A% O) ?9 D' ^* i% Z1 f0 q }% `
8
1 V- P% C9 O9 b) r* X
9
" q) ~, @, A2 `/ m7 e9 d
10
- w5 v p$ s% |* n0 {; }& F! _
11
, {* i- V9 X, v! J, \; N
12
# O9 |/ f% c$ r( Z1 x' [% z
13
- a1 A& R1 z4 v5 Y
得到结果:
* c1 X7 ]+ x' \6 e# F( r$ u6 I1 p# L
3 t6 z: M9 r; r A+ Y
7 v* U* l% P9 R5 |7 e
这里需要注意,lingo中如果没有代码说明,是默认 xx 的值大于0的。代码中用 bndbnd 函数限制了 xx 的范围。
# S% m# S1 n+ h" y' t
那么再进阶一下,Lingo在处理TSP问题的时候表现如何呢?
1 a8 E1 i# y+ H8 }& ?
( N% p$ ?% J7 ^+ s$ f
例3: 现需在一台机器上加工 nn 个零件(如烧瓷器),这些零件可按任意先后顺序在机器上加工。我们希望加工完成所有零件的总时间尽可能少。由于加工工艺的要求,加工零件 jj 时机器必须处于相应状态 sjsj(如炉温)。设起始未加工任何零件时机器处于状态 s0s0 ,且当所有零件加工完成后需恢复到 s0s0 状态。已知从状态 sisi 调整到状态 sj(j≠i)sj(j≠i) 需要时间 cijcij 零件 jj 本身加工时间为 pjpj。为方便起见,引入一个虚零件 00,其加工时间为 00,要求状态为 s0s0,则 0,1,2,…,n0,1,2,…,n 的一个圈置换 ππ 就表示对所有零件的一个加工顺序,在此置换下,完成所有加工所需要的总时间为
9 P z6 D* ]2 H f! A8 w) M" T
∑i=0n(ciπ(i)+piπ(i))=∑i=0nciπ(i)+∑j=0npj
, m) Z- W! @$ u: H
∑i=0n(ciπ(i)+piπ(i))=∑i=0nciπ(i)+∑j=0npj
, D; o9 Z& K6 }. a8 m% o
由于 ∑nj=0pj∑j=0npj 是一个常数,故该零件的加工顺序问题变成TSP。
, m" \1 k/ w/ O5 l) }* I- \
. s' h. t( F% v+ F( X& G; L
代码:
( V. u4 ?( B: v
3 \! g$ i5 m9 w! {( n: y
!旅行商问题;
; z: c$ t& ]9 t9 @
model:
. a1 P: R g, R$ |8 z! a
sets:
7 G! I) q% Z. E2 P" V. t4 A
city / 1.. 5/: u;
8 ?) S7 K' J( l2 C1 r$ `
link(city, city):
3 q. S0 @5 @, A5 X8 e2 p8 v
dist, x; !距离矩阵;
! f7 g4 T. J% K
endsets
* j' v& N+ k" J; V* T$ G
n = @size(city);
/ S5 t9 L$ e4 z' l+ X
data: !距离矩阵,它并不需要是对称的;
! A$ C* [" v7 f1 a
dist = @qrand(1); !随机产生,这里可改为你要解决的问题的数据;
. E, h, S& K$ ?' W
enddata
) i( \; b* H" E1 u+ j6 }
min = @sum(link:dist * x);
R9 m1 B( L+ d* x/ J% v
@FOR(city(K):
! }0 H" H5 X2 @
@sum(city(I)|I #ne# K: x(I, K)) = 1;
8 E5 y. [2 U8 u4 n
!进入城市K;
7 N0 v2 V# P {# c d& F
@sum(city(J)|J #ne# K: x(K, J)) = 1;
_1 v) {- u- e. Y) V
);
8 c! E/ v& n2 ^) P' P3 c
@for(city(I)|I #gt# 1:
, d: c9 w8 L- G
@for(city( J)| J#gt#1 #and# I #ne# J:
% D6 @ d7 q: Q- p2 p; V2 ]
u(I) - u(J) + n * x(I,J) <= n - 1);
% f; t6 j2 U3 n, B# i
);
: t9 k& R; E( O) F
@for(city(I)|I #gt# 1: u(I) <= n - 2);
: `) u, K) f2 S. _
@for(link: @bin(x));
. m) }, T% _! d, u0 v6 ~
end
0 @/ g. e$ ?2 k5 \2 w" l! a2 e- I/ w8 X
1
" [- S" B; T- f% k' f, x
2
) a6 J9 J! t, V% K. b- U3 g
3
" Y8 D- I# r% \* s2 I
4
2 `0 b. i/ l5 U5 g' G" V2 S
5
3 x& M1 x. S( k& l
6
8 {) f7 G! v7 D6 Q0 v# R* q$ i8 e
7
2 i! ]! V4 y0 q& q! `% f9 O
8
, G5 d8 q4 z1 j% }! r
9
5 t& L$ v6 b+ v U% _# w& x
10
- ?* Q$ c6 T" q$ }; B
11
% E) Q3 x* m% L: o5 ^$ A% R
12
& J/ m8 b B% W* C( R2 ~
13
# M! y0 T) a( W! X S5 q9 P
14
q g N3 M; P, d* t/ z
15
, e8 u* h/ r6 T0 o& @* x
16
; i6 {+ N9 C- e' j7 N
17
$ ~- a! T* d; F2 W2 a
18
. b3 ^/ ~7 `8 x7 s! Z) ?( W6 ^1 u
19
4 G" f: W, `% @
20
2 Z2 }% f( a# u
21
" |; {4 I: c" ~& P0 c7 k5 j1 e& f
22
( C) P1 W5 P* L8 ?7 W
23
, W8 N6 v$ r L# N
24
) x6 f. ]3 r) U4 K I" t2 M
可以得到结果:
5 D U8 a% w* ~% W) a& c% h/ g; F
8 ]9 J8 f9 ]4 [1 O$ O# ~
---------------------
; t L$ r9 @' r0 w, C7 h
; g( k% ]: [- d( Y6 ~9 v+ Q
F8 F4 Q/ y6 O6 u! h
0 C; J+ q! s( _3 v
; b1 V( G& D% W
% u. \) J' U, D" A9 t k T
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5