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