用Pyomo解决MINLP问题。有没有关于'开始可行解决方案'的设置?

时间:2017-06-14 09:54:28

标签: python optimization pyomo

我的环境是:Python 3.5.2,Anaconda 4.2.0(32位),Pyomo 4.4.1(VOTD)(W7上的CPython 3.5.2),男爵17.3.31

我目前正在与Pyomo和Baron一起进行优化作为求解器。为了测试,使用minlp问题。我可以通过运行main.py代码获得最佳解决方案,如下所示。每次运行代码时,在第一次运行之后,我将获得与第一次运行相同的解决方案。结果将显示:

  

启动解决方案是可行的,值为xxxxx
  做本地搜索
  解决边界LP
  开始多方开始本地搜索
  完成本地搜索

每次开始可行的解决方案都是一样的。

但是,在我重新启动内核(重新启动Spyder)并再次运行该文件后,它可能会得到不同的解决方案。为什么?有没有重置优化过程的方法?如何在不重新启动内核的情况下获得各种解决方案?

我做了一些尝试:imp.reload(pyomo.environ),imp.reload(pyomo.opt)......等等

请帮忙。谢谢。

主文件main.py如下:

from pyomo.environ import *
from pyomo.opt import SolverFactory
from minlp import model


instance = model.create_instance()
instance.dual = Suffix(direction=Suffix.IMPORT)
minlpopt = SolverFactory("baron")
results = minlpopt.solve(instance, tee=True)
print('Objective Fucntion: ' + str(instance.obj()))

模型文件minlp.py如下:

from pyomo.environ import *

# SETS ========================================================================
model = ConcreteModel()

model.y1 = Var(within=Binary)
model.y2 = Var(within=Binary)
model.y3 = Var(within=Binary)
model.x1 = Var(within=PositiveReals, bounds=(0,2))
model.x2 = Var(within=PositiveReals, bounds=(0,2))
model.x3 = Var(within=PositiveReals, bounds=(0,1))


# RULE ========================================================================
def obj_rule(model):
    return (5 * model.y1 + 6 * model.y2 + 8 * model.y3 + 10 * model.x1 \
            - 7 * model.x3 - 18 * log(model.x2 + 1) \
            - 19.2 * log(model.x1 - model.x2 + 1) + 10)
model.obj = Objective(rule=obj_rule, sense=minimize)


def c1_rule(model):
    return (0.8 * log(model.x2 + 1) + 0.96 * log(model.x1 - model.x2 + 1) \
            - 0.8 * model.x3) >= 0
model.c1 = Constraint(rule=c1_rule)

def c2_rule(model):
    return (log(model.x2 + 1) + 1.2 * log(model.x1 - model.x2 + 1) - model.x3 \
            - 2 * model.y3) >= -2
model.c2 = Constraint(rule=c2_rule)

def c3_rule(model):
    return model.x2 - model.x1 <= 0
model.c3 = Constraint(rule=c3_rule)

def c4_rule(model):
    return model.x2 - 2 * model.y1 <= 0
model.c4 = Constraint(rule=c4_rule)

def c5_rule(model):
    return model.x1 - model.x2 - 2 * model.y2 <= 0
model.c5 = Constraint(rule=c5_rule)

def c6_rule(model):
    return model.y1 + model.y2 <= 1
model.c6 = Constraint(rule=c6_rule)

1 个答案:

答案 0 :(得分:1)

如果您将keepfiles=True添加到solve()来电,它会打印出发送给Baron的临时.bar文件(请注意,我们也支持Baron的NL文件界面,这需要baron_ampl解算器)。此外,添加symbolic_solver_labels=True将使用模型上的对象的原始名称来编写文件,从而使该文件更容易阅读。

我建议在每次迭代时为不同的运行区分这些文件。例如,如果第一次迭代的.bar文件对于两次不同的运行是相同的,但是在该迭代之后解决方案是不同的,则意味着非确定性行为在Baron内部(可能存在Baron选项)控制这个)。否则,在代码中查找迭代顺序可能会在运行之间发生更改的位置,这可能会导致某些操作产生不同的结果(例如,迭代字典键的位置)。

Pyomo求解器的默认行为通常足以使输出文件对于等效的模型看起来相同。如果不是这种情况,很可能是因为对象没有以相同的顺序添加到父块。在这种情况下,您可以尝试将file_determinism=3添加到solve()调用基于文件的解算器。这将导致在写入文件之前进行一些额外的排序,这可确保输出文件看起来总是相同。