如何理解Lingo语法-以用Lingo求解运输问题为例

百度经验

页面数据加载中...

会了么

一. 运输模型

设有m个产地A1,…,Am其产量(供应量)分别为Si;n个销地B1,…,Bn,其销量(需求量)分别为Dj;从产地A;运往销地B;的运费为Cij.假设产销平衡,问如何安排运输方案能使总运费最小?

这就是经典的运输问题,设从A;运往B,的运量为xj(决策变量),则建立产销平衡的运输模型,其中,约束条件 (1) 表示从i地运出量等于i地的供应量;约束条件 (2) 表示运往j地的运量等于j地的需求量。

若约束 (1) 若改为 <= , 约束 (2) 仍为 = ,则为产大于销的运输模型;

若约束 (2) 若改为 <= , 约束 (1) 仍为=,则为销大于产的运输模型。

1/2

用Lingo求解举例建模

用Lingo求解,只需要将上述模型按照Lingo语法表示出来,而不用操心任何求解细节。

例1某公司从三个产地A1,A2,A3,A4将产品运往四个销地B1,B2,B3,B4各产地的产量,各销地的销量,及各产地往各销地的运费单价如表所示。应如何调运可使运费最小?

1/2

本页面非法爬取自百度经验

本页面非法爬取自百度经验
本页面非法爬取自百度经验

2/2

建立运输模型(产销平衡),如下图所示:

1/2

Lingo操作步骤

Lingo版本为:Lingo 17 X64 商业版,代码如下图所示

Lingo代码如下:

sets:

supplys/1..3/: S;

demands/1..4/: D;

links(supplys, demands): c, x;

endsets

data:

S = 7,4,9;

D = 3,6,5,6;

c = 3  11  3  10

    1  9  2  8

    7  4  10  5;

enddata

min = @sum(links(i,j): c(i,j) * x(i,j));

@for(supplys(i): @sum(demands(j): x(i,j)) = S(i));

@for(demands(j): @sum(supplys(i): x(i,j)) = D(j));

2/2

运行结果(部分)如下图所示,结果解释:最优运费是85,运输方案是:S1往D3、D4分别运送5和2;S2往D1、D4分别运送3和1;S3往D2、D4分别运送6和3.

1/4

Lingo语法说明

1. Lingo代码段Lingo代码分为若干片段,比如上面代码包含了:集合段:sets: ...... endsets ——用来声明和定义数组变量;数据段:data: ...... enddata ——用数据对变量赋值;目标与约束段: 即具体模型表述部分(不需起止标志)。注:另外还可以有初始段和计算段。例 1 中涉及到两个一维数据:供应 [公式] 、需求 [公式] ; 以及一个二维数据 [公式] . 所以要存储和使用它们,必须要用到集合段和数据段,当然还必须有模型段。 
1. Lingo代码段Lingo代码分为若干片段,比如上面代码包含了:集合段:sets: ...... endsets ——用来声明和定义数组变量;数据段:data: ...... enddata ——用数据对变量赋值;目标与约束段: 即具体模型表述部分(不需起止标志)。注:另外还可以有初始段和计算段。例 1 中涉及到两个一维数据:供应 [公式] 、需求 [公式] ; 以及一个二维数据 [公式] . 所以要存储和使用它们,必须要用到集合段和数据段,当然还必须有模型段。 

2/4

2. 集合段部分(1) 集合段第一句:supplys /1 .. 3/: S;声明一个长度为 3 的一维数组 supplys, 并用它定义一个这样的一维数组变量 S.先是数组名(随便起),再是用两个 / 夹在中间的是数组的下标范围,中间 .. 是省略表示法,接着用 : 定义数组变量 S。(2) 同理,第二句 demands/1..4/: D; 声明一个长度为 4 的一维数组 demands,并定义一个这样的一维数组变量 D。(3) 第三句 links(supplys, demands): c, x; 声明一个 [公式] 的二维数组 links,并用它定义两个这样的二维数组变量 c, x.把两个一维数组放一起,起个名字
2. 集合段部分(1) 集合段第一句:supplys /1 .. 3/: S;声明一个长度为 3 的一维数组 supplys, 并用它定义一个这样的一维数组变量 S.先是数组名(随便起),再是用两个 / 夹在中间的是数组的下标范围,中间 .. 是省略表示法,接着用 : 定义数组变量 S。(2) 同理,第二句 demands/1..4/: D; 声明一个长度为 4 的一维数组 demands,并定义一个这样的一维数组变量 D。(3) 第三句 links(supplys, demands): c, x; 声明一个 [公式] 的二维数组 links,并用它定义两个这样的二维数组变量 c, x.把两个一维数组放一起,起个名字叫 links,得到二维数组 links,第1个一维数组的维数就是二维数组的行数维度,第2个一维数组的维数就是二维数组的列数维度。 注意:这里 links 不是Lingo关键字,可以随便起名。
叫 links,得到二维数组 links,第1个一维数组的维数就是二维数组的行数维度,第2个一维数组的维数就是二维数组的列数维度。 注意:这里 links 不是Lingo关键字,可以随便起名。

3/4

3. 数据段部分前面定义好的数组变量 [公式] ,就是为了存放已知数据的,把已知数据赋值给它们,以便目标与约束段使用。数据中间用 逗号/空格 隔开都可以,二维数据写成一行也行,这样写比较易读而已。 
3. 数据段部分前面定义好的数组变量 [公式] ,就是为了存放已知数据的,把已知数据赋值给它们,以便目标与约束段使用。数据中间用 逗号/空格 隔开都可以,二维数据写成一行也行,这样写比较易读而已。 

4/4

4. 目标与约束段部分

为什么不叫模型段呢,是因为Lingo一般是把全部代码放在 model: ....... end 中间(就解决一个问题,省略也行),整个叫做模型段。该部分就是把模型公式“原样”表述出来,咱们对照着来看:

如何理解Lingo语法-以用Lingo求解运输问题为例

如何理解Lingo语法-以用Lingo求解运输问题为例

[重新阅读]
辅助模式