首页 > 解决方案 > CPLEX - 优化 - 按期间最小化生产成本:错误:模型是非凸的

问题描述


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

我的问题是:

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

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

使用下面的代码,我收到错误 Error: Model is non-convex

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)

标签: optimizationcplexdocplex

解决方案


您的模型包含具有 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 (the active_value),则约束为x[1,2]==0真。

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

如果您对模型的重新制定有疑问,请告诉我。


推荐阅读