OR-Tools工具是否支持生成原始排列与组合的功能?
用OR-Tools实现排列与组合生成
完全可以用OR-Tools实现类似permutations和combinations的排列/组合列表生成,以下是具体实现示例:
一、生成排列(对应permutations)
利用OR-Tools约束规划模块的AddAllDifferent约束保证元素不重复,枚举所有可行解即可得到排列列表:
from ortools.sat.python import cp_model def generate_permutations(items, k): model = cp_model.CpModel() # 创建k个变量,取值范围覆盖目标元素的最小到最大值 vars_ = [model.NewIntVar(min(items), max(items), f'var_{i}') for i in range(k)] # 添加元素互不相同的约束 model.AddAllDifferent(vars_) # 自定义解收集器 class SolutionCollector(cp_model.CpSolverSolutionCallback): def __init__(self, variables, target_items): cp_model.CpSolverSolutionCallback.__init__(self) self.variables = variables self.target_set = set(target_items) self.permutations = [] def on_solution_callback(self): perm = tuple(self.Value(var) for var in self.variables) # 过滤掉不在原列表中的值(避免变量范围包含无关数) if all(x in self.target_set for x in perm): self.permutations.append(perm) solver = cp_model.CpSolver() collector = SolutionCollector(vars_, items) # 枚举所有可行解 solver.SearchForAllSolutions(model, collector) return collector.permutations # 测试 print(generate_permutations([1,2,3,4], 2))
二、生成组合(对应combinations)
组合不考虑元素顺序,因此在排列的基础上添加变量递增约束,避免重复的无序组合:
from ortools.sat.python import cp_model def generate_combinations(items, k): sorted_items = sorted(items) model = cp_model.CpModel() vars_ = [model.NewIntVar(sorted_items[0], sorted_items[-1], f'var_{i}') for i in range(k)] # 1. 元素互不相同 model.AddAllDifferent(vars_) # 2. 添加递增约束,保证组合无重复 for i in range(k-1): model.Add(vars_[i] < vars_[i+1]) class SolutionCollector(cp_model.CpSolverSolutionCallback): def __init__(self, variables, target_set): cp_model.CpSolverSolutionCallback.__init__(self) self.variables = variables self.target_set = target_set self.combinations = [] def on_solution_callback(self): comb = tuple(self.Value(var) for var in self.variables) if all(x in self.target_set for x in comb): self.combinations.append(comb) solver = cp_model.CpSolver() collector = SolutionCollector(vars_, set(sorted_items)) solver.SearchForAllSolutions(model, collector) return collector.combinations # 测试 print(generate_combinations([1,2,3,4], 2))
补充说明
OR-Tools核心定位是优化求解器,单纯生成排列组合时,itertools库会更高效;但如果是在优化问题流程中需要生成排列组合作为中间环节,用OR-Tools内部实现可以避免依赖外部库,衔接更顺畅。
内容的提问来源于stack exchange,提问作者Mark Onishchenko
相关产品推荐
相关产品推荐

