pyomo 的 AbstractModel VS ConcreteModel? "opt.options["tol"]" 在寻找最佳解决方案方面有何不同?

AbstractModel VS ConcreteModel of pyomo? how does "opt.options["tol"]" make the difference in finding optimal solution?

我有一个 AbstractModel 和一个 ConcreteModel 解决同样的问题,但它们的表现不同。主要是一个变量的初值和ipopt的容差。

  1. 当我将变量 model.x 初始化为 10 并且 opt.options["tol"] = 1E-64: ConcreteModel可以找到最优解,而抽象模型"Solved To Acceptable Level"。 (但是他们找到的解其实是一样的)

  2. 当我将变量 model.x 初始化为 100 并且 opt.options["tol"] = 1E-64: 具体模型可以找到最优解,而抽象模型有时"Solved To Acceptable Level",有时"Cannot load a SolverResults object with bad status: error"。

  3. 如果我直接使用ipopt默认的tolerance值,不管我怎么初始化变量,ConcreteModel和AbstractModel都能找到相同的最优解model.x。

所以我想知道 opt.options["tol"] 有何不同?为什么在这种情况下 ConcreteModel 总能找到最优解,而 AbstractModel 却不能?

变量

model.x = Var(model.Crops, model.Inputs, initialize = 100, within=NonNegativeReals)

解决抽象模型的脚本

instance = model.create_instance(data="AbstractCDFarm.dat")
opt = SolverFactory("ipopt")
opt.options["tol"] = 1E-64
results = opt.solve(instance, tee=True) 
instance.display()

求解 ConcreteModel 的脚本

opt = SolverFactory('ipopt')
opt.solve(model, tee=True) 
opt.options["tol"] = 1E-64
results = opt.solve
model.display()

您为 ConcreteModel 调用了两次 solve ,看起来您看到的输出是针对默认的 Ipopt 公差,而不是针对 1E-64 的公差。你为什么设置这么低的容忍度? 1E-64 小于机器精度,因此它是一个不可能收敛的小公差。