我正试图解决一个日程安排问题。作为输入,我有工人数量和轮班数
之后,我放置所有约束,包括:
然后我尝试最大化给定的移位序列
例如,我可以接收序列:123BBBB。这意味着我必须最大化每个工作人员在其日历中的此序列外观
我为每个工人计算全年(比如说365天)的日程安排。我试着对每个可能的序列进行布尔运算:所以对于范围(1,长度(序列)),范围(2,长度(序列))中的天数,等等
然后我加上一个约束,从今天到len(sequence)
的移位之和是len(sequence)
。因此,我也将轮班表示为bools(shifts[(w, d, s)]
),这意味着shifts[(0, 3, 0)]
第3天的工人1在轮班1工作
给定序列的约束仅在为该序列创建的布尔为真时才有效。然后我尝试最大化为每个序列创建的布尔值之和
问题:我试着运行这个,运行了8个小时后,我放弃了。它给我找到了大约62个序列,但却花了太长时间才停下来或找到另一个。我的问题是:如何更有效地做到这一点
守则:
shift_requests = []
requiredShift = "111222333BBBBBB"
appearences_for_1 = 0
appearences_for_2 = 0
appearences_for_3 = 0
appearences_for_L = 0
for i in requiredShift:
if i == '1':
appearences_for_1 += 1
for i in requiredShift:
if i == '2':
appearences_for_2 += 1
for i in requiredShift:
if i == '3':
appearences_for_3 += 1
for i in requiredShift:
if i == 'B':
appearences_for_B += 1
print(appearences_for_1, appearences_for_2, appearences_for_3, appearences_for_B)
for w in range(worker):
shift_requests.append([])
poz = 0
dayz = 1
while dayz + len(requiredShift) <= 365:
shift_requests[w].append(model.NewBoolVar(f'{w}_{dayz}_{dayz + len(requiredShift)}'))
first_range = dayz + appearences_for_1
second_range = first_range + appearences_for_2
third_range = second_range + appearences_for_3
fourth_range = third_range + appearences_for_B
#shift = 5 ( 0 is shift 1, 1 is shift 2, 2 is shift 3, 3 is break, 4 is holiday)
model.Add(sum(shifts[(w, d, shift - 2 - 3)] for d in range(dayz, first_range))+
sum(shifts[(w, d, shift - 2 - 2)] for d in range(first_range, second_range))+
sum(shifts[(w, d, shift - 2 - 1)] for d in range(second_range, third_range))+
sum(shifts[(w, d, shift - 2)] for d in range(third_range, fourth_range)) == len(requiredShift))\
.OnlyEnforceIf(shift_requests[w][poz])
dayz += 1
poz += 1
model.Maximize(sum(shift_requests[w][poz] for w in range(worker) for poz in range(len(shift_requests[w]))))
这是我从你说的话中理解的,我想我没有正确理解,因为这是我以前做的。我有5个工人,每天都试着按照每个工人的顺序开始工作。很可能我不明白你想说什么,因为在8核上解决这个问题可能需要一天以上的时间。也很抱歉将此作为answear发布,但我不知道如何在评论部分发布代码。注:我所说的工人是指在我的算法中轮班工作的人,而不是处理器核心
对于每个开始日期
d
,可以有一个布尔变量s_d
假设模式为“123BBB”,您可以
s_d
意味着序列从此日期开始:然后最大化正
s_d
的数量相关问题 更多 >
编程相关推荐