【问题标题】:How to check solver convergence with GEKKO and APOPT如何使用 GEKKO 和 APPT 检查求解器收敛性
【发布时间】:2020-04-12 13:56:24
【问题描述】:

我正在处理一些小的 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

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


所以我有两个问题:

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

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

【问题讨论】:

    标签: python convergence gekko


    【解决方案1】:

    目前,无法从 APOPT 报告混合整数迭代次数。但是,您可以通过将minlp_maximum_iterations 设置为较大的值(例如100000)来确保APPT 永远不会过早停止。 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

    【讨论】:

    • 谢谢。关于我的问题 2:由于评估所有选项可能太昂贵,我不想强​​制执行,我只想知道求解器是否过早停止。
    • 我在 Github 上将此作为功能请求添加:github.com/BYU-PRISM/GEKKO/issues/81
    【解决方案2】:

    来自John Hedengren's answer

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

    目前,无法从 APPT 报告混合整数迭代次数

    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
    

    【讨论】:

      猜你喜欢
      • 2019-06-06
      • 1970-01-01
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多