簡體   English   中英

時間表不會顯示

[英]Schedule won't show up

我復制了一個代碼示例,它本身可以正常工作,並且在我的版本中也可以工作。 問題是在詢問用戶員工人數、班次和計划天數后,程序不會顯示求解器的結果。 它將僅針對示例代碼執行此操作,但不會針對我為控制它而編寫的代碼執行此操作。 如果有人可以看看這個,看看為什么,將不勝感激。

from ortools.sat.python import cp_model

def sup_functions(): # supervisor functions
    sup_task = input('I want to: ')   
    # scheduling employees
    if sup_task == 'schedule employees':
        class EmpsPartialSolutionPrinter(cp_model.CpSolverSolutionCallback):
            
            def __init__(self, shifts, num_emps, num_days, num_shifts, sols):
                cp_model.CpSolverSolutionCallback.__init__(self)
                self._shifts = shifts
                self._num_emps = num_emps
                self._num_days = num_days
                self._num_shifts = num_shifts
                self._solutions = set(sols)
                self._solution_count = 1
            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_emps):
                            is_working = False
                            for s in range(self._num_shifts):
                                if self.Value(self._shifts[(n, d, s)]):
                                    is_working = True
                                    print('  Employee %i works shift %i' % (n, s))
                                if not is_working:
                                    print('  Employee {} does not work'.format(n))
                    print()
                self._solution_count += 1
            
            def solution_count(self):
                return self._solution_count
        
        def main():
            # Data.
            num_emps = int(input("How many employees are you scheduling? "))
            num_days = int(input("How many days are you scheduling for? "))
            num_shifts = int(input(f"How many shifts are you scheduling for each employees for {num_days} days? "))
            all_emps = range(num_emps)
            all_shifts = range(num_shifts)
            all_days = range(num_days)
            # Creates the model.
            model = cp_model.CpModel()

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

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

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

            # Try to distribute the shifts evenly, so that each employee works
            # min_shifts_per_emp 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_emp = (num_shifts * num_days) // num_emps
            if num_shifts * num_days % num_emps == 0:
                max_shifts_per_emp = min_shifts_per_emp
            else:
                max_shifts_per_emp = min_shifts_per_emp + 1
            for n in all_emps:
                num_shifts_worked = 0
                for d in all_days:
                    for s in all_shifts:
                        num_shifts_worked += shifts[(n, d, s)]
                    model.Add(min_shifts_per_emp <= num_shifts_worked)
                    model.Add(num_shifts_worked <= max_shifts_per_emp)

            # 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, num_emps,
                                                    num_days, num_shifts,
                                                    a_few_solutions)
            solver.SearchForAllSolutions(model, solution_printer)
        if __name__ == '__main__':
            main()

# lets program know which functions to call
def emporsup():
    emp_or_sup = input('Are you an employee or supervisor? ')  # determines if user is an employee or the owner
    if emp_or_sup == "supervisor":
        sup_functions()
    #elif emp_or_sup == "employee":
        #emp_functions()
    else:
        print("not a valid response")
        emporsup()
emporsup()

過了某個時間點,最好嘗試一種更簡潔的方法,而不是精確定位當前錯誤的位置。 這是一種更好的方式來構建你正在做的事情,它似乎可以正常工作。

首先,從示例中復制的代碼,將“nurses”替換為“employees”,並且 static 分配更改為用戶輸入,正如您所做的那樣。 我還將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, d, 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, d,
                        s)] = model.NewBoolVar('shift_n%id%is%i' % (n, d, 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, d, 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, d, 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, d, 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, num_employees,
                                                    num_days, num_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方法,但現在這很簡短,在這里很好。

基本規則是:首先在頂層定義您的類和函數等,然后使用您想要的任何控制流邏輯來決定調用什么、如何調用以及何時調用。 您最終可能希望在條件和/或函數中定義類,但這是非常不尋常的,並且適用於復雜的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM