如何在OR-Tools中同时设置时间限制与解数量限制?
OR-Tools CP求解器实现“找2个解或超时停止”的方案
我正在使用OR-Tools进行简单求解,但对如何使用
SolveWithTimeLimitSampleSat和StopAfterNSolutionsSampleSat感到困惑。我希望求解器尝试找到2个解,但如果在指定时长内未找到2个解则停止。谷歌官网的文档帮助有限,既未说明这些函数的参数也没有示例。我尝试使用VarArraySolutionPrinterWithLimit,但Jupyter无法识别该函数,我的求解器也无法识别前两个函数。请说明如何在以下代码的标记区域添加代码以实现上述需求:
solver = cp_model.CpSolver() ### Something goes here ### status = solver.Solve(model) if status in [cp_model.OPTIMAL, cp_model.FEASIBLE]: for i in range(0, 30): print(f'{i + 1} is {solver.Value(Car[i]) + 1}') else: print('unsat')
你提到的SolveWithTimeLimitSampleSat、StopAfterNSolutionsSampleSat和VarArraySolutionPrinterWithLimit都是OR-Tools示例代码中的自定义函数/类,并非官方库的内置API,直接调用会报错。正确的做法是通过自定义解回调函数+求解器参数设置来实现需求,具体修改如下:
完整修改代码
from ortools.sat.python import cp_model # 自定义解收集回调类:控制解数量上限 class SolutionCollector(cp_model.CpSolverSolutionCallback): def __init__(self, max_solutions): super().__init__() self.max_solutions = max_solutions self.solution_count = 0 self.solutions = [] # 存储所有找到的解 def OnSolutionCallback(self): # 每次找到解时触发,计数+1并保存解 self.solution_count += 1 # 保存当前Car变量的解(根据你的需求调整) current_sol = [self.Value(Car[i]) + 1 for i in range(30)] self.solutions.append(current_sol) # 达到目标解数时停止搜索 if self.solution_count >= self.max_solutions: self.StopSearch() solver = cp_model.CpSolver() ### 这里是需要添加的代码 ### # 1. 设置超时时间(单位:秒,比如10秒) solver.parameters.max_time_in_seconds = 10.0 # 2. 初始化解收集器,目标找2个解 solution_collector = SolutionCollector(max_solutions=2) ### 添加代码结束 ### # 传入回调函数执行求解 status = solver.Solve(model, solution_collector) # 处理输出结果 if solution_collector.solution_count > 0: print(f"找到 {solution_collector.solution_count} 个可行解:") for sol_idx, sol in enumerate(solution_collector.solutions): print(f"\n解 {sol_idx + 1}:") for i in range(30): print(f'{i + 1} is {sol[i]}') else: print('未找到可行解')
关键说明
- 自定义回调类:
SolutionCollector继承自CpSolverSolutionCallback,通过OnSolutionCallback方法捕获每个找到的解,计数达到2时调用StopSearch()终止求解。 - 超时设置:通过
solver.parameters.max_time_in_seconds直接设置求解器的最长运行时间,超时后自动停止。 - 解的存储:所有找到的解会存在
solution_collector.solutions列表中,避免了直接用solver.Value()只能获取最后一个解的问题。
内容的提问来源于stack exchange,提问作者MrCasual
相关产品推荐
相关产品推荐

