Я пытаюсь решить проблему оптимизации с помощью решателя 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()
Любая помощь в определении проблемы будет высоко оценена. Большое спасибо.
Оптимизатор пытается максимизировать целевую функцию, приближая (foodvars[i][0]+foodvars[i][1]-foodvars[i][2])
к нулю. Это дает бесконечную целевую функцию, которая приводит к результату NaN
. Два предложения:
(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
---------------------------------------------------