Lingo使用筆記
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));