Gurobi中quicksum结合循环构建约束时内层t循环未执行问题
Gurobi约束生成异常:仅遍历Task维度,未生成Time维度约束
问题描述
期望生成144×96(任务数×时间步长)个约束,但实际仅生成与任务数量对应的约束,代码中Taskexecution约束的时间维度t循环未生效。
核心代码
time = list() for x in range(0,int(num_t)): time.append(x) res_list = [res for cat, cat_res in res_cat2idx.items() for res in cat_res] task_list=[task for cat, cat_task in tasks.items() for task in cat_task] Resources=steel.addVars(res_list,time,vtype=GRB.INTEGER,name="Resources") Tasks=steel.addVars(task_list,time,vtype= GRB.BINARY,name="Tasks") Taskexecution=steel.addConstrs((gp.quicksum(Tasks[task,t] for t in time )==1 for task in heat2tasks), name="Taskexecution[%s,%d]"%(task,t))
原因分析
- 约束遍历维度错误:当前约束推导式仅外层遍历
task,t仅作为quicksum的求和范围,并非约束的独立遍历维度。这导致每个任务仅生成1个约束(要求任务在所有时间步的执行次数之和为1),而非每个任务+每个时间步生成1个约束。 - 约束名称变量无效:
name参数中的t未在约束的循环上下文定义,属于无效引用,会导致逻辑错误。
解决方法
若需生成任务×时间步维度的约束,需将t加入约束的推导式循环,构建双层遍历结构。示例如下(可根据实际业务需求修改约束表达式):
# 修改约束生成逻辑,加入时间维度的遍历 Taskexecution = steel.addConstrs( # 替换为你的实际约束条件,比如限制某任务在某时间步的执行状态 (Tasks[task, t] == 0 for task in heat2tasks for t in time), name="Taskexecution[%s,%d]" )
若你的原始需求是每个任务必须在所有时间步中执行恰好一次,则当前代码的约束数量是符合逻辑的,只需修正name参数的错误:
# 修正约束名称的变量引用问题 Taskexecution=steel.addConstrs((gp.quicksum(Tasks[task,t] for t in time )==1 for task in heat2tasks), name="Taskexecution[%s]"%(task))
内容的提问来源于stack exchange,提问作者Margi Shah
相关产品推荐
相关产品推荐

