哪种算法用于分配移位(离散优化问题)

时间:2009-02-21 20:14:29

标签: algorithm discrete-mathematics mathematical-optimization linear-programming

我正在开发一种应用程序,可以最佳地为医院的护士分配班次。我认为这是离散变量的linear programming问题,因此可能是NP难的:

  • 每天,每位护士(约15-20岁)都会获得轮班
  • 有少量(约6个)不同班次
  • 有相当多的约束和优化标准,无论是关于一天,还是关于一个emplyoee,例如:
    • 每天必须为每个轮班分配最少人数
    • 有些班次重叠,所以如果有人做中间班次,可以让一个人在早班换一个人少
    • 有些人更喜欢提前班次,有些人更喜欢延迟班次,但需要进行最小班次调整才能获得更高的轮班工资。
    • 一天不允许一个人上班,第二天上班(由于最短的休息时间规定)
    • 满足指定的工作周长度(不同的人不同)
    • ...

所以基本上有一个大数(一个20 * 30 = 600)个变量,每个变量都可以取少量的离散值。

目前,我的计划是使用修改后的Min-conflicts algorithm

  • 从随机分配开始
  • 每个人和每天都有健身功能
  • 选择健康状况最差的人或日
  • 随机选择当天/人的某个作业,并将其设置为产生最佳适合度值的值
  • 重复,直到达到最大迭代次数或者找不到所选日期/人的改善

有更好的想法吗?我有点担心它会陷入局部最佳状态。我应该使用某种形式的simulated annealing吗?或者不仅考虑一次改变一个变量,而且特别考虑两个人之间的转换(当前手动算法中的主要部分)?我想避免将算法定制到当前约束,因为那些可能会改变。

编辑:没有必要找到严格的最佳解决方案;名单目前是手工完成的,我很确定结果在大多数时候都是非常不理想的 - 不应该难以击败。短期调整和手动覆盖也一定是必要的,但我不认为这是一个问题;将过去和手动分配标记为“已修复”实际上应该通过减少解决方案空间来简化任务。

9 个答案:

答案 0 :(得分:11)

这是一个难以解决的难题。有关此主题的学术论文很多,特别是在Operations Research领域 - 例如nurse rostering papers 2007-2008或只是google“护士排班运算研究”。复杂性还取决于以下方面:需要多少天才能解决;护士可以做出什么样的“要求”;名单是“循环的”;这是一个长期计划还是需要处理短期排班“维修”,如疾病和掉期等等。

您描述的算法是heuristic方法。 你可能会发现你可以调整它以适应问题的一个特定实例,但是一旦“某些东西”被改变它可能不会那么好(例如局部最优,收敛性差)。

但是,根据您的特定业务需求,这种方法可能已足够 - 例如获得最优解决方案有多重要,您所描述的问题大纲应保持不变,潜在的节省(资金和资源)是多少,护士对质量的看法有多重要他们的名单,这项工作的预算是多少等。

答案 1 :(得分:4)

嗯,你知道有些ILP解决方案做得很好吗?试试AIMMS,Mathematica或GNU编程套件! 600变量当然比Lenstra定理容易解决的要多得多,但有时这些ILP求解器有很好的处理能力,而在AIMMS中,你可以稍微修改分支策略。此外,ILP的速度非常快100%。

答案 2 :(得分:3)

我最近为一家大型制造工厂解决了班次分配问题。首先,我们尝试生成纯随机时间表并返回通过is_schedule_valid测试的任何一个 - 后备算法。当然,这是缓慢且不确定的。

接下来我们尝试了遗传算法(正如你所建议的那样),但找不到适合任何可行解决方案的良好适应度函数(因为最小的变化可能使整个时间表正确或错误 - 几乎没有分数。) / p>

最后我们选择了以下方法(效果很好!):

  1. 随机化输入集(即工作,班次,员工等)。
  2. 创建一个有效的元组并将其添加到您的暂定时间表中。
  3. 如果无效,则可以创建元组,回滚(并递增)添加的最后一个元组。
  4. 将部分计划传递给测试could_schedule_be_valid的函数,也就是说,如果剩余的元组以可能的方式填充,此计划是否有效
  5. 如果!could_schedule_be_valid,只需回滚(并递增)(2)中添加的元组。
  6. 如果schedule_is_completereturn schedule
  7. 转到(2)
  8. 您可以通过这种方式逐步建立部分转换。好处是可以在步骤2(预测试)中轻松完成一些有效计划的测试,其他测试必须保留在步骤5(测试后)。

    祝你好运。我们浪费了几天时间尝试前两种算法,但是在不到5小时的开发时间内,我们立即得到了推荐的算法来生成有效的时间表。

    此外,我们支持算法会尊重的分配的预先修复和后期修复。您只是不在步骤1中随机化这些插槽。您会发现解决方案不必接近最佳状态。我们的解决方案至少是O(N * M),但对于整个制造工厂,在不到半秒的时间内以PHP(!)执行。美丽是通过良好的could_schedule_be_valid测试快速排除糟糕的时间表。

    过去习惯这样做的人并不关心是否需要一个小时 - 他们只是知道他们不再需要手动操作。

答案 3 :(得分:2)

迈克,

不知道你是否得到了一个很好的答案,但我很确定约束编程是票。虽然GA可能会给您一个答案,但CP旨在为您提供许多答案或告诉您是否没有可行的解决方案。搜索“约束编程”和调度应该会带来很多信息。这是一个相对较新的领域,CP方法适用于传统优化方法陷入困境的许多类型的问题。

答案 4 :(得分:0)

贝尔?Dynamic programming有点听起来就像它有一个地方:重叠的子问题,最佳的子结构。

答案 5 :(得分:0)

您可以做的一件事是尝试在问题中寻找对称性。例如。为了问题的目的,你能否将所有护士视为等同?如果是这样,那么您只需要以任意顺序考虑护士 - 您可以避免考虑解决方案,以便任何护士 i 安排在任何护士 j 之前> Ĵ。 (你的确表示个别护士有首选班次,这与这个例子相矛盾,虽然这可能是一个不太重要的目标?)

答案 6 :(得分:0)

我认为你应该使用遗传算法,因为:

另请注意:a similar questionanother one

答案 7 :(得分:0)

使用CSP编程我制作了自动shitfs排班的程序。例如:

  1. 2班制 - 测试100多名护士,30天时间范围,10岁以上 规则
  2. 三班制 - 为80多名护士测试,30天时间范围,10多条规则
  3. 3班制,4队 - 测试365天,10多条规则,
  4. 以及几个类似的系统。所有这些都在我的家用电脑(1.8GHz,双核)上进行了测试。执行时间总是可以接受的,即。 3 /它需要大约5分钟和300MB RAM。

    这个问题最困难的部分是选择合适的解算器和正确的解决策略。

答案 8 :(得分:0)

Metaheuristics International Nurse Rostering Competition 2010上做得非常好。

有关实施,请参阅此video with a continuous nurse rostering (java)

相关问题