Как проверить сходимость решателя с GEKKO и APOPT - PullRequest
2 голосов
/ 12 апреля 2020

Я имею дело с небольшими проблемами 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 ]

2 голосов
/ 13 апреля 2020

В данный момент нет способа сообщить количество итераций Mixed Integer из APOPT. Однако вы можете гарантировать, что APOPT никогда не остановится преждевременно, установив minlp_maximum_iterations на большое значение, такое как 100000. 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))

Более подробная информация о параметрах решателя .

0 голосов
/ 14 апреля 2020

Из Ответ Джона Хеденгрена :

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
...