我正在处理较小的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)如何确定求解器是否检查了每个候选者,从而找到了最佳实例化?
答案 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))
答案 1 :(得分:0)
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