Julia调用Gurobi添加含重复索引变量报错如何解决
问题描述
在Julia环境中搭配Gurobi求解器构建线性规划模型时,若传入包含重复元素的列表作为索引添加变量,会触发运行错误。
触发错误的变量定义代码如下:
@variable(model, materialResources[[1, 1]])
代码中使用的模型对象model通过以下命令初始化:
model = Model(with_optimizer(Gurobi.Optimizer, OutputFlag=0));
运行后程序返回的错误信息为:
ERROR: LoadError: Repeated index 1. Index sets must have unique elements.
需要实现的目标:为索引包含重复元素的materialResources变量向量添加对应条目。
解决方案
JuMP框架对变量索引集合有强制约束:所有索引元素必须唯一,不支持直接传入含重复值的列表作为变量索引,这个设计是为了从根源上避免索引指向歧义。要实现重复索引的变量定义,可参考以下两种可行方案:
- 方案一:用位置索引做中转,建立原索引到变量的映射
先按列表长度生成连续的唯一位置索引完成变量定义,再手动建立原重复索引和对应变量的绑定关系,既符合框架的索引规则,也能保留原重复索引的使用逻辑。示例代码如下:
后续建模过程中,需要调用原索引为1的变量时,直接取# 原始带重复值的索引列表 raw_idx = [1, 1] # 先用唯一的位置索引定义变量,绕过索引唯一性校验 @variable(model, materialResources[pos=1:length(raw_idx)]) # 构建映射字典,支持单个索引对应多个变量 idx_to_vars = Dict{Int, Vector{VariableRef}}() for (pos, real_idx) in enumerate(raw_idx) if !haskey(idx_to_vars, real_idx) idx_to_vars[real_idx] = [] end push!(idx_to_vars[real_idx], materialResources[pos]) endidx_to_vars[1]即可拿到对应两个变量,和直接用重复索引定义的使用效果没有区别。 - 方案二:按业务逻辑聚合同索引变量
如果重复索引只是业务分类标识,不需要单独区分同索引下的不同变量,可直接调整建模逻辑,对同索引对应的变量做合并聚合,从源头消除重复索引即可。
注意:不建议通过修改JuMP底层源码的方式跳过索引唯一性校验,这种操作会破坏模型内部的索引一致性,大概率会引发后续变量引用、约束添加时的隐性bug。
内容的提问来源于stack exchange,提问作者graphtheory123
相关产品推荐
相关产品推荐

