数学建模社区-数学中国
标题:
2-7、规划问题的Lingo解法
[打印本页]
作者:
杨利霞
时间:
2019-4-25 16:16
标题:
2-7、规划问题的Lingo解法
2-7、规划问题的Lingo解法
$ ?. V! A( D3 B/ F! h! |
一、 从规划问题引入
# C. M+ R4 S( k* s
& n/ h4 [! I% B3 z8 o6 D6 A- j
在我们学习探索的各个领域,规划问题都是无处不在的。通过列出约束条件及目标函数,再画出约束条件所表示的可行域,就能在可行域内求得目标函数的最优解以及最优值。当然我们在高中就已经学习过线性规划的相关知识,对于理科同学来说,大多数同学应该感觉难度不大,或者说是送分考点。然而到了大学阶段,一些规划问题的求解已经不是人力可以轻松算出来的了,必须借助于计算机来进行计算。那么对于规划问题的软件选择,又应当如何进行呢?
$ Q: d2 G$ s) X) j& y
. o; I0 z: D5 f. ^
二、 软件分析与选择
8 g7 ?: ]- o+ G3 ]: M
9 B) L; V$ C d* F4 _ z
Matlab相比之下是一个面面俱到的编程软件,也可用于求解规划问题。但是如果一定要去和某些“针对特定功能而开发的软件”去比的话,Matlab有时也会稍显逊色。就好比一款顶级的耳机能通吃高中低音,但是去和另一款顶级的为高音而设计的耳机去比较的话,也难免会被比下去。这也就是为什么在规划问题上,很多人会去使用Lingo进行求解。
( `% T6 I% n3 H+ @! I' F. r% O
& b A M; p1 { x: m
首先我们来区分一下Lindo和Lingo这两款软件。Lingo是在Lindo基础之上做成的软件,处理解线性规划问题之外还加了非线性的求解器,更关键的是还追加了集的概念。可以更方便的解决复杂的问题。所以本文只对Lingo进行讲解。
2 \0 n% I# V6 f& V1 {( F
而对于Matlab与Lingo的区别,就好比手动挡与自动挡的区别,有针对性的专业软件会对用户做很多的优化。这里引用知乎上大佬 花开花落 的回答
3 M: |9 X# f# v% {0 H
https://www.zhihu.com/question/49319704/answer/165923451
7 w& m$ L* |# V
) T! r* Q# B9 @: y
用MATLAB求解线性规划和整数规划问题,需要先将问题转化成如下标准型,其中X只能是向量,也就是单下标变量,然后用向量和矩阵来表达目标函数和约束条件。
7 d4 J3 P0 v$ Z8 O: |# Z
然而,许多问题(如指派问题和运输问题)由于参数和决策变量是双下标变量,必须在基本的数学模型的基础上进行变换才能求解,这样得到的等式约束和不等式约束的系数矩阵规模就非常庞大,当然由MATLAB计算问题不大,但转换工作完全要由人工完成,工作量大而且容易出错,因此在这一块效率不高。
+ S( ^/ N) r* N; V; c$ Y
而LINGO有自己的建模语言,在建立了集合的基础上,能够高效表达目标函数和各种约束条件。所写的模型基本上可以看作是对数学模型的翻译,不需要太多的转换。
& {" K; E7 M; z: e9 H3 q$ Q
0 t$ E/ K& w" Y* U2 ?- C# V
那么现在我们基本上对LINGO和MATLAB对规划问题的处理方面有了初步认识与了解,至于是执着于MATLAB还是选择开辟LINGO这片新的领域,取决于队伍自身了。
: r. V) ]$ _3 {: Z
* _( e6 S% H1 q$ u
三、 如何上手Lingo
) x1 E& E4 @; J) j4 ^* u
4 O5 @6 a( c3 b- H; F
有很多人对于Lingo的评价都是,非常简单的软件,很好上手。
& d# z# l% E* m6 k& z! d
“简单”一词我觉得还比较恰当。Lingo的各种版本几乎全部都是免安装版本的,界面很简单,功能用法很简单,处理问题的方式简单快捷。确实是跟“简单”一词挂钩的。但是任何一款软件想要精通,都是有一定难度的。如果你只需要用Lingo处理一些简单的线性问题,那么2个小时不到,0编程基础的朋友就能上手。如果你认准了Lingo就是你处理各类规划问题的御用软件,那么还是有很长一段路要走的。当然这也取决于用户的编程基础。如果学习过面向对象的程序设计课程的朋友,对于类与对象概念有所了解,那么对于集这一概念也能快速理解上手,学习起来更加轻松。
1 I+ G/ C5 c( S' b
) i+ X3 d& L1 u5 _0 _! p
四、 Lingo的基本语法规则
1 m e C4 c: B5 o. a
3 \) P1 [* f" \8 E4 Y' p
1、求目标函数的最大最小值用 MAX=MAX= 和 MIN=MIN= 来表示;
) v) g8 Q1 E( _' |2 l
2、每个语句必须用分号“;”结束,每行可以有许多语句,一个语句可以跨行;
" F1 h) W, u! ?
3、变量名必须以字母A-Z开头,由字母、数字0-9和下划线组成,长度不超过32个字符,不区分大小写;
& v( G3 X' C4 b d- P3 h
4、可以给语句加上标号;
5 {$ J& G3 v/ E# _# p$ c! P1 a5 m+ K1 c
5、注释以“!”开头以“;”结束;
0 X- W f. S( j5 Q7 ?5 U: t9 N
6、默认所有的决策变量为非负数;
2 H3 ~( j3 `: u
7、Lingo模型以“MODEL”开头以“END”结束。
0 P1 i$ u+ K. q
8、Lingo把相联系的对象聚合成集,借助集,就能够用一个单一的长的简明的公式表示一系列相应的约束。
* H( ~4 g) w# Q/ r. `3 j
9、Lingo程序会包含集合段,数据输入段,优化目标和约束段,初始段和数据预处理部分。
( T6 {# p8 Y2 R( N9 [. @
10、Lingo函数包括有数学函数,金融函数,概率函数,变量界定义函数,集操作函数,集循环函数,输入输出函数,辅助函数等等。
- ] e, S7 V$ J' {8 M
( B4 P ~3 K! z; V( E* ~
五、 谈一谈例子
0 N% I6 D2 E& z" l
; a! \0 |4 f6 C7 r" T
那么Lingo用起来到底有多简单呢,我们来看一个例子。
- L* f/ h$ q5 ^6 H* T
; O& S% L9 C/ u3 [0 ]
例1:某家公诉制造书桌、餐桌和椅子,所用的资源有三种:木料、木工和漆工。生产数据如下表所示:
: h9 Z6 u; ~0 Q9 l; g$ }1 t' i
- _& }! i1 X; F/ ]8 V
每个书桌 每个餐桌 每个椅子 现有资源总数
/ C4 Q5 \0 _% l4 `6 X
木料 8个单位 6个单位 1个单位 48个单位
9 R4 B$ l- C' t/ Y5 K( f
漆工 4个单位 2个单位 1.5个单位 20个单位
1 t1 @1 G+ C8 d( O# r
木工 2个单位 1.5个单位 0.5个单位 8个单位
. k5 d, J+ m4 }2 t
成品单价 60个单位 30个单位 20个单位
; z& ?- X3 e, [. y
若要求桌子的生产量不超过5件,如何安排三种产品的生产可使利润最大?
' P1 W# w* B G! C3 R, n
. p" r% l5 S1 i6 U
解:代码
& g9 M k4 O4 g) |7 r2 H7 R \
1 A8 b" [5 o1 H* f+ L
max = 60 * desks + 30 * tables + 20 * chairs;
2 l7 n5 S. o# X5 i+ s3 q# b5 T
8 * desks + 6 * tables + chairs <= 48;
- S; }! R$ \7 p
4 * desks + 2 * tables + 1.5 * chairs <= 20;
% ^# v$ o/ ^$ \: l4 i: Q. K" R9 E0 E
2 * desks + 1.5 * tables + .5 * chairs <= 8;
* V# X, z- J$ |: J
tables <= 5;
- E/ Y% Y" F/ I& X$ ~4 l
1
) G0 m3 N4 I1 Z+ T% w# b) @
2
5 {4 t+ L1 h. N. h, O
3
* W. s- |; M0 p1 L1 ]
4
# X; q: [, {$ r+ w( a9 B0 L) ~
5
" @# B% @, c* O, E+ `# b* ?
可以得到结果:
) b" T+ M' G6 f' i
8 D0 e" J- c" S
这里的 Total solver iteration 表示一共迭代2次得到最优解。
5 ~+ A7 ]2 V6 }- ?3 ?
Objective value 表示最优值为280,而取280的时候各个变量取多少呢,底下的表格给出了答案。
" t2 c, U+ T; ?3 I% }, X& [
可以看到,没有定义变量,简简单单一个函数一个约束条件,迅速计算出了答案。Lingo看上去就像是为了非编程人员量身定制的一样。
- }. {8 ]4 K- l
5 H9 b* x- T; N: _0 C/ G/ ?
例2:给定一个直角三角形,求包含该三角形的最小正方形。
+ v" p6 I* K0 z+ U+ |6 c( ^4 p
1 U/ v3 Q J; Z
我们可以作出如下正方形:
3 _$ f4 ~. Y7 s" T' @+ g7 e+ x
4 {/ G2 Z! v; x0 d0 L/ H
, F% @ x, a2 e/ y2 H9 u
CE=asinx,AD=bcosx,DE=acosx+bsinxCE=asinx,AD=bcosx,DE=acosx+bsinx
/ j6 z& C0 S$ v" R# ?
转化为了规划问题那么正方形面积最小的时候即为最优解。
, d9 k4 [# Q4 B) |/ {
代码:
% Q8 G$ \8 H; l4 V. V4 d
: n2 R6 m( a2 n, d/ Y3 h) o% `
model:
" r9 w9 |6 i- L; ]
sets:
; j9 u# d X+ X) p+ g# j
object/1..3/:f;
* V; k7 j: T$ @# y
endsets
- z* z5 r$ ~8 ]; O
data:
% a1 n( a( C. A
a, b = 3, 4;
- x7 P* C1 c ^) S: R# O% z
enddata
. q) B; J) {: p/ ?. j6 l
f(1) = a * @sin(x);
0 x9 E2 t N! M7 F$ [ j6 [
f(2) = b * @cos(x);
& V, G6 x4 x' w
f(3) = a * @cos(x) + b * @sin(x);
' D9 D" ]2 D& G$ b2 m: ?0 ^* ~
min = @smax(f(1), f(2), f(3));
' ?; A8 |6 v) e' q
@bnd(0, x, 1.57);
5 j: F2 n2 M9 j$ j0 y/ b% W
end
$ v+ I. z4 C% C# ~$ a* Q
1
7 }, S5 W1 P* M/ `' {9 U
2
: e9 a( d4 h2 t, i' q' }" }
3
0 \) P8 s" [( x5 h: D3 Q6 o
4
8 K4 m! B$ k1 v! q; Q" ]3 s
5
9 S4 U/ A, ]( ?3 w6 b
6
' N, K1 A1 h) }; S: m
7
* y$ E/ E' }" @+ B4 P7 k% U' C
8
5 w h+ i: O1 a, c9 H. E
9
4 s! W$ t% q, m/ l& g! k
10
: E" b, A9 T T% ?# V) }9 h1 Q
11
' y! p- r$ w# u: w; b6 o, C
12
) \4 X( Z$ ^/ |7 t" B8 z% ~/ W
13
: Z7 v: N) q9 F2 S
得到结果:
7 K/ E! l: [- I- P) I
5 W0 [; B' i( f1 I% k" c) g2 X
V9 d' S2 v4 K$ t! C' F Q
这里需要注意,lingo中如果没有代码说明,是默认 xx 的值大于0的。代码中用 bndbnd 函数限制了 xx 的范围。
& d, D* Z& o1 f. N- g( E$ Q
那么再进阶一下,Lingo在处理TSP问题的时候表现如何呢?
! k* `2 B! F4 `) E8 U) V
l" M) `7 M, W& L0 v
例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 的一个圈置换 ππ 就表示对所有零件的一个加工顺序,在此置换下,完成所有加工所需要的总时间为
! ~+ l+ j3 G( I6 {. C
∑i=0n(ciπ(i)+piπ(i))=∑i=0nciπ(i)+∑j=0npj
4 r( ^! e- ?5 |6 Z+ ]$ h
∑i=0n(ciπ(i)+piπ(i))=∑i=0nciπ(i)+∑j=0npj
6 i2 M0 c x# w% q# ~$ B
由于 ∑nj=0pj∑j=0npj 是一个常数,故该零件的加工顺序问题变成TSP。
U. i ^. M5 ]
! e& u6 `& h' b9 ]4 X: K
代码:
$ f3 c, ~/ \& ~0 [% F: Z' t2 ^
7 b7 b4 T* g7 F+ ?0 y. @% k* w
!旅行商问题;
, A' t& k8 X' @1 B! h! F$ ~7 Y. y
model:
# O% A1 ?+ p8 U4 n
sets:
. L( @; `3 y: R
city / 1.. 5/: u;
: x# |$ C9 T$ |, R! I* m
link(city, city):
6 S' z( M, k% q5 p' A" y
dist, x; !距离矩阵;
5 j8 D) X! f* }5 c5 p* t
endsets
& H7 W# q5 ~. I+ v
n = @size(city);
- o& `; Z& }4 h' [6 e
data: !距离矩阵,它并不需要是对称的;
% g# E0 ^6 x! n5 q
dist = @qrand(1); !随机产生,这里可改为你要解决的问题的数据;
, d3 T: Z2 _/ b
enddata
0 }! t- M$ d" F2 J+ D, |1 z
min = @sum(link:dist * x);
# ]: u3 v. V$ f) j8 j5 o# A
@FOR(city(K):
# H7 H6 `0 d' E, a1 E( M) e
@sum(city(I)|I #ne# K: x(I, K)) = 1;
- C, K* G0 R4 u" i3 b
!进入城市K;
* `% ?0 Q2 g/ P1 g$ h v% P
@sum(city(J)|J #ne# K: x(K, J)) = 1;
- K6 X# Z: p) @' Z/ S0 C
);
: L$ G5 m+ h% `4 ?2 Q/ k4 X* D8 r
@for(city(I)|I #gt# 1:
: u! j. t. k* v$ p3 V$ W
@for(city( J)| J#gt#1 #and# I #ne# J:
/ H2 ~# |8 j7 R. k' n: A
u(I) - u(J) + n * x(I,J) <= n - 1);
0 [& ?& V( E1 c, r9 V
);
" H* P: {) j& l
@for(city(I)|I #gt# 1: u(I) <= n - 2);
6 p* U8 d7 R7 M/ F& g4 J; U# ^
@for(link: @bin(x));
* W) y7 _% ` J. x* L
end
% P8 X& U3 H0 k' r
1
! T# V. X0 g% t
2
% f- M+ B* l9 Z% B
3
! A p! o/ ?5 M9 L4 `# ] ?
4
6 C1 r3 F2 L, V* M3 P
5
9 A0 W0 k' @7 ~: H0 g) M
6
- o' |6 r" w' i" b$ y7 y' p6 l
7
& O3 `1 k/ ~" Q% z
8
( N; Q; J4 B7 Y& |. B/ z
9
9 A6 X& z2 F. y: p ?$ {* @4 A
10
# |, `0 v- t: l; a, ~$ Q, ^2 M
11
4 G1 U x. \& _* B
12
# `7 T* t9 s/ E0 c9 k
13
+ ]4 b/ }8 y$ g3 t! E" W! k# J
14
4 w2 f1 e6 S7 i5 ^
15
! o3 g5 @) O5 A# u5 v# E
16
) f6 Z6 f0 D' R# A
17
: K5 P$ s* g! i) g3 k, ^3 l
18
; P1 b2 K6 `+ p
19
6 Z) A4 V+ S, a; H' N6 [
20
! ^/ `( N' }! i$ Z
21
# `3 U# @ j' [$ s1 s' v
22
; m+ U; g# e4 e
23
" M# C4 c. T3 @+ {4 s2 G0 x9 y
24
) S7 h- u1 Q3 n& G9 v
可以得到结果:
) i( t" R8 [' r7 ?
/ z1 Q6 U/ K( H+ a! y% S
---------------------
6 U$ m" J) E3 s. I: Y
4 N* D! T' ~$ R: [7 n, j; K
1 M' p( q; T+ ?
# ~4 B0 `6 b: G2 K7 ^! l0 W, R
% M+ {( }( E( P5 j# X
. E% y. O' f& k8 U) f
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5