如何使用 GEKKO 和 APOPT 检查求解器的收敛性
How to check solver convergence with GEKKO and APOPT
我正在处理我已固定最大迭代次数的小型 MILP 问题。我想确定我们确信我们已经达到最佳状态的实例。
调用m.solve(disp=True)
时,如果解算器提前停止,它会显示警告:
Warning: reached maximum MINLP iterations, returning best solution
我想以编程方式检查我们是否处于这种情况。我试过了
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) 如何确定求解器是否检查了每个候选并因此找到了最佳实例?
目前,无法从 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) 如何查看求解器已经使用的迭代次数?
Right now, there is no way to report the number of Mixed Integer iterations from APOPT
2) 如何确定求解器是否确实检查了每个候选并因此找到了最佳实例?
I added this as a feature request on 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
我正在处理我已固定最大迭代次数的小型 MILP 问题。我想确定我们确信我们已经达到最佳状态的实例。
调用m.solve(disp=True)
时,如果解算器提前停止,它会显示警告:
Warning: reached maximum MINLP iterations, returning best solution
我想以编程方式检查我们是否处于这种情况。我试过了
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) 如何确定求解器是否检查了每个候选并因此找到了最佳实例?
目前,无法从 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) 如何查看求解器已经使用的迭代次数?
Right now, there is no way to report the number of Mixed Integer iterations from APOPT
2) 如何确定求解器是否确实检查了每个候选并因此找到了最佳实例?
I added this as a feature request on 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