GEKKO: избегайте использования первого значения MV при прогнозировании

#python #mathematical-optimization #gekko

#python #математическая оптимизация #gekko

Вопрос:

Я использую GEKKO в режиме MPC (решатель APOPT). Я определяю свою управляемую переменную следующим образом:

 u = m.MV(lb=0, ub=1, integer=True)
u.STATUS = 1 
  

Я намеренно не использую:

 u = m.MV(value=1 ,lb=0, ub=1, integer=True)
u.STATUS = 1 
  

Или:

 u = m.MV(value=0 ,lb=0, ub=1, integer=True)
u.STATUS = 1 
  

потому что я не знаю, каким будет следующее решение, и я хочу, чтобы мой оптимизатор определил его. По-видимому, когда вы не определяете значение u , GEKKO присваивает ему значение по умолчанию 0 .

Проблема в том, что это значение u используется в моих прогнозах модели, а также в других вычислениях, что нежелательно (см. Рисунок). Как вы можете видеть, новое значение u — это значение, означающее холодильник в моем случае. Но прогноз температуры начинается со значения по умолчанию u , которое равно 0. Следовательно, температура в холодильнике повышается на следующем временном шаге и начинает падать только на следующем временном шаге. У меня есть возможность определить значение как предыдущий результат u , но и это было бы неправильно на 100%.

Как я могу этого избежать? Есть ли какие-либо другие варианты, чтобы мое предсказание начиналось правильно?

Я ценю помощь 🙂

контроль температуры холодильника

Ответ №1:

Существует возможность вычисления начального условия для любого параметра или переменной, включая MV:

 m.free_initial(u)
  

Вот простое приложение, которое показывает разницу, которую эта функция вносит в решение.

С помощью free_initial(mv)

Свободное начальное условие

 import numpy as np
from gekko import GEKKO
m = GEKKO(remote=False)
m.time = np.linspace(0,10,11)
mv = m.MV(value=0,lb=0,ub=1,integer=True);    mv.STATUS=1
cv = m.CV(value=1); cv.SPHI=0.6; cv.SPLO=0.4; cv.STATUS=1
m.Equation(3*cv.dt() (cv-1)==-0.8*mv)
m.free_initial(mv)
m.options.IMODE=6; m.options.CV_TYPE=1
m.options.NODES=3; m.options.MV_TYPE=0
m.options.SOLVER =1
m.solve(disp=False)

import matplotlib.pyplot as plt
plt.step(m.time,mv,'r.',markersize=5,where='post',label='MV')
plt.plot(m.time,cv,'b:',label='CV')
plt.plot([0,10],[0.6,0.6],'k:',label='SP Range')
plt.plot([0,10],[0.4,0.4],'k:')
plt.legend(); plt.xlabel('Time')
plt.show()
  

Без free_initial(mv)

С фиксированным начальным условием

Комментарии:

1. Большое спасибо. Это именно то, что я искал.

2. Почему здесь используется «cv.STATUS = 1»?

3. СТАТУС указывает, следует ли включать CV в целевую функцию. Это то, как включить или выключить CV. apmonitor.com/do/index.php/Main/ControllerObjective