change cp-sat python cloning example to use deepcopy
This commit is contained in:
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user