Lingo是用于求解线性规划、非线性规划、整数规划的专门软件。使用Lingo建模语言描述问题后,软件能自动化为标准形式,并根据问题选择相应的求解器。
Lingo代码每行以分号结尾。变量和关键字不区分大小写。除Calc段和Init段外,代码各行的顺序随意。
Lingo中变量不需要定义直接使用。默认变量类型为非负实数。使用
@FREE(x) !移除非负约束
@GIN(x) !添加整数约束
@BND(lower_bound, x, upper_bound) !上下界约束
@SEMIC( lower_bound, variable, upper_bound) !上下界或零
Lingo中没有”数组”的概念,对应最接近的概念是”Set集合”。
Set是Lingo中的核心概念之一,是描述具有轮转和对称性约束的主要手段。
在Lingo中使用sets: …… endsets
关键字定义集合段。
定义一维集合
setname [/ member_list /] [: attribute_list];
WAREHOUSES /1..6/: location,price;
定义集合时也可以不指定大小,lingo会根据初始值的维度自动决定
定义二维集合
setname(parent_set_list) [ / member_list /] [: attribute_list];
SETS:
PRODUCT / A B/;
MACHINE / M N/;
WEEK / 1..2/;
ALLOWED(PRODUCT, MACHINE, WEEK);
ENDSETS
ALLOWED集合是PRODUCT和MACHINE集合的笛卡尔积。
若只需要生成部分集合,可手工指定成员列表
ALLOWED(PRODUCT, MACHINE, WEEK) / A M 1, A N 2, B N 1/;
还可在定义集合时使用条件判断
HEAVY_DUTY(TRUCKS) | CAPACITY(&1) #GT# 50000:;
其中&1
是集合的索引符。
使用data: …… enddata
关键字定义数据段,数据段中向集合元素赋值
SETS:
SET1: X, Y;
ENDSETS
DATA:
SET1 = A B C;
X = 1 2 3;
Y = 4 5 6;
ENDDATA
或者
SETS:
SET1: X, Y;
ENDSETS
DATA:
SET1 X Y = A 1 4
B 2 5
C 3 6;
ENDDATA
也就是说,Lingo中按照列读入数据。
使用@FOR @SUM @MIN @MAX @PROD批量设定约束,例如
@FOR(NUMBERS(I):
RECIPROCAL(I) = 1 / VALUE(I)
DEMAND_L3 = @SUM(VENDORS(J) | J #LE# 3: DEMAND(J));
MIN_DEMAND = @MIN(VENDORS(J): DEMAND(J));
综合运用
MIN = @SUM(DAYS(I): START(I));
@FOR( DAYS(J):
@SUM( DAYS(I) | I #LE# 5:
START(@WRAP(J - I + 1, 7)))>= REQUIRED(J));
上面这个约束对应“雇员调度问题”。雇员每周工作5天休息2天,商店各日需要的人数不同。故任意一天所需要的人数 REQUIRED(J)
应小于等于过去5天开始工作的雇员总人数 @SUM(DAYS(I) | I #LE# 5: START(@WRAP(J-I+1,7)))
@FOR( NUTS(I):
@SUM( BRANDS(J):
OUNCES(I, J) * PRODUCE(J) / 16) <= SUPPLY(I));
上面这个约束对应生产J种商品所用的I种原料均不超过供应
PAIRS(ANALYSTS, ANALYSTS) | &2 #GT# &1:
RATING, MATCH;
DATA:
RATING =
9 3 4 2 1 5 6
1 7 3 5 2 1
4 4 2 9 2
1 5 5 2
8 7 6
2 3
4;
ENDDATA
MIN = @SUM(PAIRS(I,J):
RATING(I,J) * MATCH(I,J));
@FOR(ANALYSTS(I):
@SUM(PAIRS(J,K) | J #EQ# I #OR# K #EQ# I:
MATCH(J,K)) = 1);
@FOR(PAIRS(I,J): @BIN(MATCH(I,J)));
配对问题。在建立集合PAIRS的时候使用布尔条件,只建立上三角阵。第一个FOR设定一对一配对约束;第二个FOR设定0-1整数变量。
常用条件运算符
#EQ# equal
#NE# not equal
#GE# greater-than-or-equal-to
#LE# less-than-or-equal-to
#GT# greater than
#LT# less than
约束可以命名,以在方便在结果报告和错误报告中指代。使用符号[]
放在约束的开头。
[OBJECTIVE] MIN = X;
@FOR( LINKS( I, J): [DEMAND_ROW]
@SUM( SOURCES( I): SHIP( I, J)) >=
DEMAND( J));