首页 > 数据库 > 数据库开发技术 > 使用cp-sat解决非线性问题
cp-sat是ortools的一个强大的约束规划求解器,但其也能设定目标函数,且在开源免费求解器中求解效率非常高。

cp-sat的求解功能非常强大,谷歌的官网介绍比较少,需要大家对cp-sat底层的API深入研究才能逐渐发现其强大的求解功能。
本文介绍cp-sat求解非线性规划问题的建模技巧。
一个简单的非线性问题。
约束条件:x1,x2 为0到20的整数;
x1*x1 + x2 <= 40 ;
x1 + x2 <= 30
目标函数:max:x1 + 2 * x2
因为cp-sat不能直接识别x1*x1两个乘积的变量,直接按照常规方法建模会报错。
from ortools.sat.python import cp_model
# 创建模型
model = cp_model.CpModel()
# 定义变量
x1 = model.NewIntVar(0, 20, 'x1')
x2 = model.NewIntVar(0, 20, 'x2')
# 添加约束条件
model.Add(x1*x1 + x2 <= 40)
model.Add(x1 + x2 <= 30)
# 定义目标函数
model.Maximize(x1 + 2 * x2)
# 创建求解器并求解
solver = cp_model.CpSolver()
status = solver.Solve(model)
# 输出结果
if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:
print(f'Optimal solution found: x1 = {solver.Value(x1)}, x2 = {solver.Value(x2)}')
print(f'Objective value: {solver.ObjectiveValue()}')
else:
print('No solution found.')
引入新变量x3,让x3=x1*x1,
model.AddMultiplicationEquality(x3, [x1,x1])#x3=x1*x1
完整代码:
from ortools.sat.python import cp_model
# 创建模型
model = cp_model.CpModel()
# 定义变量
x1 = model.NewIntVar(0, 20, 'x1')
x2 = model.NewIntVar(0, 20, 'x2')
x3 = model.NewIntVar(0, 400, 'x3')
# 添加约束条件
model.Add(x3 + x2 <= 40)
model.AddMultiplicationEquality(x3, [x1,x1])
model.Add(x1 + x2 <= 30)
# 定义目标函数
model.Maximize(x1 + 2 * x2)
# 创建求解器并求解
solver = cp_model.CpSolver()
status = solver.Solve(model)
# 输出结果
if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:
print(f'Optimal solution found: x1 = {solver.Value(x1)}, x2 = {solver.Value(x2)}, x3 = {solver.Value(x3)}')
print(f'Objective value: {solver.ObjectiveValue()}')
else:
print('No solution found.')
增加新变量,更新建模方法以后,可以顺利求解以上问题。
cp-sat还有许多这种非线性函数给建模提供了便利,比如一堆变量或参数的最小值、最大值、取模运算、取余运算、取绝对值运算等,使用这些函数建模解决非线性问题非常方便。
另外大家使用在cp-sat建模要注意,若变量有小数位,可以放大变量变成整数,因为cp-sat只能解决变量是整数的问题。
原文作者:Python学习杂记;如有侵权,请联系管理员删除。