lingo变量无限制版本_【运筹学】用Lingo求解运输问题,兼谈Lingo语法
一. 運輸模型
設有
個產地 其產量(供應量)分別為 ; 個銷地 , 其銷量(需求量)分別為 ;從產地 運往銷地 的運費為 . 假設產銷平衡,問如何安排運輸方案能使總運費最小?這就是經典的運輸問題,設從
運往 的運量為 (決策變量),則建立產銷平衡的運輸模型:其中,約束條件 (1) 表示從
地運出量等于地的供應量;約束條件 (2) 表示運往地的運量等于地的需求量。若約束 (1) 若改為
, 約束 (2) 仍為 ,則為產大于銷的運輸模型;若約束 (2) 若改為
, 約束 (1) 仍為 ,則為銷大于產的運輸模型。二. Lingo求解
用Lingo求解,只需要將上述模型按照Lingo語法表示出來,而不用操心任何求解細節。
例 1
建立運輸模型(產銷平衡):
其中,運價
供應
,需求 .Lingo代碼:
sets運行結果(部分):
結果解釋:最優運費是85,運輸方案是:S1往D3、D4分別運送5和2;S2往D1、D4分別運送3和1;S3往D2、D4分別運送6和3.
三. 程序說明
授人予魚不如授人與漁,所以再講解一下上面代碼涉及到的Lingo語法。
1. Lingo代碼段
Lingo代碼分為若干片段,比如上面代碼包含了:
集合段:sets: ...... endsets ——用來聲明和定義數組變量;
數據段:data: ...... enddata ——用數據對變量賦值;
目標與約束段: 即具體模型表述部分(不需起止標志)。
注:另外還可以有初始段和計算段(暫且不談)。
例 1 涉及到兩個一維數據:供應
、需求 ; 以及一個二維數據 . 所以要存儲和使用它們,必須要用到集合段和數據段,當然還必須有模型段。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關鍵字,可以隨便起名。
3. 數據段部分
前面定義好的數組變量
,就是為了存放已知數據的,把已知數據賦值給它們,以便目標與約束段使用。數據中間用 逗號/空格 隔開都可以,二維數據寫成一行也行,我這樣寫比較易讀而已。
4. 目標與約束段部分
為什么不叫模型段呢,是因為Lingo一般是把全部代碼放在 model: ....... end 中間(就解決一個問題,省略也行),整個叫做模型段。
該部分就是把模型公式“原樣”表述出來,咱們對照著來看:
min目標函數是求最小,所以用 “min=”
有
,所以需要用到 @sum() 函數, 這是Lingo里的求和函數,首先得告訴它求和的范圍, 從1到3, 從1到4,這不正好是前面聲明的(對應的)二維數組 links 的大小嗎,所以就用 links(i, j)來告訴(也只能用聲明的數組來告訴),并用 表示行索引, 表列索引。然后,冒號,求和里面的表達式。
@for注意到隨著
變化,這實際上是 3 個式子。要表示這種多個重復式子,就用到Lingo里的 @for() 函數,首先得告訴它有多少重復的式子,同樣只能用聲明的(對應的)數組來告訴,這里是 supplys(i), 并用 表示重復的索引。關于這種“對應”,有信息提示,比如維數得相同,比如
是從1到3,表示的供應(產地)的下標。處理完式子的重復,就剩下表示每次的式子了,有
按前面講到的 @sum() 函數規則來寫就行了。@for注:上例是產銷平衡運輸問題,若不是產銷平衡,把模型表示部分的代碼對應位置的“=”換成“<" 即可(Lingo中 ”<“就是“<=”)。
————————————————————
原創作品,轉載請注明,禁止出版盜用。
總結
以上是生活随笔為你收集整理的lingo变量无限制版本_【运筹学】用Lingo求解运输问题,兼谈Lingo语法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 事务里面捕获异常_三问Spring事务:
- 下一篇: c语言如何判断数据是否符合正态分布_如何