OPL建模語言從入門到放棄(二)
OPL是ILOG團隊為運籌學研究者定製的一種優化建模語言,語法相對簡單,接近運籌學研究者習慣的數學表達。
導航地址
OPL建模語言從入門到放棄(一) 基本組成
OPL建模語言從入門到放棄(二) 數據結構
OPL建模語言從入門到放棄(三) 數據源
OPL建模語言從入門到放棄(四) 決策變數
OPL建模語言從入門到放棄(五) 表達式
OPL建模語言從入門到放棄(六) 約束條件
OPL建模語言從入門到放棄(七) 參數
OPL建模語言從入門到放棄(八) 預處理語句
下文描述了OPL的基本數據類型和複合數據類型。
基本數據類型
整數
int n = 3; int size = n*n;
浮點數
float f = 3.2;
字元串
{string} Tasks = {"masonry","carpentry","plumbing","ceiling", "roofing","painting","windows","facade", "garden","moving"};
分段函數
分段函數,就是對自變數的不同取值範圍,有著不同的對應法則的函數。
分段函數由一個元組定義:
F = piecewise(S, T, t0, v0)
其中字母代表如下含義:
- S 表示第 n - 1 個分界點和第 n 個分界點之間的斜率
- T 表示第 n 個分界點和第 n + 1個分界點之間的斜率
- t0 和 v0 表示分段函數分界點的橫縱坐標
例如,下面的代碼數分別代表了左圖和右圖的分段函數:
// 負無窮到10:斜率為 -1 ; 10到正無窮:斜率為 s ; 分界點為 (10, 0)pwlFunction F1 = piecewise{ -1->10; s } (10, 0);pwlFunction F[i in 1..n] = piecewise{ -U[i]->T[i]; V[i] } (T[i],0);
逐步函數
逐步函數是分段函數的特殊情況。
當一個分段函數所有區間內斜率都為0時,這個函數就是逐步函數。
逐步函數由一個元組定義:
F = stepwise(V, T)
其中字母代表如下含義:
- S 表示第 n - 1 個分界點和第 n 個分界點之間的函數值
- T 表示第 n 個分界點和第 n + 1個分界點之間的函數值
其中,所有區間都是左閉右開的。
例如,下面的代碼數分別代表了左圖和右圖的分段函數:
// [-∞, 0) 函數值為0 ; [0, 20) 函數值為100 ...stepFunction F2 = stepwise{ 0->0; 100->20; 60->30; 100 };stepFunction F3 = stepwise(i in 0..51, p in 0..1) { 100*p -> (7*i)+(5*p) ; 0 };
複合數據類型
範圍
範圍定義
range Rows = 1..10; // 最小值...最大值range float X = 1.0..10.0; // 浮點數範圍
範圍可以用來聲明數組
range R = 1..100;int A[R]; // A是一個長度為100的整數數組
範圍可以用來迭代
range R = 1..100;forall(i in R) { ...}
範圍可以用來聲明決策變數定義域
dvar int i in R;
元組
元組定義
tuple Point { int x; int y; };
元祖可以用來聲明元祖對象
Point p = <2,3>;// 獲取對象屬性int x = p.x;
元組可以用來聲明元祖數組
Point point[i in 1..3] = <i, i+1>;
元祖可以用來聲明元祖集合
{Point} points = {<1,2>, <2,3>};
元祖中可以聲明鍵
tuple nurse { key string name; int seniority; int qualification; int payRate;}
具有鍵的元祖數組可以直接使用鍵索引
NurseWorkTime[<"Isabelle">]// 等效於 <name, seniority, qualification, payRate>NurseWorkTime[<"Isabelle",3,1,16>]
鍵可以有多個,但不能重複
tuple shift { key string departmentName; key string day; key int startTime; key int endTime; int minRequirement; int maxRequirement; }
集合
集合聲明
{int} setInt = ...; setof(Precedence) precedences = ...; tuple Precedence { int before; int after; }{Precedence} precedences = {<1,2>, <1,3>, <3,4>};
集合的默認方法
precedence elt = <2,3>;// union, inter, diff, symdiffset1 union set2// first, lastfirst(set1)// next, prev, nextc, prevcnext(set1, elt, 1)// itemitem(set1, 1)// orditem(set1, elt)
集合的默認順序為添加順序
// 默認為 ordered,以下兩者等效{int} S1 = {3,2,5};ordered {int} S1 = {3,2,5};
集合可以聲明為升序排列
// 以下兩者等效sorted {int} sortedS = {3,2,5};ordered {int} orderedS = {2,3,5};
集合可以聲明為降序排列
// 以下兩者等效reversed {int} sortedS = {3,2,5};ordered {int} orderedS = {5,3,2};
數組
數組通過範圍定義
int a[1..4] = [10, 20, 30, 40]; float f[1..4] = [1.2, 2.3, 3.4, 4.5];string d[1..2] = [「Monday」, 「Wednesday」];
數組通過元組定義
tuple Edges { int orig; int dest; } {Edge} Edges = {<1,2>, <1,4>, <1,5>};int a[Edges] = [10,20,30];
多維數組定義
int a[1..2][1..3] = ...; // 可以使用逗號分割{string} Warehouses = ...;{string} Customers = ...;int transp[Warehouses,Customers] = ...;
推薦閱讀: