时间表不会出现

问题描述

我复制了一个 code example,它本身可以正常工作,并且在我的版本中也可以正常工作。问题是在向用户询问员工人数、班次和计划天数后,程序不会显示求解器的结果。它将单独对示例代码执行此操作,但不会使用我编写的用于控制它的代码。如果有人可以看看这个以了解原因,我们将不胜感激。

C#-8

解决方法

过了某个时间点,最好尝试一种更简洁的方法,而不是查明当前错误的确切位置。这里有一个更好的方法来组织你正在做的事情,它似乎工作正常。

首先,复制自 example 的代码,“nurses”替换为“employees”,静态分配更改为用户输入,正如您所做的那样。我还将 main 重命名为 schedule_employees

from ortools.sat.python import cp_model

class EmpsPartialSolutionPrinter(cp_model.CpSolverSolutionCallback):
    """Print intermediate solutions."""

    def __init__(self,shifts,num_employees,num_days,num_shifts,sols):
        cp_model.CpSolverSolutionCallback.__init__(self)
        self._shifts = shifts
        self._num_employees = num_employees
        self._num_days = num_days
        self._num_shifts = num_shifts
        self._solutions = set(sols)
        self._solution_count = 0

    def on_solution_callback(self):
        if self._solution_count in self._solutions:
            print('Solution %i' % self._solution_count)
            for d in range(self._num_days):
                print('Day %i' % d)
                for n in range(self._num_employees):
                    is_working = False
                    for s in range(self._num_shifts):
                        if self.Value(self._shifts[(n,d,s)]):
                            is_working = True
                            print('  Nurse %i works shift %i' % (n,s))
                    if not is_working:
                        print('  Nurse {} does not work'.format(n))
            print()
        self._solution_count += 1

    def solution_count(self):
        return self._solution_count

def schedule_employees():
    # Data.
    num_employees = int(input("How many employees are you scheduling? "))
    num_days = int(input("How many days are you scheduling for? "))
    num_shifts = int(input("How many shifts are you scheduling for each "
                          f"employees for {num_days} days? "))
    all_employees = range(num_employees)
    all_shifts = range(num_shifts)
    all_days = range(num_days)
    # Creates the model.
    model = cp_model.CpModel()

    # Creates shift variables.
    # shifts[(n,s)]: nurse 'n' works shift 's' on day 'd'.
    shifts = {}
    for n in all_employees:
        for d in all_days:
            for s in all_shifts:
                shifts[(n,s)] = model.NewBoolVar('shift_n%id%is%i' % (n,s))

    # Each shift is assigned to exactly one nurse in the schedule period.
    for d in all_days:
        for s in all_shifts:
            model.Add(sum(shifts[(n,s)] for n in all_employees) == 1)

    # Each nurse works at most one shift per day.
    for n in all_employees:
        for d in all_days:
            model.Add(sum(shifts[(n,s)] for s in all_shifts) <= 1)

    # Try to distribute the shifts evenly,so that each nurse works
    # min_shifts_per_nurse shifts. If this is not possible,because the total
    # number of shifts is not divisible by the number of employees,some employees will
    # be assigned one more shift.
    min_shifts_per_nurse = (num_shifts * num_days) // num_employees
    if num_shifts * num_days % num_employees == 0:
        max_shifts_per_nurse = min_shifts_per_nurse
    else:
        max_shifts_per_nurse = min_shifts_per_nurse + 1
    for n in all_employees:
        num_shifts_worked = 0
        for d in all_days:
            for s in all_shifts:
                num_shifts_worked += shifts[(n,s)]
        model.Add(min_shifts_per_nurse <= num_shifts_worked)
        model.Add(num_shifts_worked <= max_shifts_per_nurse)

    # Creates the solver and solve.
    solver = cp_model.CpSolver()
    solver.parameters.linearization_level = 0
    # Display the first five solutions.
    a_few_solutions = range(5)
    solution_printer = EmpsPartialSolutionPrinter(shifts,a_few_solutions)
    solver.SearchForAllSolutions(model,solution_printer)

这或多或少是您需要添加/更改的全部内容。顶级入口点——基本上,你希望在执行脚本时首先发生的事情——进入 __name__ == '__main__' 检查,就像示例所做的那样。当然,不同之处在于我们在调用以前简单的 main 方法之前执行了一些检查。

if __name__ == '__main__':
    valid_roles = ['supervisor','employee']
    
    role = input('Are you an employee or supervisor? ')
    while role not in valid_roles:
        print('not a valid response')
        role = input('Are you an employee or supervisor? ')
    
    task = input('I want to: ')
    if role == 'supervisor' and task == 'schedule employees':
        schedule_employees()

如果您添加到此程序并且这些检查变得更加复杂,您可以考虑将它们捆绑到您自己的新 main 方法中,或者甚至创建一个单独的 get_role 方法,例如,但现在这很短也很简单,在这里没问题。

基本规则是:首先在顶层定义您的类和函数等,然后然后使用您想要的任何控制流逻辑来决定调用什么、如何调用以及何时调用.您可能最终想要在条件和/或函数中定义类是有原因的,但这是非常不寻常的,并且适用于复杂的情况。