数学建模社区-数学中国
标题:
2-7、规划问题的Lingo解法
[打印本页]
作者:
杨利霞
时间:
2019-4-25 16:16
标题:
2-7、规划问题的Lingo解法
2-7、规划问题的Lingo解法
* u+ i- m1 n! p( S6 L/ `
一、 从规划问题引入
% g% F" N/ s% E2 V
4 S" e" k) s& j. @" F, i
在我们学习探索的各个领域,规划问题都是无处不在的。通过列出约束条件及目标函数,再画出约束条件所表示的可行域,就能在可行域内求得目标函数的最优解以及最优值。当然我们在高中就已经学习过线性规划的相关知识,对于理科同学来说,大多数同学应该感觉难度不大,或者说是送分考点。然而到了大学阶段,一些规划问题的求解已经不是人力可以轻松算出来的了,必须借助于计算机来进行计算。那么对于规划问题的软件选择,又应当如何进行呢?
! f6 M. H# c$ l
9 ?5 m7 `. g9 C
二、 软件分析与选择
- {6 X; z4 i7 A+ J
: y3 g( K9 j# b! M% P: g8 X6 ?
Matlab相比之下是一个面面俱到的编程软件,也可用于求解规划问题。但是如果一定要去和某些“针对特定功能而开发的软件”去比的话,Matlab有时也会稍显逊色。就好比一款顶级的耳机能通吃高中低音,但是去和另一款顶级的为高音而设计的耳机去比较的话,也难免会被比下去。这也就是为什么在规划问题上,很多人会去使用Lingo进行求解。
+ B7 y7 I/ Q; Q
. z2 ^! C9 ?) v9 R9 v) m* V; d9 Y
首先我们来区分一下Lindo和Lingo这两款软件。Lingo是在Lindo基础之上做成的软件,处理解线性规划问题之外还加了非线性的求解器,更关键的是还追加了集的概念。可以更方便的解决复杂的问题。所以本文只对Lingo进行讲解。
" ^" f+ c- k) U6 Q9 K
而对于Matlab与Lingo的区别,就好比手动挡与自动挡的区别,有针对性的专业软件会对用户做很多的优化。这里引用知乎上大佬 花开花落 的回答
5 U9 R# }( V7 J; J- K. ~/ r0 Z
https://www.zhihu.com/question/49319704/answer/165923451
; q$ ?: }; v v) V
$ p! w% Z$ l' H, a
用MATLAB求解线性规划和整数规划问题,需要先将问题转化成如下标准型,其中X只能是向量,也就是单下标变量,然后用向量和矩阵来表达目标函数和约束条件。
+ j. ^- N* u* E
然而,许多问题(如指派问题和运输问题)由于参数和决策变量是双下标变量,必须在基本的数学模型的基础上进行变换才能求解,这样得到的等式约束和不等式约束的系数矩阵规模就非常庞大,当然由MATLAB计算问题不大,但转换工作完全要由人工完成,工作量大而且容易出错,因此在这一块效率不高。
! } J8 b3 T% ]% r
而LINGO有自己的建模语言,在建立了集合的基础上,能够高效表达目标函数和各种约束条件。所写的模型基本上可以看作是对数学模型的翻译,不需要太多的转换。
, i t3 p: M; W- t( M9 i
/ n) h* D: v9 d- N
那么现在我们基本上对LINGO和MATLAB对规划问题的处理方面有了初步认识与了解,至于是执着于MATLAB还是选择开辟LINGO这片新的领域,取决于队伍自身了。
' G4 K& f1 B" D% A
) Z1 B) }4 ]9 j: f
三、 如何上手Lingo
- `9 Q- Q0 y- S7 W4 y
1 j# _) q( S( `$ m& K* ]
有很多人对于Lingo的评价都是,非常简单的软件,很好上手。
4 X$ Q% g, P [/ n* H1 j& Q
“简单”一词我觉得还比较恰当。Lingo的各种版本几乎全部都是免安装版本的,界面很简单,功能用法很简单,处理问题的方式简单快捷。确实是跟“简单”一词挂钩的。但是任何一款软件想要精通,都是有一定难度的。如果你只需要用Lingo处理一些简单的线性问题,那么2个小时不到,0编程基础的朋友就能上手。如果你认准了Lingo就是你处理各类规划问题的御用软件,那么还是有很长一段路要走的。当然这也取决于用户的编程基础。如果学习过面向对象的程序设计课程的朋友,对于类与对象概念有所了解,那么对于集这一概念也能快速理解上手,学习起来更加轻松。
! e0 e( o/ I+ _' P; J& T
/ U# m3 }/ z J- B8 K; O' d3 p
四、 Lingo的基本语法规则
2 P" _7 S% q' v: h6 C8 a
3 Y- B5 z" Q3 _: C% V
1、求目标函数的最大最小值用 MAX=MAX= 和 MIN=MIN= 来表示;
' z- h5 L F. q6 E" K, S8 m
2、每个语句必须用分号“;”结束,每行可以有许多语句,一个语句可以跨行;
" L% f6 T9 \* h* c( g! X, n" @
3、变量名必须以字母A-Z开头,由字母、数字0-9和下划线组成,长度不超过32个字符,不区分大小写;
/ t+ k2 x: G. ~" r
4、可以给语句加上标号;
/ w5 N; B1 N' N1 c
5、注释以“!”开头以“;”结束;
# M- Y0 i! Q0 |8 G. \& R( P6 Z
6、默认所有的决策变量为非负数;
+ n; p3 k8 Y7 S- x
7、Lingo模型以“MODEL”开头以“END”结束。
$ X4 o' b5 Z* K% y
8、Lingo把相联系的对象聚合成集,借助集,就能够用一个单一的长的简明的公式表示一系列相应的约束。
# j4 `! t0 ? y& e5 T# Z8 f
9、Lingo程序会包含集合段,数据输入段,优化目标和约束段,初始段和数据预处理部分。
8 X V" }! H$ d: J9 p
10、Lingo函数包括有数学函数,金融函数,概率函数,变量界定义函数,集操作函数,集循环函数,输入输出函数,辅助函数等等。
) K8 v& c/ n9 {, w
$ K& P5 Q0 G" ^0 h. m
五、 谈一谈例子
5 j i/ A% S! A' r$ l4 N5 g
; \# [5 `% b# ?3 v$ m/ n: @; Y
那么Lingo用起来到底有多简单呢,我们来看一个例子。
4 ?- i4 Z; _. g' y8 W; w! T9 `0 H
1 T& @7 G: p) G2 Q: G
例1:某家公诉制造书桌、餐桌和椅子,所用的资源有三种:木料、木工和漆工。生产数据如下表所示:
; g$ g# ^ A/ s/ a
& o2 z5 F2 d+ a* Z t/ j4 a/ S+ }
每个书桌 每个餐桌 每个椅子 现有资源总数
, C; t7 ^$ K! s
木料 8个单位 6个单位 1个单位 48个单位
% a- u. k# |: c, B+ e) a. [
漆工 4个单位 2个单位 1.5个单位 20个单位
- b' ~3 J8 i+ V4 h: k. o
木工 2个单位 1.5个单位 0.5个单位 8个单位
5 @. M4 U) h8 ~) q8 G$ ~+ w
成品单价 60个单位 30个单位 20个单位
" K4 V) Y" {9 r) |+ d3 \
若要求桌子的生产量不超过5件,如何安排三种产品的生产可使利润最大?
3 E* c' e9 Z1 [! D/ Y, I0 P
g* B; x7 S0 [: y2 Q! o
解:代码
# G( H- O+ A+ C7 ?9 G8 Z2 {0 V$ u
; A) @6 Y1 o% {, R
max = 60 * desks + 30 * tables + 20 * chairs;
8 O0 I& X+ k& i7 O
8 * desks + 6 * tables + chairs <= 48;
/ Z- U) R7 x: A8 L. B3 g/ X7 ^- z
4 * desks + 2 * tables + 1.5 * chairs <= 20;
5 P' h8 h) d) g# n7 w
2 * desks + 1.5 * tables + .5 * chairs <= 8;
# P3 f( Q d, ?& i! Q2 e
tables <= 5;
1 @ p6 m# W5 G0 j
1
2 h9 }$ z1 C* D' d8 I& ?9 r
2
; n/ G" P# t7 S; l* p. f0 g- K- h
3
3 Y4 I: f7 o4 w, J, T
4
5 e. o; B' T" S" U
5
- F' ^& ^; B6 i# f
可以得到结果:
* a0 P( \* o4 v4 o0 o
+ Y% n3 q6 E1 y$ S% h' L$ O
这里的 Total solver iteration 表示一共迭代2次得到最优解。
% R3 F' h* ?3 X2 G$ x7 f" K9 x/ { y
Objective value 表示最优值为280,而取280的时候各个变量取多少呢,底下的表格给出了答案。
9 o" E1 d4 M4 z6 Y z" `; s/ z
可以看到,没有定义变量,简简单单一个函数一个约束条件,迅速计算出了答案。Lingo看上去就像是为了非编程人员量身定制的一样。
) f' C q& A: \/ l5 g
1 L* {3 |4 V& j
例2:给定一个直角三角形,求包含该三角形的最小正方形。
7 W$ a) K( q9 R5 B! ?1 s
8 Y& [7 j5 T. H
我们可以作出如下正方形:
2 Z) B* u2 ~) C1 x& I# h
7 M7 w& E; [" k4 c% N# m
; G* I: c) N6 ]2 d5 V
CE=asinx,AD=bcosx,DE=acosx+bsinxCE=asinx,AD=bcosx,DE=acosx+bsinx
+ y* Q. l" E' P2 G) q0 ]0 f
转化为了规划问题那么正方形面积最小的时候即为最优解。
1 l# w: q4 W& T+ A+ x9 {6 S3 r
代码:
5 M0 D% @ C% F6 A# E" s3 L6 g
9 S# G' P; O( y* X* Z3 [9 `8 g
model:
6 F. z" O0 y1 \ t
sets:
7 _! V- N- l, L* s3 Z l, X
object/1..3/:f;
Y- A1 y& L+ @/ b' E
endsets
! d% E Z( ~. Z+ s- N4 X* X
data:
+ R5 l" B7 ~( s) k ^( b# u/ x; ~
a, b = 3, 4;
m- @$ v6 M7 l+ |; Y
enddata
8 P/ C1 E1 D% Z: z) I/ }' a1 p5 a
f(1) = a * @sin(x);
+ R& c9 I0 _+ s/ ]8 t
f(2) = b * @cos(x);
! T. `9 ?! C5 Z$ m) N; d' ?8 Y
f(3) = a * @cos(x) + b * @sin(x);
z: n% H% W7 Q* Z( d4 w. ^
min = @smax(f(1), f(2), f(3));
1 r/ t. {: G$ Z, D4 V0 C
@bnd(0, x, 1.57);
; U& V% ^3 P) R! P8 T
end
$ p7 x$ D( G2 H& N
1
# q6 s. [) D' s' L1 x* G; k" \
2
% x; x% v8 t( a0 V0 u
3
* C2 M4 P! p0 [' X0 p9 I" ~0 Y; M
4
' I5 V. h, x5 i" K. L$ ]
5
4 d D5 F$ F( ? T9 L
6
3 F/ \7 Q# ] s/ H, G/ b8 O
7
/ U4 O5 E1 F! S8 m5 D% p: E0 X$ e
8
3 x% p) o2 H' m5 L
9
3 A( ?, y0 d9 U
10
3 v$ ^& U7 K) o/ U* O3 a
11
6 _7 Q# f7 \7 q f
12
9 T5 i# n. n% x" E; A: V3 s
13
0 R! x1 _. v5 E) e) A) z. F
得到结果:
, ^. X1 _* _& {" ~( o
/ K0 R4 A4 v$ z8 O' }* L% _5 ~
" f* p) L7 A3 x
这里需要注意,lingo中如果没有代码说明,是默认 xx 的值大于0的。代码中用 bndbnd 函数限制了 xx 的范围。
9 G9 C1 p2 `. q Q" ^: t
那么再进阶一下,Lingo在处理TSP问题的时候表现如何呢?
( W" @& q) P5 y# W A ^1 a
( F& T" ? I1 a: D: i
例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 的一个圈置换 ππ 就表示对所有零件的一个加工顺序,在此置换下,完成所有加工所需要的总时间为
0 g& c: `7 C! S P! f* s
∑i=0n(ciπ(i)+piπ(i))=∑i=0nciπ(i)+∑j=0npj
- |) e+ n" f9 d8 q9 q6 }/ Z! ^( X& g
∑i=0n(ciπ(i)+piπ(i))=∑i=0nciπ(i)+∑j=0npj
' ~8 U4 O0 K$ w# e C3 S b8 {
由于 ∑nj=0pj∑j=0npj 是一个常数,故该零件的加工顺序问题变成TSP。
9 B) D2 ~7 B) ~6 B
9 {9 a6 n' ^* Q. N- d i/ r
代码:
. k$ @- A+ L. G
1 G t' s/ A0 w- |
!旅行商问题;
$ V& t: S N2 W, N
model:
& Q0 t/ z8 F5 i) n/ j0 {. c; t+ l
sets:
/ ~1 i. d6 L/ m* F6 M: w
city / 1.. 5/: u;
3 x) C H' H P) i5 S; {
link(city, city):
5 x" E; }) n4 i l I5 H/ K
dist, x; !距离矩阵;
" J3 t& T9 f7 \. z1 g
endsets
+ x' T1 R/ |4 f Q, T0 y
n = @size(city);
, [# `- W* Q* i) m: L* ]
data: !距离矩阵,它并不需要是对称的;
8 R$ h: B8 U, Z
dist = @qrand(1); !随机产生,这里可改为你要解决的问题的数据;
' e8 o, r# t w6 G9 z; E
enddata
: P: v+ t" c+ i! a/ D$ n4 ~1 A4 o
min = @sum(link:dist * x);
/ @. Z( v3 x6 M; T }$ }- s
@FOR(city(K):
% h9 f6 {) _0 k/ X
@sum(city(I)|I #ne# K: x(I, K)) = 1;
% O2 @3 Z% ^0 [& f5 l. j
!进入城市K;
# d# l2 H$ I7 i, g J5 i
@sum(city(J)|J #ne# K: x(K, J)) = 1;
- q7 B$ X/ U1 Q/ Z D: ]2 L
);
% R0 d% U2 i/ H Q s, _- i7 a
@for(city(I)|I #gt# 1:
+ t. h, b' t2 U: A
@for(city( J)| J#gt#1 #and# I #ne# J:
8 Q- s s* r4 z. K
u(I) - u(J) + n * x(I,J) <= n - 1);
! H9 F/ M% |! c& U% L* ]( `
);
( Z7 d5 h$ @: u0 ?& r
@for(city(I)|I #gt# 1: u(I) <= n - 2);
; d' i! N' |! C
@for(link: @bin(x));
/ H& F d/ ] P. v! D
end
# K9 g/ A" f+ u* b' w% p/ e, i: Y$ d
1
# Z( O. I5 ?$ X: l5 Q! v
2
) `0 K/ y5 T+ I+ W
3
9 s+ Y) h2 z+ u( T( S
4
' B E/ v7 F& L% s
5
" `9 j( u5 F8 u5 s8 y) @* |
6
8 D. o5 F# v, @2 i: }
7
5 R- e, p' V- ~
8
9 ^2 w: B: [# P3 @' r7 L# O3 w2 @% q7 N
9
! r0 `- S( W0 y. `& X
10
) D W* O) R1 ^
11
8 {" _8 ?* b8 o
12
& D1 D6 @- [2 q5 Q
13
5 c/ ~1 _+ I3 b$ @7 F
14
+ {" E5 z/ Z$ S, a6 a5 l
15
* C" m& e4 N: M
16
$ E) b( b6 R8 e! ?2 W3 F$ {# m& R0 q
17
% t* |* r( f" M7 M* p* \
18
: U* X$ O9 p, v, U
19
, X# a6 P. b2 C& T1 B
20
4 B5 ]9 i" X( U/ b6 v) Q
21
' X/ c% w6 G2 t2 ]6 m: C
22
3 _& F) v8 c+ a: b- \2 E
23
) j; h7 O! e* T3 w! o8 }9 B3 F' a' h
24
7 w5 B q* T$ n
可以得到结果:
$ Q" O) Y3 }+ Z1 ]) h8 Q
4 b$ Y2 L1 E9 J2 g( j7 W7 I/ y
---------------------
' X5 h4 D; P0 p3 r
u1 Y: t5 B, M# X! v4 R' s
. B3 I5 v8 G' U, _- \
& l, o/ m( `$ I
; ~. L# j7 w, W7 g6 b& Y
: H' x; {! S; A/ C% x3 b: }
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5