Получение значения NAN для успешно решенной задачи оптимизации с помощью GEKKO на Python

Я пытаюсь решить проблему оптимизации с помощью решателя GEKKO на Python, но продолжаю получать целевое значение NAN, даже если проблема успешно решена. Кажется, что-то мне не хватает, но я не смог определить, что это такое. Я пытался убедиться, что ничего не делится на ноль, но, насколько я могу судить, это не так. Код у меня есть:

class FoodItem(): 
    def__init__(self,name,wastefactor,lossfactor,prioritylevel):
            self.name = name 
            self.wastefactor = wastefactor
            self.lossfactor = lossfactor 
            self.prioritylevel = prioritylevel 

wheatflour = FoodItem(name='WheatFlour',wastefactor= 0.15, lossfactor= 0.15, prioritylevel=1)

tomatoes = FoodItem(name='Tomatoes', wastefactor=0.15, lossfactor=0.15, prioritylevel=2)

oranges = FoodItem(name='Oranges', wastefactor=0.15, lossfactor=0.15, prioritylevel=2)

beans = FoodItem(name='Beans', wastefactor=0.15, lossfactor=0.15, prioritylevel=2)

beef = FoodItem(name='Beef',wastefactor=0.15, lossfactor=0.15, prioritylevel=1)

milk = FoodItem(name='Milk',wastefactor=0.15,lossfactor=0.15, prioritylevel=1)

fooditems = [wheatflour, tomatoes, oranges, beans, beef, milk]

m = GEKKO(remote=False)

foodvars = m.Array(m.Var,(len(fooditems),5))
fooditems_params = m.Array(m.Param,(len(fooditems),4))

def fillparametersFood(i,j):
    fooditems_params[j][0] = i.name
    fooditems_params[j][1] = i.wastefactor
    fooditems_params[j][2] = i.lossfactor
    fooditems_params[j][3] = i.prioritylevel
    return

j=0
for i in fooditems:
    fillparametersFood(i,j)
    j +=1

pop=1000
for i in range(len(foodvars)):    
    m.Equation(foodvars[i][0]+foodvars[i][1]-foodvars[i][2]==foodvars[i][3])
   
    m.Equation(foodvars[i][3]==(foodvars[i][4]*pop*365.25)/(10**6*(1-fooditems_params[i][1])*(1-fooditems_params[i][2])))


ssr_priority=0 

for i in range(len(foodvars)):
    ssr_priority += (foodvars[i][0]/(foodvars[i][0]+foodvars[i][1]-foodvars[i][2]))/fooditems_params[i][3]
    
m.Maximize(ssr_priority)

m.solve()

Любая помощь в определении проблемы будет высоко оценена. Большое спасибо.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
27
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Оптимизатор пытается максимизировать целевую функцию, приближая (foodvars[i][0]+foodvars[i][1]-foodvars[i][2]) к нулю. Это дает бесконечную целевую функцию, которая приводит к результату NaN. Два предложения:

  • Умножьте обе части уравнения 2 на (10**6*(1-fooditems_params[i][1])*(1-fooditems_params[i][2])), чтобы удалить потенциальное деление на ноль.
  • Установите ограничения на foodvars, чтобы предотвратить деление на ноль в цели.
from gekko import GEKKO
m = GEKKO(remote=False)

class FoodItem(): 
    def __init__(self,name,wastefactor,lossfactor,prioritylevel):
            self.name = name 
            self.wastefactor = wastefactor
            self.lossfactor = lossfactor 
            self.prioritylevel = prioritylevel 

wheatflour = FoodItem(name='WheatFlour',wastefactor= 0.15, lossfactor= 0.15, prioritylevel=1)

tomatoes = FoodItem(name='Tomatoes', wastefactor=0.15, lossfactor=0.15, prioritylevel=2)

oranges = FoodItem(name='Oranges', wastefactor=0.15, lossfactor=0.15, prioritylevel=2)

beans = FoodItem(name='Beans', wastefactor=0.15, lossfactor=0.15, prioritylevel=2)

beef = FoodItem(name='Beef',wastefactor=0.15, lossfactor=0.15, prioritylevel=1)

milk = FoodItem(name='Milk',wastefactor=0.15,lossfactor=0.15, prioritylevel=1)

fooditems = [wheatflour, tomatoes, oranges, beans, beef, milk]

m = GEKKO(remote=False)

foodvars = m.Array(m.Var,(len(fooditems),5),lb=1,ub=100)
fooditems_params = m.Array(m.Param,(len(fooditems),4))

def fillparametersFood(i,j):
    fooditems_params[j][0] = i.name
    fooditems_params[j][1] = i.wastefactor
    fooditems_params[j][2] = i.lossfactor
    fooditems_params[j][3] = i.prioritylevel
    return

j=0
for i in fooditems:
    fillparametersFood(i,j)
    j +=1

pop=1000
for i in range(len(foodvars)):    
    m.Equation(foodvars[i][0]+foodvars[i][1]-foodvars[i][2]\
    ==foodvars[i][3])
   
    m.Equation((10**6*(1-fooditems_params[i][1])*(1-fooditems_params[i][2]))*foodvars[i][3]==(foodvars[i][4]*pop*365.25))


ssr_priority=0 

for i in range(len(foodvars)):
    ssr_priority += (foodvars[i][0]/(foodvars[i][0]+foodvars[i][1]-foodvars[i][2]))/fooditems_params[i][3]
    
m.Maximize(ssr_priority)

m.solve()

Это дает успешное решение с целью 450. Gekko преобразует задачу максимизации в задачу минимизации, умножая на -1, чтобы цель выглядела отрицательной.

 ----------------------------------------------
 Steady State Optimization with APOPT Solver
 ----------------------------------------------
 
 Iter    Objective  Convergence
    0 -6.37500E+00  6.81400E-01
    1 -1.31250E+01  1.37806E-10
    2 -3.19432E+01  0.00000E+00
    3 -2.20125E+02  0.00000E+00
    4 -3.49596E+02  0.00000E+00
    5 -3.50465E+02  0.00000E+00
    6 -3.59156E+02  0.00000E+00
    7 -4.46063E+02  0.00000E+00
    8 -4.50000E+02  0.00000E+00
 
 Iter    Objective  Convergence
   10 -4.50000E+02  0.00000E+00
 Successful solution
 
 ---------------------------------------------------
 Solver         :  IPOPT (v3.12)
 Solution time  :   9.600000019418076E-003 sec
 Objective      :   -450.000000000000     
 Successful solution
 ---------------------------------------------------

Другие вопросы по теме