首页 > 解决方案 > 使用 ortools 的 OnSolutionCallback 出错

问题描述

我尝试从这里调整代码https://developers.google.com/optimization/scheduling/employee_scheduling,但是运行时出现此错误:

libc++abi.dylib:以 Swig::DirectorMethodException 类型的未捕获异常终止:SWIG 导演方法错误。调用“SolutionCallback.OnSolutionCallback”时检测到错误

我的部分解决方案打印机的代码是:

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

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

    def __init__(self, shifts, all_nurses, days, shifts_per_day, sols):
        cp_model.CpSolverSolutionCallback.__init__(self)
        self._shifts = shifts
        self._all_nurses = all_nurses
        self._days = days
        self._shifts_per_day = shifts_per_day
        self._solutions = set(sols)
        self._solution_count = 0

    def OnSolutionCallback(self):
        if self._solution_count in self._solutions:
            print('Solution %i' % self._solution_count)
            # for d in range(self._num_days):
            for d in self._days.keys():
                print('Day %s' % d)
                # for n in range(self._num_nurses):
                for n in self._all_nurses:
                    is_working = False
                    # for s in range(self._num_shifts):
                    current_shifts = list(self._shifts_per_day[str(days[d])].keys())
                    for s in current_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

我在 main 中这样称呼它:

    # Display the first five solutions.
    a_few_solutions = range(5)
    solution_printer = NursesPartialSolutionPrinter(shifts, all_nurses, days, shifts_per_day, a_few_solutions)
    solver.SearchForAllSolutions(model, solution_printer)

如果有人可以帮忙,那就太棒了,这是紧急情况:(

标签: pythonmacos-mojaveor-toolsanaconda3

解决方案


我建议您添加一个 try+exceptOnSolutionCallback来调试此类错误:

import traceback

...
def OnSolutionCallback(self):
    try:
        if self._solution_count in self._solutions:
            print('Solution %i' % self._solution_count)
        ...
    except Exception as e:
        traceback.print_exc()
        raise e

这给了我:

Traceback (most recent call last):
  File ..., line 31, in OnSolutionCallback
    for d in self._days.keys():
AttributeError: 'int' object has no attribute 'keys'

推荐阅读