简体   繁体   English

在 GEKKO 中使用带有 integer = True 的变量时的奇怪优化器行为

[英]Strange optimizer behavior when using variables with integer = True in GEKKO

I'm trying to use GEKKO to solve some kind of the shop stock balance problem - the main goal is to determine which arrival (x) of goods per day will provide sufficient stock (Inv) in the store, taking into account sales (s) and demand (d).我正在尝试使用 GEKKO 来解决某种商店库存平衡问题 - 主要目标是确定每天哪些货物到达 (x) 将在商店中提供足够的库存 (Inv),同时考虑到销售额 (s ) 和需求 (d)。

So, my objective function is:所以,我的目标 function 是:

客观的

With restrictions:有限制:

约束

See them in code below:在下面的代码中查看它们:

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)])

I'm using APOPT (v1.0) and, as you can see, variables with integer=True are used for balancies and arrivals.我正在使用 APOPT (v1.0),如您所见, integer=True的变量用于余额和到达。 But when I look at the values of balancies y[i] in output, I can see, that for some days (when the deficit is expected), optimizer somehow selected float values for integer variable, for example:但是当我查看 output 中的余额y[i]的值时,我可以看到,在某些日子里(当预期出现赤字时),优化器以某种方式为 integer 变量选择了浮点值,例如:

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

I expected, that type of variable will be taken into account when manipulating with variable.我预计,在使用变量进行操作时会考虑到这种类型的变量。 So, how is it possible?那么,怎么可能呢? Have I miss some variables parameters, model options?我是否错过了一些变量参数,model 选项?

There is an option in APOPT that gives a tolerance for what is considered an integer value. APPT 中有一个选项可以为 integer 值提供容差。 It is the amount that a candidate solution variable can deviate from an integer solution and still be considered an integer and has a default value of 1.0e-2 .这是候选解变量可以偏离 integer 解但仍被视为 integer 的量,默认值为1.0e-2

minlp_integer_tol 1.0e-2

This means that it can deviate up to 0.01 away from an integer value and still be considered an integer.这意味着它可以偏离 integer 值最多 0.01,但仍被视为 integer。 You can adjust this and other solver options in Gekko as shown in the documentation .您可以在 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']

If you set minlp_integer_tol 0 it may increase the solution time but will give you exact integer solutions.如果您将minlp_integer_tol 0 ,它可能会增加求解时间,但会为您提供准确的 integer 解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM