如何使用GEKKO和APOPT检查求解器的收敛性

时间:2020-04-12 13:56:24

标签: python convergence gekko

我正在处理较小的MILP问题,为此我已确定了最大迭代次数。我想确定可以确保达到最佳状态的实例。

调用m.solve(disp=True)时,如果求解器提前停止,则会显示警告:

警告:达到最大MINLP次迭代,返回最佳解决方案

我想以编程方式检查我们是否处于这种情况。我尝试过

1)查看文档,但是从求解器找到可行解的那一刻起,m.options.SOLVESTATUS始终为1,m.options.APPINFO始终为0。

2)

optimum = m.options.ITERATIONS < m.options.MAX_ITER

但是它不起作用,因为实际上m.options.ITERATIONS并没有达到我的预期(它总是比m.options.MAX_ITER低得多)。

3)举起然后抓住警告:

import warnings
warnings.filterwarnings("error")

try:
    self.model.solve()
    optimum = True
except:
    optimum = False

但是它也不起作用(不会引发错误)。


所以我有2个问题:

1)如何检查求解器已使用的迭代次数?

2)如何确定求解器是否检查了每个候选者,从而找到了最佳实例化?

2 个答案:

答案 0 :(得分:2)

目前,尚无法报告APOPT的“混合整数”迭代次数。但是,可以通过将minlp_maximum_iterations设置为较大的值(例如100000)来确保APOPT永远不会过早停止。 m.options.ITERATIONS报告上一次分支求值的NLP次迭代。

您可以通过将minlp_gap_tol设置为零来确保评估所有候选解决方案。如果满足间隙公差条件,则求解器将终止。将其设置为零意味着将评估所有选项。但是,这可能需要更长的时间来评估所有选项。

from gekko import GEKKO
m = GEKKO(remote=False) # Initialize gekko
m.options.SOLVER=1  # APOPT is an MINLP solver

# optional solver settings with APOPT
m.solver_options = ['minlp_maximum_iterations 100000', \
                    # minlp iterations with integer solution
                    'minlp_max_iter_with_int_sol 10', \
                    # nlp sub-problem max iterations
                    'nlp_maximum_iterations 50', \
                    # covergence tolerance
                    'minlp_gap_tol 0.00']

# Initialize variables
x1 = m.Var(value=1,lb=1,ub=5)
x2 = m.Var(value=5,lb=1,ub=5)
# Integer constraints for x3 and x4
x3 = m.Var(value=5,lb=1,ub=5,integer=True)
x4 = m.Var(value=1,lb=1,ub=5,integer=True)
# Equations
m.Equation(x1*x2*x3*x4>=25)
m.Equation(x1**2+x2**2+x3**2+x4**2==40)
m.Obj(x1*x4*(x1+x2+x3)+x3) # Objective
m.solve(disp=True) # Solve
print('Results')
print('Iterations: ' + str(m.options.ITERATIONS))
print('x1: ' + str(x1.value))
print('x2: ' + str(x2.value))
print('x3: ' + str(x3.value))
print('x4: ' + str(x4.value))
print('Objective: ' + str(m.options.objfcnval))

还有更多information on solver options

答案 1 :(得分:0)

来自John Hedengren's answer

1)如何检查求解器已使用的迭代次数?

目前,无法报告APOPT的混合整数迭代次数

2)如何确定求解器是否检查了每个候选者,从而找到了最佳实例化?

我将此添加为Github上的功能请求:github.com/BYU-PRISM/GEKKO/issues/81

目前,我已经实施了一个难看的解决方案:

# redirect stdout
sys.stdout = open('tmp_output', 'w')

# solve and output to the tmp file
try:
    self.model.solve(disp=True)
except:
    pass #solution not found

# read the file
with open('tmp_output', 'r') as f:
    line = f.readline()

    # skip the first lines
    while line[:5] != "Iter:":
        line = f.readline()

    # skip the next lines (one line per iteration)
    while line[:5] in ["Iter:", "--Int"]:
        line = f.readline()

    # check the warning
    optimal = line != " Warning: reached maximum MINLP iterations, returning best solution\n"

return optimal