如何修改现有 Google OR-Tools 约束编程模型的变量和约束?

问题描述

我使用 Python 中的 Google OR 工具编写了一个约束编程模型,该模型使用了 CP 求解器。我需要多次运行该模型,并在每次运行中修改约束。目前,每次我想运行模型时,我都会从头开始创建模型对象。无论如何,我可以修改现有模型的变量/约束,这样我就不需要每次都从头开始构建模型吗?

为了提供更好的上下文,请考虑以下示例模型。

from ortools.sat.python import cp_model
model = cp_model.CpModel()
num_vals = 3
a = model.NewIntvar(0,num_vals -1,'a')
b = model.NewIntvar(0,'b')
c = model.NewIntvar(0,'c')
model.Add(a == b)
solver = cp_model.cpsolver()
solver.solve(model)

现在,在问题的第二次运行中,我想做以下更改。

  1. 将变量c的上界改为5
  2. 删除约束a==b
  3. 创建新约束 a==c

如何在不从头开始构建模型的情况下实现这一目标?

解决方法

首先,您可以看看这个page

基本思想是,您可以操作存储在 cp_model 类中的底层 protobuf。唯一的规则是你不应该删除一个变量,因为它们被其他约束中的索引引用。

要删除约束,只需对其调用 Clear()(请参阅此 link)。 要添加约束,请使用普通 API。 要更改变量的域,您可以操作其域。请注意,域存储为不相交闭区间的扁平列表。

,

这是 Laurent 回答后的代码:

select array_agg( std.id),mxdate.created_at 
from 
STUDENT std 
join (select std_co .student_id,max(std_co .date) as created_at 
from STUDENTS_COURSES std_co group by std_co .student_id) mxdate 
on mxdate.student_id = std.student_id 
group by mxdate.created_at;
# 1. change c upper bound to 5
c.Proto().domain._values = []
c.Proto().domain.extend(cp_model.Domain(0,5).FlattenedIntervals())