GLPK/GMPL 解決方案
外觀
< GLPK
此頁面提供了 GMPL (MathProg) 不支援的功能的替代結構。
GLPK 不提供 IF-THEN-ELSE 語法,這在對結果進行後處理時通常很有用。請改用以下語法
for {{0}: condition}{ # IF condition THEN
} for {{0}: not condition} { # ELSE
} # ENDIF
{0} 可以被任何只有一個元素的集合替換。for 語句將只在後續大括號內的表示式上迭代一次。
以下最小示例建立具有不同行格式的輸出,這取決於數字是偶數還是奇數
for{ c in {1..10} } {
for {{0}: c mod 2 == 0} {
printf "even\t%d\n", c;
} for {{0}: c mod 2 != 0} {
printf "odd\t%d\n", c;
}
}
end;
您可能希望輸出排序序列。以下示例顯示瞭如何操作
# sorting_symbolic.mod - how to sort arrays in MathProg
# based on code by Andrew Makhorin
# Sometimes it is necessary to print parameters or variables in the
# order of ascending or descending their values. Suppose, for example,
# that we have the following subscripted parameter:
set I;
param a{i in I} := Uniform(2, 7);
# If we print all its members:
printf{i in I} "a[%2s] = %g\n", i, a[i];
# the output may look like follows:
#
# a[a] = 2.64156
# a[b] = 2.04798
# a[c] = 2.14843
# a[d] = 4.76896
# a[e] = 6.09132
# a[f] = 3.27780
# a[g] = 4.06113
# a[h] = 4.05898
# a[i] = 6.63120
# a[j] = 6.50318
# a[k] = 3.46065
# a[l] = 4.69845
#
# However, we would like the parameter members to appear in the order
# of ascending values.
#
# Introduce the following auxiliary parameter:
param pos{i in I} :=
card({j in I: a[j] < a[i] or a[j] = a[i] and j < i});
# where pos[i] = k - 1 means that in the sorted list member a[i] has
# k-th position, 1 <= k <= |I|. Then introduce another auxiliary
# parameter:
set ind{k in 1..card(I)} := setof{i in I: pos[i] = k - 1} i;
# where ind[k] = {i} iff pos[k] = i.
#
# Now, the following statement:
printf "\n";
printf{k in 1..card(I), l in ind[k]} "a[%2s] = %g\n", l, a[l];
# prints the parameter members in the desired order:
#
# a[b] = 2.04798
# a[c] = 2.14843
# a[a] = 2.64156
# a[f] = 3.27780
# a[k] = 3.46065
# a[h] = 4.05898
# a[g] = 4.06113
# a[l] = 4.69845
# a[d] = 4.76896
# a[e] = 6.09132
# a[j] = 6.50318
# a[i] = 6.63120
solve;
data;
set I := a b c d e f g h i j k l;
#set I := 1 2 3 4 5 6 7 8 9 10 11 12;
end;
AMPL 語言有一個稱為定義變數的結構。 [1] 定義變數由一個帶有等號的變數宣告和一個右邊的項組成。舉個例子
var f{k in 1..K} = sum{i in 1..I, j in 1..J} x[i,j,k]*w[i];
這裡f是一個定義的變數。上面的語句實際上並沒有宣告一個結構變數,而是像一種宏一樣工作——因此,每個出現的f[k]將被替換為
sum{i in 1..I, j in 1..J} x[i,j,k]*w[i]
此結構不受 GMPL 支援。但是,您可以使用結構變數和約束來實現相同的效果——缺點是這種公式可能會使您的問題更難解決
var f{k in 1..K};
s.t. c1{k in 1..K} : f[k] = sum{i in 1..I, j in 1..J} x[i,j,k]*w[i];
GMPL 中不存在集合的集合。相反,可以使用索引集合和索引集合。下面的示例顯示瞭如何列舉給定大小的超集的所有子集。
/**********************************************
*
* For a set of superset S determine all subsets
* of size m
*
**********************************************/
# Superset
set S;
# Number of elements in subset
param m;
# Number of elements in superset
param n := card(S);
# Set of subset sizes less or equal to m
set I := {1 .. m};
# Set of indices for a subset of size i of set S
set J{i in I} := { 1 .. round((prod{a in {1..n}}a) /
(prod{a in {1..i}}a) / (prod{a in {1..n-i}}a)) };
# Set of indices for S
set K := {1 .. n};
# Set containing the kth member of S
set L{k in K} := setof{s in S : k == sum{t in S : t <= s} 1} s;
# Set of integers in [i, n]
set M{i in I} := {i .. n};
# Number of subsets of size i of a set of size j - 1
param ji{i in I, j in M[i]} := if i==j then 0
else round((prod{a in {1..j-1}}a) /
(prod{a in {1..i}}a) / (prod{a in {1..j-1-i}}a)) ;
# Subsets j of size i
set N{i in I, j in J[i]} :=
if i == 1
then L[j]
else N[i-1,j - ji[i,max{k in M[i] : ji[i,k] < j} k]]
union L[max{k in M[i] : ji[i,k] < j} k];
# Set of subsets of size m
set C := J[m];
# Elements in subset c
set Sc{c in C} := N[m, c];
solve;
printf "Last 100 subsets\n";
for {c in C: c > card(C) - 100} {
printf "[%d]: ", c;
printf {s in Sc[c]} "%s ", s;
printf "\n";
}
printf "\nChecking cardinality\n";
printf {c in C}
"%s", if card(Sc[c]) != m then "Wrong cardinality! " else "";
printf "\n";
printf "Checking disjunctness\n";
for {c in C}
printf {d in C: d > c} "%s",
if card(Sc[c] union Sc[d]) <= m then "Two subsets are the same!" else "";
printf "\n";
printf "Number of subsets = %d\n\n", card(C);
data;
param m:= 4;
set S := A B C D E F G H I J K L;
end;
- ↑ Fourer, Robert; Gay, David M.; Kerningham, Brian W. (2002). AMPL : a modeling language for mathematical programming (2nd ed.). Duxbury Press. p. 131. ISBN 978-0534388096. 可作為可下載的 PDF 檔案獲取。