change cp-sat python cloning example to use deepcopy

This commit is contained in:
Laurent Perron
2025-03-07 10:30:10 +01:00
parent daf04c8ed6
commit 3f0a93e3e2
5 changed files with 53 additions and 16 deletions

View File

@@ -360,17 +360,22 @@ func main() {
## Model copy
The CpModel classes supports deep copy from a previous model. This is useful to
solve variations of a base model. The trick is to recover the copies of the
The `CpModel` classes supports deep copy from a previous model. This is useful
to solve variations of a base model. The trick is to recover the copies of the
variables in the original model to be able to manipulate the new model. This is
illustrated in the following examples.
### Python code
The deep copy python mechanism relies on the
[`copy` Python Standard Library](https://docs.python.org/3/library/copy.html).
```python
#!/usr/bin/env python3
"""Showcases deep copying of a model."""
import copy
from ortools.sat.python import cp_model
@@ -397,15 +402,24 @@ def clone_model_sample_sat():
if status == cp_model.OPTIMAL:
print("Optimal value of the original model: {}".format(solver.objective_value))
# Clones the model.
copy = model.clone()
# Creates a dictionary holding the model and the variables you want to use.
to_clone = {
"model": model,
"x": x,
"y": y,
"z": z,
}
copy_x = copy.get_int_var_from_proto_index(x.index)
copy_y = copy.get_int_var_from_proto_index(y.index)
# Deep copy the dictionary.
clone = copy.deepcopy(to_clone)
copy.add(copy_x + copy_y <= 1)
# Retrieve the cloned model and variables.
cloned_model: cp_model.CpModel = clone["model"]
cloned_x = clone["x"]
cloned_y = clone["y"]
cloned_model.add(cloned_x + cloned_y <= 1)
status = solver.solve(copy)
status = solver.solve(cloned_model)
if status == cp_model.OPTIMAL:
print("Optimal value of the modified model: {}".format(solver.objective_value))

View File

@@ -266,7 +266,7 @@ class IntVar(cmh.BaseIntVar):
"""Returns a shallowcopy of the variable."""
return IntVar(self.__model, self.index, self.is_boolean, None)
def __deepcopy__(self, memo) -> "IntVar":
def __deepcopy__(self, memo: Any) -> "IntVar":
"""Returns a deepcopy of the variable."""
return IntVar(
copy.deepcopy(self.__model, memo), self.index, self.is_boolean, None

View File

@@ -1799,6 +1799,18 @@ class CpModelTest(absltest.TestCase):
self.assertEqual(y.index, clone_y.index)
self.assertEqual(i.index, clone_i.index)
solo_copy_b = copy.copy(b)
self.assertEqual(b.index, solo_copy_b.index)
self.assertEqual(b.is_boolean, solo_copy_b.is_boolean)
self.assertIs(solo_copy_b.model_proto, b.model_proto)
solo_copy_x = copy.copy(x)
self.assertEqual(x.index, solo_copy_x.index)
self.assertEqual(x.is_boolean, solo_copy_x.is_boolean)
self.assertIs(solo_copy_x.model_proto, x.model_proto)
solo_copy_i = copy.copy(i)
self.assertEqual(i.index, solo_copy_i.index)
self.assertIs(solo_copy_i.model_proto, i.model_proto)
model_copy = copy.copy(model)
copy_b = model_copy.get_bool_var_from_proto_index(b.index)
copy_x = model_copy.get_int_var_from_proto_index(x.index)

View File

@@ -15,6 +15,8 @@
"""Showcases deep copying of a model."""
# [START program]
import copy
from ortools.sat.python import cp_model
@@ -51,17 +53,26 @@ def clone_model_sample_sat():
if status == cp_model.OPTIMAL:
print("Optimal value of the original model: {}".format(solver.objective_value))
# Clones the model.
# [START clone]
copy = model.clone()
# Creates a dictionary holding the model and the variables you want to use.
to_clone = {
"model": model,
"x": x,
"y": y,
"z": z,
}
copy_x = copy.get_int_var_from_proto_index(x.index)
copy_y = copy.get_int_var_from_proto_index(y.index)
# Deep copy the dictionary.
clone = copy.deepcopy(to_clone)
copy.add(copy_x + copy_y <= 1)
# Retrieve the cloned model and variables.
cloned_model: cp_model.CpModel = clone["model"]
cloned_x = clone["x"]
cloned_y = clone["y"]
cloned_model.add(cloned_x + cloned_y <= 1)
# [END clone]
status = solver.solve(copy)
status = solver.solve(cloned_model)
if status == cp_model.OPTIMAL:
print("Optimal value of the modified model: {}".format(solver.objective_value))

View File

@@ -1,4 +1,4 @@
// Copyright 2010-2025 Google LLC
// Copyright 2019-2023 RTE
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at