或工具:如果"num_nurses"不等于"num_shifts",Python



我正在尝试使用熟悉谷歌或工具。我尝试了Employee调度python示例的简化版本。

from __future__ import print_function
import sys
from ortools.constraint_solver import pywrapcp

def main():
    # Creates the solver.
    solver = pywrapcp.Solver("employee_scheduling")
    num_nurses = 3
    num_shifts = 3
    num_days = 1
    # [START]
    # Create shift variables.
    shifts = {}
    for j in range(num_nurses):
        for i in range(num_days):
            shifts[(j, i)] = solver.IntVar(
                0, num_shifts - 1, "shifts(%i,%i)" % (j, i))
    shifts_flat = [shifts[(j, i)] for j in range(num_nurses)
                for i in range(num_days)]
    # Create nurse variables.
    nurses = {}
    for j in range(num_shifts):
        for i in range(num_days):
            nurses[(j, i)] = solver.IntVar(
                0, num_nurses - 1, "shift%d day%d" % (j, i))
    # Set relationships between shifts and nurses.
    for day in range(num_days):
        nurses_for_day = [nurses[(j, day)] for j in range(num_shifts)]
        for j in range(num_nurses):
            s = shifts[(j, day)]
            solver.Add(s.IndexOf(nurses_for_day) == j)
    # Create the decision builder.
    db = solver.Phase(shifts_flat, solver.CHOOSE_FIRST_UNBOUND,
                    solver.ASSIGN_MIN_VALUE)
    # Create the solution collector.
    solution = solver.Assignment()
    solution.Add(shifts_flat)
    collector = solver.AllSolutionCollector(solution)
    solver.Solve(db, [collector])
    print("Solutions found:", collector.SolutionCount())
    print("Time:", solver.WallTime(), "ms")
    print()

if __name__ == "__main__":
    main()

正如你所看到的,我唯一保留的限制是轮班和护士之间的关系。在num_nurses=3、num_shifts=3和num_days=1的情况下,解算器能够找到6个解。但是,如果将num_shifts更改为2,则解算器将返回0个解。这不是也应该有三个解决方案吗(指派一名护士,不指派另外两名护士(?

事实证明,这是employee_scheduling目前编写方式的限制。它的重写工作目前正在进行中,应该在几周内完成。

https://github.com/google/or-tools/issues/932

我推荐这个版本的轮班调度,它实现了一些不同的约束:

https://github.com/google/or-tools/blob/master/examples/python/shift_scheduling_sat.py

最新更新