Python 在GEKKO中使用integer=True的变量时出现奇怪的优化器行为

Python 在GEKKO中使用integer=True的变量时出现奇怪的优化器行为,python,nonlinear-optimization,gekko,Python,Nonlinear Optimization,Gekko,我试图用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 valu

我试图用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, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,
                      0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0,
                      0, 1, 0, 0], integer=True)  # Sales
demand_coef = m.Param([0.218, 0.218, 0.218, 0.218, 0.218, 0.218, 0.218, 0.218, 0.218, 0.218, 0.218, 0.218, 0.218, 0.218,
                       0.218, 0.218, 0.218, 0.218, 0.218, 0.218, 0.218, 0.206, 0.206, 0.206, 0.206, 0.206, 0.206, 0.206,
                       0.206, 0.206, 0.206, 0.206, 0.206, 0.206, 0.206, 0.206, 0.251, 0.251, 0.251, 0.251, 0.251, 0.251,
                       0.251, 0.251, 0.251, 0.251, 0.251, 0.251, 0.251, 0.251, 0.251, 0.251, 0.21, 0.21, 0.21, 0.21,
                       0.21, 0.21, 0.21, 0.21, 0.21, 0.21, 0.21, 0.21, 0.21, 0.21, 0.21, 0.21, 0.21, 0.21], integer=False)  # Demand

x = m.Array(m.MV, n, lb=0, integer=True)  # Arrival
y = m.Array(m.MV, n, lb=0, 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])
我预计,在使用变量进行操作时,将考虑该类型的变量。 那么,这怎么可能呢?我是否遗漏了一些变量、参数、模型选项?

有一个变量,它给出了被视为整数值的公差。它是指候选解决方案变量可以偏离整数解决方案且仍被视为整数的量,其默认值为
1.0e-2

minlp_integer_tol 1.0e-2
这意味着它可以偏离整数值0.01,并且仍然被视为整数。您可以根据需要在Gekko中调整此解算器选项和其他解算器选项

m.solver\u options=['minlp\u integer\u tol 1.0e-2'\
“minlp_gap_tol 1.0e-2”\
“最小迭代次数最大迭代次数10000次”\
“minlp_max_iter_与_int_sol 500”]

如果您将
minlp\u integer\u tol设置为0
可能会增加求解时间,但会给出精确的整数解。

谢谢您的回复!我已经读过这个解算器选项,并在其中一个版本中使用了它,但问题似乎在另一个地方。这里:
y[i]=m.mediate(m.max2(y[i-1]-sales_coef[i-1],zero)+x[i])
i分配给integer MV Intermediate expression,之后它就不是整数了,对吧?如果得到的是非最佳结果,请尝试使用
max3
(二进制开关形式)而不是
max2
(MPCC形式)。您的
y[i]
表达式仍然应该是整数,因为所有的项都是整数,没有除法,只有加法和减法。y[i]也用于目标函数中,其值与需求进行比较:
[m.max2(需求系数[i]-y[i],零)用于范围(n)]内的i
,需求可以是(在本例中始终是)一个浮点。所以优化器似乎将其考虑在内,并设置一些y[i]=需求值