问题描述
我正在尝试使用 GEKKO 来解决某种商店库存平衡问题 - 主要目标是确定每天到达 (x) 次的商品将在商店中提供足够的库存 (Inv),同时考虑销售(s)和需求(d)。
所以,我的目标函数是:
有限制:
在下面的代码中查看它们:
from gekko import GEKKO
m = GEKKO(remote=False)
n = 70 # Number of days,iterations
a = m.Param(144.846147/n) # coefficient for balance valuation
b = m.Param(417.33) # coefficient for deficit valuation
zero = m.Param(0.001)
receptions = [24,31,38,45,52,59,66] # Days when arrival expected
sales_coef = m.Param([0,1,0],integer=True) # Sales
demand_coef = m.Param([0.218,0.218,0.206,0.251,0.21,0.21],integer=False) # Demand
x = m.Array(m.MV,n,lb=0,integer=True) # Arrival
y = m.Array(m.MV,integer=True) # Balance
# Restrictions
for i in range(n):
if i + 1 in receptions: # if arrival expected
m.Equation(x[i] >= 0)
x[i].STATUS = 1
else:
x[i].VALUE = 0 # In other days arrival fixed to 0
x[i].STATUS = 0
if i > 0: # Restrictions for balance,except first day with initial value
y[i] = m.Intermediate(m.max2(y[i - 1] - sales_coef[i - 1],zero) + x[i])
else:
y[i].VALUE = 5 # Initial balance
y[i].STATUS = 0
m.Obj(a * m.sum(y) + b * m.sum([m.max2(demand_coef[i] - y[i],zero) for i in range(n)]))
m.options.soLVER = 1
m.options.IMODE = 5
m.options.MAX_ITER = 1000
m.solve(disp=True)
print([(i + 1,yi) for i,yi in enumerate(y)])
我正在使用 APOPT (v1.0),如您所见,带有 integer=True
的变量用于余额和到达。
但是,当我查看输出中余额 y[i]
的值时,我可以看到,在某些日子(预计出现赤字时),优化器以某种方式为整数变量选择了浮点值,例如:
(24,[1.0]),(25,[0.2059999]),(26,[0.2059999])
我预计,在使用变量进行操作时会考虑到该类型的变量。 那么,怎么可能呢?我是否错过了一些变量参数、模型选项?
解决方法
有一个 option in APOPT 给出被认为是整数值的容差。它是候选解变量可以偏离整数解但仍被视为整数且默认值为 1.0e-2
的量。
minlp_integer_tol 1.0e-2
这意味着它可以偏离整数值最多 0.01 并且仍然被认为是整数。您可以将 Gekko 中的此求解器选项和其他求解器选项调整为 shown in the documentation。
m.solver_options = ['minlp_integer_tol 1.0e-2',\
'minlp_gap_tol 1.0e-2',\
'minlp_maximum_iterations 10000',\
'minlp_max_iter_with_int_sol 500']
如果您设置 minlp_integer_tol 0
,它可能会增加求解时间,但会为您提供精确的整数解。