【问题标题】:CPLEX - Optimization - Minimize production cost by period: Error: Model is non-convexCPLEX - 优化 - 按期间最小化生产成本:错误:模型是非凸的
【发布时间】:2021-02-24 06:10:30
【问题描述】:

我正在尝试使用 CPLEX 创建优化模型。

我的问题是:

我有生产产品的需求、生产能力(按机器计算)和生产成本(按机器计算)。 有些机器生产相同产品的成本和生产能力不同。

我正在尝试建立一个优化模型,在生产需求产品的同时最大限度地降低生产成本。

使用下面的代码,我得到了错误 错误:模型是非凸的

import pandas as pd
dmd =  {
        'TONS_BY_MONTH': {'PRODUCT_A': 27283.781, 'PRODUCT_B': 119.477, 'PRODUCT_C': 4651.003}
    }
df_demanda = pd.DataFrame(dmd)
df_demanda

custo = {
     'MC05': {'PRODUCT_A': 1368, 'PRODUCT_B': 1368, 'PRODUCT_C': 1368},
     'MC06': {'PRODUCT_A': 1435, 'PRODUCT_B': 1435, 'PRODUCT_C': 1427},
     'MC07': {'PRODUCT_A': 1189, 'PRODUCT_B': 1207, 'PRODUCT_C': 0},
     'MC08': {'PRODUCT_A': 1221, 'PRODUCT_B': 1209, 'PRODUCT_C': 0},
     'MC09': {'PRODUCT_A': 1905, 'PRODUCT_B': 1907, 'PRODUCT_C': 1965}
     } 

df_custo = pd.DataFrame(custo)
df_custo

produtos = ['PRODUCT_A', 'PRODUCT_B', 'PRODUCT_C']
maquinas = ['MC05','MC06','MC07','MC08','MC09']
dias = list(range(1,30))

capacidade = {
    'MC05': {'PRODUCT_A': 371, 'PRODUCT_B': 371, 'PRODUCT_C': 427},
    'MC06': {'PRODUCT_A': 396, 'PRODUCT_B': 396, 'PRODUCT_C': 435},
    'MC07': {'PRODUCT_A': 547, 'PRODUCT_B': 571, 'PRODUCT_C': 0},
    'MC08': {'PRODUCT_A': 476, 'PRODUCT_B': 497, 'PRODUCT_C': 0},
    'MC09': {'PRODUCT_A': 657, 'PRODUCT_B': 692, 'PRODUCT_C': 790}
    }
df_capacidade = pd.DataFrame(capacidade)
df_capacidade

from docplex.mp.model import Model
mdl = Model(name="DEMANDA_BY_DAY")



x  = {(i,j):
      mdl.continuous_var(name="PRODUCAO_{0}_{1}".format(i,j)) for i in produtos for j in maquinas }


DIAS  = {(d):
         mdl.binary_var(name="DIA_{0}".format(d)) for d in dias}

mdl.minimize(mdl.sum([ DIAS[d] * (df_custo.loc[i,j] * x[(i,j)]) for d in dias for i in produtos for j in maquinas]))



for i in produtos:
             mdl.add_constraint( mdl.sum([x[(i,j)] * DIAS[d] for d in DIAS  for j in maquinas ]) == df_demanda.loc[i,'TONS_BY_MONTH'])

for i in produtos:
             mdl.add_constraint(  mdl.sum([x[(i,j)] * DIAS[d]  for d in DIAS for j in maquinas ]) <= mdl.sum([df_capacidade.loc[i,s] for s in maquinas]))
        
        
mdl.solve(log_output=True)

【问题讨论】:

    标签: optimization cplex docplex


    【解决方案1】:

    您的模型包含具有 x_i * y_+i 形式的项总和的约束。 这样的约束不是凸的,基本上两个不同变量 X * Y 的任何二次乘积都是非凸的。 CPLEX 尚未解决非凸 QCP,因此您需要在没有这些产品的情况下重新表述您的问题。我看到了两种可能的方法:

    • 或者将 X 变量矩阵(顺便说一句,您可能使用 Model.continuous_var_matrix 来简化)扩展一个额外的维度数天,并且每个三元组(产品、机器、天)有一个变量

    • 还检查指标约束:指标约束动态链接二进制变量的值和线性约束。换句话说,如果在寻找解决方案的过程中,二进制变量变为 1(或 0),则强制执行某种线性约束,否则不确定是真还是假。

    比如下面的代码

    mdl.add_indicator(dias[0], x[1,2] ==0, active_value=0)
    

    表示如果二进制变量dias[0] 的最终值为0(active_value),则约束x[1,2]==0 变为真。

    请注意,这是单向的:二进制变量的值会影响约束的状态,但反过来不会。

    如果您对模型的重新表述有任何疑问,请告诉我。

    【讨论】:

    • 嗨菲利普,感谢您的宝贵时间。我明白我需要消除两个不同变量的乘积。但是我不确定如果没有这个,我怎么能建立目标和约束。我将使用您的建议将版本发布几天。我会感谢任何 cmets。
    • 尝试来自@philippe-couronne 的建议,使用额外维度消除两个不同变量的乘积数天:使用下面的代码,我得到了不可行响应,因为模型无法找到匹配项需求的价值。我这样做对吗?
    • x = {(i,j, d): mdl.continuous_var(name="PRODUCAO_{0}_{1}_{2}".format(i,j,d)) i in produtos for j in maquinas for d in dias} ## 目标:最小生产成本 x 天 mdl.minimize( mdl.sum([ (df_custo.loc[i,j] * d) * x[(i,j ,d)] for i in produtos for j in maquinas for d in dias]) ) ## CONSTRAINT: 对产品中 i in produtos 的需求: mdl.add_constraint( mdl.sum([x[(i,j,d)]对于 maquinas 中的 j 对于 dias 中的 d]) == df_demanda.loc[i,'TONS_BY_MONTH'])
    • ## 约束 2:产品中 i 的产品成本:maquinas 中的 j:dias 中的 d:mdl.add_constraint(mdl.sum([x[(i,j,d)] ]) == df_custo.loc[i,j] *d) mdl.solve(log_output=True)
    • 我建议您先以文本形式提供问题的规范,然后再讨论实现。
    猜你喜欢
    • 2016-06-16
    • 1970-01-01
    • 2016-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-24
    • 2023-03-19
    • 2023-03-06
    相关资源
    最近更新 更多