OR-Tools的CP-SAT求解器入门案例


前言

近几年,在工业界的大规模问题上,越来越多的人将目光聚焦于问题的可行解,而非最优解上。也就是所谓的约束满足问题,而市面上能解决工业级大规模问题的规划求解器主要有CPLEX的CP组件(商业),和OR-Tools的CP-SAT求解器(开源)。

本文介绍的CP-SAT的底层是C++,而且包含了多种语言的API,即时是Python调用也十分高效。它的底层算法利用了一些约束满足性传播搜索等方法,在定义域上搜索满足所有约束的可行解,在一些高度非凸问题上,CP-SAT相比一些MIP求解器具有支配性的效率。这里将引用公开资料当中的案例,介绍下如何用CP-SAT进行求解。

CP-SAT入门案例

简单案例:给出如下问题:有三个变量 x , y , x x,y,x x,y,x,它们的取值范围均为 {0,1,2}。求 x + y + z x+y+z x+y+z 满足约束条件 x ≠ y x ≠ y x=y 下的最大取值,并给出相应的变量值。

案例来源:利用OR-Tools求解器的callback功能返回可行解

1. 建立模型实例

引入相关 cp_model 模块,并建立 CpModel 实例,作为存储模型信息的对象。

from ortools.sat.python import cp_model

model = cp_model.CpModel()

2. 建立决策变量

接着对决策变量进行建模,CP-SAT只支持建立整数类型(布尔类型)的基础变量,高级变量(区间变量)也是围绕整数建立的。通过 NewIntVar() 建立 x , y , z x,y,z x,y,z 三个变量。

x = model.NewIntVar(lb=0, ub=2, name='x')
y = model.NewIntVar(lb=0, ub=2, name='y')
z = model.NewIntVar(lb=0, ub=2, name='z')

3. 建立约束条件

这个案例中的约束条件仅有 x ≠ y x\neq y x=y,建立如下约束:

model.Add( x != y )

4. 建立目标函数

案例目标是最大化 x + y + z x+y+z x+y+z 的取值,通过如下代码将目标函数添加到模型当中。

model.Maximize( x + y + z )

5. 求解问题

CP-SAT的求解需要先创建一个 CpSolver 类,并将模型传入该类的 Solve 函数。模型求解如下:

solver = cp_model.CpSolver()
status = solver.Solve(model=model)

模型求解之后,可以通过 solver.Value(var) 获取变量 var 的求解结果,通过 solver.objectiveValue() 获取目标函数值。

if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:
    print(f'Maximum of objective function: {solver.ObjectiveValue()}\n')
    print(f'x = {solver.Value(x)}')
    print(f'y = {solver.Value(y)}')
    print(f'z = {solver.Value(z)}')
else: 
	print('No solution found.')

输出结果如下:

Maximum of objective function: 5.0

x = 1
y = 2
z = 2

除此之外,可以通过 print(solver.ResponseStats()) 将求解结果全打印出来(如下)。也可以通过仅通过 print(solver.param) 来打印指定信息,例如 print(solver.BestObjectiveBound())

CpSolverResponse summary:
status: OPTIMAL
objective: 5
best_bound: 5
integers: 1
booleans: 0
conflicts: 0
branches: 0
propagations: 0
integer_propagations: 1
restarts: 0
lp_iterations: 0
walltime: 0.010765
usertime: 0.0107651
deterministic_time: 0
gap_integral: 0
solution_fingerprint: 0xbc76f3d3e780d9b7
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lins号丹

小小鼓励,满满动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值