如何利用双重循环生成两个枚举类型间的关联关系
解决枚举与班次的关联映射问题
可以通过双重循环+区间/序号计算来实现班次到周次的关联,以下是两种基于MiniZinc语法的实现方案:
方案一:基于区间判断的双重循环
enum weeks = {w1,w2,w3,w4}; array[weeks] of 1..10 : weekShiftQty = [4,5,7,4]; % total shift = 20 enum shift = _(1..20); % 预计算每个周的起始班次位置 array[weeks] of int: weekStart = let { array[weeks] of int: cumulative = [sum(weekShiftQty[w'] | w' in weeks where w' < w) + 1 | w in weeks] } in cumulative; % 生成班次-周次映射 array[shift] of weeks : shiftWeek = [ w | w in weeks, s in shift where s >= weekStart[w] /\ s <= weekStart[w] + weekShiftQty[w] - 1 ];
逻辑说明
- 先计算每个周的起始班次:通过累积求和前面所有周的班次数量,得到当前周的第一个班次序号(比如w2的起始是
4+1=5) - 双重循环遍历:外层循环每个周
w,内层循环所有班次s,判断s是否落在当前周的班次区间内,符合条件的s直接关联到周次w
方案二:基于序号生成的双重循环
enum weeks = {w1,w2,w3,w4}; array[weeks] of 1..10 : weekShiftQty = [4,5,7,4]; % total shift = 20 enum shift = _(1..20); % 生成班次-周次映射 array[shift] of weeks : shiftWeek = [ w | w in weeks, idx in 1..weekShiftQty[w], let { int: prevTotal = sum(weekShiftQty[w'] | w' in weeks where w' < w); int: s = prevTotal + idx; } in s in shift ];
逻辑说明
- 外层循环每个周
w,中层循环该周的每个班次序号idx(从1到该周的班次总数) - 计算当前班次的全局序号
s:前面所有周的班次总和加上当前的idx - 直接将该全局序号
s对应的shiftWeek值设为当前周w
两种方案都能实现你需要的映射效果,可根据代码习惯选择。
内容的提问来源于stack exchange,提问作者qin cubism
相关产品推荐
相关产品推荐

