(一)在Lingo中使用集合
1. 在Lingo中使用集合
4.1 集合的基本用法和lingo模型的基本要素
Lingo虽然使用方便,但是如果要解决几万个,几十万个变量的优化问题时,我们总不能一个一个地列出x1,x2,…,x1000来解决,而这样的问题在实际企业的应用中也是经常遇到的。好在Lingo中设计了集合语言来表示大规模变量的输入,只需一行文字就可以建立起含有大规模变量的目标函数和成千上万条约束。而Lingo的早期版本软件Lindo却不包含这样的功能。
现通过下例来对Lingo的集合、属性概念进行介绍。
例2 SAILCO公司需要决定决定下四个季度的帆船生产量。下四个季度的帆船需求量分别为40条,60条,75条,25条,这些需求必须按时满足。每个季度正常的生产能力是40条帆船,每条帆船的生产费用为400美元。如果加班生产,每条船的生产费用为450美元。每个季度末,每条船的库存费用为20美元。假定生产提前期为0,初始库存为10条船。如何安排生产可使总费用最小?
分析与解:用DEM、RP、OP、INV分别表示需求量,正常生产的产量,加班生产的产量,库存量。则DEM、RP、OP、INV对每个季度都应有一个对应的值,也就是说他们都应该是一个由4个元素组成的数组,其中DEM已知,而RP,OP,INV未知。现在我们可以写出该问题的模型:
此外还有各变量非负的约束。
记4个季度组成的集合,他们就是DEM、RP、OP、INV等变量的下标集合,对于,都有值与之对应。LINGO正是充分利用这种数组及其下标的关系,引入了“集合”与“属性”的概念。本例中我们把称之为集合,DEM、RP、OP、INV称为集合具有的属性(即定义在该集合上的属性)。下图表示了这种集合与属性的关系。
|
集合QUARTERS的元素 |
1 |
2 |
3 |
4 |
|
|
定义在集合QUARTERS上的属性 |
DEM |
DEM(1) |
DEM(2) |
DEM(3) |
DEM(4) |
|
RP |
RP(1) |
RP(2) |
RP(3) |
RP(4) |
|
|
OP |
OP(1) |
OP(2) |
OP(3) |
OP(4) |
|
|
INV |
INV(1) |
INV(2) |
INV(3) |
INV(4) |
|
下面我们看看Lingo中具体如何定义集合及其属性。下面是例2的Lingo代码:
Model: Sets: QUARTERS/,,,/:DEM,RP,OP,INV; Endsets Min=@sum(QUARTERS:*RP+*OP+*INV); @for(QUARTERS(I):RP(I)<=;); @for(QUARTERS(I)|I#GT#: INV(I)=INV(I-)+RP(I)+OP(I)-DEM(I);); INV()=+RP()+OP()-DEM(); DATA: DEM=,,,; Enddata End
我们总结一下上面代码的特点:
(1)、模型以“MODEL:”开始,以“END”结束。它们之间由语句组成,可以分成三步分。
(2)、集合定义部分以“SETS:”开始,以“ENDSETS”结束。中间定义了集合和相应属性。语句“QUARTERS/1,2,3,4/:DEM,RP,OP,INV;”定义了集合QUARTERS,以及该集合的属性DEM、RP、OP、INV,其结果正是上表里面的16个变量名。可以定义空集合,比如“Empty set/1,2,3,4/;”空集合的用法将在派生集中讲述。
(3)、数据输入部分以“DATA:”开始,以“ENDDATA”结束,语句“DEM=40,60,75,25;”给出了常量DEM的值,即DEM(1)=40,DEM(2)=60,DEM(3)=75,DEM(4)=25. 语句“DEM=40,60,75,25;”也可以写成语句“DEM=40 60 75 25;”即数据之间可以用逗号或空格分开。
(4)、其他部分,给出了目标函数和约束。其中目标函数(“min=”后面所接的表达式)是用求和函数
“@sum=(集合(下标):关于集合的属性的表达式)”
的方式定义的,这个函数的功能是对语句冒号“:”后面的表达式,按照“:”前面的集合指定的下标元素进行求和。本例中目标函数也可以写成
“Min=@sum(QUARTERS(i):400*RP(i)+450*OP(i)+20*INV(i))”
这里“@sum”相当于求和符号,而“QUARTERS(i)”相当于“”,而由于本例中已默认对所有的QUARTERS的元素求和,所以实例中可以将下标i省略。
约束是用循环函数“@for(集合(下标):关于集合的属性的约束关系式)”的方式定义的,意思是对于“:”前面的集合的每个元素(下标),冒号“:”后面的约束关系式都要成立。但对于这个约束,实际上I=1时要用到变量,但我们定义属性变量的时候是从I=1开始的,即是一个常数,为了区别I=1和I=2,3,4,我们要将I=1的约束单独列出来,而对I=2,3,4的约束我们对集合下标做了的约束,即用了“#GT#1”(这个限制条件与集合之间有一个竖线“|”分开,称为过滤条件),“I#GT#1”就表示,“#GT#”是lingo中的逻辑表达式。
小结一下lingo模型最基本的组成要素:
(1)
集合段:以“SETS:”开始,以“ENDSETS”结束。作用在于定义必要的集合和属性。注意一个细节,我们可以定义QUARTERS/1,2,3,4/,若QUARTERS有1000个元素,我们也不必将其一一列出,而可以简写为QUARTERS/1..1000/.
(2)
目标和约束段:这部分不像其他部分,没有段的开始和结束的标记。因此是除去其他段以外的所有语句。
(3)
数据段:以“DATA:”开始,以“ENDDATA”结束,作用在于对集合的属性输入必要的常数数据,格式为: 属性=常数列表;常数列表中的常数或以逗号“,”分开,或以空格分开“ ”.
(4)
初始段:以“INIT:”开始,以“ENDINIT”结束。作用在于对集合的属性定义初值。因为求解算法是迭代算法,所以一个好的初值可以让程序更快解决。定义初值的格式为:
属性=常数列表;
(5)
计算段:以“CALC:”开始,以“ENDCALC”结束,作用在于对一些原始数据进行计算处理,这种处理是在输入数据后,求解模型前进行的。例如,对上面的例子,如果我们希望可以得到全年的总需求和季度平均需求,可以增加这个段:
CALC:
T_DEM=@sum(QUARTERS:DEM);!总需求;
A_DEM=T_DEM/@size(QUARTERS);!平均需求;
ENDCALC
要注意的是计算段中语句是按顺序执行的,故上面的两个语句不能调换。
(一)在Lingo中使用集合的更多相关文章
- Java 中的集合接口——List、Set、Map
Java 中的集合接口——List.Set.Map 什么叫集合:集合就是Java API所提供的一系列类的实例,可以用于动态存放多个对象.这跟我们学过的数组差不多,那为什么我们还要学集合,我们看看数组 ...
- C#中的集合有几种?
C#中的集合有几种? Array ArrayList List<T> Stack<T> Queue<T> Dictionary<K,V> HashTab ...
- Java中的集合框架
概念与作用 集合概念 现实生活中:很多事物凑在一起 数学中的集合:具有共同属性的事物的总体 java中的集合类:是一种工具类,就像是容器,储存任意数量的具有共同属性的对象 在编程时,常常需要集中存放多 ...
- 实现java 中 list集合中有几十万条数据,每100条为一组取出
解决"java 中 list集合中有几十万条数据,每100条为一组取出来如何实现,求代码!!!"的问题. 具体解决方案如下: /** * 实现java 中 list集合中有几十万条 ...
- 线程高级应用-心得8-java5线程并发库中同步集合Collections工具类的应用及案例分析
1. HashSet与HashMap的联系与区别? 区别:前者是单列后者是双列,就是hashmap有键有值,hashset只有键: 联系:HashSet的底层就是HashMap,可以参考HashSe ...
- 14.python中的集合
什么是集合?正如其字面的意思,一堆东西集中合并到一起.乍一听貌似和容器没什么差别,嗯,好吧,集合也算是一种容器. 在学习这个容器有什么不同之前,先看看集合是如何创建的: a = set() #可变集合 ...
- java中对集合对象list的几种循环访问
java中对集合对象list的几种循环访问的总结如下 1 经典的for循环 public static void main(String[] args) { List<String> li ...
- C#中的集合
[集合不同于数组,是一组可变类型的.可变数量的元素的组合,这些元素可能共享某些特征,需要以某种操作方式一起进行操作.一般来讲,为了便于操作这些元素的类型是相同的] [集合与数组的区别:数组是连续的.同 ...
- 菜鸟日记之 java中的集合框架
java中的集合框架图 如图所示:java中的集合分为两种Collection和Map两种接口 可分为Collection是单列集合和Map的双列集合 Collection单列集合:继承了Iterat ...
随机推荐
- 图论 Kruskal算法 并查集
#include<iostream> #include<cstring> #include<string> #include<cstdio> #incl ...
- SGU 223 little kings BSOJ2772 状压DP
1896 [SCOI2005]互不侵犯King [问题描述]在n*n(1<=n<=10)的棋盘上放k(0<=k<=n*n)个国王(可攻击相邻的8 个格子),求使它们无法互相攻击 ...
- 利用css制作带边框的小三角
标签(空格分隔):css 在项目中会使用到的小实例,目前知道的有两种方法来实现 设置元素的宽和高,利用rotate实现,比较简单的一种 div{ width: 10px; height: 10px; ...
- 增加kms计数
@echo offset skms=10.15.68.62for %%i in (. . . . . . . . . . . . . . . . . . . . . . . . . .) do cal ...
- ACM数论之旅2---快速幂,快速求a^b((ノ`Д´)ノ做人就要坚持不懈)
a的b次方怎么求 pow(a, b)是数学头文件math.h里面有的函数 可是它返回值是double类型,数据有精度误差 那就自己写for循环咯 LL pow(LL a, LL b){//a的b次方 ...
- SQL中MAX()和MIN()函数的使用(比较字符串的大小)
在SQL数据库中,最大/最小值函数—MAX()/MIN()是经常要用到的,下面就将为您分别介绍MAX()函数和MIN()函数的使用,供您参考,希望对您学习SQL数据库能有些帮助. 当需要了解一列中的最 ...
- LInux查看网速带宽及各进程占用情况:nethogs
安装: #Ubuntu: sudo apt-get install nethogs #CentOS: sudo yum install nethogs 使用: $ sudo nethogs
- BZOJ5089 最大连续子段和(分块)
假设所有操作都是对整个序列的.考虑每个子区间,区间和与其被加的值构成一次函数关系.最大子段和相当于多个子区间取最大值,答案显然就在这些一次函数构成的下凸壳上.如果预处理出凸壳,只要在凸壳上暴力跳就可以 ...
- 一文看尽HashMap
前言 日常开发中,经常会使用到JDK自带的集合类:List.Set.Map三者的实现,ArrayList.LinkedList.HashSet.TreeSet.HashMap.TreeMap等.其中L ...
- BZOJ2159 Crash 的文明世界 【第二类斯特林数 + 树形dp】
题目链接 BZOJ2159 题解 显然不能直接做点分之类的,观察式子中存在式子\(n^k\) 可以考虑到 \[n^k = \sum\limits_{i = 0} \begin{Bmatrix} k \ ...