or-tools : Python 如果 `num_nurses` 不等于 `num_shifts` 员工调度不给出任何解决方案
or-tools : Python employee scheduling does not give any solutions if `num_nurses` is not equal to `num_shifts`
我正在尝试使用熟悉 google 或-工具。我尝试了 Employee scheduling 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,求解器将 returns 0 个解决方案。
这不应该也有 3 个解决方案吗(分配一个护士,让其他两个未分配)?
事实证明,这是 employee_scheduling 现在编写方式的限制。目前正在进行重写,应该会在几周内完成。
我推荐这个版本的班次安排,它实现了一些不同的约束:
https://github.com/google/or-tools/blob/master/examples/python/shift_scheduling_sat.py
我正在尝试使用熟悉 google 或-工具。我尝试了 Employee scheduling 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,求解器将 returns 0 个解决方案。 这不应该也有 3 个解决方案吗(分配一个护士,让其他两个未分配)?
事实证明,这是 employee_scheduling 现在编写方式的限制。目前正在进行重写,应该会在几周内完成。
我推荐这个版本的班次安排,它实现了一些不同的约束:
https://github.com/google/or-tools/blob/master/examples/python/shift_scheduling_sat.py