#python #mathematical-optimization #gekko
Вопрос:
У меня есть проблема оптимизации, которую я пытаюсь решить с помощью Gekko. Когда я устанавливаю начальные значения для переменных со значениями возможного решения, которое удовлетворяло ограничениям, Гекко не может найти решение. Как я могу найти первопричину?
Я получаю эту ошибку:
Error: Exception: Access Violation
At line 1341 of file MUMPS/src/dmumps_part2.F
Traceback: not available, compile with -ftrace=frame or -ftrace=full
Error: 'results.json' not found. Check above for additional error details
did not managed to solve
((1)*((d_t200_3_1-d_t100_3_1)))
Вот модель оптимизации, которую я запускаю
m = GEKKO(remote=False)
m.options.MAX_ITER=1000
m.options.IMODE=3
d_t200_3_0 = m.Var(540, name='d_t200_3_0')
d_t200_3_2 = m.Var(180, name='d_t200_3_2')
d_t200_3_1 = m.Var(360, name='d_t200_3_1')
d_t100_3_0 = m.Var(60, name='d_t100_3_0')
d_t100_3_2 = m.Var(20, name='d_t100_3_2')
d_t100_3_1 = m.Var(40, name='d_t100_3_1')
m.Equation(m.abs2(d_t100_3_0) >= 0.0)
m.Equation(200 > m.abs2(d_t100_3_0))
m.Equation(m.abs2(d_t100_3_2) >= 0.0)
m.Equation(200 > m.abs2(d_t100_3_2))
m.Equation(m.abs2(d_t100_3_1) >= 0.0)
m.Equation(200 > m.abs2(d_t100_3_1))
m.Equation(m.abs2(-1.0*m.abs2(d_t100_3_0) - -1.0*m.abs2(d_t100_3_2)) >= 0.0)
m.Equation(200 > m.abs2(-1.0*m.abs2(d_t100_3_0) - -1.0*m.abs2(d_t100_3_2)))
m.Equation(m.abs2(-1.0*m.abs2(d_t100_3_0) - -1.0*m.abs2(d_t100_3_1)) >= 0.0)
m.Equation(200 > m.abs2(-1.0*m.abs2(d_t100_3_0) - -1.0*m.abs2(d_t100_3_1)))
m.Equation(m.abs2(-1.0*m.abs2(d_t100_3_2) - -1.0*m.abs2(d_t100_3_1)) >= 0.0)
m.Equation(200 > m.abs2(-1.0*m.abs2(d_t100_3_2) - -1.0*m.abs2(d_t100_3_1)))
m.Equation(m.abs2(d_t200_3_0) >= 200.0)
m.Equation(600 > m.abs2(d_t200_3_0))
m.Equation(m.abs2(d_t200_3_2) >= 0.0)
m.Equation(200 > m.abs2(d_t200_3_2))
m.Equation(m.abs2(d_t200_3_1) >= 200.0)
m.Equation(400 > m.abs2(d_t200_3_1))
m.Equation(m.abs2(-1.0*m.abs2(d_t200_3_0) - -1.0*m.abs2(d_t200_3_2)) >= 200.0)
m.Equation(400 > m.abs2(-1.0*m.abs2(d_t200_3_0) - -1.0*m.abs2(d_t200_3_2)))
m.Equation(m.abs2(-1.0*m.abs2(d_t200_3_0) - -1.0*m.abs2(d_t200_3_1)) >= 0.0)
m.Equation(200 > m.abs2(-1.0*m.abs2(d_t200_3_0) - -1.0*m.abs2(d_t200_3_1)))
m.Equation(m.abs2(-1.0*m.abs2(d_t200_3_2) - -1.0*m.abs2(d_t200_3_1)) >= 0.0)
m.Equation(200 > m.abs2(-1.0*m.abs2(d_t200_3_2) - -1.0*m.abs2(d_t200_3_1)))
m.Obj(d_t200_3_2 - d_t100_3_2)
m.solve(debug =1, disp=True)
При решении этой задачи без значений инициалов я получаю решение, но иногда возникает несоответствие, т. Е. другое решение для одной и той же проблемы. Есть какие-нибудь намеки на то, почему это могло произойти? Я думал, что происходит какое-то случайное инициирование и начальное значение меняется, но, согласно документации, начальные значения по умолчанию равны 0.
Спасибо!
Просто чтобы уточнить, что я еще не нашел проблему, но если посмотреть на подмножество переменных оптимизации и соответствующие ограничения, я смогу получить результаты оптимизации. вот подмножество:
d_t200_1_0 = m.Var(180, name='d_t200_1_0')
d_t200_1_2 = m.Var(180, name='d_t200_1_2')
d_t100_1_0 = m.Var(20, name='d_t100_1_0')
d_t100_1_2 = m.Var(20, name='d_t100_1_2')
m.Equation(m.abs2(d_t100_1_0) >= 0.0)
m.Equation(200 > m.abs2(d_t100_1_0))
m.Equation(m.abs2(d_t100_1_2) >= 0.0)
m.Equation(200 > m.abs2(d_t100_1_2))
m.Equation(m.abs2(-1.0*m.abs2(d_t100_1_0) - 1.0*m.abs2(d_t100_1_2)) >= 0.0)
m.Equation(200 > m.abs2(-1.0*m.abs2(d_t100_1_0) - 1.0*m.abs2(d_t100_1_2)))
m.Equation(m.abs2(d_t200_1_0) >= 0.0)
m.Equation(200 > m.abs2(d_t200_1_0))
m.Equation(m.abs2(d_t200_1_2) >= 0.0)
m.Equation(200 > m.abs2(d_t200_1_2))
m.Equation(m.abs2(-1.0*m.abs2(d_t200_1_0) - 1.0*m.abs2(d_t200_1_2)) >= 200.0)
m.Equation(400 > m.abs2(-1.0*m.abs2(d_t200_1_0) - 1.0*m.abs2(d_t200_1_2)))
Комментарии:
1. Просто чтобы уточнить, что я еще не нашел проблему, но если посмотреть на подмножество переменных оптимизации и соответствующие ограничения, я смогу получить результаты оптимизации. вот подмножество: « «
Ответ №1:
Переключение на abs3()
помогает решить проблему. Кроме того, некоторые уравнения не нужны, потому что они всегда выполняются.
from gekko import GEKKO
m = GEKKO(remote=False)
m.options.MAX_ITER=1000
m.options.IMODE=3
d_t200_3_0 = m.Var(540, name='d_t200_3_0')
d_t200_3_2 = m.Var(180, name='d_t200_3_2')
d_t200_3_1 = m.Var(360, name='d_t200_3_1')
d_t100_3_0 = m.Var(60, name='d_t100_3_0')
d_t100_3_2 = m.Var(20, name='d_t100_3_2')
d_t100_3_1 = m.Var(40, name='d_t100_3_1')
# these equations are not needed
# all values will satisfy the equation
#m.Equation(m.abs3(d_t100_3_0) >= 0.0)
#m.Equation(m.abs3(d_t100_3_2) >= 0.0)
#m.Equation(m.abs3(d_t100_3_1) >= 0.0)
#m.Equation(m.abs3(d_t200_3_2) >= 0.0)
# reform to eliminate absolute value with simple inequalities
#m.Equation(200 > m.abs3(d_t100_3_0))
#m.Equation(200 > m.abs3(d_t100_3_2))
#m.Equation(200 > m.abs3(d_t100_3_1))
#m.Equation(200 > m.abs3(d_t200_3_2))
#m.Equation(600 > m.abs3(d_t200_3_0))
#m.Equation(400 > m.abs3(d_t200_3_1))
v = [d_t100_3_0,d_t100_3_2,d_t100_3_1,d_t200_3_2,d_t200_3_0,d_t200_3_1]
b = [200,200,200,200,600,400]
for i,vi in enumerate(v):
vi.LOWER = -b[i]
vi.UPPER = b[i]
m.Equation(m.abs3(d_t200_3_0) >= 200.0)
m.Equation(m.abs3(d_t200_3_1) >= 200.0)
m.Equation(m.abs3(-1.0*m.abs3(d_t100_3_0) - -1.0*m.abs3(d_t100_3_2)) >= 0.0)
m.Equation(200 > m.abs3(-1.0*m.abs3(d_t100_3_0) - -1.0*m.abs3(d_t100_3_2)))
m.Equation(m.abs3(-1.0*m.abs3(d_t100_3_0) - -1.0*m.abs3(d_t100_3_1)) >= 0.0)
m.Equation(200 > m.abs3(-1.0*m.abs3(d_t100_3_0) - -1.0*m.abs3(d_t100_3_1)))
m.Equation(m.abs3(-1.0*m.abs3(d_t100_3_2) - -1.0*m.abs3(d_t100_3_1)) >= 0.0)
m.Equation(200 > m.abs3(-1.0*m.abs3(d_t100_3_2) - -1.0*m.abs3(d_t100_3_1)))
m.Equation(m.abs3(-1.0*m.abs3(d_t200_3_0) - -1.0*m.abs3(d_t200_3_2)) >= 200.0)
m.Equation(400 > m.abs3(-1.0*m.abs3(d_t200_3_0) - -1.0*m.abs3(d_t200_3_2)))
m.Equation(m.abs3(-1.0*m.abs3(d_t200_3_0) - -1.0*m.abs3(d_t200_3_1)) >= 0.0)
m.Equation(200 > m.abs3(-1.0*m.abs3(d_t200_3_0) - -1.0*m.abs3(d_t200_3_1)))
m.Equation(m.abs3(-1.0*m.abs3(d_t200_3_2) - -1.0*m.abs3(d_t200_3_1)) >= 0.0)
m.Equation(200 > m.abs3(-1.0*m.abs3(d_t200_3_2) - -1.0*m.abs3(d_t200_3_1)))
m.Minimize(d_t200_3_2 - d_t100_3_2)
m.solve(disp=True)
Это дает успешное решение.
--------- APM Model Size ------------
Each time step contains
Objects : 0
Constants : 0
Variables : 172
Intermediates: 0
Connections : 0
Equations : 129
Residuals : 129
Number of state variables: 172
Number of total equations: - 128
Number of slack variables: - 90
---------------------------------------
Degrees of freedom : -46
* Warning: DOF <= 0
----------------------------------------------
Steady State Optimization with APOPT Solver
----------------------------------------------
Iter: 1 I: 0 Tm: 0.02 NLPi: 8 Dpth: 0 Lvs: 3 Obj: -2.00E 02 Gap: NaN
--Integer Solution: -2.00E 02 Lowest Leaf: -2.00E 02 Gap: 0.00E 00
Iter: 2 I: 0 Tm: 0.02 NLPi: 1 Dpth: 1 Lvs: 3 Obj: -2.00E 02 Gap: 0.00E 00
Successful solution
---------------------------------------------------
Solver : APOPT (v1.0)
Solution time : 0.0469 sec
Objective : -200.0000000002
Successful solution
---------------------------------------------------
Комментарии:
1. Спасибо! это работает. какова интуиция использования abs3 вместо abs 2.Я понимаю, что e abs2 возвращает абсолютное значение с непрерывными первой и второй производными, в то время как abs3 генерирует абсолютное значение с помощью двоичного переключателя. когда имеет смысл выбирать первое, а не второе? Спасибо!
2. Форма MPCC (2) обычно не работает так хорошо, когда существуют конкурирующие цели для переменных slack. В этих случаях я рекомендую вариант (3).
3. Спасибо, Джон! Интересно, что при изменении «реформы для устранения абсолютной величины с помощью простых неравенств» обратно на исходные неравенства решатель не может найти решение. Ты знаешь, почему? в чем разница между ними двумя?
4. Слабые переменные немного сложнее решить, чем общие неравенства. Я не уверен, почему, но, скорее всего, потому, что проблему легче решить.
5. Я заметил еще одну проблему, которая может быть связана с функциями abs. взяв ваш код из этого ответа и изменив внутренний порядок этой строки: m.Уравнение(m.abs3(-1,0*m.abs3(d_t200_3_0) — -1,0*m.abs3(d_t200_3_2)) >= 200,0), в этом порядке: m.Уравнение(m.abs3(-1,0*m.abs3(d_t200_3_2) — -1,0*m.abs3(d_t200_3_0)) >>= 200,0) и проблема теперь это неразрешимо. У вас есть идеи, почему? эти уравнения эквивалентны. В последнем случае измените внешний abs3 на abs2, и проблема снова разрешима. Я не уверен, почему?