Используя Gekko Optimization, почему мой конструктор моделей намного медленнее моего решателя? - PullRequest
3 голосов
/ 17 января 2020

Я работаю над довольно большой MINLP с размером модели около 270 000 переменных и уравнениями - 5 000 двоичных файлов. Используя Gekko с решателем APOPT, я могу решить проблему за 868 секунд (менее 15 минут). Однако решение проблемы на суперкомпьютере для увеличения памяти требует около 27 часов для получения результатов.

Кажется, что тратит все свое время на создание модели. Читая немного об APOPT, он упоминает, что он работает лучше всего, когда Степени Свободы меньше 2000 (у меня около 3500). Тем не менее, я также читал, что это единственный смешанный решатель целых чисел, доступный с Gekko?

Мне интересно, если это так или есть другие варианты этой программы в Gekko? (как я предпочел бы кодировать в Python). В приложении мне нужно будет запускать этот код несколько раз с разными загруженными таблицами Excel, так что, если есть необходимость сохранить конструкцию модели для будущих запусков, это также может быть полезным.

1 Ответ

2 голосов
/ 20 января 2020

Это впечатляющий размер проблемы MINLP. Чтобы определить, как сделать это быстрее при предварительной обработке, вам нужно собрать некоторую дополнительную информацию о том, где время используется с DIAGLEVEL>=1.

m.options.DIAGLEVEL = 1

. Это дает отчет о том, как долго принимает для каждого из шагов. Вот пример проблемы MINLP (см. # 10) .

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

# optional solver settings with APOPT
m.solver_options = ['minlp_maximum_iterations 500', \
                    # minlp iterations with integer solution
                    'minlp_max_iter_with_int_sol 10', \
                    # treat minlp as nlp
                    'minlp_as_nlp 0', \
                    # nlp sub-problem max iterations
                    'nlp_maximum_iterations 50', \
                    # 1 = depth first, 2 = breadth first
                    'minlp_branch_method 1', \
                    # maximum deviation from whole number
                    'minlp_integer_tol 0.05', \
                    # covergence tolerance
                    'minlp_gap_tol 0.01']

# 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

. Это приводит к следующим результатам синхронизации:

Timer #     1       0.03/       1 =       0.03 Total system time
Timer #     2       0.02/       1 =       0.02 Total solve time
Timer #     3       0.00/      42 =       0.00 Objective Calc: apm_p
Timer #     4       0.00/      29 =       0.00 Objective Grad: apm_g
Timer #     5       0.00/      42 =       0.00 Constraint Calc: apm_c
Timer #     6       0.00/       0 =       0.00 Sparsity: apm_s
Timer #     7       0.00/       0 =       0.00 1st Deriv #1: apm_a1
Timer #     8       0.00/      29 =       0.00 1st Deriv #2: apm_a2
Timer #     9       0.00/       1 =       0.00 Custom Init: apm_custom_init
Timer #    10       0.00/       1 =       0.00 Mode: apm_node_res::case 0
Timer #    11       0.00/       1 =       0.00 Mode: apm_node_res::case 1
Timer #    12       0.00/       1 =       0.00 Mode: apm_node_res::case 2
Timer #    13       0.00/       1 =       0.00 Mode: apm_node_res::case 3
Timer #    14       0.00/      89 =       0.00 Mode: apm_node_res::case 4
Timer #    15       0.00/      58 =       0.00 Mode: apm_node_res::case 5
Timer #    16       0.00/       0 =       0.00 Mode: apm_node_res::case 6
Timer #    17       0.00/      29 =       0.00 Base 1st Deriv: apm_jacobian
Timer #    18       0.00/      29 =       0.00 Base 1st Deriv: apm_condensed_jacobian
Timer #    19       0.00/       1 =       0.00 Non-zeros: apm_nnz
Timer #    20       0.00/       0 =       0.00 Count: Division by zero
Timer #    21       0.00/       0 =       0.00 Count: Argument of LOG10 negative
Timer #    22       0.00/       0 =       0.00 Count: Argument of LOG negative
Timer #    23       0.00/       0 =       0.00 Count: Argument of SQRT negative
Timer #    24       0.00/       0 =       0.00 Count: Argument of ASIN illegal
Timer #    25       0.00/       0 =       0.00 Count: Argument of ACOS illegal
Timer #    26       0.00/       1 =       0.00 Extract sparsity: apm_sparsity
Timer #    27       0.00/      13 =       0.00 Variable ordering: apm_var_order
Timer #    28       0.00/       1 =       0.00 Condensed sparsity
Timer #    29       0.00/       0 =       0.00 Hessian Non-zeros
Timer #    30       0.00/       1 =       0.00 Differentials
Timer #    31       0.00/       0 =       0.00 Hessian Calculation
Timer #    32       0.00/       0 =       0.00 Extract Hessian
Timer #    33       0.00/       1 =       0.00 Base 1st Deriv: apm_jac_order
Timer #    34       0.01/       1 =       0.01 Solver Setup
Timer #    35       0.00/       1 =       0.00 Solver Solution
Timer #    36       0.00/      53 =       0.00 Number of Variables
Timer #    37       0.00/      35 =       0.00 Number of Equations
Timer #    38       0.01/      14 =       0.00 File Read/Write
Timer #    39       0.00/       0 =       0.00 Dynamic Init A
Timer #    40       0.00/       0 =       0.00 Dynamic Init B
Timer #    41       0.00/       0 =       0.00 Dynamic Init C
Timer #    42       0.00/       1 =       0.00 Init: Read APM File
Timer #    43       0.00/       1 =       0.00 Init: Parse Constants
Timer #    44       0.00/       1 =       0.00 Init: Model Sizing
Timer #    45       0.00/       1 =       0.00 Init: Allocate Memory
Timer #    46       0.00/       1 =       0.00 Init: Parse Model
Timer #    47       0.00/       1 =       0.00 Init: Check for Duplicates
Timer #    48       0.00/       1 =       0.00 Init: Compile Equations
Timer #    49       0.00/       1 =       0.00 Init: Check Uninitialized
Timer #    50      -0.00/      13 =      -0.00 Evaluate Expression Once
Timer #    51       0.00/       0 =       0.00 Sensitivity Analysis: LU Factorization
Timer #    52       0.00/       0 =       0.00 Sensitivity Analysis: Gauss Elimination
Timer #    53       0.00/       0 =       0.00 Sensitivity Analysis: Total Time

APOPT сохраняет экземпляр проблемы между NLP выполняется так, чтобы быстро выполнить переоценку с другими ограничениями, так как он выполняет ветвление и связывание. APOPT использует функцию «горячего старта» для быстрой оценки ограниченных проблем оптимизации НЛП. Однако эта функция горячего старта недоступна для пользователя Gekko. Есть другие решатели, доступные с Gekko (тот, который может быть настроен для MINLP), но они требуют коммерческой лицензии. Есть также бесплатные решатели MINLP, такие как Couenne и Bonmin, которые доступны в COIN-OR, но они еще не поддерживаются. Вы можете добавить запрос для Gekko , если решите, что предварительная обработка APOPT является проблемой, и вы хотите попробовать другой решатель. Вот результат оптимизации, который показывает время для каждой итерации.

 ----------------------------------------------
 Steady State Optimization with APOPT Solver
 ----------------------------------------------
Iter:     1 I:  0 Tm:      0.00 NLPi:    7 Dpth:    0 Lvs:    3 Obj:  1.70E+01 Gap:       NaN
--Integer Solution:   1.75E+01 Lowest Leaf:   1.70E+01 Gap:   3.00E-02
Iter:     2 I:  0 Tm:      0.00 NLPi:    5 Dpth:    1 Lvs:    2 Obj:  1.75E+01 Gap:  3.00E-02
Iter:     3 I:  0 Tm:      0.00 NLPi:    6 Dpth:    1 Lvs:    2 Obj:  1.75E+01 Gap:  3.00E-02
--Integer Solution:   1.75E+01 Lowest Leaf:   1.70E+01 Gap:   3.00E-02
Iter:     4 I:  0 Tm:      0.00 NLPi:    6 Dpth:    2 Lvs:    1 Obj:  2.59E+01 Gap:  3.00E-02
Iter:     5 I:  0 Tm:      0.00 NLPi:    5 Dpth:    1 Lvs:    0 Obj:  2.15E+01 Gap:  3.00E-02
 No additional trial points, returning the best integer solution
 Successful solution

 ---------------------------------------------------
 Solver         :  APOPT (v1.0)
 Solution time  :   1.649999999790452E-002 sec
 Objective      :    17.5322673012512     
 Successful solution
 ---------------------------------------------------

Вот несколько вещей, чтобы попытаться диагностировать или улучшить время решения:

  • Попробуйте решатель IPOPT для нецелого решения. Требуется ли еще 27 часов, чтобы завершить решение с этим решателем? Это может указывать на то, что APOPT выполняет предварительную обработку решения.
  • Замените gekko константы и параметры на Python с плавающей запятой, где это возможно. Это сокращает время обработки модели.
  • Использование встроенных объектов gekko , таких как m.sum(), вместо функции Python sum. Как правило, это улучшает производительность обработки модели.
  • Автоматическое c уменьшение модели с m.options.REDUCE=3 или ручное уменьшение модели с использованием Intermediate переменных .
...