我想用二进制变量来最大化毛利率(总利润/总收入),比如产品是否会被混合,即变量将是1还是0(二进制),试图用Gekko混合整数非线性规划来求解

下面是3个产品的示例,我们希望保留任意2个产品

3个产品的变量:x1、x2和x3

利润总额=150*x1+120*x2+100*x3

总收入=200*x1+150x2+250*x3

毛利率=总利润/总收入

solution tried

m = GEKKO()
x1 = m.Var(integer=True, lb=0, ub=1)
x2 = m.Var(integer=True, lb=0, ub=1)
x3 = m.Var(integer=True, lb=0, ub=1)
m.Maximize((150*x1 + 120*x2 + 100*x3)/(200*x1 + 150*x2 + 250*x3))
m.Equation(x1 + x2 + x3 == 2)
m.options.SOLVER = 1
m.solve()

result

x1: 0
x2: 0
x3: 0
objective function: nan

things tried

i) tried with adding one more constraint with the denominator > 0, getting same solution
ii) tried with changing lb=0 to any other integer value and it is working (say lb=1, ub=2), not sure if anything particularly needs to be added for using lb=0
ii) tried absolute profit maximization (removing the denominator) and it is working fine

如有任何帮助,我们将不胜感激,并预先表示感谢

推荐答案

try 对至少一个变量使用不同于0的初始猜测:

x1 = m.Var(value=1,integer=True, lb=0, ub=1)

Gekko使用默认的起始值0.基于梯度的优化器需要计算搜索方向,而零的初始猜测导致目标函数的Inf判断.以下是完整的脚本,其中包含定义变量的简明方式:

from gekko import GEKKO
m = GEKKO()
x1,x2,x3 = m.Array(m.Var,3,value=1,integer=True,lb=0,ub=1)
m.Maximize((150*x1 + 120*x2 + 100*x3)/(200*x1 + 150*x2 + 250*x3))
m.Equation(x1 + x2 + x3 == 2)
m.options.SOLVER = 1
m.solve()

这提供了一个成功的解决方案:

 ---------------------------------------------------
 Solver         :  APOPT (v1.0)
 Solution time  :   3.579999999965366E-002 sec
 Objective      :  -0.771428571428571     
 Successful solution
 ---------------------------------------------------

Gekko将最大化问题转化为MINLP和NLP求解器标准的最小化问题,因此目标函数值是真实值的负值.使用此选项可获得0.7714的最大化目标:

print(-m.options.OBJFCNVAL)

Python相关问答推荐

Pandas 除以一列中出现的每个值

Polars:使用列值引用when / then表达中的其他列

Pandas 填充条件是另一列

Pandas 在最近的日期合并,考虑到破产

Pandas 滚动最接近的价值

Python中的嵌套Ruby哈希

如何使用表达式将字符串解压缩到Polars DataFrame中的多个列中?

PyQt5,如何使每个对象的 colored颜色 不同?'

pandas:排序多级列

Odoo 16使用NTFS使字段只读

在pandas中使用group_by,但有条件

如何并行化/加速并行numba代码?

启动带有参数的Python NTFS会导致文件路径混乱

在单次扫描中创建列表

为什么我的sundaram筛这么低效

pandas fill和bfill基于另一列中的条件

仅使用预先计算的排序获取排序元素

我可以不带视频系统的pygame,只用于游戏手柄输入吗?''

为什么在Python中00是一个有效的整数?

在round函数中使用列值