如何从OR-Tools SAT模块获取全部可行解的结构化列表?
如何从OR-Tools SAT求解器中获取所有可行解的结构化列表
我完全理解你想把所有可行解以字典列表或嵌套列表的形式保存下来,而不是仅仅打印输出——之前尝试自定义回调类导致Python内核崩溃确实挺闹心的。下面给你一个稳定可靠的实现方式,通过自定义回调类安全收集所有解:
完整实现代码
from ortools.sat.python import cp_model class SolutionCollector(cp_model.CpSolverSolutionCallback): def __init__(self, variables): super().__init__() self.variables = variables self.solutions = [] # 用于存储所有解的容器 def OnSolutionCallback(self): # 方案1:以字典形式存储(键为变量名,值为变量取值) current_solution = {var.Name(): self.Value(var) for var in self.variables} self.solutions.append(current_solution) # 如果你需要嵌套列表形式(仅存值,按变量传入顺序),可以替换上面两行为: # current_solution = [self.Value(var) for var in self.variables] # self.solutions.append(current_solution) # 1. 构建你的CP模型 model = cp_model.CpModel() x00 = model.NewBoolVar('x00') x01 = model.NewBoolVar('x01') x02 = model.NewBoolVar('x02') model.AddBoolOr([x00, x01, x02.Not()]) model.AddBoolOr([x00.Not(), x02.Not()]) # 2. 创建求解器和解收集器 solver = cp_model.CpSolver() solution_collector = SolutionCollector([x00, x01, x02]) # 3. 搜索所有解并收集 solver.SearchForAllSolutions(model, solution_collector) # 4. 访问收集到的解 print("所有可行解(字典列表):") for idx, sol in enumerate(solution_collector.solutions): print(f"解 {idx}: {sol}") # 如果用嵌套列表形式,输出会是类似: # 所有可行解(嵌套列表): # 解 0: [0, 1, 0] # 解 1: [0, 0, 0] # ...
为什么之前的尝试会崩溃?
大概率是因为你在回调中直接操作了全局列表,而OR-Tools的求解器是在后台线程中执行搜索的,回调函数运行在这个后台线程里,直接操作全局变量可能会引发线程安全问题,导致内核崩溃。
而上面的实现中,我们把解存储在回调类的实例属性self.solutions中,这是线程安全的——求解器会正确处理回调的执行上下文,避免了全局变量的冲突问题。
额外说明
- 你可以根据需求自由选择存储格式:字典形式可读性更强(能看到变量名),嵌套列表更紧凑节省空间。
- 如果你的变量很多,也可以在收集时只存储你关心的变量,不需要传入所有变量到
SolutionCollector中。
内容的提问来源于stack exchange,提问作者mcsoini
相关产品推荐
相关产品推荐

