CPLEX作业车间调度如何绑定operazioni元组与set_operazioni
CPLEX作业车间调度场景建模与元组绑定方案
元组结构修正与绑定逻辑
你原来的set_operazioni字段定义为int类型无法存储多个工序的关联关系,需要调整为工序ID的集合类型,通过工序ID作为中间键实现两个元组的绑定,修正后的OPL代码如下:
// 1. 定义全局工序索引与工序属性元组 int total_ops = ...; // 所有作业的总工序数量 range OpRange = 1..total_ops; tuple operazioni { int macchine; // 工序所需机器类型ID int processamento; // 工序加工时长 int operatori; // 工序所需操作人员数量 } // 全局工序属性数组,用工序ID作为索引 operazioni op_attr[OpRange] = ...; // 2. 修正作业元组定义 tuple job { int release_date; // 作业释放时间 int due_date; // 作业截止时间 {int} set_operazioni; // 该作业包含的工序ID有序集合,按工序执行顺序排列 } int total_jobs = ...; // 总作业数量 range JobRange = 1..total_jobs; // 全局作业属性数组,用作业ID作为索引 job job_attr[JobRange] = ...;
绑定逻辑非常直接:作业元组的set_operazioni字段存储属于该作业的所有工序ID,需要获取某作业下的工序属性时,遍历该集合内的ID,直接从op_attr[工序ID]中读取对应属性即可。
核心约束定义示例
基于上述索引结构,你可以快速实现各类调度约束:
- 作业释放时间约束:作业第一道工序的开始时间不早于作业释放时间
// 定义工序的时间区间决策变量,长度等于加工时长 dvar interval op_interval[o in OpRange] size op_attr[o].processamento; forall(j in JobRange) { startOf(op_interval[first(job_attr[j].set_operazioni)]) >= job_attr[j].release_date; }
- 工序顺序约束:同一作业下的工序按顺序依次执行
forall(j in JobRange, o in job_attr[j].set_operazioni: o != last(job_attr[j].set_operazioni)) { endOf(op_interval[o]) <= startOf(op_interval[next(job_attr[j].set_operazioni, o)]); }
- 机器资源约束:同一台机器上的工序不能重叠加工
int total_machines = ...; range MachineRange = 1..total_machines; forall(m in MachineRange) { noOverlap(all(o in OpRange: op_attr[o].macchine == m) op_interval[o]); }
- 人员资源约束:同一时间所有在加工序的人员需求总和不超过总可用人数
int total_operators = ...; sum(o in OpRange) pulse(op_interval[o], op_attr[o].operatori) <= total_operators;
- 作业截止时间约束:作业最后一道工序的完成时间不晚于作业截止时间
forall(j in JobRange) { endOf(op_interval[last(job_attr[j].set_operazioni)]) <= job_attr[j].due_date; }
数据赋值参考
你可以在dat文件中按如下格式给上述结构赋值:
total_ops = 4; op_attr = [ <1, 5, 2>, <2, 3, 1>, <1, 4, 1>, <2, 6, 2> ]; total_jobs = 2; job_attr = [ <0, 15, {1,2}>, <2, 20, {3,4}> ];
内容的提问来源于stack exchange,提问作者Francesca
相关产品推荐
相关产品推荐

