OR-Tools排班求解器结果不显示问题排查求助
问题排查:整合控制逻辑后求解器结果不显示
让我们一步步拆解你的问题,核心原因大概率集中在以下几点,对应的修复方案也给你整理好了:
1. 输入匹配的严格性导致逻辑分支未触发
你的代码里只有当用户**完全输入小写的schedule employees**时才会进入调度逻辑:
if sup_task == 'schedule employees': # 调度逻辑代码
如果用户输入时不小心用了大写(比如Schedule Employees)、拼写错误(比如少打了s写成schedule employee)或者多了空格,都会直接跳过调度分支,自然不会有任何求解结果输出。
修复方案:
改成不区分大小写的容错匹配:
if sup_task.strip().lower() == 'schedule employees': # 原调度逻辑代码保持不变
2. SolutionPrinter的计数逻辑与预期不匹配
你的EmpsPartialSolutionPrinter类里,_solution_count初始值设为1,但传入的sols是range(5)(也就是{0,1,2,3,4})。第一次找到解时self._solution_count是1,会正常打印,但如果求解器找不到解,就不会触发任何打印动作。另外,初始计数的设计也会让你错过第0个索引对应的解。
优化方案:
- 先给求解器加状态输出,确认是否找到解:
在solver.SearchForAllSolutions(model, solution_printer)之后添加:print(f"\n求解器状态: {solver.StatusName()}") print(f"找到的有效解数量: {solution_printer.solution_count() - 1}") - 调整初始计数逻辑,让前5个解都能被捕获:
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 = 0 # 初始值改为0 def on_solution_callback(self): if self._solution_count in self._solutions: print('Solution %i' % (self._solution_count + 1)) # 打印时从1开始计数 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
3. main()函数的调用依赖__name__判断(逻辑冗余)
虽然直接运行脚本时if __name__ == '__main__':会成立,但把这个判断嵌套在sup_functions()内部,逻辑上不够清晰,且在某些交互式运行环境下可能出现意外。
修复方案:
移除这个判断,直接在sup_task匹配成功后调用main():
if sup_task.strip().lower() == 'schedule employees': # 定义EmpsPartialSolutionPrinter和main函数... # 直接调用main,去掉多余的__name__判断 main()
4. 输入参数导致模型无解
如果用户输入的num_emps、num_days、num_shifts组合违反了约束条件,模型会没有可行解,求解器也就不会输出任何结果。比如:
- 当
num_emps=1,num_days=2,num_shifts=3时,总班次是6,要求这个员工每天做3个班次,但约束明确了每个员工每天最多1个班次,矛盾导致无解。
验证方法:
添加求解器状态输出后,若显示Status = INFEASIBLE,说明模型无解,需要调整输入参数。
内容的提问来源于stack exchange,提问作者user14702942
相关产品推荐
相关产品推荐

