我正在研究医生调度应用程序,我们正在使用线性编程和求解器如cplex / lindo来解决我们的模型。由于一些建模限制,我们需要为夜班生成二进制模式。
通常我们会生成一个月的时间表,因此我们需要考虑为夜班生成30天的模式。
夜班有一些限制,比如如果一个人连续夜班,那么医生将在接下来的五天内无法工作。所以波纹是约束的一些例子。
111000001111100000111110000011 Valid
111000001100000000111110000011 Valid
111010001111101000111110000011 Invalid
还有其他约束,如模式中的数量应小于某个定义值,连续数量应小于某个定义值等。
首先我尝试了简单的算法,它从0开始并使用按位运算符并添加一个以获得下一个排列并检查所有约束的下一个排列,如果无效则获得下一个排列并忽略无效模式。由于这个模式长度为30位(2 30 = 1073741824),因此检查模式的数量很大,我的简单算法。我想要找出所有有效模式需要24小时以上。
现在我的问题是
我会针对给定问题使用哪种算法,以时间有效的方式找到约束条件的所有排列?
这个问题是一个确切的封面问题吗?我可以应用跳舞链接等算法来解决我面临的问题吗?
请提供一些链接,了解您为此问题提出的解决方案?
答案 0 :(得分:0)
我在“计算机程序设计的艺术 - 第4A卷 - 组合算法,Donald Knuth的第1部分”部分“7.2.1.2算法G(通用置换生成器)”中找到了非常好的解决方案。作者在其中描述了绕过不需要的技术我正在实现算法,增量生成一个可行区域的树并绕过任何不可行的路径。我将以一种方式实现,例如从值为0的节点开始,并且该节点有两个子节点0和1,并且每个每次添加新的子节点时,节点都有子节点0和1,如果它不符合约束,我们将使用我们的约束集检查不要添加子节点,例如,如果算法要在级别5添加节点,结果字符串在5级是11101,由于夜班约束“101”在11101结束时不符合夜班规则,所以不添加值为1的5级节点。继续添加子节点,直到我们有根节点。所以最终我们会有的e只有可行区域,因为我们绕过了不需要的块。通过这种方式,我永远不会触及不可行区域。