数学建模社区-数学中国

标题: 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 ]: M9 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 Hhttps://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 N6、默认所有的决策变量为非负数; 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 l1) G0 m3 N4 I1 Z+ T% w# b) @
25 {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$ @# yendsets- z* z5 r$ ~8 ]; O
data:
% a1 n( a( C. A    a, b = 3, 4;
- x7 P* C1 c  ^) S: R# O% zenddata. 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 U2: e9 a( d4 h2 t, i' q' }" }
3
0 \) P8 s" [( x5 h: D3 Q6 o48 K4 m! B$ k1 v! q; Q" ]3 s
59 S4 U/ A, ]( ?3 w6 b
6' N, K1 A1 h) }; S: m
7* y$ E/ E' }" @+ B4 P7 k% U' C
85 w  h+ i: O1 a, c9 H. E
94 s! W$ t% q, m/ l& g! k
10
: E" b, A9 T  T% ?# V) }9 h1 Q11' 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=0npj4 r( ^! e- ?5 |6 Z+ ]$ h
∑i=0n(ciπ(i)+piπ(i))=∑i=0nciπ(i)+∑j=0npj6 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 edata: !距离矩阵,它并不需要是对称的;% 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* Lend% P8 X& U3 H0 k' r
1
! T# V. X0 g% t2% f- M+ B* l9 Z% B
3
! A  p! o/ ?5 M9 L4 `# ]  ?46 C1 r3 F2 L, V* M3 P
5
9 A0 W0 k' @7 ~: H0 g) M6
- o' |6 r" w' i" b$ y7 y' p6 l7
& O3 `1 k/ ~" Q% z8( N; Q; J4 B7 Y& |. B/ z
99 A6 X& z2 F. y: p  ?$ {* @4 A
10# |, `0 v- t: l; a, ~$ Q, ^2 M
11
4 G1 U  x. \& _* B12# `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# E16
) f6 Z6 f0 D' R# A17
: K5 P$ s* g! i) g3 k, ^3 l18
; P1 b2 K6 `+ p19
6 Z) A4 V+ S, a; H' N6 [20
! ^/ `( N' }! i$ Z21
# `3 U# @  j' [$ s1 s' v22
; m+ U; g# e4 e23" 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