首页 > 解决方案 > 在 GEKKO 中使用整数 = True 的变量时出现奇怪的优化器行为

问题描述

我正在尝试使用 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)])

我正在使用 APPT (v1.0),如您所见,变量integer=True用于余额和到达。但是当我查看y[i]输出中的平衡值时,我可以看到,在某些日子里(当预期出现赤字时),优化器以某种方式为整数变量选择了浮点值,例如:

(24, [1.0]), (25, [0.2059999]), (26, [0.2059999])

我预计,在使用变量进行操作时会考虑到这种类型的变量。那么,怎么可能呢?我是否错过了一些变量参数、模型选项?

标签: pythonnonlinear-optimizationgekko

解决方案


APPT 中有一个选项可以对被认为是整数值的值提供容差。它是候选解变量可以偏离整数解但仍被视为整数且默认值为 的量1.0e-2

minlp_integer_tol 1.0e-2

这意味着它可以偏离整数值最多 0.01,但仍被视为整数。您可以在 Gekko 中调整此和其他求解器选项,如文档中所示

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它可能会增加求解时间,但会给你精确的整数解。


推荐阅读