用 Pyomo 求解 MINLP。 'Starting feasible solution'有什么设置吗?

Solving MINLP with Pyomo. Is there any setting about 'Starting feasible solution'?

我的环境是:Python 3.5.2, Anaconda 4.2.0 (32-bit), Pyomo 4.4.1 (VOTD) (CPython 3.5.2 on W7), Baron 17.3.31

我目前正在使用 Pyomo 和 Baron 作为求解器进行优化。为了进行测试,使用了 minlp 问题。我可以通过 运行 宁 main.py 代码得到最优解如下。我每次运行代码,在第一次运行之后,都会得到和第一次运行一样的解法。结果将显示:

Starting solution is feasible with a value of xxxxx
Doing local search
Solving bounding LP
Starting multi-start local search
Done with local search

起始可行解每次都相同。

然而,在我重新启动内核(重新启动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)

如果将keepfiles=True添加到solve()调用中,它将打印出发送给男爵的临时.bar文件(注意我们也支持NL文件接口来男爵,这需要 baron_ampl 解算器)。此外,添加 symbolic_solver_labels=True 将使该文件更易于阅读,因为使用模型上对象的原始名称来写入文件。

我建议在每次迭代时针对不同的 运行s 比较这些文件。例如,如果第一次迭代的 .bar 文件对于两个不同的 运行s 是相同的,但在该迭代之后解决方案不同,这意味着非确定性行为在 Baron 内部(可能有一个 Baron 选项可以控制它)。否则,在您的代码中寻找迭代顺序可能从 运行 运行 改变的地方,这可能会导致某些操作的不同结果(例如,您迭代字典键的地方)。

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