如何从字符串元素数组中高效,快速地找到有效的组合以进行员工调度?

时间:2019-06-29 20:14:22

标签: python python-3.x list combinations scheduling

我正在一个需要非常具体的计划的项目(以及为什么不使用库)。它可以工作,但是我正在尝试找到以下问题的更快解决方案:

我们有员工每周要求下班时间。他们输入一周的总可用时间(例如:8-1 M,W,R)。他们每个星期必须工作10个小时,而且每个班次必须至少连续2个小时。 (所有班次都是连续的,中间不间断)。

例如,员工1的可用性为:8-3 M,W,R,F:他可以安排在M上停留3个小时,在W上停留3个小时,在F上停留2个小时,或其他任意组合(例如4,4,2; 2,2,4等)。问题是试图找到这些组合。 现在,我将它们的可用性存储为以分号分隔的字符串(例如:8,9,10,11,12,1; 8,9,10,11,12,1; 8,9,10 ;; 8,9每天(5天)为几小时 在调度过程中,我将它们分成一个数组,这对我来说是困难的部分:

我希望能够确定这些小时的组合,其中每个组合每天至少有2个小时,而所有小时都是连续的,并且总共选择了10个小时。现在,我的解决方案是蛮力的。

我使用itertools组合。我考虑了它们的可用性,并每天将相应日期的字母附加到其上并放入一个数组中。这样的例子8,9,10,11; 8,9 ;; 8,9,10,11;变成[m8,m9,m10,m11,t8,t9,r8,r9,r10,r11]

然后,我使用itertools组合查看此数组的所有组合,并具有读取以下内容的功能:每天是否有连续的小时,至少2小时的班次以及总共10小时(或其他数字)小时,这可能会改变)。

这是一个非常缓慢的过程,因为某人的可用性为8-5 M-F,他们可以有很多可行和不可行的组合。 (原因是我需要进行全部测试,因为我们有100多名员工担任相似的角色,并且如果担任一个角色,则此时无法安排另一名员工)

我现在如何做的例子。


    # let availability be the string of availability 
    availability = "8,9,10,11;8,9;;8,9,10,11;"
    poss_times = availability.split(";")
    # where I put into one array with each day letter in front
    sched=[]
    sched.extend(["m" + day for day in list(filter(None,poss_times[0].split(",")))])
    sched.extend(["t" + day for day in list(filter(None,poss_times[1].split(",")))])
    sched.extend(["w" + day for day in list(filter(None,poss_times[2].split(",")))])
    sched.extend(["r" + day for day in list(filter(None,poss_times[3].split(",")))])
    sched.extend(["f" + day for day in list(filter(None,poss_times[4].split(",")))])
    sched.extend(["s" + day for day in list(filter(None,poss_times[5].split(",")))])
    sched.extend(["u" + day for day in list(filter(None,poss_times[6].split(",")))])

    for poss_combination in itertools.combinations(sched, 10):
        # check if the combination fulfills the requirements, and if so continue to see if it is possible to schedule that employee

我希望可以有一个更快,更优雅的解决方案来加速这一过程。感谢您的任何帮助。

1 个答案:

答案 0 :(得分:10)

我认为这是著名的Nurse scheduling problem的一个例子。这个问题是NP难题,即要找到最佳解决方案,您必须创建所有可能的分配组合,然后选择最合适的分配。由于这具有指数级的时间复杂度,因此仅适用于小问题,而您的问题显然已经太大了。
如果您只想找到一个合理的(不是最佳的)解决方案,则可以应用通用随机算法,如上面提到的Wiki帖子中引用的那样,例如随机优化,遗传算法和模拟退火。但是这类方法通常需要较长的计算时间。
无论如何,here是通过遗传算法解决护士调度问题的示例。也许您可以尝试将其应用于您的问题,并检查它是否可以改善您的情况。