我有一些 .mod 格式的 AMPL 文件,我想将其转换为 .nl 格式。 通过这种方式,我可以轻松解析它们以进行进一步处理。
但是,我注意到在转换中问题发生了变化。
出现此问题的输入示例如下,摘自此处。
var x {1..4} >= 0;
minimize obj:
2-x[1]*x[2]*x[3]
;
subject to constr1: x[1] + 2*x[2] + 2*x[3] - x[4] = 0;
subject to constr2: x[1] <= 1;
subject to constr3: x[2] <= 1;
subject to constr4: x[3] <= 1;
subject to constr5: x[4] <= 2;
let x[1] := 2;
let x[2] := 2;
let x[3] := 2;
let x[4] := 2;
#printf "optimal solution as starting point \n";
#let x[1] := 2/3;
#let x[2] := 1/3;
#let x[3] := 1/3;
#let x[4] := 2;
我尝试通过运行来转换它
ampl -oghs041 hs041.mod
生成以下
hs041.nl
文件
g3 2 1 0 # problem hs041
4 1 1 0 1 # vars, constraints, objectives, ranges, eqns
0 1 # nonlinear constraints, objectives
0 0 # network constraints: nonlinear, linear
0 3 0 # nonlinear vars in constraints, objectives, both
0 0 0 1 # linear network variables; functions; arith, flags
0 0 0 0 0 # discrete variables: binary, integer, nonlinear (b,c,o)
4 3 # nonzeros in Jacobian, gradients
0 0 # max name lengths: constraints, variables
0 0 0 0 0 # common exprs: b,c,o,c1,o1
b
0 0 1
0 0 1
0 0 1
0 0 2
x4
0 2
1 2
2 2
3 2
r
4 0
C0
n0
O0 0
o1
n2
o2
o2
v0
v1
v2
k3
1
2
3
J0 4
0 1
1 2
2 2
3 -1
G0 3
0 0
1 0
2 0
这不是我期望的输出,因为只剩下一个
0=0
形式的约束。
我的猜测是,在转换问题之前进行了一些简化,并且生成的问题始终等于原始问题。
这个猜测正确吗?我可以相信 .nl 文件中的问题与原始问题相同这一事实吗?
有没有办法避免这种简化?我尝试使用
-P
和 -L0
选项
-Ln {0 = treat linear definitional constrs and var = decls as nonlin}
-P {skip presolve -- same as "option presolve 0;" }
但它们无助于解决这个问题。
Ampl 在生成 nl 文件之前执行预求解算法,因此某些变量和约束可能会在此时消失。您可以使用预求解选项控制 Ampl 的预求解(
option presolve 0;
将禁用预求解迭代)。其他简化仍将进行,但它们应该是微不足道的。例如,x + 2 >= x + 1 - 2
可以得到简化。
但是,在您的情况下,大多数约束只是变量的界限(
subject to constr2: x[1] <= 1
),因此它们会被这样对待。在 nl 文件的“b”部分中,您可以看到这些约束:
b
0 0 1
0 0 1
0 0 1
0 0 2
所以 x1 有 2 个边界,0 和 1,x2、x3 相同,x4 有 2 个边界,0 和 2。我想发送变量的边界以及设置这些边界的约束是多余的。
对于任何具有稍微困难的约束的进一步示例,您可以只生成一个 nl 文件而不进行简化,但涉及一个变量和一个常量的约束将被转换为该变量的边界。
是的,nl 文件应该与模型等效,但经过简化和减少。
我不知道有什么选项可以实现你所说的功能,但这里有很多选项你可以尝试以防万一,请参阅预求解选项和求解选项部分: https://dev.ampl.com/ampl/options.html#presolve-options
顺便说一下,我通常通过“写命令”生成一个nl文件,而不是传递参数。
write gmymodel;
将生成 mymodel.nl
。
用于查看模型的其他一些有用命令是
expand;
和 solexpand;
。
“通过这种方式,我可以轻松解析它们以进行进一步处理。”,我很好奇如何比模型本身更好地解析 nl 文件!我很好奇你在做什么。