DOcplex中如何获取目标函数的各项系数
问题原因
你遇到的系数全为1的现象是DOcplex的正常处理逻辑,不是代码报错,核心原因有两点:
- 调用
model.abs()生成绝对值表达式时,DOcplex不会直接把绝对值内的线性表达式嵌入目标函数,而是自动创建一批以_abs开头的辅助变量,同时在模型中添加对应的线性化约束来等价表示绝对值关系。最终生成的目标函数本质是这90个辅助变量的求和,每个辅助变量的系数自然是1,直接遍历obj对象只能拿到这些辅助变量的系数,拿不到绝对值内部原始决策变量的系数。 - 你现有代码存在两处不严谨的写法,虽然暂时没影响目标构建,但容易埋隐患:
- 初始化
expraR时用了[[0] * len(vars)] * rows,这是Python列表浅拷贝写法,后续修改列表元素时容易出现引用联动问题。 - 内层遍历矩阵列的循环用了
range(N),和你之前定义的总列数变量colstot不统一,当N和实际矩阵列数不一致时会出现索引越界或者漏算变量的问题。
- 初始化
正确提取系数的方案
你在构建过程中已经把90个绝对值表达式全部存在了expraR列表中,不需要从最终的obj对象反推系数,直接遍历expraR每个元素,取出绝对值包裹的内部线性表达式即可提取原始系数,参考代码如下:
# 按行存储每个绝对值表达式的系数,结构:{行索引i: {变量对象: 系数值, 'constant': 常数项}} row_coefs = {} for row_idx in range(rows): abs_expr = expraR[row_idx] # 获取绝对值内部包裹的原始线性表达式,即 expra - floatnumber 部分 inner_expr = abs_expr.expr coef_map = {} # 先提取表达式的常数项(也就是你传入的floatnumber偏移量) coef_map['constant'] = inner_expr.constant # 遍历内部表达式关联的所有决策变量,提取对应系数 for v in inner_expr.iter_variables(): coef_map[v] = inner_expr.get_coef(v) row_coefs[row_idx] = coef_map
如果需要校验构建的目标函数是否符合预期,可以调用model.export_as_lp("check_model.lp")导出标准LP格式的模型文件,打开后可以直接看到完整的目标函数、自动生成的辅助变量和绝对值线性化约束,比直接打印obj对象的输出清晰很多。
如果你没有提前保存
expraR列表,也可以通过遍历模型自动生成的约束反推每个_abs辅助变量对应的原始表达式,但这个方法需要遍历全量约束做匹配,效率很低,非必要不使用。
内容的提问来源于stack exchange,提问作者Roland
相关产品推荐
相关产品推荐

