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 文件获取。