繁体   English   中英

Or-Tools CP-SAT 求解器导出/导入:加载 model 后如何访问变量?

[英]Or-Tools CP-SAT solver export/import: how to access vars after loading a model?

使用 OR-Tools CP-CAT 求解器的 Python 接口(参考) ,我希望能够保存 cp_model,稍后或从不同的进程加载它,并继续与之交互。

我能够将 model 序列化为 Protubuf,然后加载并解决它:

from google.protobuf import text_format
from ortools.sat.python import cp_model

def create_model():
    model = cp_model.CpModel()
    a = model.NewIntVar(0, 10, "var_a")
    b = model.NewIntVar(0, 10, "var_b")

    model.Maximize(a + b)
    return model
    
def clone_model(model):
    new_model = cp_model.CpModel()
    text_format.Parse(str(model), new_model.Proto())
    
    return new_model

def solve_model(model):
    solver = cp_model.CpSolver()
    status = solver.Solve(new_model)

    print(solver.StatusName(status))
    print(solver.ObjectiveValue())

# Works fine
model = create_model()
new_model = clone_model(model)
solve_model(new_model)

(资源)

但是,我想在加载后继续与 model 交互。 例如,我希望能够执行以下操作:

model = create_model()
new_model = clone_model(model)

c = new_model.NewIntVar(0, 5, "var_c")    
new_model.Add(a < c)

问题是最后一行不起作用,因为a没有定义; 而且我找不到任何方法来访问现有模型的变量。

我正在寻找类似的东西: a = new_model.getExistingVariable("var_a")这将允许我在加载后继续与 model 中的预先存在的变量进行交互。

根据@Stradivari 的评论,一种似乎有效的方法是简单地pickle model 及其变量。

例如:

from ortools.sat.python import cp_model
import pickle

class ClonableModel:
    def __init__(self):
        self.model = cp_model.CpModel()
        self.vars = {}
        
    def create_model(self):
        self.vars['a'] = self.model.NewIntVar(0, 10, "var_a")
        self.vars['b'] = self.model.NewIntVar(0, 10, "var_b")

        self.model.Maximize(self.vars['a'] + self.vars['b'])
        
    # Also possible to serialize via a file / over network 
    def clone(self):
        return pickle.loads(pickle.dumps(self))
    
    def solve(self):
        solver = cp_model.CpSolver()
        status = solver.Solve(self.model)

        return '%s: %i' % (solver.StatusName(status), solver.ObjectiveValue())

现在,以下工作按预期工作:

model = ClonableModel()
model.create_model()

new_model = model.clone()
new_model.model.NewIntVar(0,5,"c")
new_model.model.Add(new_model.vars['a'] < c)

print('Original model: %s' % model.solve())
print('Cloned model: %s' % new_model.solve())

# Original model: OPTIMAL: 20
# Cloned model: OPTIMAL: 14

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM