diff --git a/docs/python/ortools/algorithms/pywrapknapsack_solver.html b/docs/python/ortools/algorithms/pywrapknapsack_solver.html index 70ddecbfb4..4a7edac69c 100644 --- a/docs/python/ortools/algorithms/pywrapknapsack_solver.html +++ b/docs/python/ortools/algorithms/pywrapknapsack_solver.html @@ -1,286 +1,511 @@ - - - -pywrapknapsack_solver API documentation - - - - - - - - - - - + + + + pywrapknapsack_solver API documentation + + + + + + - -
-
-
-

Module pywrapknapsack_solver

-
-
-
- -Expand source code - -
# This file was automatically generated by SWIG (http://www.swig.org).
-# Version 4.0.2
-#
-# Do not make changes to this file unless you know what you are doing--modify
-# the SWIG interface file instead.
+        
+    
+
+

+pywrapknapsack_solver

+ + +
+ View Source +
# This file was automatically generated by SWIG (http://www.swig.org).
+# Version 4.0.1
+#
+# Do not make changes to this file unless you know what you are doing--modify
+# the SWIG interface file instead.
+
+from sys import version_info as _swig_python_version_info
+if _swig_python_version_info < (2, 7, 0):
+    raise RuntimeError("Python 2.7 or later required")
+
+# Import the low-level C/C++ module
+if __package__ or "." in __name__:
+    from . import _pywrapknapsack_solver
+else:
+    import _pywrapknapsack_solver
+
+try:
+    import builtins as __builtin__
+except ImportError:
+    import __builtin__
+
+def _swig_repr(self):
+    try:
+        strthis = "proxy of " + self.this.__repr__()
+    except __builtin__.Exception:
+        strthis = ""
+    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
 
 
-class _SwigNonDynamicMeta(type):
-    """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
-    __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)
+def _swig_setattr_nondynamic_instance_variable(set):
+    def set_instance_attr(self, name, value):
+        if name == "thisown":
+            self.this.own(value)
+        elif name == "this":
+            set(self, name, value)
+        elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
+            set(self, name, value)
+        else:
+            raise AttributeError("You cannot add instance attributes to %s" % self)
+    return set_instance_attr
 
 
-class KnapsackSolver(object):
-    r"""
-     This library solves knapsack problems.
+def _swig_setattr_nondynamic_class_variable(set):
+    def set_class_attr(cls, name, value):
+        if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
+            set(cls, name, value)
+        else:
+            raise AttributeError("You cannot add class attributes to %s" % cls)
+    return set_class_attr
 
-     Problems the library solves include:
-      - 0-1 knapsack problems,
-      - Multi-dimensional knapsack problems,
 
-    Given n items, each with a profit and a weight, given a knapsack of
-    capacity c, the goal is to find a subset of items which fits inside c
-    and maximizes the total profit.
-    The knapsack problem can easily be extended from 1 to d dimensions.
-    As an example, this can be useful to constrain the maximum number of
-    items inside the knapsack.
-    Without loss of generality, profits and weights are assumed to be positive.
+def _swig_add_metaclass(metaclass):
+    """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
+    def wrapper(cls):
+        return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
+    return wrapper
 
-    From a mathematical point of view, the multi-dimensional knapsack problem
-    can be modeled by d linear constraints:
 
-        ForEach(j:1..d)(Sum(i:1..n)(weight_ij * item_i) <= c_j
-            where item_i is a 0-1 integer variable.
+class _SwigNonDynamicMeta(type):
+    """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
+    __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)
 
-    Then the goal is to maximize:
 
-        Sum(i:1..n)(profit_i * item_i).
+class KnapsackSolver(object):
+    r"""
+     This library solves knapsack problems.
 
-    There are several ways to solve knapsack problems. One of the most
-    efficient is based on dynamic programming (mainly when weights, profits
-    and dimensions are small, and the algorithm runs in pseudo polynomial time).
-    Unfortunately, when adding conflict constraints the problem becomes strongly
-    NP-hard, i.e. there is no pseudo-polynomial algorithm to solve it.
-    That's the reason why the most of the following code is based on branch and
-    bound search.
+     Problems the library solves include:
+      - 0-1 knapsack problems,
+      - Multi-dimensional knapsack problems,
 
-    For instance to solve a 2-dimensional knapsack problem with 9 items,
-    one just has to feed a profit vector with the 9 profits, a vector of 2
-    vectors for weights, and a vector of capacities.
-    E.g.:
+    Given n items, each with a profit and a weight, given a knapsack of
+    capacity c, the goal is to find a subset of items which fits inside c
+    and maximizes the total profit.
+    The knapsack problem can easily be extended from 1 to d dimensions.
+    As an example, this can be useful to constrain the maximum number of
+    items inside the knapsack.
+    Without loss of generality, profits and weights are assumed to be positive.
 
-      **Python**:
+    From a mathematical point of view, the multi-dimensional knapsack problem
+    can be modeled by d linear constraints:
 
-      .. code-block:: python
+        ForEach(j:1..d)(Sum(i:1..n)(weight_ij * item_i) <= c_j
+            where item_i is a 0-1 integer variable.
 
-              profits = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
-              weights = [ [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
-                          [ 1, 1, 1, 1, 1, 1, 1, 1, 1 ]
-                        ]
-              capacities = [ 34, 4 ]
+    Then the goal is to maximize:
 
-              solver = pywrapknapsack_solver.KnapsackSolver(
-                  pywrapknapsack_solver.KnapsackSolver
-                      .KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER,
-                  'Multi-dimensional solver')
-              solver.Init(profits, weights, capacities)
-              profit = solver.Solve()
+        Sum(i:1..n)(profit_i * item_i).
 
-      **C++**:
+    There are several ways to solve knapsack problems. One of the most
+    efficient is based on dynamic programming (mainly when weights, profits
+    and dimensions are small, and the algorithm runs in pseudo polynomial time).
+    Unfortunately, when adding conflict constraints the problem becomes strongly
+    NP-hard, i.e. there is no pseudo-polynomial algorithm to solve it.
+    That's the reason why the most of the following code is based on branch and
+    bound search.
 
-      .. code-block:: c++
+    For instance to solve a 2-dimensional knapsack problem with 9 items,
+    one just has to feed a profit vector with the 9 profits, a vector of 2
+    vectors for weights, and a vector of capacities.
+    E.g.:
 
-             const std::vector<int64_t> profits = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
-             const std::vector<std::vector<int64_t>> weights =
-                 { { 1, 2, 3, 4, 5, 6, 7, 8, 9 },
-                   { 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
-             const std::vector<int64_t> capacities = { 34, 4 };
+      **Python**:
+      .py}
+          profits = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
+          weights = [ [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
+                      [ 1, 1, 1, 1, 1, 1, 1, 1, 1 ]
+                    ]
+          capacities = [ 34, 4 ]
 
-             KnapsackSolver solver(
-                 KnapsackSolver::KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER,
-                 "Multi-dimensional solver");
-             solver.Init(profits, weights, capacities);
-             const int64_t profit = solver.Solve();
+          solver = pywrapknapsack_solver.KnapsackSolver(
+              pywrapknapsack_solver.KnapsackSolver
+                  .KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER,
+              'Multi-dimensional solver')
+          solver.Init(profits, weights, capacities)
+          profit = solver.Solve()
 
-      **Java**:
 
-      .. code-block:: java
+      **C++**:
+      .cpp}
+         const std::vector<int64_t> profits = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+         const std::vector<std::vector<int64_t>> weights =
+             { { 1, 2, 3, 4, 5, 6, 7, 8, 9 },
+               { 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
+         const std::vector<int64_t> capacities = { 34, 4 };
 
-            final long[] profits = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
-            final long[][] weights = { { 1, 2, 3, 4, 5, 6, 7, 8, 9 },
-                   { 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
-            final long[] capacities = { 34, 4 };
+         KnapsackSolver solver(
+             KnapsackSolver::KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER,
+             "Multi-dimensional solver");
+         solver.Init(profits, weights, capacities);
+         const int64_t profit = solver.Solve();
 
-            KnapsackSolver solver = new KnapsackSolver(
-                KnapsackSolver.SolverType.KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER,
-                "Multi-dimensional solver");
-            solver.init(profits, weights, capacities);
-            final long profit = solver.solve();
-    """
 
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-    KNAPSACK_BRUTE_FORCE_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_BRUTE_FORCE_SOLVER
-    r"""
-     Brute force method.
+      **Java**:
+      .java}
+        final long[] profits = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+        final long[][] weights = { { 1, 2, 3, 4, 5, 6, 7, 8, 9 },
+               { 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
+        final long[] capacities = { 34, 4 };
 
-    Limited to 30 items and one dimension, this
-    solver uses a brute force algorithm, ie. explores all possible states.
-    Experiments show competitive performance for instances with less than
-    15 items.
-    """
-    KNAPSACK_64ITEMS_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_64ITEMS_SOLVER
-    r"""
-     Optimized method for single dimension small problems
+        KnapsackSolver solver = new KnapsackSolver(
+            KnapsackSolver.SolverType.KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER,
+            "Multi-dimensional solver");
+        solver.init(profits, weights, capacities);
+        final long profit = solver.solve();
 
-    Limited to 64 items and one dimension, this
-    solver uses a branch & bound algorithm. This solver is about 4 times
-    faster than KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER.
-    """
-    KNAPSACK_DYNAMIC_PROGRAMMING_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_DYNAMIC_PROGRAMMING_SOLVER
-    r"""
-     Dynamic Programming approach for single dimension problems
+    """
 
-    Limited to one dimension, this solver is based on a dynamic programming
-    algorithm. The time complexity is O(capacity * number_of_items^2) and
-    the space complexity is O(capacity + number_of_items).
-    """
-    KNAPSACK_MULTIDIMENSION_CBC_MIP_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_MULTIDIMENSION_CBC_MIP_SOLVER
-    r"""
-     CBC Based Solver
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+    KNAPSACK_BRUTE_FORCE_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_BRUTE_FORCE_SOLVER
+    r"""
+     Brute force method.
 
-     This solver can deal with both large number of items and several
-    dimensions. This solver is based on Integer Programming solver CBC.
-    """
-    KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER
-    r"""
-     Generic Solver.
+    Limited to 30 items and one dimension, this
+    solver uses a brute force algorithm, ie. explores all possible states.
+    Experiments show competitive performance for instances with less than
+    15 items.
+    """
+    KNAPSACK_64ITEMS_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_64ITEMS_SOLVER
+    r"""
+     Optimized method for single dimension small problems
 
-    This solver can deal with both large number of items and several
-    dimensions. This solver is based on branch and bound.
-    """
-    KNAPSACK_MULTIDIMENSION_SCIP_MIP_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_MULTIDIMENSION_SCIP_MIP_SOLVER
-    r"""
-     SCIP based solver
+    Limited to 64 items and one dimension, this
+    solver uses a branch & bound algorithm. This solver is about 4 times
+    faster than KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER.
+    """
+    KNAPSACK_DYNAMIC_PROGRAMMING_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_DYNAMIC_PROGRAMMING_SOLVER
+    r"""
+     Dynamic Programming approach for single dimension problems
 
-    This solver can deal with both large number of items and several
-    dimensions. This solver is based on Integer Programming solver SCIP.
-    """
+    Limited to one dimension, this solver is based on a dynamic programming
+    algorithm. The time and space complexity is O(capacity *
+    number_of_items).
+    """
+    KNAPSACK_MULTIDIMENSION_CBC_MIP_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_MULTIDIMENSION_CBC_MIP_SOLVER
+    r"""
+     CBC Based Solver
 
-    def __init__(self, *args):
-        _pywrapknapsack_solver.KnapsackSolver_swiginit(self, _pywrapknapsack_solver.new_KnapsackSolver(*args))
-    __swig_destroy__ = _pywrapknapsack_solver.delete_KnapsackSolver
+     This solver can deal with both large number of items and several
+    dimensions. This solver is based on Integer Programming solver CBC.
+    """
+    KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER
+    r"""
+     Generic Solver.
 
-    def Init(self, profits: "std::vector< int64_t > const &", weights: "std::vector< std::vector< int64_t > > const &", capacities: "std::vector< int64_t > const &") -> "void":
-        r"""Initializes the solver and enters the problem to be solved."""
-        return _pywrapknapsack_solver.KnapsackSolver_Init(self, profits, weights, capacities)
+    This solver can deal with both large number of items and several
+    dimensions. This solver is based on branch and bound.
+    """
+    KNAPSACK_MULTIDIMENSION_SCIP_MIP_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_MULTIDIMENSION_SCIP_MIP_SOLVER
+    r"""
+     SCIP based solver
 
-    def Solve(self) -> "int64_t":
-        r"""Solves the problem and returns the profit of the optimal solution."""
-        return _pywrapknapsack_solver.KnapsackSolver_Solve(self)
+    This solver can deal with both large number of items and several
+    dimensions. This solver is based on Integer Programming solver SCIP.
+    """
 
-    def BestSolutionContains(self, item_id: "int") -> "bool":
-        r"""Returns true if the item 'item_id' is packed in the optimal knapsack."""
-        return _pywrapknapsack_solver.KnapsackSolver_BestSolutionContains(self, item_id)
+    def __init__(self, *args):
+        _pywrapknapsack_solver.KnapsackSolver_swiginit(self, _pywrapknapsack_solver.new_KnapsackSolver(*args))
+    __swig_destroy__ = _pywrapknapsack_solver.delete_KnapsackSolver
 
-    def set_use_reduction(self, use_reduction: "bool") -> "void":
-        return _pywrapknapsack_solver.KnapsackSolver_set_use_reduction(self, use_reduction)
+    def Init(self, profits: "std::vector< int64_t > const &", weights: "std::vector< std::vector< int64_t > > const &", capacities: "std::vector< int64_t > const &") -> "void":
+        r"""Initializes the solver and enters the problem to be solved."""
+        return _pywrapknapsack_solver.KnapsackSolver_Init(self, profits, weights, capacities)
 
-    def set_time_limit(self, time_limit_seconds: "double") -> "void":
-        r"""
-         Time limit in seconds.
+    def Solve(self) -> "int64_t":
+        r"""Solves the problem and returns the profit of the optimal solution."""
+        return _pywrapknapsack_solver.KnapsackSolver_Solve(self)
 
-        When a finite time limit is set the solution obtained might not be optimal
-        if the limit is reached.
-        """
-        return _pywrapknapsack_solver.KnapsackSolver_set_time_limit(self, time_limit_seconds)
+    def BestSolutionContains(self, item_id: "int") -> "bool":
+        r"""Returns true if the item 'item_id' is packed in the optimal knapsack."""
+        return _pywrapknapsack_solver.KnapsackSolver_BestSolutionContains(self, item_id)
+
+    def set_use_reduction(self, use_reduction: "bool") -> "void":
+        return _pywrapknapsack_solver.KnapsackSolver_set_use_reduction(self, use_reduction)
+
+    def set_time_limit(self, time_limit_seconds: "double") -> "void":
+        r"""
+         Time limit in seconds.
+
+        When a finite time limit is set the solution obtained might not be optimal
+        if the limit is reached.
+        """
+        return _pywrapknapsack_solver.KnapsackSolver_set_time_limit(self, time_limit_seconds)
+
+# Register KnapsackSolver in _pywrapknapsack_solver:
+_pywrapknapsack_solver.KnapsackSolver_swigregister(KnapsackSolver)
+
+ +
+ +
+
+
+ #   + + + class + KnapsackSolver: +
+ +
+ View Source +
class KnapsackSolver(object):
+    r"""
+     This library solves knapsack problems.
+
+     Problems the library solves include:
+      - 0-1 knapsack problems,
+      - Multi-dimensional knapsack problems,
+
+    Given n items, each with a profit and a weight, given a knapsack of
+    capacity c, the goal is to find a subset of items which fits inside c
+    and maximizes the total profit.
+    The knapsack problem can easily be extended from 1 to d dimensions.
+    As an example, this can be useful to constrain the maximum number of
+    items inside the knapsack.
+    Without loss of generality, profits and weights are assumed to be positive.
+
+    From a mathematical point of view, the multi-dimensional knapsack problem
+    can be modeled by d linear constraints:
+
+        ForEach(j:1..d)(Sum(i:1..n)(weight_ij * item_i) <= c_j
+            where item_i is a 0-1 integer variable.
+
+    Then the goal is to maximize:
+
+        Sum(i:1..n)(profit_i * item_i).
+
+    There are several ways to solve knapsack problems. One of the most
+    efficient is based on dynamic programming (mainly when weights, profits
+    and dimensions are small, and the algorithm runs in pseudo polynomial time).
+    Unfortunately, when adding conflict constraints the problem becomes strongly
+    NP-hard, i.e. there is no pseudo-polynomial algorithm to solve it.
+    That's the reason why the most of the following code is based on branch and
+    bound search.
+
+    For instance to solve a 2-dimensional knapsack problem with 9 items,
+    one just has to feed a profit vector with the 9 profits, a vector of 2
+    vectors for weights, and a vector of capacities.
+    E.g.:
+
+      **Python**:
+      .py}
+          profits = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
+          weights = [ [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
+                      [ 1, 1, 1, 1, 1, 1, 1, 1, 1 ]
+                    ]
+          capacities = [ 34, 4 ]
+
+          solver = pywrapknapsack_solver.KnapsackSolver(
+              pywrapknapsack_solver.KnapsackSolver
+                  .KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER,
+              'Multi-dimensional solver')
+          solver.Init(profits, weights, capacities)
+          profit = solver.Solve()
+
+
+      **C++**:
+      .cpp}
+         const std::vector<int64_t> profits = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+         const std::vector<std::vector<int64_t>> weights =
+             { { 1, 2, 3, 4, 5, 6, 7, 8, 9 },
+               { 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
+         const std::vector<int64_t> capacities = { 34, 4 };
+
+         KnapsackSolver solver(
+             KnapsackSolver::KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER,
+             "Multi-dimensional solver");
+         solver.Init(profits, weights, capacities);
+         const int64_t profit = solver.Solve();
+
+
+      **Java**:
+      .java}
+        final long[] profits = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+        final long[][] weights = { { 1, 2, 3, 4, 5, 6, 7, 8, 9 },
+               { 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
+        final long[] capacities = { 34, 4 };
+
+        KnapsackSolver solver = new KnapsackSolver(
+            KnapsackSolver.SolverType.KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER,
+            "Multi-dimensional solver");
+        solver.init(profits, weights, capacities);
+        final long profit = solver.solve();
+
+    """
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+    KNAPSACK_BRUTE_FORCE_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_BRUTE_FORCE_SOLVER
+    r"""
+     Brute force method.
+
+    Limited to 30 items and one dimension, this
+    solver uses a brute force algorithm, ie. explores all possible states.
+    Experiments show competitive performance for instances with less than
+    15 items.
+    """
+    KNAPSACK_64ITEMS_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_64ITEMS_SOLVER
+    r"""
+     Optimized method for single dimension small problems
+
+    Limited to 64 items and one dimension, this
+    solver uses a branch & bound algorithm. This solver is about 4 times
+    faster than KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER.
+    """
+    KNAPSACK_DYNAMIC_PROGRAMMING_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_DYNAMIC_PROGRAMMING_SOLVER
+    r"""
+     Dynamic Programming approach for single dimension problems
+
+    Limited to one dimension, this solver is based on a dynamic programming
+    algorithm. The time and space complexity is O(capacity *
+    number_of_items).
+    """
+    KNAPSACK_MULTIDIMENSION_CBC_MIP_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_MULTIDIMENSION_CBC_MIP_SOLVER
+    r"""
+     CBC Based Solver
+
+     This solver can deal with both large number of items and several
+    dimensions. This solver is based on Integer Programming solver CBC.
+    """
+    KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER
+    r"""
+     Generic Solver.
+
+    This solver can deal with both large number of items and several
+    dimensions. This solver is based on branch and bound.
+    """
+    KNAPSACK_MULTIDIMENSION_SCIP_MIP_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_MULTIDIMENSION_SCIP_MIP_SOLVER
+    r"""
+     SCIP based solver
+
+    This solver can deal with both large number of items and several
+    dimensions. This solver is based on Integer Programming solver SCIP.
+    """
+
+    def __init__(self, *args):
+        _pywrapknapsack_solver.KnapsackSolver_swiginit(self, _pywrapknapsack_solver.new_KnapsackSolver(*args))
+    __swig_destroy__ = _pywrapknapsack_solver.delete_KnapsackSolver
+
+    def Init(self, profits: "std::vector< int64_t > const &", weights: "std::vector< std::vector< int64_t > > const &", capacities: "std::vector< int64_t > const &") -> "void":
+        r"""Initializes the solver and enters the problem to be solved."""
+        return _pywrapknapsack_solver.KnapsackSolver_Init(self, profits, weights, capacities)
+
+    def Solve(self) -> "int64_t":
+        r"""Solves the problem and returns the profit of the optimal solution."""
+        return _pywrapknapsack_solver.KnapsackSolver_Solve(self)
+
+    def BestSolutionContains(self, item_id: "int") -> "bool":
+        r"""Returns true if the item 'item_id' is packed in the optimal knapsack."""
+        return _pywrapknapsack_solver.KnapsackSolver_BestSolutionContains(self, item_id)
+
+    def set_use_reduction(self, use_reduction: "bool") -> "void":
+        return _pywrapknapsack_solver.KnapsackSolver_set_use_reduction(self, use_reduction)
+
+    def set_time_limit(self, time_limit_seconds: "double") -> "void":
+        r"""
+         Time limit in seconds.
+
+        When a finite time limit is set the solution obtained might not be optimal
+        if the limit is reached.
+        """
+        return _pywrapknapsack_solver.KnapsackSolver_set_time_limit(self, time_limit_seconds)
+
+ +
+ +

This library solves knapsack problems.

+ +

Problems the library solves include:

+ +
    +
  • 0-1 knapsack problems,
  • +
  • Multi-dimensional knapsack problems,
  • +
-# Register KnapsackSolver in _pywrapknapsack_solver: -_pywrapknapsack_solver.KnapsackSolver_swigregister(KnapsackSolver)
-
-
-
-
-
-
-
-
-
-

Classes

-
-
-class KnapsackSolver -(*args) -
-
-

This library solves knapsack problems.

-

Problems the library solves include: -- 0-1 knapsack problems, -- Multi-dimensional knapsack problems,

Given n items, each with a profit and a weight, given a knapsack of capacity c, the goal is to find a subset of items which fits inside c and maximizes the total profit. @@ -288,14 +513,20 @@ The knapsack problem can easily be extended from 1 to d dimensions. As an example, this can be useful to constrain the maximum number of items inside the knapsack. Without loss of generality, profits and weights are assumed to be positive.

+

From a mathematical point of view, the multi-dimensional knapsack problem can be modeled by d linear constraints:

+
ForEach(j:1..d)(Sum(i:1..n)(weight_ij * item_i) <= c_j
     where item_i is a 0-1 integer variable.
 
-

Then the goal is to maximize:

-
Sum(i:1..n)(profit_i * item_i).
-
+ +
Then the goal is to maximize
+ +
+

Sum(i:1..n)(profit_i * item_i).

+
+

There are several ways to solve knapsack problems. One of the most efficient is based on dynamic programming (mainly when weights, profits and dimensions are small, and the algorithm runs in pseudo polynomial time). @@ -303,397 +534,297 @@ Unfortunately, when adding conflict constraints the problem becomes strongly NP-hard, i.e. there is no pseudo-polynomial algorithm to solve it. That's the reason why the most of the following code is based on branch and bound search.

+

For instance to solve a 2-dimensional knapsack problem with 9 items, one just has to feed a profit vector with the 9 profits, a vector of 2 vectors for weights, and a vector of capacities. E.g.:

-

Python:

-

.. code-block:: python

-
      profits = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
+
+

Python: + .py} + profits = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] weights = [ [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ], [ 1, 1, 1, 1, 1, 1, 1, 1, 1 ] ] - capacities = [ 34, 4 ] + capacities = [ 34, 4 ]

- solver = pywrapknapsack_solver.KnapsackSolver( - pywrapknapsack_solver.KnapsackSolver - .KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER, - 'Multi-dimensional solver') - solver.Init(profits, weights, capacities) - profit = solver.Solve() +
  solver = pywrapknapsack_solver.KnapsackSolver(
+      pywrapknapsack_solver.KnapsackSolver
+          .KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER,
+      'Multi-dimensional solver')
+  solver.Init(profits, weights, capacities)
+  profit = solver.Solve()
 
-

C++:

-

.. code-block:: c++

-
     const std::vector<int64_t> profits = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
-     const std::vector<std::vector<int64_t>> weights =
+
+

C++: + .cpp} + const std::vector profits = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + const std::vector> weights = { { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1 } }; - const std::vector<int64_t> capacities = { 34, 4 }; + const std::vector capacities = { 34, 4 };

- KnapsackSolver solver( - KnapsackSolver::KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER, - "Multi-dimensional solver"); - solver.Init(profits, weights, capacities); - const int64_t profit = solver.Solve(); +
 KnapsackSolver solver(
+     KnapsackSolver::KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER,
+     "Multi-dimensional solver");
+ solver.Init(profits, weights, capacities);
+ const int64_t profit = solver.Solve();
 
-

Java:

-

.. code-block:: java

-
    final long[] profits = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+
+

Java: + .java} + final long[] profits = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; final long[][] weights = { { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1 } }; - final long[] capacities = { 34, 4 }; + final long[] capacities = { 34, 4 };

- KnapsackSolver solver = new KnapsackSolver( - KnapsackSolver.SolverType.KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER, - "Multi-dimensional solver"); - solver.init(profits, weights, capacities); - final long profit = solver.solve(); -
-
- -Expand source code - -
class KnapsackSolver(object):
-    r"""
-     This library solves knapsack problems.
+
KnapsackSolver solver = new KnapsackSolver(
+    KnapsackSolver.SolverType.KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER,
+    "Multi-dimensional solver");
+solver.init(profits, weights, capacities);
+final long profit = solver.solve();
+
+ - Problems the library solves include: - - 0-1 knapsack problems, - - Multi-dimensional knapsack problems, - Given n items, each with a profit and a weight, given a knapsack of - capacity c, the goal is to find a subset of items which fits inside c - and maximizes the total profit. - The knapsack problem can easily be extended from 1 to d dimensions. - As an example, this can be useful to constrain the maximum number of - items inside the knapsack. - Without loss of generality, profits and weights are assumed to be positive. +
+
#   - From a mathematical point of view, the multi-dimensional knapsack problem - can be modeled by d linear constraints: + + KnapsackSolver(*args) +
- ForEach(j:1..d)(Sum(i:1..n)(weight_ij * item_i) <= c_j - where item_i is a 0-1 integer variable. +
+ View Source +
    def __init__(self, *args):
+        _pywrapknapsack_solver.KnapsackSolver_swiginit(self, _pywrapknapsack_solver.new_KnapsackSolver(*args))
+
- Then the goal is to maximize: +
- Sum(i:1..n)(profit_i * item_i). + - There are several ways to solve knapsack problems. One of the most - efficient is based on dynamic programming (mainly when weights, profits - and dimensions are small, and the algorithm runs in pseudo polynomial time). - Unfortunately, when adding conflict constraints the problem becomes strongly - NP-hard, i.e. there is no pseudo-polynomial algorithm to solve it. - That's the reason why the most of the following code is based on branch and - bound search. +
+
+
#   - For instance to solve a 2-dimensional knapsack problem with 9 items, - one just has to feed a profit vector with the 9 profits, a vector of 2 - vectors for weights, and a vector of capacities. - E.g.: + thisown +
- **Python**: +

The membership flag

+
- .. code-block:: python - profits = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] - weights = [ [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ], - [ 1, 1, 1, 1, 1, 1, 1, 1, 1 ] - ] - capacities = [ 34, 4 ] +
+
+
#   - solver = pywrapknapsack_solver.KnapsackSolver( - pywrapknapsack_solver.KnapsackSolver - .KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER, - 'Multi-dimensional solver') - solver.Init(profits, weights, capacities) - profit = solver.Solve() + KNAPSACK_BRUTE_FORCE_SOLVER = 0 +
- **C++**: +

Brute force method.

- .. code-block:: c++ - - const std::vector<int64_t> profits = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - const std::vector<std::vector<int64_t>> weights = - { { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, - { 1, 1, 1, 1, 1, 1, 1, 1, 1 } }; - const std::vector<int64_t> capacities = { 34, 4 }; - - KnapsackSolver solver( - KnapsackSolver::KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER, - "Multi-dimensional solver"); - solver.Init(profits, weights, capacities); - const int64_t profit = solver.Solve(); - - **Java**: - - .. code-block:: java - - final long[] profits = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - final long[][] weights = { { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, - { 1, 1, 1, 1, 1, 1, 1, 1, 1 } }; - final long[] capacities = { 34, 4 }; - - KnapsackSolver solver = new KnapsackSolver( - KnapsackSolver.SolverType.KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER, - "Multi-dimensional solver"); - solver.init(profits, weights, capacities); - final long profit = solver.solve(); - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - KNAPSACK_BRUTE_FORCE_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_BRUTE_FORCE_SOLVER - r""" - Brute force method. - - Limited to 30 items and one dimension, this - solver uses a brute force algorithm, ie. explores all possible states. - Experiments show competitive performance for instances with less than - 15 items. - """ - KNAPSACK_64ITEMS_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_64ITEMS_SOLVER - r""" - Optimized method for single dimension small problems - - Limited to 64 items and one dimension, this - solver uses a branch & bound algorithm. This solver is about 4 times - faster than KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER. - """ - KNAPSACK_DYNAMIC_PROGRAMMING_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_DYNAMIC_PROGRAMMING_SOLVER - r""" - Dynamic Programming approach for single dimension problems - - Limited to one dimension, this solver is based on a dynamic programming - algorithm. The time complexity is O(capacity * number_of_items^2) and - the space complexity is O(capacity + number_of_items). - """ - KNAPSACK_MULTIDIMENSION_CBC_MIP_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_MULTIDIMENSION_CBC_MIP_SOLVER - r""" - CBC Based Solver - - This solver can deal with both large number of items and several - dimensions. This solver is based on Integer Programming solver CBC. - """ - KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER - r""" - Generic Solver. - - This solver can deal with both large number of items and several - dimensions. This solver is based on branch and bound. - """ - KNAPSACK_MULTIDIMENSION_SCIP_MIP_SOLVER = _pywrapknapsack_solver.KnapsackSolver_KNAPSACK_MULTIDIMENSION_SCIP_MIP_SOLVER - r""" - SCIP based solver - - This solver can deal with both large number of items and several - dimensions. This solver is based on Integer Programming solver SCIP. - """ - - def __init__(self, *args): - _pywrapknapsack_solver.KnapsackSolver_swiginit(self, _pywrapknapsack_solver.new_KnapsackSolver(*args)) - __swig_destroy__ = _pywrapknapsack_solver.delete_KnapsackSolver - - def Init(self, profits: "std::vector< int64_t > const &", weights: "std::vector< std::vector< int64_t > > const &", capacities: "std::vector< int64_t > const &") -> "void": - r"""Initializes the solver and enters the problem to be solved.""" - return _pywrapknapsack_solver.KnapsackSolver_Init(self, profits, weights, capacities) - - def Solve(self) -> "int64_t": - r"""Solves the problem and returns the profit of the optimal solution.""" - return _pywrapknapsack_solver.KnapsackSolver_Solve(self) - - def BestSolutionContains(self, item_id: "int") -> "bool": - r"""Returns true if the item 'item_id' is packed in the optimal knapsack.""" - return _pywrapknapsack_solver.KnapsackSolver_BestSolutionContains(self, item_id) - - def set_use_reduction(self, use_reduction: "bool") -> "void": - return _pywrapknapsack_solver.KnapsackSolver_set_use_reduction(self, use_reduction) - - def set_time_limit(self, time_limit_seconds: "double") -> "void": - r""" - Time limit in seconds. - - When a finite time limit is set the solution obtained might not be optimal - if the limit is reached. - """ - return _pywrapknapsack_solver.KnapsackSolver_set_time_limit(self, time_limit_seconds)
-
-

Class variables

-
-
var KNAPSACK_64ITEMS_SOLVER
-
-

Optimized method for single dimension small problems

-

Limited to 64 items and one dimension, this -solver uses a branch & bound algorithm. This solver is about 4 times -faster than KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER.

-
-
var KNAPSACK_BRUTE_FORCE_SOLVER
-
-

Brute force method.

Limited to 30 items and one dimension, this solver uses a brute force algorithm, ie. explores all possible states. Experiments show competitive performance for instances with less than -15 items.

-
-
var KNAPSACK_DYNAMIC_PROGRAMMING_SOLVER
-
-

Dynamic Programming approach for single dimension problems

-

Limited to one dimension, this solver is based on a dynamic programming -algorithm. The time complexity is O(capacity * number_of_items^2) and -the space complexity is O(capacity + number_of_items).

-
-
var KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER
-
-

Generic Solver.

-

This solver can deal with both large number of items and several -dimensions. This solver is based on branch and bound.

-
-
var KNAPSACK_MULTIDIMENSION_CBC_MIP_SOLVER
-
-

CBC Based Solver

-

This solver can deal with both large number of items and several -dimensions. This solver is based on Integer Programming solver CBC.

-
-
var KNAPSACK_MULTIDIMENSION_SCIP_MIP_SOLVER
-
-

SCIP based solver

-

This solver can deal with both large number of items and several -dimensions. This solver is based on Integer Programming solver SCIP.

-
-
-

Instance variables

-
-
var thisown
-
-

The membership flag

-
- -Expand source code - -
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-
-
-

Methods

-
-
-def BestSolutionContains(self, item_id: int) ‑> bool -
-
-

Returns true if the item 'item_id' is packed in the optimal knapsack.

-
- -Expand source code - -
def BestSolutionContains(self, item_id: "int") -> "bool":
-    r"""Returns true if the item 'item_id' is packed in the optimal knapsack."""
-    return _pywrapknapsack_solver.KnapsackSolver_BestSolutionContains(self, item_id)
-
-
-
-def Init(self, profits: std::vector< int64_t > const &, weights: std::vector< std::vector< int64_t > > const &, capacities: std::vector< int64_t > const &) ‑> void -
-
-

Initializes the solver and enters the problem to be solved.

-
- -Expand source code - -
def Init(self, profits: "std::vector< int64_t > const &", weights: "std::vector< std::vector< int64_t > > const &", capacities: "std::vector< int64_t > const &") -> "void":
-    r"""Initializes the solver and enters the problem to be solved."""
-    return _pywrapknapsack_solver.KnapsackSolver_Init(self, profits, weights, capacities)
-
-
-
-def Solve(self) ‑> int64_t -
-
-

Solves the problem and returns the profit of the optimal solution.

-
- -Expand source code - -
def Solve(self) -> "int64_t":
-    r"""Solves the problem and returns the profit of the optimal solution."""
-    return _pywrapknapsack_solver.KnapsackSolver_Solve(self)
-
-
-
-def set_time_limit(self, time_limit_seconds: double) ‑> void -
-
-

Time limit in seconds.

-

When a finite time limit is set the solution obtained might not be optimal -if the limit is reached.

-
- -Expand source code - -
def set_time_limit(self, time_limit_seconds: "double") -> "void":
-    r"""
-     Time limit in seconds.
-
-    When a finite time limit is set the solution obtained might not be optimal
-    if the limit is reached.
-    """
-    return _pywrapknapsack_solver.KnapsackSolver_set_time_limit(self, time_limit_seconds)
-
-
-
-def set_use_reduction(self, use_reduction: bool) ‑> void -
-
-
-
- -Expand source code - -
def set_use_reduction(self, use_reduction: "bool") -> "void":
-    return _pywrapknapsack_solver.KnapsackSolver_set_use_reduction(self, use_reduction)
-
-
-
-
-
-
-
- -
- + + + +
+
#   + + KNAPSACK_64ITEMS_SOLVER = 1 +
+ +

Optimized method for single dimension small problems

+ +

Limited to 64 items and one dimension, this +solver uses a branch & bound algorithm. This solver is about 4 times +faster than KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER.

+
+ + +
+
+
#   + + KNAPSACK_DYNAMIC_PROGRAMMING_SOLVER = 2 +
+ +

Dynamic Programming approach for single dimension problems

+ +

Limited to one dimension, this solver is based on a dynamic programming +algorithm. The time and space complexity is O(capacity * +number_of_items).

+
+ + +
+
+
#   + + KNAPSACK_MULTIDIMENSION_CBC_MIP_SOLVER = 3 +
+ +

CBC Based Solver

+ +

This solver can deal with both large number of items and several +dimensions. This solver is based on Integer Programming solver CBC.

+
+ + +
+
+
#   + + KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER = 5 +
+ +

Generic Solver.

+ +

This solver can deal with both large number of items and several +dimensions. This solver is based on branch and bound.

+
+ + +
+
+
#   + + KNAPSACK_MULTIDIMENSION_SCIP_MIP_SOLVER = 6 +
+ +

SCIP based solver

+ +

This solver can deal with both large number of items and several +dimensions. This solver is based on Integer Programming solver SCIP.

+
+ + +
+
+
#   + + + def + Init( + self, + profits: 'std::vector< int64_t > const &', + weights: 'std::vector< std::vector< int64_t > > const &', + capacities: 'std::vector< int64_t > const &' +) -> 'void': +
+ +
+ View Source +
    def Init(self, profits: "std::vector< int64_t > const &", weights: "std::vector< std::vector< int64_t > > const &", capacities: "std::vector< int64_t > const &") -> "void":
+        r"""Initializes the solver and enters the problem to be solved."""
+        return _pywrapknapsack_solver.KnapsackSolver_Init(self, profits, weights, capacities)
+
+ +
+ +

Initializes the solver and enters the problem to be solved.

+
+ + +
+
+
#   + + + def + Solve(self) -> 'int64_t': +
+ +
+ View Source +
    def Solve(self) -> "int64_t":
+        r"""Solves the problem and returns the profit of the optimal solution."""
+        return _pywrapknapsack_solver.KnapsackSolver_Solve(self)
+
+ +
+ +

Solves the problem and returns the profit of the optimal solution.

+
+ + +
+
+
#   + + + def + BestSolutionContains(self, item_id: int) -> bool: +
+ +
+ View Source +
    def BestSolutionContains(self, item_id: "int") -> "bool":
+        r"""Returns true if the item 'item_id' is packed in the optimal knapsack."""
+        return _pywrapknapsack_solver.KnapsackSolver_BestSolutionContains(self, item_id)
+
+ +
+ +

Returns true if the item 'item_id' is packed in the optimal knapsack.

+
+ + +
+
+
#   + + + def + set_use_reduction(self, use_reduction: bool) -> 'void': +
+ +
+ View Source +
    def set_use_reduction(self, use_reduction: "bool") -> "void":
+        return _pywrapknapsack_solver.KnapsackSolver_set_use_reduction(self, use_reduction)
+
+ +
+ + + +
+
+
#   + + + def + set_time_limit(self, time_limit_seconds: 'double') -> 'void': +
+ +
+ View Source +
    def set_time_limit(self, time_limit_seconds: "double") -> "void":
+        r"""
+         Time limit in seconds.
+
+        When a finite time limit is set the solution obtained might not be optimal
+        if the limit is reached.
+        """
+        return _pywrapknapsack_solver.KnapsackSolver_set_time_limit(self, time_limit_seconds)
+
+ +
+ +

Time limit in seconds.

+ +

When a finite time limit is set the solution obtained might not be optimal +if the limit is reached.

+
+ + +
+ + \ No newline at end of file diff --git a/docs/python/ortools/constraint_solver/pywrapcp.html b/docs/python/ortools/constraint_solver/pywrapcp.html index a057fbd821..0707fa1608 100644 --- a/docs/python/ortools/constraint_solver/pywrapcp.html +++ b/docs/python/ortools/constraint_solver/pywrapcp.html @@ -1,29453 +1,35152 @@ - - - -pywrapcp API documentation - - - - - - - - - - - + + + + pywrapcp API documentation + + + + + + - -
-
-
-

Module pywrapcp

-
-
-
- -Expand source code - -
# This file was automatically generated by SWIG (http://www.swig.org).
-# Version 4.0.2
-#
-# Do not make changes to this file unless you know what you are doing--modify
-# the SWIG interface file instead.
-
-from sys import version_info as _swig_python_version_info
-if _swig_python_version_info < (2, 7, 0):
-    raise RuntimeError("Python 2.7 or later required")
-
-# Import the low-level C/C++ module
-if __package__ or "." in __name__:
-    from . import _pywrapcp
-else:
-    import _pywrapcp
-
-try:
-    import builtins as __builtin__
-except ImportError:
-    import __builtin__
-
-def _swig_repr(self):
-    try:
-        strthis = "proxy of " + self.this.__repr__()
-    except __builtin__.Exception:
-        strthis = ""
-    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
-
-
-def _swig_setattr_nondynamic_instance_variable(set):
-    def set_instance_attr(self, name, value):
-        if name == "thisown":
-            self.this.own(value)
-        elif name == "this":
-            set(self, name, value)
-        elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
-            set(self, name, value)
-        else:
-            raise AttributeError("You cannot add instance attributes to %s" % self)
-    return set_instance_attr
-
-
-def _swig_setattr_nondynamic_class_variable(set):
-    def set_class_attr(cls, name, value):
-        if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
-            set(cls, name, value)
-        else:
-            raise AttributeError("You cannot add class attributes to %s" % cls)
-    return set_class_attr
-
-
-def _swig_add_metaclass(metaclass):
-    """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
-    def wrapper(cls):
-        return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
-    return wrapper
-
-
-class _SwigNonDynamicMeta(type):
-    """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
-    __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)
-
-
-import weakref
-
-class DefaultPhaseParameters(object):
-    r"""
-    This struct holds all parameters for the default search.
-    DefaultPhaseParameters is only used by Solver::MakeDefaultPhase methods.
-    Note this is for advanced users only.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-    CHOOSE_MAX_SUM_IMPACT = _pywrapcp.DefaultPhaseParameters_CHOOSE_MAX_SUM_IMPACT
-    CHOOSE_MAX_AVERAGE_IMPACT = _pywrapcp.DefaultPhaseParameters_CHOOSE_MAX_AVERAGE_IMPACT
-    CHOOSE_MAX_VALUE_IMPACT = _pywrapcp.DefaultPhaseParameters_CHOOSE_MAX_VALUE_IMPACT
-    SELECT_MIN_IMPACT = _pywrapcp.DefaultPhaseParameters_SELECT_MIN_IMPACT
-    SELECT_MAX_IMPACT = _pywrapcp.DefaultPhaseParameters_SELECT_MAX_IMPACT
-    NONE = _pywrapcp.DefaultPhaseParameters_NONE
-    NORMAL = _pywrapcp.DefaultPhaseParameters_NORMAL
-    VERBOSE = _pywrapcp.DefaultPhaseParameters_VERBOSE
-    var_selection_schema = property(_pywrapcp.DefaultPhaseParameters_var_selection_schema_get, _pywrapcp.DefaultPhaseParameters_var_selection_schema_set, doc=r"""
-    This parameter describes how the next variable to instantiate
-    will be chosen.
-    """)
-    value_selection_schema = property(_pywrapcp.DefaultPhaseParameters_value_selection_schema_get, _pywrapcp.DefaultPhaseParameters_value_selection_schema_set, doc=r""" This parameter describes which value to select for a given var.""")
-    initialization_splits = property(_pywrapcp.DefaultPhaseParameters_initialization_splits_get, _pywrapcp.DefaultPhaseParameters_initialization_splits_set, doc=r"""
-    Maximum number of intervals that the initialization of impacts will scan
-    per variable.
-    """)
-    run_all_heuristics = property(_pywrapcp.DefaultPhaseParameters_run_all_heuristics_get, _pywrapcp.DefaultPhaseParameters_run_all_heuristics_set, doc=r"""
-    The default phase will run heuristics periodically. This parameter
-    indicates if we should run all heuristics, or a randomly selected
-    one.
-    """)
-    heuristic_period = property(_pywrapcp.DefaultPhaseParameters_heuristic_period_get, _pywrapcp.DefaultPhaseParameters_heuristic_period_set, doc=r"""
-    The distance in nodes between each run of the heuristics. A
-    negative or null value will mean that we will not run heuristics
-    at all.
-    """)
-    heuristic_num_failures_limit = property(_pywrapcp.DefaultPhaseParameters_heuristic_num_failures_limit_get, _pywrapcp.DefaultPhaseParameters_heuristic_num_failures_limit_set, doc=r""" The failure limit for each heuristic that we run.""")
-    persistent_impact = property(_pywrapcp.DefaultPhaseParameters_persistent_impact_get, _pywrapcp.DefaultPhaseParameters_persistent_impact_set, doc=r"""
-    Whether to keep the impact from the first search for other searches,
-    or to recompute the impact for each new search.
-    """)
-    random_seed = property(_pywrapcp.DefaultPhaseParameters_random_seed_get, _pywrapcp.DefaultPhaseParameters_random_seed_set, doc=r""" Seed used to initialize the random part in some heuristics.""")
-    display_level = property(_pywrapcp.DefaultPhaseParameters_display_level_get, _pywrapcp.DefaultPhaseParameters_display_level_set, doc=r"""
-    This represents the amount of information displayed by the default search.
-    NONE means no display, VERBOSE means extra information.
-    """)
-    decision_builder = property(_pywrapcp.DefaultPhaseParameters_decision_builder_get, _pywrapcp.DefaultPhaseParameters_decision_builder_set, doc=r""" When defined, this overrides the default impact based decision builder.""")
-
-    def __init__(self):
-        _pywrapcp.DefaultPhaseParameters_swiginit(self, _pywrapcp.new_DefaultPhaseParameters())
-    __swig_destroy__ = _pywrapcp.delete_DefaultPhaseParameters
-
-# Register DefaultPhaseParameters in _pywrapcp:
-_pywrapcp.DefaultPhaseParameters_swigregister(DefaultPhaseParameters)
-
-class Solver(object):
-    r"""
-    Solver Class
-
-    A solver represents the main computation engine. It implements the entire
-    range of Constraint Programming protocols:
-      - Reversibility
-      - Propagation
-      - Search
-
-    Usually, Constraint Programming code consists of
-      - the creation of the Solver,
-      - the creation of the decision variables of the model,
-      - the creation of the constraints of the model and their addition to the
-        solver() through the AddConstraint() method,
-      - the creation of the main DecisionBuilder class,
-      - the launch of the solve() method with the decision builder.
-
-    For the time being, Solver is neither MT_SAFE nor MT_HOT.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-    INT_VAR_DEFAULT = _pywrapcp.Solver_INT_VAR_DEFAULT
-    r""" The default behavior is CHOOSE_FIRST_UNBOUND."""
-    INT_VAR_SIMPLE = _pywrapcp.Solver_INT_VAR_SIMPLE
-    r""" The simple selection is CHOOSE_FIRST_UNBOUND."""
-    CHOOSE_FIRST_UNBOUND = _pywrapcp.Solver_CHOOSE_FIRST_UNBOUND
-    r"""
-    Select the first unbound variable.
-    Variables are considered in the order of the vector of IntVars used
-    to create the selector.
-    """
-    CHOOSE_RANDOM = _pywrapcp.Solver_CHOOSE_RANDOM
-    r""" Randomly select one of the remaining unbound variables."""
-    CHOOSE_MIN_SIZE_LOWEST_MIN = _pywrapcp.Solver_CHOOSE_MIN_SIZE_LOWEST_MIN
-    r"""
-    Among unbound variables, select the variable with the smallest size,
-    i.e., the smallest number of possible values.
-    In case of a tie, the selected variables is the one with the lowest min
-    value.
-    In case of a tie, the first one is selected, first being defined by the
-    order in the vector of IntVars used to create the selector.
-    """
-    CHOOSE_MIN_SIZE_HIGHEST_MIN = _pywrapcp.Solver_CHOOSE_MIN_SIZE_HIGHEST_MIN
-    r"""
-    Among unbound variables, select the variable with the smallest size,
-    i.e., the smallest number of possible values.
-    In case of a tie, the selected variable is the one with the highest min
-    value.
-    In case of a tie, the first one is selected, first being defined by the
-    order in the vector of IntVars used to create the selector.
-    """
-    CHOOSE_MIN_SIZE_LOWEST_MAX = _pywrapcp.Solver_CHOOSE_MIN_SIZE_LOWEST_MAX
-    r"""
-    Among unbound variables, select the variable with the smallest size,
-    i.e., the smallest number of possible values.
-    In case of a tie, the selected variables is the one with the lowest max
-    value.
-    In case of a tie, the first one is selected, first being defined by the
-    order in the vector of IntVars used to create the selector.
-    """
-    CHOOSE_MIN_SIZE_HIGHEST_MAX = _pywrapcp.Solver_CHOOSE_MIN_SIZE_HIGHEST_MAX
-    r"""
-    Among unbound variables, select the variable with the smallest size,
-    i.e., the smallest number of possible values.
-    In case of a tie, the selected variable is the one with the highest max
-    value.
-    In case of a tie, the first one is selected, first being defined by the
-    order in the vector of IntVars used to create the selector.
-    """
-    CHOOSE_LOWEST_MIN = _pywrapcp.Solver_CHOOSE_LOWEST_MIN
-    r"""
-    Among unbound variables, select the variable with the smallest minimal
-    value.
-    In case of a tie, the first one is selected, "first" defined by the
-    order in the vector of IntVars used to create the selector.
-    """
-    CHOOSE_HIGHEST_MAX = _pywrapcp.Solver_CHOOSE_HIGHEST_MAX
-    r"""
-    Among unbound variables, select the variable with the highest maximal
-    value.
-    In case of a tie, the first one is selected, first being defined by the
-    order in the vector of IntVars used to create the selector.
-    """
-    CHOOSE_MIN_SIZE = _pywrapcp.Solver_CHOOSE_MIN_SIZE
-    r"""
-    Among unbound variables, select the variable with the smallest size.
-    In case of a tie, the first one is selected, first being defined by the
-    order in the vector of IntVars used to create the selector.
-    """
-    CHOOSE_MAX_SIZE = _pywrapcp.Solver_CHOOSE_MAX_SIZE
-    r"""
-    Among unbound variables, select the variable with the highest size.
-    In case of a tie, the first one is selected, first being defined by the
-    order in the vector of IntVars used to create the selector.
-    """
-    CHOOSE_MAX_REGRET_ON_MIN = _pywrapcp.Solver_CHOOSE_MAX_REGRET_ON_MIN
-    r"""
-    Among unbound variables, select the variable with the largest
-    gap between the first and the second values of the domain.
-    """
-    CHOOSE_PATH = _pywrapcp.Solver_CHOOSE_PATH
-    r"""
-    Selects the next unbound variable on a path, the path being defined by
-    the variables: var[i] corresponds to the index of the next of i.
-    """
-    INT_VALUE_DEFAULT = _pywrapcp.Solver_INT_VALUE_DEFAULT
-    r""" The default behavior is ASSIGN_MIN_VALUE."""
-    INT_VALUE_SIMPLE = _pywrapcp.Solver_INT_VALUE_SIMPLE
-    r""" The simple selection is ASSIGN_MIN_VALUE."""
-    ASSIGN_MIN_VALUE = _pywrapcp.Solver_ASSIGN_MIN_VALUE
-    r""" Selects the min value of the selected variable."""
-    ASSIGN_MAX_VALUE = _pywrapcp.Solver_ASSIGN_MAX_VALUE
-    r""" Selects the max value of the selected variable."""
-    ASSIGN_RANDOM_VALUE = _pywrapcp.Solver_ASSIGN_RANDOM_VALUE
-    r""" Selects randomly one of the possible values of the selected variable."""
-    ASSIGN_CENTER_VALUE = _pywrapcp.Solver_ASSIGN_CENTER_VALUE
-    r"""
-    Selects the first possible value which is the closest to the center
-    of the domain of the selected variable.
-    The center is defined as (min + max) / 2.
-    """
-    SPLIT_LOWER_HALF = _pywrapcp.Solver_SPLIT_LOWER_HALF
-    r"""
-    Split the domain in two around the center, and choose the lower
-    part first.
-    """
-    SPLIT_UPPER_HALF = _pywrapcp.Solver_SPLIT_UPPER_HALF
-    r"""
-    Split the domain in two around the center, and choose the lower
-    part first.
-    """
-    SEQUENCE_DEFAULT = _pywrapcp.Solver_SEQUENCE_DEFAULT
-    SEQUENCE_SIMPLE = _pywrapcp.Solver_SEQUENCE_SIMPLE
-    CHOOSE_MIN_SLACK_RANK_FORWARD = _pywrapcp.Solver_CHOOSE_MIN_SLACK_RANK_FORWARD
-    CHOOSE_RANDOM_RANK_FORWARD = _pywrapcp.Solver_CHOOSE_RANDOM_RANK_FORWARD
-    INTERVAL_DEFAULT = _pywrapcp.Solver_INTERVAL_DEFAULT
-    r""" The default is INTERVAL_SET_TIMES_FORWARD."""
-    INTERVAL_SIMPLE = _pywrapcp.Solver_INTERVAL_SIMPLE
-    r""" The simple is INTERVAL_SET_TIMES_FORWARD."""
-    INTERVAL_SET_TIMES_FORWARD = _pywrapcp.Solver_INTERVAL_SET_TIMES_FORWARD
-    r"""
-    Selects the variable with the lowest starting time of all variables,
-    and fixes its starting time to this lowest value.
-    """
-    INTERVAL_SET_TIMES_BACKWARD = _pywrapcp.Solver_INTERVAL_SET_TIMES_BACKWARD
-    r"""
-    Selects the variable with the highest ending time of all variables,
-    and fixes the ending time to this highest values.
-    """
-    TWOOPT = _pywrapcp.Solver_TWOOPT
-    r"""
-    Operator which reverses a sub-chain of a path. It is called TwoOpt
-    because it breaks two arcs on the path; resulting paths are called
-    two-optimal.
-    Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5
-    (where (1, 5) are first and last nodes of the path and can therefore not
-    be moved):
-      1 -> [3 -> 2] -> 4  -> 5
-      1 -> [4 -> 3  -> 2] -> 5
-      1 ->  2 -> [4 -> 3] -> 5
-    """
-    OROPT = _pywrapcp.Solver_OROPT
-    r"""
-    Relocate: OROPT and RELOCATE.
-    Operator which moves a sub-chain of a path to another position; the
-    specified chain length is the fixed length of the chains being moved.
-    When this length is 1, the operator simply moves a node to another
-    position.
-    Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5, for a chain
-    length of 2 (where (1, 5) are first and last nodes of the path and can
-    therefore not be moved):
-      1 ->  4 -> [2 -> 3] -> 5
-      1 -> [3 -> 4] -> 2  -> 5
-
-    Using Relocate with chain lengths of 1, 2 and 3 together is equivalent
-    to the OrOpt operator on a path. The OrOpt operator is a limited
-     version of 3Opt (breaks 3 arcs on a path).
-    """
-    RELOCATE = _pywrapcp.Solver_RELOCATE
-    r""" Relocate neighborhood with length of 1 (see OROPT comment)."""
-    EXCHANGE = _pywrapcp.Solver_EXCHANGE
-    r"""
-    Operator which exchanges the positions of two nodes.
-    Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5
-    (where (1, 5) are first and last nodes of the path and can therefore not
-    be moved):
-      1 -> [3] -> [2] ->  4  -> 5
-      1 -> [4] ->  3  -> [2] -> 5
-      1 ->  2  -> [4] -> [3] -> 5
-    """
-    CROSS = _pywrapcp.Solver_CROSS
-    r"""
-    Operator which cross exchanges the starting chains of 2 paths, including
-    exchanging the whole paths.
-    First and last nodes are not moved.
-    Possible neighbors for the paths 1 -> 2 -> 3 -> 4 -> 5 and 6 -> 7 -> 8
-    (where (1, 5) and (6, 8) are first and last nodes of the paths and can
-    therefore not be moved):
-      1 -> [7] -> 3 -> 4 -> 5  6 -> [2] -> 8
-      1 -> [7] -> 4 -> 5       6 -> [2 -> 3] -> 8
-      1 -> [7] -> 5            6 -> [2 -> 3 -> 4] -> 8
-    """
-    MAKEACTIVE = _pywrapcp.Solver_MAKEACTIVE
-    r"""
-    Operator which inserts an inactive node into a path.
-    Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive
-    (where 1 and 4 are first and last nodes of the path) are:
-      1 -> [5] ->  2  ->  3  -> 4
-      1 ->  2  -> [5] ->  3  -> 4
-      1 ->  2  ->  3  -> [5] -> 4
-    """
-    MAKEINACTIVE = _pywrapcp.Solver_MAKEINACTIVE
-    r"""
-    Operator which makes path nodes inactive.
-    Possible neighbors for the path 1 -> 2 -> 3 -> 4 (where 1 and 4 are
-    first and last nodes of the path) are:
-      1 -> 3 -> 4 with 2 inactive
-      1 -> 2 -> 4 with 3 inactive
-    """
-    MAKECHAININACTIVE = _pywrapcp.Solver_MAKECHAININACTIVE
-    r"""
-    Operator which makes a "chain" of path nodes inactive.
-    Possible neighbors for the path 1 -> 2 -> 3 -> 4 (where 1 and 4 are
-    first and last nodes of the path) are:
-      1 -> 3 -> 4 with 2 inactive
-      1 -> 2 -> 4 with 3 inactive
-      1 -> 4 with 2 and 3 inactive
-    """
-    SWAPACTIVE = _pywrapcp.Solver_SWAPACTIVE
-    r"""
-    Operator which replaces an active node by an inactive one.
-    Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive
-    (where 1 and 4 are first and last nodes of the path) are:
-      1 -> [5] ->  3  -> 4 with 2 inactive
-      1 ->  2  -> [5] -> 4 with 3 inactive
-    """
-    EXTENDEDSWAPACTIVE = _pywrapcp.Solver_EXTENDEDSWAPACTIVE
-    r"""
-    Operator which makes an inactive node active and an active one inactive.
-    It is similar to SwapActiveOperator except that it tries to insert the
-    inactive node in all possible positions instead of just the position of
-    the node made inactive.
-    Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive
-    (where 1 and 4 are first and last nodes of the path) are:
-      1 -> [5] ->  3  -> 4 with 2 inactive
-      1 ->  3  -> [5] -> 4 with 2 inactive
-      1 -> [5] ->  2  -> 4 with 3 inactive
-      1 ->  2  -> [5] -> 4 with 3 inactive
-    """
-    PATHLNS = _pywrapcp.Solver_PATHLNS
-    r"""
-    Operator which relaxes two sub-chains of three consecutive arcs each.
-    Each sub-chain is defined by a start node and the next three arcs. Those
-    six arcs are relaxed to build a new neighbor.
-    PATHLNS explores all possible pairs of starting nodes and so defines
-    n^2 neighbors, n being the number of nodes.
-    Note that the two sub-chains can be part of the same path; they even may
-    overlap.
-    """
-    FULLPATHLNS = _pywrapcp.Solver_FULLPATHLNS
-    r"""
-    Operator which relaxes one entire path and all inactive nodes, thus
-    defining num_paths neighbors.
-    """
-    UNACTIVELNS = _pywrapcp.Solver_UNACTIVELNS
-    r"""
-    Operator which relaxes all inactive nodes and one sub-chain of six
-    consecutive arcs. That way the path can be improved by inserting
-    inactive nodes or swapping arcs.
-    """
-    INCREMENT = _pywrapcp.Solver_INCREMENT
-    r"""
-    Operator which defines one neighbor per variable. Each neighbor tries to
-    increment by one the value of the corresponding variable. When a new
-    solution is found the neighborhood is rebuilt from scratch, i.e., tries
-    to increment values in the variable order.
-    Consider for instance variables x and y. x is incremented one by one to
-    its max, and when it is not possible to increment x anymore, y is
-    incremented once. If this is a solution, then next neighbor tries to
-    increment x.
-    """
-    DECREMENT = _pywrapcp.Solver_DECREMENT
-    r"""
-    Operator which defines a neighborhood to decrement values.
-    The behavior is the same as INCREMENT, except values are decremented
-    instead of incremented.
-    """
-    SIMPLELNS = _pywrapcp.Solver_SIMPLELNS
-    r"""
-    Operator which defines one neighbor per variable. Each neighbor relaxes
-    one variable.
-    When a new solution is found the neighborhood is rebuilt from scratch.
-    Consider for instance variables x and y. First x is relaxed and the
-    solver is looking for the best possible solution (with only x relaxed).
-    Then y is relaxed, and the solver is looking for a new solution.
-    If a new solution is found, then the next variable to be relaxed is x.
-    """
-    GE = _pywrapcp.Solver_GE
-    r""" Move is accepted when the current objective value >= objective.Min."""
-    LE = _pywrapcp.Solver_LE
-    r""" Move is accepted when the current objective value <= objective.Max."""
-    EQ = _pywrapcp.Solver_EQ
-    r"""
-    Move is accepted when the current objective value is in the interval
-    objective.Min .. objective.Max.
-    """
-    DELAYED_PRIORITY = _pywrapcp.Solver_DELAYED_PRIORITY
-    r"""
-    DELAYED_PRIORITY is the lowest priority: Demons will be processed after
-    VAR_PRIORITY and NORMAL_PRIORITY demons.
-    """
-    VAR_PRIORITY = _pywrapcp.Solver_VAR_PRIORITY
-    r""" VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY."""
-    NORMAL_PRIORITY = _pywrapcp.Solver_NORMAL_PRIORITY
-    r""" NORMAL_PRIORITY is the highest priority: Demons will be processed first."""
-
-    def __init__(self, *args):
-        _pywrapcp.Solver_swiginit(self, _pywrapcp.new_Solver(*args))
-
-        self.__python_constraints = []
-
-
-
-    __swig_destroy__ = _pywrapcp.delete_Solver
-
-    def Parameters(self) -> "operations_research::ConstraintSolverParameters":
-        r""" Stored Parameters."""
-        return _pywrapcp.Solver_Parameters(self)
-
-    @staticmethod
-    def DefaultSolverParameters() -> "operations_research::ConstraintSolverParameters":
-        r""" Create a ConstraintSolverParameters proto with all the default values."""
-        return _pywrapcp.Solver_DefaultSolverParameters()
-
-    def AddConstraint(self, c: "Constraint") -> "void":
-        r"""
-        Adds the constraint 'c' to the model.
-
-        After calling this method, and until there is a backtrack that undoes the
-        addition, any assignment of variables to values must satisfy the given
-        constraint in order to be considered feasible. There are two fairly
-        different use cases:
-
-        - the most common use case is modeling: the given constraint is really
-        part of the problem that the user is trying to solve. In this use case,
-        AddConstraint is called outside of search (i.e., with state() ==
-        OUTSIDE_SEARCH). Most users should only use AddConstraint in this
-        way. In this case, the constraint will belong to the model forever: it
-        cannot not be removed by backtracking.
-
-        - a rarer use case is that 'c' is not a real constraint of the model. It
-        may be a constraint generated by a branching decision (a constraint whose
-        goal is to restrict the search space), a symmetry breaking constraint (a
-        constraint that does restrict the search space, but in a way that cannot
-        have an impact on the quality of the solutions in the subtree), or an
-        inferred constraint that, while having no semantic value to the model (it
-        does not restrict the set of solutions), is worth having because we
-        believe it may strengthen the propagation. In these cases, it happens
-        that the constraint is added during the search (i.e., with state() ==
-        IN_SEARCH or state() == IN_ROOT_NODE). When a constraint is
-        added during a search, it applies only to the subtree of the search tree
-        rooted at the current node, and will be automatically removed by
-        backtracking.
-
-        This method does not take ownership of the constraint. If the constraint
-        has been created by any factory method (Solver::MakeXXX), it will
-        automatically be deleted. However, power users who implement their own
-        constraints should do: solver.AddConstraint(solver.RevAlloc(new
-        MyConstraint(...));
-        """
-        return _pywrapcp.Solver_AddConstraint(self, c)
-
-    def Solve(self, *args) -> "bool":
-        return _pywrapcp.Solver_Solve(self, *args)
-
-    def NewSearch(self, *args) -> "void":
-        return _pywrapcp.Solver_NewSearch(self, *args)
-
-    def NextSolution(self) -> "bool":
-        return _pywrapcp.Solver_NextSolution(self)
-
-    def RestartSearch(self) -> "void":
-        return _pywrapcp.Solver_RestartSearch(self)
-
-    def EndSearch(self) -> "void":
-        return _pywrapcp.Solver_EndSearch(self)
-
-    def SolveAndCommit(self, *args) -> "bool":
-        return _pywrapcp.Solver_SolveAndCommit(self, *args)
-
-    def CheckAssignment(self, solution: "Assignment") -> "bool":
-        r""" Checks whether the given assignment satisfies all relevant constraints."""
-        return _pywrapcp.Solver_CheckAssignment(self, solution)
-
-    def CheckConstraint(self, ct: "Constraint") -> "bool":
-        r"""
-        Checks whether adding this constraint will lead to an immediate
-        failure. It will return false if the model is already inconsistent, or if
-        adding the constraint makes it inconsistent.
-        """
-        return _pywrapcp.Solver_CheckConstraint(self, ct)
-
-    def Fail(self) -> "void":
-        r""" Abandon the current branch in the search tree. A backtrack will follow."""
-        return _pywrapcp.Solver_Fail(self)
-
-    @staticmethod
-    def MemoryUsage() -> "int64_t":
-        r""" Current memory usage in bytes"""
-        return _pywrapcp.Solver_MemoryUsage()
-
-    def WallTime(self) -> "int64_t":
-        r"""
-        DEPRECATED: Use Now() instead.
-        Time elapsed, in ms since the creation of the solver.
-        """
-        return _pywrapcp.Solver_WallTime(self)
+        
+    
+
+

+pywrapcp

+ + +
+ View Source +
# This file was automatically generated by SWIG (http://www.swig.org).
+# Version 4.0.1
+#
+# Do not make changes to this file unless you know what you are doing--modify
+# the SWIG interface file instead.
+
+from sys import version_info as _swig_python_version_info
+if _swig_python_version_info < (2, 7, 0):
+    raise RuntimeError("Python 2.7 or later required")
+
+# Import the low-level C/C++ module
+if __package__ or "." in __name__:
+    from . import _pywrapcp
+else:
+    import _pywrapcp
+
+try:
+    import builtins as __builtin__
+except ImportError:
+    import __builtin__
+
+def _swig_repr(self):
+    try:
+        strthis = "proxy of " + self.this.__repr__()
+    except __builtin__.Exception:
+        strthis = ""
+    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
+
+
+def _swig_setattr_nondynamic_instance_variable(set):
+    def set_instance_attr(self, name, value):
+        if name == "thisown":
+            self.this.own(value)
+        elif name == "this":
+            set(self, name, value)
+        elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
+            set(self, name, value)
+        else:
+            raise AttributeError("You cannot add instance attributes to %s" % self)
+    return set_instance_attr
+
+
+def _swig_setattr_nondynamic_class_variable(set):
+    def set_class_attr(cls, name, value):
+        if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
+            set(cls, name, value)
+        else:
+            raise AttributeError("You cannot add class attributes to %s" % cls)
+    return set_class_attr
+
+
+def _swig_add_metaclass(metaclass):
+    """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
+    def wrapper(cls):
+        return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
+    return wrapper
+
+
+class _SwigNonDynamicMeta(type):
+    """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
+    __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)
+
+
+import weakref
+
+class DefaultPhaseParameters(object):
+    r""" This struct holds all parameters for the default search. DefaultPhaseParameters is only used by Solver::MakeDefaultPhase methods. Note this is for advanced users only."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+    CHOOSE_MAX_SUM_IMPACT = _pywrapcp.DefaultPhaseParameters_CHOOSE_MAX_SUM_IMPACT
+    CHOOSE_MAX_AVERAGE_IMPACT = _pywrapcp.DefaultPhaseParameters_CHOOSE_MAX_AVERAGE_IMPACT
+    CHOOSE_MAX_VALUE_IMPACT = _pywrapcp.DefaultPhaseParameters_CHOOSE_MAX_VALUE_IMPACT
+    SELECT_MIN_IMPACT = _pywrapcp.DefaultPhaseParameters_SELECT_MIN_IMPACT
+    SELECT_MAX_IMPACT = _pywrapcp.DefaultPhaseParameters_SELECT_MAX_IMPACT
+    NONE = _pywrapcp.DefaultPhaseParameters_NONE
+    NORMAL = _pywrapcp.DefaultPhaseParameters_NORMAL
+    VERBOSE = _pywrapcp.DefaultPhaseParameters_VERBOSE
+    var_selection_schema = property(_pywrapcp.DefaultPhaseParameters_var_selection_schema_get, _pywrapcp.DefaultPhaseParameters_var_selection_schema_set, doc=r""" This parameter describes how the next variable to instantiate will be chosen.""")
+    value_selection_schema = property(_pywrapcp.DefaultPhaseParameters_value_selection_schema_get, _pywrapcp.DefaultPhaseParameters_value_selection_schema_set, doc=r""" This parameter describes which value to select for a given var.""")
+    initialization_splits = property(_pywrapcp.DefaultPhaseParameters_initialization_splits_get, _pywrapcp.DefaultPhaseParameters_initialization_splits_set, doc=r""" Maximum number of intervals that the initialization of impacts will scan per variable.""")
+    run_all_heuristics = property(_pywrapcp.DefaultPhaseParameters_run_all_heuristics_get, _pywrapcp.DefaultPhaseParameters_run_all_heuristics_set, doc=r""" The default phase will run heuristics periodically. This parameter indicates if we should run all heuristics, or a randomly selected one.""")
+    heuristic_period = property(_pywrapcp.DefaultPhaseParameters_heuristic_period_get, _pywrapcp.DefaultPhaseParameters_heuristic_period_set, doc=r""" The distance in nodes between each run of the heuristics. A negative or null value will mean that we will not run heuristics at all.""")
+    heuristic_num_failures_limit = property(_pywrapcp.DefaultPhaseParameters_heuristic_num_failures_limit_get, _pywrapcp.DefaultPhaseParameters_heuristic_num_failures_limit_set, doc=r""" The failure limit for each heuristic that we run.""")
+    persistent_impact = property(_pywrapcp.DefaultPhaseParameters_persistent_impact_get, _pywrapcp.DefaultPhaseParameters_persistent_impact_set, doc=r""" Whether to keep the impact from the first search for other searches, or to recompute the impact for each new search.""")
+    random_seed = property(_pywrapcp.DefaultPhaseParameters_random_seed_get, _pywrapcp.DefaultPhaseParameters_random_seed_set, doc=r""" Seed used to initialize the random part in some heuristics.""")
+    display_level = property(_pywrapcp.DefaultPhaseParameters_display_level_get, _pywrapcp.DefaultPhaseParameters_display_level_set, doc=r""" This represents the amount of information displayed by the default search. NONE means no display, VERBOSE means extra information.""")
+    decision_builder = property(_pywrapcp.DefaultPhaseParameters_decision_builder_get, _pywrapcp.DefaultPhaseParameters_decision_builder_set, doc=r""" When defined, this overrides the default impact based decision builder.""")
+
+    def __init__(self):
+        _pywrapcp.DefaultPhaseParameters_swiginit(self, _pywrapcp.new_DefaultPhaseParameters())
+    __swig_destroy__ = _pywrapcp.delete_DefaultPhaseParameters
+
+# Register DefaultPhaseParameters in _pywrapcp:
+_pywrapcp.DefaultPhaseParameters_swigregister(DefaultPhaseParameters)
+
+class Solver(object):
+    r""" Solver Class A solver represents the main computation engine. It implements the entire range of Constraint Programming protocols:   - Reversibility   - Propagation   - Search Usually, Constraint Programming code consists of   - the creation of the Solver,   - the creation of the decision variables of the model,   - the creation of the constraints of the model and their addition to the     solver() through the AddConstraint() method,   - the creation of the main DecisionBuilder class,   - the launch of the solve() method with the decision builder. For the time being, Solver is neither MT_SAFE nor MT_HOT."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+    INT_VAR_DEFAULT = _pywrapcp.Solver_INT_VAR_DEFAULT
+    r""" The default behavior is CHOOSE_FIRST_UNBOUND."""
+    INT_VAR_SIMPLE = _pywrapcp.Solver_INT_VAR_SIMPLE
+    r""" The simple selection is CHOOSE_FIRST_UNBOUND."""
+    CHOOSE_FIRST_UNBOUND = _pywrapcp.Solver_CHOOSE_FIRST_UNBOUND
+    r""" Select the first unbound variable. Variables are considered in the order of the vector of IntVars used to create the selector."""
+    CHOOSE_RANDOM = _pywrapcp.Solver_CHOOSE_RANDOM
+    r""" Randomly select one of the remaining unbound variables."""
+    CHOOSE_MIN_SIZE_LOWEST_MIN = _pywrapcp.Solver_CHOOSE_MIN_SIZE_LOWEST_MIN
+    r""" Among unbound variables, select the variable with the smallest size, i.e., the smallest number of possible values. In case of a tie, the selected variables is the one with the lowest min value. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector."""
+    CHOOSE_MIN_SIZE_HIGHEST_MIN = _pywrapcp.Solver_CHOOSE_MIN_SIZE_HIGHEST_MIN
+    r""" Among unbound variables, select the variable with the smallest size, i.e., the smallest number of possible values. In case of a tie, the selected variable is the one with the highest min value. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector."""
+    CHOOSE_MIN_SIZE_LOWEST_MAX = _pywrapcp.Solver_CHOOSE_MIN_SIZE_LOWEST_MAX
+    r""" Among unbound variables, select the variable with the smallest size, i.e., the smallest number of possible values. In case of a tie, the selected variables is the one with the lowest max value. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector."""
+    CHOOSE_MIN_SIZE_HIGHEST_MAX = _pywrapcp.Solver_CHOOSE_MIN_SIZE_HIGHEST_MAX
+    r""" Among unbound variables, select the variable with the smallest size, i.e., the smallest number of possible values. In case of a tie, the selected variable is the one with the highest max value. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector."""
+    CHOOSE_LOWEST_MIN = _pywrapcp.Solver_CHOOSE_LOWEST_MIN
+    r""" Among unbound variables, select the variable with the smallest minimal value. In case of a tie, the first one is selected, "first" defined by the order in the vector of IntVars used to create the selector."""
+    CHOOSE_HIGHEST_MAX = _pywrapcp.Solver_CHOOSE_HIGHEST_MAX
+    r""" Among unbound variables, select the variable with the highest maximal value. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector."""
+    CHOOSE_MIN_SIZE = _pywrapcp.Solver_CHOOSE_MIN_SIZE
+    r""" Among unbound variables, select the variable with the smallest size. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector."""
+    CHOOSE_MAX_SIZE = _pywrapcp.Solver_CHOOSE_MAX_SIZE
+    r""" Among unbound variables, select the variable with the highest size. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector."""
+    CHOOSE_MAX_REGRET_ON_MIN = _pywrapcp.Solver_CHOOSE_MAX_REGRET_ON_MIN
+    r""" Among unbound variables, select the variable with the largest gap between the first and the second values of the domain."""
+    CHOOSE_PATH = _pywrapcp.Solver_CHOOSE_PATH
+    r""" Selects the next unbound variable on a path, the path being defined by the variables: var[i] corresponds to the index of the next of i."""
+    INT_VALUE_DEFAULT = _pywrapcp.Solver_INT_VALUE_DEFAULT
+    r""" The default behavior is ASSIGN_MIN_VALUE."""
+    INT_VALUE_SIMPLE = _pywrapcp.Solver_INT_VALUE_SIMPLE
+    r""" The simple selection is ASSIGN_MIN_VALUE."""
+    ASSIGN_MIN_VALUE = _pywrapcp.Solver_ASSIGN_MIN_VALUE
+    r""" Selects the min value of the selected variable."""
+    ASSIGN_MAX_VALUE = _pywrapcp.Solver_ASSIGN_MAX_VALUE
+    r""" Selects the max value of the selected variable."""
+    ASSIGN_RANDOM_VALUE = _pywrapcp.Solver_ASSIGN_RANDOM_VALUE
+    r""" Selects randomly one of the possible values of the selected variable."""
+    ASSIGN_CENTER_VALUE = _pywrapcp.Solver_ASSIGN_CENTER_VALUE
+    r""" Selects the first possible value which is the closest to the center of the domain of the selected variable. The center is defined as (min + max) / 2."""
+    SPLIT_LOWER_HALF = _pywrapcp.Solver_SPLIT_LOWER_HALF
+    r""" Split the domain in two around the center, and choose the lower part first."""
+    SPLIT_UPPER_HALF = _pywrapcp.Solver_SPLIT_UPPER_HALF
+    r""" Split the domain in two around the center, and choose the lower part first."""
+    SEQUENCE_DEFAULT = _pywrapcp.Solver_SEQUENCE_DEFAULT
+    SEQUENCE_SIMPLE = _pywrapcp.Solver_SEQUENCE_SIMPLE
+    CHOOSE_MIN_SLACK_RANK_FORWARD = _pywrapcp.Solver_CHOOSE_MIN_SLACK_RANK_FORWARD
+    CHOOSE_RANDOM_RANK_FORWARD = _pywrapcp.Solver_CHOOSE_RANDOM_RANK_FORWARD
+    INTERVAL_DEFAULT = _pywrapcp.Solver_INTERVAL_DEFAULT
+    r""" The default is INTERVAL_SET_TIMES_FORWARD."""
+    INTERVAL_SIMPLE = _pywrapcp.Solver_INTERVAL_SIMPLE
+    r""" The simple is INTERVAL_SET_TIMES_FORWARD."""
+    INTERVAL_SET_TIMES_FORWARD = _pywrapcp.Solver_INTERVAL_SET_TIMES_FORWARD
+    r""" Selects the variable with the lowest starting time of all variables, and fixes its starting time to this lowest value."""
+    INTERVAL_SET_TIMES_BACKWARD = _pywrapcp.Solver_INTERVAL_SET_TIMES_BACKWARD
+    r""" Selects the variable with the highest ending time of all variables, and fixes the ending time to this highest values."""
+    TWOOPT = _pywrapcp.Solver_TWOOPT
+    r""" Operator which reverses a sub-chain of a path. It is called TwoOpt because it breaks two arcs on the path; resulting paths are called two-optimal. Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5 (where (1, 5) are first and last nodes of the path and can therefore not be moved):   1 -> [3 -> 2] -> 4  -> 5   1 -> [4 -> 3  -> 2] -> 5   1 ->  2 -> [4 -> 3] -> 5"""
+    OROPT = _pywrapcp.Solver_OROPT
+    r""" Relocate: OROPT and RELOCATE. Operator which moves a sub-chain of a path to another position; the specified chain length is the fixed length of the chains being moved. When this length is 1, the operator simply moves a node to another position. Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5, for a chain length of 2 (where (1, 5) are first and last nodes of the path and can therefore not be moved):   1 ->  4 -> [2 -> 3] -> 5   1 -> [3 -> 4] -> 2  -> 5 Using Relocate with chain lengths of 1, 2 and 3 together is equivalent to the OrOpt operator on a path. The OrOpt operator is a limited  version of 3Opt (breaks 3 arcs on a path)."""
+    RELOCATE = _pywrapcp.Solver_RELOCATE
+    r""" Relocate neighborhood with length of 1 (see OROPT comment)."""
+    EXCHANGE = _pywrapcp.Solver_EXCHANGE
+    r""" Operator which exchanges the positions of two nodes. Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5 (where (1, 5) are first and last nodes of the path and can therefore not be moved):   1 -> [3] -> [2] ->  4  -> 5   1 -> [4] ->  3  -> [2] -> 5   1 ->  2  -> [4] -> [3] -> 5"""
+    CROSS = _pywrapcp.Solver_CROSS
+    r""" Operator which cross exchanges the starting chains of 2 paths, including exchanging the whole paths. First and last nodes are not moved. Possible neighbors for the paths 1 -> 2 -> 3 -> 4 -> 5 and 6 -> 7 -> 8 (where (1, 5) and (6, 8) are first and last nodes of the paths and can therefore not be moved):   1 -> [7] -> 3 -> 4 -> 5  6 -> [2] -> 8   1 -> [7] -> 4 -> 5       6 -> [2 -> 3] -> 8   1 -> [7] -> 5            6 -> [2 -> 3 -> 4] -> 8"""
+    MAKEACTIVE = _pywrapcp.Solver_MAKEACTIVE
+    r""" Operator which inserts an inactive node into a path. Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive (where 1 and 4 are first and last nodes of the path) are:   1 -> [5] ->  2  ->  3  -> 4   1 ->  2  -> [5] ->  3  -> 4   1 ->  2  ->  3  -> [5] -> 4"""
+    MAKEINACTIVE = _pywrapcp.Solver_MAKEINACTIVE
+    r""" Operator which makes path nodes inactive. Possible neighbors for the path 1 -> 2 -> 3 -> 4 (where 1 and 4 are first and last nodes of the path) are:   1 -> 3 -> 4 with 2 inactive   1 -> 2 -> 4 with 3 inactive"""
+    MAKECHAININACTIVE = _pywrapcp.Solver_MAKECHAININACTIVE
+    r""" Operator which makes a "chain" of path nodes inactive. Possible neighbors for the path 1 -> 2 -> 3 -> 4 (where 1 and 4 are first and last nodes of the path) are:   1 -> 3 -> 4 with 2 inactive   1 -> 2 -> 4 with 3 inactive   1 -> 4 with 2 and 3 inactive"""
+    SWAPACTIVE = _pywrapcp.Solver_SWAPACTIVE
+    r""" Operator which replaces an active node by an inactive one. Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive (where 1 and 4 are first and last nodes of the path) are:   1 -> [5] ->  3  -> 4 with 2 inactive   1 ->  2  -> [5] -> 4 with 3 inactive"""
+    EXTENDEDSWAPACTIVE = _pywrapcp.Solver_EXTENDEDSWAPACTIVE
+    r""" Operator which makes an inactive node active and an active one inactive. It is similar to SwapActiveOperator except that it tries to insert the inactive node in all possible positions instead of just the position of the node made inactive. Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive (where 1 and 4 are first and last nodes of the path) are:   1 -> [5] ->  3  -> 4 with 2 inactive   1 ->  3  -> [5] -> 4 with 2 inactive   1 -> [5] ->  2  -> 4 with 3 inactive   1 ->  2  -> [5] -> 4 with 3 inactive"""
+    PATHLNS = _pywrapcp.Solver_PATHLNS
+    r""" Operator which relaxes two sub-chains of three consecutive arcs each. Each sub-chain is defined by a start node and the next three arcs. Those six arcs are relaxed to build a new neighbor. PATHLNS explores all possible pairs of starting nodes and so defines n^2 neighbors, n being the number of nodes. Note that the two sub-chains can be part of the same path; they even may overlap."""
+    FULLPATHLNS = _pywrapcp.Solver_FULLPATHLNS
+    r""" Operator which relaxes one entire path and all inactive nodes, thus defining num_paths neighbors."""
+    UNACTIVELNS = _pywrapcp.Solver_UNACTIVELNS
+    r""" Operator which relaxes all inactive nodes and one sub-chain of six consecutive arcs. That way the path can be improved by inserting inactive nodes or swapping arcs."""
+    INCREMENT = _pywrapcp.Solver_INCREMENT
+    r""" Operator which defines one neighbor per variable. Each neighbor tries to increment by one the value of the corresponding variable. When a new solution is found the neighborhood is rebuilt from scratch, i.e., tries to increment values in the variable order. Consider for instance variables x and y. x is incremented one by one to its max, and when it is not possible to increment x anymore, y is incremented once. If this is a solution, then next neighbor tries to increment x."""
+    DECREMENT = _pywrapcp.Solver_DECREMENT
+    r""" Operator which defines a neighborhood to decrement values. The behavior is the same as INCREMENT, except values are decremented instead of incremented."""
+    SIMPLELNS = _pywrapcp.Solver_SIMPLELNS
+    r""" Operator which defines one neighbor per variable. Each neighbor relaxes one variable. When a new solution is found the neighborhood is rebuilt from scratch. Consider for instance variables x and y. First x is relaxed and the solver is looking for the best possible solution (with only x relaxed). Then y is relaxed, and the solver is looking for a new solution. If a new solution is found, then the next variable to be relaxed is x."""
+    GE = _pywrapcp.Solver_GE
+    r""" Move is accepted when the current objective value >= objective.Min."""
+    LE = _pywrapcp.Solver_LE
+    r""" Move is accepted when the current objective value <= objective.Max."""
+    EQ = _pywrapcp.Solver_EQ
+    r""" Move is accepted when the current objective value is in the interval objective.Min .. objective.Max."""
+    DELAYED_PRIORITY = _pywrapcp.Solver_DELAYED_PRIORITY
+    r""" DELAYED_PRIORITY is the lowest priority: Demons will be processed after VAR_PRIORITY and NORMAL_PRIORITY demons."""
+    VAR_PRIORITY = _pywrapcp.Solver_VAR_PRIORITY
+    r""" VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY."""
+    NORMAL_PRIORITY = _pywrapcp.Solver_NORMAL_PRIORITY
+    r""" NORMAL_PRIORITY is the highest priority: Demons will be processed first."""
+
+    def __init__(self, *args):
+        _pywrapcp.Solver_swiginit(self, _pywrapcp.new_Solver(*args))
+
+        self.__python_constraints = []
+
+
+
+    __swig_destroy__ = _pywrapcp.delete_Solver
+
+    def Parameters(self) -> "operations_research::ConstraintSolverParameters":
+        r""" Stored Parameters."""
+        return _pywrapcp.Solver_Parameters(self)
+
+    @staticmethod
+    def DefaultSolverParameters() -> "operations_research::ConstraintSolverParameters":
+        r""" Create a ConstraintSolverParameters proto with all the default values."""
+        return _pywrapcp.Solver_DefaultSolverParameters()
+
+    def AddConstraint(self, c: "Constraint") -> "void":
+        r""" Adds the constraint 'c' to the model. After calling this method, and until there is a backtrack that undoes the addition, any assignment of variables to values must satisfy the given constraint in order to be considered feasible. There are two fairly different use cases: - the most common use case is modeling: the given constraint is really part of the problem that the user is trying to solve. In this use case, AddConstraint is called outside of search (i.e., with state() == OUTSIDE_SEARCH). Most users should only use AddConstraint in this way. In this case, the constraint will belong to the model forever: it cannot not be removed by backtracking. - a rarer use case is that 'c' is not a real constraint of the model. It may be a constraint generated by a branching decision (a constraint whose goal is to restrict the search space), a symmetry breaking constraint (a constraint that does restrict the search space, but in a way that cannot have an impact on the quality of the solutions in the subtree), or an inferred constraint that, while having no semantic value to the model (it does not restrict the set of solutions), is worth having because we believe it may strengthen the propagation. In these cases, it happens that the constraint is added during the search (i.e., with state() == IN_SEARCH or state() == IN_ROOT_NODE). When a constraint is added during a search, it applies only to the subtree of the search tree rooted at the current node, and will be automatically removed by backtracking. This method does not take ownership of the constraint. If the constraint has been created by any factory method (Solver::MakeXXX), it will automatically be deleted. However, power users who implement their own constraints should do: solver.AddConstraint(solver.RevAlloc(new MyConstraint(...));"""
+        return _pywrapcp.Solver_AddConstraint(self, c)
+
+    def Solve(self, *args) -> "bool":
+        return _pywrapcp.Solver_Solve(self, *args)
+
+    def NewSearch(self, *args) -> "void":
+        return _pywrapcp.Solver_NewSearch(self, *args)
+
+    def NextSolution(self) -> "bool":
+        return _pywrapcp.Solver_NextSolution(self)
+
+    def RestartSearch(self) -> "void":
+        return _pywrapcp.Solver_RestartSearch(self)
+
+    def EndSearch(self) -> "void":
+        return _pywrapcp.Solver_EndSearch(self)
+
+    def SolveAndCommit(self, *args) -> "bool":
+        return _pywrapcp.Solver_SolveAndCommit(self, *args)
+
+    def CheckAssignment(self, solution: "Assignment") -> "bool":
+        r""" Checks whether the given assignment satisfies all relevant constraints."""
+        return _pywrapcp.Solver_CheckAssignment(self, solution)
+
+    def CheckConstraint(self, ct: "Constraint") -> "bool":
+        r""" Checks whether adding this constraint will lead to an immediate failure. It will return false if the model is already inconsistent, or if adding the constraint makes it inconsistent."""
+        return _pywrapcp.Solver_CheckConstraint(self, ct)
+
+    def Fail(self) -> "void":
+        r""" Abandon the current branch in the search tree. A backtrack will follow."""
+        return _pywrapcp.Solver_Fail(self)
+
+    @staticmethod
+    def MemoryUsage() -> "int64_t":
+        r""" Current memory usage in bytes"""
+        return _pywrapcp.Solver_MemoryUsage()
+
+    def WallTime(self) -> "int64_t":
+        r""" DEPRECATED: Use Now() instead. Time elapsed, in ms since the creation of the solver."""
+        return _pywrapcp.Solver_WallTime(self)
+
+    def Branches(self) -> "int64_t":
+        r""" The number of branches explored since the creation of the solver."""
+        return _pywrapcp.Solver_Branches(self)
+
+    def Solutions(self) -> "int64_t":
+        r""" The number of solutions found since the start of the search."""
+        return _pywrapcp.Solver_Solutions(self)
 
-    def Branches(self) -> "int64_t":
-        r""" The number of branches explored since the creation of the solver."""
-        return _pywrapcp.Solver_Branches(self)
-
-    def Solutions(self) -> "int64_t":
-        r""" The number of solutions found since the start of the search."""
-        return _pywrapcp.Solver_Solutions(self)
-
-    def Failures(self) -> "int64_t":
-        r""" The number of failures encountered since the creation of the solver."""
-        return _pywrapcp.Solver_Failures(self)
-
-    def AcceptedNeighbors(self) -> "int64_t":
-        r""" The number of accepted neighbors."""
-        return _pywrapcp.Solver_AcceptedNeighbors(self)
-
-    def Stamp(self) -> "uint64_t":
-        r"""
-        The stamp indicates how many moves in the search tree we have performed.
-        It is useful to detect if we need to update same lazy structures.
-        """
-        return _pywrapcp.Solver_Stamp(self)
-
-    def FailStamp(self) -> "uint64_t":
-        r""" The fail_stamp() is incremented after each backtrack."""
-        return _pywrapcp.Solver_FailStamp(self)
-
-    def IntVar(self, *args) -> "operations_research::IntVar *":
-        r"""
-        *Overload 1:*
-        MakeIntVar will create the best range based int var for the bounds given.
-
-        |
-
-        *Overload 2:*
-        MakeIntVar will create a variable with the given sparse domain.
-
-        |
+    def Failures(self) -> "int64_t":
+        r""" The number of failures encountered since the creation of the solver."""
+        return _pywrapcp.Solver_Failures(self)
 
-        *Overload 3:*
-        MakeIntVar will create a variable with the given sparse domain.
+    def AcceptedNeighbors(self) -> "int64_t":
+        r""" The number of accepted neighbors."""
+        return _pywrapcp.Solver_AcceptedNeighbors(self)
 
-        |
+    def Stamp(self) -> "uint64_t":
+        r""" The stamp indicates how many moves in the search tree we have performed. It is useful to detect if we need to update same lazy structures."""
+        return _pywrapcp.Solver_Stamp(self)
 
-        *Overload 4:*
-        MakeIntVar will create the best range based int var for the bounds given.
+    def FailStamp(self) -> "uint64_t":
+        r""" The fail_stamp() is incremented after each backtrack."""
+        return _pywrapcp.Solver_FailStamp(self)
 
-        |
+    def IntVar(self, *args) -> "operations_research::IntVar *":
+        r"""
+        *Overload 1:*
+        MakeIntVar will create the best range based int var for the bounds given.
 
-        *Overload 5:*
-        MakeIntVar will create a variable with the given sparse domain.
+        |
 
-        |
+        *Overload 2:*
+        MakeIntVar will create a variable with the given sparse domain.
 
-        *Overload 6:*
-        MakeIntVar will create a variable with the given sparse domain.
-        """
-        return _pywrapcp.Solver_IntVar(self, *args)
+        |
 
-    def BoolVar(self, *args) -> "operations_research::IntVar *":
-        r"""
-        *Overload 1:*
-        MakeBoolVar will create a variable with a {0, 1} domain.
+        *Overload 3:*
+        MakeIntVar will create a variable with the given sparse domain.
 
-        |
+        |
 
-        *Overload 2:*
-        MakeBoolVar will create a variable with a {0, 1} domain.
-        """
-        return _pywrapcp.Solver_BoolVar(self, *args)
+        *Overload 4:*
+        MakeIntVar will create the best range based int var for the bounds given.
 
-    def IntConst(self, *args) -> "operations_research::IntVar *":
-        r"""
-        *Overload 1:*
-        IntConst will create a constant expression.
+        |
 
-        |
+        *Overload 5:*
+        MakeIntVar will create a variable with the given sparse domain.
 
-        *Overload 2:*
-        IntConst will create a constant expression.
-        """
-        return _pywrapcp.Solver_IntConst(self, *args)
+        |
 
-    def Sum(self, vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::IntExpr *":
-        r""" sum of all vars."""
-        return _pywrapcp.Solver_Sum(self, vars)
+        *Overload 6:*
+        MakeIntVar will create a variable with the given sparse domain.
+        """
+        return _pywrapcp.Solver_IntVar(self, *args)
 
-    def ScalProd(self, *args) -> "operations_research::IntExpr *":
-        r"""
-        *Overload 1:*
-        scalar product
+    def BoolVar(self, *args) -> "operations_research::IntVar *":
+        r"""
+        *Overload 1:*
+        MakeBoolVar will create a variable with a {0, 1} domain.
 
-        |
+        |
 
-        *Overload 2:*
-        scalar product
-        """
-        return _pywrapcp.Solver_ScalProd(self, *args)
+        *Overload 2:*
+        MakeBoolVar will create a variable with a {0, 1} domain.
+        """
+        return _pywrapcp.Solver_BoolVar(self, *args)
 
-    def MonotonicElement(self, values: "operations_research::Solver::IndexEvaluator1", increasing: "bool", index: "IntVar") -> "operations_research::IntExpr *":
-        r"""
-        Function based element. The constraint takes ownership of the
-        callback.  The callback must be monotonic. It must be able to
-        cope with any possible value in the domain of 'index'
-        (potentially negative ones too). Furtermore, monotonicity is not
-        checked. Thus giving a non-monotonic function, or specifying an
-        incorrect increasing parameter will result in undefined behavior.
-        """
-        return _pywrapcp.Solver_MonotonicElement(self, values, increasing, index)
+    def IntConst(self, *args) -> "operations_research::IntVar *":
+        r"""
+        *Overload 1:*
+        IntConst will create a constant expression.
 
-    def Element(self, *args) -> "operations_research::IntExpr *":
-        r"""
-        *Overload 1:*
-        values[index]
+        |
 
-        |
+        *Overload 2:*
+        IntConst will create a constant expression.
+        """
+        return _pywrapcp.Solver_IntConst(self, *args)
 
-        *Overload 2:*
-        values[index]
+    def Sum(self, vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::IntExpr *":
+        r""" sum of all vars."""
+        return _pywrapcp.Solver_Sum(self, vars)
 
-        |
+    def ScalProd(self, *args) -> "operations_research::IntExpr *":
+        r"""
+        *Overload 1:*
+        scalar product
 
-        *Overload 3:*
-        Function-based element. The constraint takes ownership of the
-        callback. The callback must be able to cope with any possible
-        value in the domain of 'index' (potentially negative ones too).
+        |
 
-        |
+        *Overload 2:*
+        scalar product
+        """
+        return _pywrapcp.Solver_ScalProd(self, *args)
 
-        *Overload 4:*
-        2D version of function-based element expression, values(expr1, expr2).
+    def MonotonicElement(self, values: "operations_research::Solver::IndexEvaluator1", increasing: "bool", index: "IntVar") -> "operations_research::IntExpr *":
+        r""" Function based element. The constraint takes ownership of the callback.  The callback must be monotonic. It must be able to cope with any possible value in the domain of 'index' (potentially negative ones too). Furtermore, monotonicity is not checked. Thus giving a non-monotonic function, or specifying an incorrect increasing parameter will result in undefined behavior."""
+        return _pywrapcp.Solver_MonotonicElement(self, values, increasing, index)
 
-        |
+    def Element(self, *args) -> "operations_research::IntExpr *":
+        r"""
+        *Overload 1:*
+        values[index]
 
-        *Overload 5:*
-        vars[expr]
-        """
-        return _pywrapcp.Solver_Element(self, *args)
+        |
 
-    def IndexExpression(self, vars: "std::vector< operations_research::IntVar * > const &", value: "int64_t") -> "operations_research::IntExpr *":
-        r"""
-        Returns the expression expr such that vars[expr] == value.
-        It assumes that vars are all different.
-        """
-        return _pywrapcp.Solver_IndexExpression(self, vars, value)
+        *Overload 2:*
+        values[index]
 
-    def Min(self, *args) -> "operations_research::IntExpr *":
-        r"""
-        *Overload 1:*
-        std::min(vars)
+        |
 
-        |
+        *Overload 3:*
+        Function-based element. The constraint takes ownership of the callback. The callback must be able to cope with any possible value in the domain of 'index' (potentially negative ones too).
 
-        *Overload 2:*
-        std::min (left, right)
+        |
 
-        |
+        *Overload 4:*
+        2D version of function-based element expression, values(expr1, expr2).
 
-        *Overload 3:*
-        std::min(expr, value)
+        |
 
-        |
+        *Overload 5:*
+        vars[expr]
+        """
+        return _pywrapcp.Solver_Element(self, *args)
 
-        *Overload 4:*
-        std::min(expr, value)
-        """
-        return _pywrapcp.Solver_Min(self, *args)
+    def IndexExpression(self, vars: "std::vector< operations_research::IntVar * > const &", value: "int64_t") -> "operations_research::IntExpr *":
+        r""" Returns the expression expr such that vars[expr] == value. It assumes that vars are all different."""
+        return _pywrapcp.Solver_IndexExpression(self, vars, value)
 
-    def Max(self, *args) -> "operations_research::IntExpr *":
-        r"""
-        *Overload 1:*
-        std::max(vars)
+    def Min(self, *args) -> "operations_research::IntExpr *":
+        r"""
+        *Overload 1:*
+        std::min(vars)
 
-        |
+        |
 
-        *Overload 2:*
-        std::max(left, right)
+        *Overload 2:*
+        std::min (left, right)
 
-        |
+        |
 
-        *Overload 3:*
-        std::max(expr, value)
+        *Overload 3:*
+        std::min(expr, value)
 
-        |
+        |
 
-        *Overload 4:*
-        std::max(expr, value)
-        """
-        return _pywrapcp.Solver_Max(self, *args)
+        *Overload 4:*
+        std::min(expr, value)
+        """
+        return _pywrapcp.Solver_Min(self, *args)
 
-    def ConvexPiecewiseExpr(self, expr: "IntExpr", early_cost: "int64_t", early_date: "int64_t", late_date: "int64_t", late_cost: "int64_t") -> "operations_research::IntExpr *":
-        r""" Convex piecewise function."""
-        return _pywrapcp.Solver_ConvexPiecewiseExpr(self, expr, early_cost, early_date, late_date, late_cost)
+    def Max(self, *args) -> "operations_research::IntExpr *":
+        r"""
+        *Overload 1:*
+        std::max(vars)
 
-    def SemiContinuousExpr(self, expr: "IntExpr", fixed_charge: "int64_t", step: "int64_t") -> "operations_research::IntExpr *":
-        r"""
-        Semi continuous Expression (x <= 0 -> f(x) = 0; x > 0 -> f(x) = ax + b)
-        a >= 0 and b >= 0
-        """
-        return _pywrapcp.Solver_SemiContinuousExpr(self, expr, fixed_charge, step)
+        |
 
-    def ConditionalExpression(self, condition: "IntVar", expr: "IntExpr", unperformed_value: "int64_t") -> "operations_research::IntExpr *":
-        r""" Conditional Expr condition ? expr : unperformed_value"""
-        return _pywrapcp.Solver_ConditionalExpression(self, condition, expr, unperformed_value)
+        *Overload 2:*
+        std::max(left, right)
 
-    def TrueConstraint(self) -> "operations_research::Constraint *":
-        r""" This constraint always succeeds."""
-        return _pywrapcp.Solver_TrueConstraint(self)
+        |
 
-    def FalseConstraint(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_FalseConstraint(self, *args)
+        *Overload 3:*
+        std::max(expr, value)
 
-    def IsEqualCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
-        r""" boolvar == (var == value)"""
-        return _pywrapcp.Solver_IsEqualCstCt(self, var, value, boolvar)
+        |
 
-    def IsEqualCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
-        r""" status var of (var == value)"""
-        return _pywrapcp.Solver_IsEqualCstVar(self, var, value)
+        *Overload 4:*
+        std::max(expr, value)
+        """
+        return _pywrapcp.Solver_Max(self, *args)
 
-    def IsEqualCt(self, v1: "IntExpr", v2: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
-        r""" b == (v1 == v2)"""
-        return _pywrapcp.Solver_IsEqualCt(self, v1, v2, b)
+    def ConvexPiecewiseExpr(self, expr: "IntExpr", early_cost: "int64_t", early_date: "int64_t", late_date: "int64_t", late_cost: "int64_t") -> "operations_research::IntExpr *":
+        r""" Convex piecewise function."""
+        return _pywrapcp.Solver_ConvexPiecewiseExpr(self, expr, early_cost, early_date, late_date, late_cost)
 
-    def IsEqualVar(self, v1: "IntExpr", v2: "IntExpr") -> "operations_research::IntVar *":
-        r""" status var of (v1 == v2)"""
-        return _pywrapcp.Solver_IsEqualVar(self, v1, v2)
+    def SemiContinuousExpr(self, expr: "IntExpr", fixed_charge: "int64_t", step: "int64_t") -> "operations_research::IntExpr *":
+        r""" Semi continuous Expression (x <= 0 -> f(x) = 0; x > 0 -> f(x) = ax + b) a >= 0 and b >= 0"""
+        return _pywrapcp.Solver_SemiContinuousExpr(self, expr, fixed_charge, step)
 
-    def IsDifferentCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
-        r""" boolvar == (var != value)"""
-        return _pywrapcp.Solver_IsDifferentCstCt(self, var, value, boolvar)
+    def ConditionalExpression(self, condition: "IntVar", expr: "IntExpr", unperformed_value: "int64_t") -> "operations_research::IntExpr *":
+        r""" Conditional Expr condition ? expr : unperformed_value"""
+        return _pywrapcp.Solver_ConditionalExpression(self, condition, expr, unperformed_value)
 
-    def IsDifferentCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
-        r""" status var of (var != value)"""
-        return _pywrapcp.Solver_IsDifferentCstVar(self, var, value)
+    def TrueConstraint(self) -> "operations_research::Constraint *":
+        r""" This constraint always succeeds."""
+        return _pywrapcp.Solver_TrueConstraint(self)
 
-    def IsDifferentVar(self, v1: "IntExpr", v2: "IntExpr") -> "operations_research::IntVar *":
-        r""" status var of (v1 != v2)"""
-        return _pywrapcp.Solver_IsDifferentVar(self, v1, v2)
+    def FalseConstraint(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_FalseConstraint(self, *args)
 
-    def IsDifferentCt(self, v1: "IntExpr", v2: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
-        r""" b == (v1 != v2)"""
-        return _pywrapcp.Solver_IsDifferentCt(self, v1, v2, b)
+    def IsEqualCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
+        r""" boolvar == (var == value)"""
+        return _pywrapcp.Solver_IsEqualCstCt(self, var, value, boolvar)
 
-    def IsLessOrEqualCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
-        r""" boolvar == (var <= value)"""
-        return _pywrapcp.Solver_IsLessOrEqualCstCt(self, var, value, boolvar)
+    def IsEqualCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
+        r""" status var of (var == value)"""
+        return _pywrapcp.Solver_IsEqualCstVar(self, var, value)
 
-    def IsLessOrEqualCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
-        r""" status var of (var <= value)"""
-        return _pywrapcp.Solver_IsLessOrEqualCstVar(self, var, value)
+    def IsEqualCt(self, v1: "IntExpr", v2: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (v1 == v2)"""
+        return _pywrapcp.Solver_IsEqualCt(self, v1, v2, b)
 
-    def IsLessOrEqualVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
-        r""" status var of (left <= right)"""
-        return _pywrapcp.Solver_IsLessOrEqualVar(self, left, right)
+    def IsEqualVar(self, v1: "IntExpr", v2: "IntExpr") -> "operations_research::IntVar *":
+        r""" status var of (v1 == v2)"""
+        return _pywrapcp.Solver_IsEqualVar(self, v1, v2)
 
-    def IsLessOrEqualCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
-        r""" b == (left <= right)"""
-        return _pywrapcp.Solver_IsLessOrEqualCt(self, left, right, b)
+    def IsDifferentCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
+        r""" boolvar == (var != value)"""
+        return _pywrapcp.Solver_IsDifferentCstCt(self, var, value, boolvar)
 
-    def IsGreaterOrEqualCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
-        r""" boolvar == (var >= value)"""
-        return _pywrapcp.Solver_IsGreaterOrEqualCstCt(self, var, value, boolvar)
+    def IsDifferentCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
+        r""" status var of (var != value)"""
+        return _pywrapcp.Solver_IsDifferentCstVar(self, var, value)
 
-    def IsGreaterOrEqualCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
-        r""" status var of (var >= value)"""
-        return _pywrapcp.Solver_IsGreaterOrEqualCstVar(self, var, value)
+    def IsDifferentVar(self, v1: "IntExpr", v2: "IntExpr") -> "operations_research::IntVar *":
+        r""" status var of (v1 != v2)"""
+        return _pywrapcp.Solver_IsDifferentVar(self, v1, v2)
 
-    def IsGreaterOrEqualVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
-        r""" status var of (left >= right)"""
-        return _pywrapcp.Solver_IsGreaterOrEqualVar(self, left, right)
+    def IsDifferentCt(self, v1: "IntExpr", v2: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (v1 != v2)"""
+        return _pywrapcp.Solver_IsDifferentCt(self, v1, v2, b)
 
-    def IsGreaterOrEqualCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
-        r""" b == (left >= right)"""
-        return _pywrapcp.Solver_IsGreaterOrEqualCt(self, left, right, b)
+    def IsLessOrEqualCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
+        r""" boolvar == (var <= value)"""
+        return _pywrapcp.Solver_IsLessOrEqualCstCt(self, var, value, boolvar)
 
-    def IsGreaterCstCt(self, v: "IntExpr", c: "int64_t", b: "IntVar") -> "operations_research::Constraint *":
-        r""" b == (v > c)"""
-        return _pywrapcp.Solver_IsGreaterCstCt(self, v, c, b)
+    def IsLessOrEqualCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
+        r""" status var of (var <= value)"""
+        return _pywrapcp.Solver_IsLessOrEqualCstVar(self, var, value)
 
-    def IsGreaterCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
-        r""" status var of (var > value)"""
-        return _pywrapcp.Solver_IsGreaterCstVar(self, var, value)
-
-    def IsGreaterVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
-        r""" status var of (left > right)"""
-        return _pywrapcp.Solver_IsGreaterVar(self, left, right)
-
-    def IsGreaterCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
-        r""" b == (left > right)"""
-        return _pywrapcp.Solver_IsGreaterCt(self, left, right, b)
+    def IsLessOrEqualVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
+        r""" status var of (left <= right)"""
+        return _pywrapcp.Solver_IsLessOrEqualVar(self, left, right)
 
-    def IsLessCstCt(self, v: "IntExpr", c: "int64_t", b: "IntVar") -> "operations_research::Constraint *":
-        r""" b == (v < c)"""
-        return _pywrapcp.Solver_IsLessCstCt(self, v, c, b)
+    def IsLessOrEqualCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (left <= right)"""
+        return _pywrapcp.Solver_IsLessOrEqualCt(self, left, right, b)
 
-    def IsLessCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
-        r""" status var of (var < value)"""
-        return _pywrapcp.Solver_IsLessCstVar(self, var, value)
+    def IsGreaterOrEqualCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
+        r""" boolvar == (var >= value)"""
+        return _pywrapcp.Solver_IsGreaterOrEqualCstCt(self, var, value, boolvar)
 
-    def IsLessVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
-        r""" status var of (left < right)"""
-        return _pywrapcp.Solver_IsLessVar(self, left, right)
+    def IsGreaterOrEqualCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
+        r""" status var of (var >= value)"""
+        return _pywrapcp.Solver_IsGreaterOrEqualCstVar(self, var, value)
 
-    def IsLessCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
-        r""" b == (left < right)"""
-        return _pywrapcp.Solver_IsLessCt(self, left, right, b)
+    def IsGreaterOrEqualVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
+        r""" status var of (left >= right)"""
+        return _pywrapcp.Solver_IsGreaterOrEqualVar(self, left, right)
 
-    def SumLessOrEqual(self, vars: "std::vector< operations_research::IntVar * > const &", cst: "int64_t") -> "operations_research::Constraint *":
-        r""" Variation on arrays."""
-        return _pywrapcp.Solver_SumLessOrEqual(self, vars, cst)
+    def IsGreaterOrEqualCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (left >= right)"""
+        return _pywrapcp.Solver_IsGreaterOrEqualCt(self, left, right, b)
 
-    def SumGreaterOrEqual(self, vars: "std::vector< operations_research::IntVar * > const &", cst: "int64_t") -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_SumGreaterOrEqual(self, vars, cst)
+    def IsGreaterCstCt(self, v: "IntExpr", c: "int64_t", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (v > c)"""
+        return _pywrapcp.Solver_IsGreaterCstCt(self, v, c, b)
 
-    def SumEquality(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_SumEquality(self, *args)
+    def IsGreaterCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
+        r""" status var of (var > value)"""
+        return _pywrapcp.Solver_IsGreaterCstVar(self, var, value)
 
-    def ScalProdEquality(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_ScalProdEquality(self, *args)
+    def IsGreaterVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
+        r""" status var of (left > right)"""
+        return _pywrapcp.Solver_IsGreaterVar(self, left, right)
 
-    def ScalProdGreaterOrEqual(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_ScalProdGreaterOrEqual(self, *args)
+    def IsGreaterCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (left > right)"""
+        return _pywrapcp.Solver_IsGreaterCt(self, left, right, b)
 
-    def ScalProdLessOrEqual(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_ScalProdLessOrEqual(self, *args)
+    def IsLessCstCt(self, v: "IntExpr", c: "int64_t", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (v < c)"""
+        return _pywrapcp.Solver_IsLessCstCt(self, v, c, b)
 
-    def MinEquality(self, vars: "std::vector< operations_research::IntVar * > const &", min_var: "IntVar") -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_MinEquality(self, vars, min_var)
+    def IsLessCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
+        r""" status var of (var < value)"""
+        return _pywrapcp.Solver_IsLessCstVar(self, var, value)
 
-    def MaxEquality(self, vars: "std::vector< operations_research::IntVar * > const &", max_var: "IntVar") -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_MaxEquality(self, vars, max_var)
+    def IsLessVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
+        r""" status var of (left < right)"""
+        return _pywrapcp.Solver_IsLessVar(self, left, right)
 
-    def ElementEquality(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_ElementEquality(self, *args)
+    def IsLessCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (left < right)"""
+        return _pywrapcp.Solver_IsLessCt(self, left, right, b)
 
-    def AbsEquality(self, var: "IntVar", abs_var: "IntVar") -> "operations_research::Constraint *":
-        r""" Creates the constraint abs(var) == abs_var."""
-        return _pywrapcp.Solver_AbsEquality(self, var, abs_var)
+    def SumLessOrEqual(self, vars: "std::vector< operations_research::IntVar * > const &", cst: "int64_t") -> "operations_research::Constraint *":
+        r""" Variation on arrays."""
+        return _pywrapcp.Solver_SumLessOrEqual(self, vars, cst)
 
-    def IndexOfConstraint(self, vars: "std::vector< operations_research::IntVar * > const &", index: "IntVar", target: "int64_t") -> "operations_research::Constraint *":
-        r"""
-        This constraint is a special case of the element constraint with
-        an array of integer variables, where the variables are all
-        different and the index variable is constrained such that
-        vars[index] == target.
-        """
-        return _pywrapcp.Solver_IndexOfConstraint(self, vars, index, target)
+    def SumGreaterOrEqual(self, vars: "std::vector< operations_research::IntVar * > const &", cst: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_SumGreaterOrEqual(self, vars, cst)
 
-    def ConstraintInitialPropagateCallback(self, ct: "Constraint") -> "operations_research::Demon *":
-        r"""
-        This method is a specialized case of the MakeConstraintDemon
-        method to call the InitiatePropagate of the constraint 'ct'.
-        """
-        return _pywrapcp.Solver_ConstraintInitialPropagateCallback(self, ct)
+    def SumEquality(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_SumEquality(self, *args)
 
-    def DelayedConstraintInitialPropagateCallback(self, ct: "Constraint") -> "operations_research::Demon *":
-        r"""
-        This method is a specialized case of the MakeConstraintDemon
-        method to call the InitiatePropagate of the constraint 'ct' with
-        low priority.
-        """
-        return _pywrapcp.Solver_DelayedConstraintInitialPropagateCallback(self, ct)
+    def ScalProdEquality(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_ScalProdEquality(self, *args)
 
-    def ClosureDemon(self, closure: "operations_research::Solver::Closure") -> "operations_research::Demon *":
-        r""" Creates a demon from a closure."""
-        return _pywrapcp.Solver_ClosureDemon(self, closure)
+    def ScalProdGreaterOrEqual(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_ScalProdGreaterOrEqual(self, *args)
 
-    def BetweenCt(self, expr: "IntExpr", l: "int64_t", u: "int64_t") -> "operations_research::Constraint *":
-        r""" (l <= expr <= u)"""
-        return _pywrapcp.Solver_BetweenCt(self, expr, l, u)
+    def ScalProdLessOrEqual(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_ScalProdLessOrEqual(self, *args)
 
-    def IsBetweenCt(self, expr: "IntExpr", l: "int64_t", u: "int64_t", b: "IntVar") -> "operations_research::Constraint *":
-        r""" b == (l <= expr <= u)"""
-        return _pywrapcp.Solver_IsBetweenCt(self, expr, l, u, b)
+    def MinEquality(self, vars: "std::vector< operations_research::IntVar * > const &", min_var: "IntVar") -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_MinEquality(self, vars, min_var)
 
-    def IsBetweenVar(self, v: "IntExpr", l: "int64_t", u: "int64_t") -> "operations_research::IntVar *":
-        return _pywrapcp.Solver_IsBetweenVar(self, v, l, u)
+    def MaxEquality(self, vars: "std::vector< operations_research::IntVar * > const &", max_var: "IntVar") -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_MaxEquality(self, vars, max_var)
 
-    def MemberCt(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_MemberCt(self, *args)
+    def ElementEquality(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_ElementEquality(self, *args)
 
-    def NotMemberCt(self, *args) -> "operations_research::Constraint *":
-        r"""
-        *Overload 1:*
-        expr not in set.
+    def AbsEquality(self, var: "IntVar", abs_var: "IntVar") -> "operations_research::Constraint *":
+        r""" Creates the constraint abs(var) == abs_var."""
+        return _pywrapcp.Solver_AbsEquality(self, var, abs_var)
 
-        |
+    def IndexOfConstraint(self, vars: "std::vector< operations_research::IntVar * > const &", index: "IntVar", target: "int64_t") -> "operations_research::Constraint *":
+        r""" This constraint is a special case of the element constraint with an array of integer variables, where the variables are all different and the index variable is constrained such that vars[index] == target."""
+        return _pywrapcp.Solver_IndexOfConstraint(self, vars, index, target)
 
-        *Overload 2:*
-        expr should not be in the list of forbidden intervals [start[i]..end[i]].
+    def ConstraintInitialPropagateCallback(self, ct: "Constraint") -> "operations_research::Demon *":
+        r""" This method is a specialized case of the MakeConstraintDemon method to call the InitiatePropagate of the constraint 'ct'."""
+        return _pywrapcp.Solver_ConstraintInitialPropagateCallback(self, ct)
 
-        |
+    def DelayedConstraintInitialPropagateCallback(self, ct: "Constraint") -> "operations_research::Demon *":
+        r""" This method is a specialized case of the MakeConstraintDemon method to call the InitiatePropagate of the constraint 'ct' with low priority."""
+        return _pywrapcp.Solver_DelayedConstraintInitialPropagateCallback(self, ct)
 
-        *Overload 3:*
-        expr should not be in the list of forbidden intervals [start[i]..end[i]].
-        """
-        return _pywrapcp.Solver_NotMemberCt(self, *args)
+    def ClosureDemon(self, closure: "operations_research::Solver::Closure") -> "operations_research::Demon *":
+        r""" Creates a demon from a closure."""
+        return _pywrapcp.Solver_ClosureDemon(self, closure)
 
-    def IsMemberCt(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_IsMemberCt(self, *args)
+    def BetweenCt(self, expr: "IntExpr", l: "int64_t", u: "int64_t") -> "operations_research::Constraint *":
+        r""" (l <= expr <= u)"""
+        return _pywrapcp.Solver_BetweenCt(self, expr, l, u)
 
-    def IsMemberVar(self, *args) -> "operations_research::IntVar *":
-        return _pywrapcp.Solver_IsMemberVar(self, *args)
-
-    def Count(self, *args) -> "operations_research::Constraint *":
-        r"""
-        *Overload 1:*
-        |{i | vars[i] == value}| == max_count
+    def IsBetweenCt(self, expr: "IntExpr", l: "int64_t", u: "int64_t", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (l <= expr <= u)"""
+        return _pywrapcp.Solver_IsBetweenCt(self, expr, l, u, b)
 
-        |
+    def IsBetweenVar(self, v: "IntExpr", l: "int64_t", u: "int64_t") -> "operations_research::IntVar *":
+        return _pywrapcp.Solver_IsBetweenVar(self, v, l, u)
 
-        *Overload 2:*
-        |{i | vars[i] == value}| == max_count
-        """
-        return _pywrapcp.Solver_Count(self, *args)
-
-    def Distribute(self, *args) -> "operations_research::Constraint *":
-        r"""
-        *Overload 1:*
-        Aggregated version of count:  |{i | v[i] == values[j]}| == cards[j]
-
-        |
-
-        *Overload 2:*
-        Aggregated version of count:  |{i | v[i] == values[j]}| == cards[j]
-
-        |
-
-        *Overload 3:*
-        Aggregated version of count:  |{i | v[i] == j}| == cards[j]
-
-        |
-
-        *Overload 4:*
-        Aggregated version of count with bounded cardinalities:
-        forall j in 0 .. card_size - 1: card_min <= |{i | v[i] == j}| <= card_max
-
-        |
-
-        *Overload 5:*
-        Aggregated version of count with bounded cardinalities:
-        forall j in 0 .. card_size - 1:
-           card_min[j] <= |{i | v[i] == j}| <= card_max[j]
-
-        |
-
-        *Overload 6:*
-        Aggregated version of count with bounded cardinalities:
-        forall j in 0 .. card_size - 1:
-           card_min[j] <= |{i | v[i] == j}| <= card_max[j]
-
-        |
-
-        *Overload 7:*
-        Aggregated version of count with bounded cardinalities:
-        forall j in 0 .. card_size - 1:
-           card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j]
-
-        |
-
-        *Overload 8:*
-        Aggregated version of count with bounded cardinalities:
-        forall j in 0 .. card_size - 1:
-           card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j]
-        """
-        return _pywrapcp.Solver_Distribute(self, *args)
-
-    def Deviation(self, vars: "std::vector< operations_research::IntVar * > const &", deviation_var: "IntVar", total_sum: "int64_t") -> "operations_research::Constraint *":
-        r"""
-        Deviation constraint:
-        sum_i |n * vars[i] - total_sum| <= deviation_var and
-        sum_i vars[i] == total_sum
-        n = #vars
-        """
-        return _pywrapcp.Solver_Deviation(self, vars, deviation_var, total_sum)
-
-    def AllDifferent(self, *args) -> "operations_research::Constraint *":
-        r"""
-        *Overload 1:*
-        All variables are pairwise different. This corresponds to the
-        stronger version of the propagation algorithm.
-
-        |
-
-        *Overload 2:*
-        All variables are pairwise different.  If 'stronger_propagation'
-        is true, stronger, and potentially slower propagation will
-        occur. This API will be deprecated in the future.
-        """
-        return _pywrapcp.Solver_AllDifferent(self, *args)
-
-    def AllDifferentExcept(self, vars: "std::vector< operations_research::IntVar * > const &", escape_value: "int64_t") -> "operations_research::Constraint *":
-        r"""
-        All variables are pairwise different, unless they are assigned to
-        the escape value.
-        """
-        return _pywrapcp.Solver_AllDifferentExcept(self, vars, escape_value)
-
-    def SortingConstraint(self, vars: "std::vector< operations_research::IntVar * > const &", sorted: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-        r"""
-        Creates a constraint binding the arrays of variables "vars" and
-        "sorted_vars": sorted_vars[0] must be equal to the minimum of all
-        variables in vars, and so on: the value of sorted_vars[i] must be
-        equal to the i-th value of variables invars.
-
-        This constraint propagates in both directions: from "vars" to
-        "sorted_vars" and vice-versa.
-
-        Behind the scenes, this constraint maintains that:
-          - sorted is always increasing.
-          - whatever the values of vars, there exists a permutation that
-            injects its values into the sorted variables.
-
-        For more info, please have a look at:
-          https://mpi-inf.mpg.de/~mehlhorn/ftp/Mehlhorn-Thiel.pdf
-        """
-        return _pywrapcp.Solver_SortingConstraint(self, vars, sorted)
-
-    def LexicalLess(self, left: "std::vector< operations_research::IntVar * > const &", right: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-        r"""
-        Creates a constraint that enforces that left is lexicographically less
-        than right.
-        """
-        return _pywrapcp.Solver_LexicalLess(self, left, right)
-
-    def LexicalLessOrEqual(self, left: "std::vector< operations_research::IntVar * > const &", right: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-        r"""
-        Creates a constraint that enforces that left is lexicographically less
-        than or equal to right.
-        """
-        return _pywrapcp.Solver_LexicalLessOrEqual(self, left, right)
-
-    def InversePermutationConstraint(self, left: "std::vector< operations_research::IntVar * > const &", right: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-        r"""
-        Creates a constraint that enforces that 'left' and 'right' both
-        represent permutations of [0..left.size()-1], and that 'right' is
-        the inverse permutation of 'left', i.e. for all i in
-        [0..left.size()-1], right[left[i]] = i.
-        """
-        return _pywrapcp.Solver_InversePermutationConstraint(self, left, right)
-
-    def NullIntersect(self, first_vars: "std::vector< operations_research::IntVar * > const &", second_vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-        r"""
-        Creates a constraint that states that all variables in the first
-        vector are different from all variables in the second
-        group. Thus the set of values in the first vector does not
-        intersect with the set of values in the second vector.
-        """
-        return _pywrapcp.Solver_NullIntersect(self, first_vars, second_vars)
-
-    def NullIntersectExcept(self, first_vars: "std::vector< operations_research::IntVar * > const &", second_vars: "std::vector< operations_research::IntVar * > const &", escape_value: "int64_t") -> "operations_research::Constraint *":
-        r"""
-        Creates a constraint that states that all variables in the first
-        vector are different from all variables from the second group,
-        unless they are assigned to the escape value. Thus the set of
-        values in the first vector minus the escape value does not
-        intersect with the set of values in the second vector.
-        """
-        return _pywrapcp.Solver_NullIntersectExcept(self, first_vars, second_vars, escape_value)
-
-    def Circuit(self, nexts: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-        r""" Force the "nexts" variable to create a complete Hamiltonian path."""
-        return _pywrapcp.Solver_Circuit(self, nexts)
-
-    def SubCircuit(self, nexts: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-        r"""
-        Force the "nexts" variable to create a complete Hamiltonian path
-        for those that do not loop upon themselves.
-        """
-        return _pywrapcp.Solver_SubCircuit(self, nexts)
-
-    def DelayedPathCumul(self, nexts: "std::vector< operations_research::IntVar * > const &", active: "std::vector< operations_research::IntVar * > const &", cumuls: "std::vector< operations_research::IntVar * > const &", transits: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-        r"""
-        Delayed version of the same constraint: propagation on the nexts variables
-        is delayed until all constraints have propagated.
-        """
-        return _pywrapcp.Solver_DelayedPathCumul(self, nexts, active, cumuls, transits)
-
-    def PathCumul(self, *args) -> "operations_research::Constraint *":
-        r"""
-        *Overload 1:*
-        Creates a constraint which accumulates values along a path such that:
-        cumuls[next[i]] = cumuls[i] + transits[i].
-        Active variables indicate if the corresponding next variable is active;
-        this could be useful to model unperformed nodes in a routing problem.
-
-        |
-
-        *Overload 2:*
-        Creates a constraint which accumulates values along a path such that:
-        cumuls[next[i]] = cumuls[i] + transit_evaluator(i, next[i]).
-        Active variables indicate if the corresponding next variable is active;
-        this could be useful to model unperformed nodes in a routing problem.
-        Ownership of transit_evaluator is taken and it must be a repeatable
-        callback.
-
-        |
-
-        *Overload 3:*
-        Creates a constraint which accumulates values along a path such that:
-        cumuls[next[i]] = cumuls[i] + transit_evaluator(i, next[i]) + slacks[i].
-        Active variables indicate if the corresponding next variable is active;
-        this could be useful to model unperformed nodes in a routing problem.
-        Ownership of transit_evaluator is taken and it must be a repeatable
-        callback.
-        """
-        return _pywrapcp.Solver_PathCumul(self, *args)
-
-    def AllowedAssignments(self, *args) -> "operations_research::Constraint *":
-        r"""
-        *Overload 1:*
-        This method creates a constraint where the graph of the relation
-        between the variables is given in extension. There are 'arity'
-        variables involved in the relation and the graph is given by a
-        integer tuple set.
-
-        |
-
-        *Overload 2:*
-        Compatibility layer for Python API.
-        """
-        return _pywrapcp.Solver_AllowedAssignments(self, *args)
-
-    def TransitionConstraint(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_TransitionConstraint(self, *args)
-
-    def NonOverlappingBoxesConstraint(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_NonOverlappingBoxesConstraint(self, *args)
-
-    def Pack(self, vars: "std::vector< operations_research::IntVar * > const &", number_of_bins: "int") -> "operations_research::Pack *":
-        r"""
-        This constraint packs all variables onto 'number_of_bins'
-        variables.  For any given variable, a value of 'number_of_bins'
-        indicates that the variable is not assigned to any bin.
-        Dimensions, i.e., cumulative constraints on this packing, can be
-        added directly from the pack class.
-        """
-        return _pywrapcp.Solver_Pack(self, vars, number_of_bins)
-
-    def FixedDurationIntervalVar(self, *args) -> "operations_research::IntervalVar *":
-        r"""
-        *Overload 1:*
-        Creates an interval var with a fixed duration. The duration must
-        be greater than 0. If optional is true, then the interval can be
-        performed or unperformed. If optional is false, then the interval
-        is always performed.
-
-        |
-
-        *Overload 2:*
-        Creates a performed interval var with a fixed duration. The duration must
-        be greater than 0.
-
-        |
-
-        *Overload 3:*
-        Creates an interval var with a fixed duration, and performed_variable.
-        The duration must be greater than 0.
-        """
-        return _pywrapcp.Solver_FixedDurationIntervalVar(self, *args)
-
-    def FixedInterval(self, start: "int64_t", duration: "int64_t", name: "std::string const &") -> "operations_research::IntervalVar *":
-        r""" Creates a fixed and performed interval."""
-        return _pywrapcp.Solver_FixedInterval(self, start, duration, name)
-
-    def IntervalVar(self, start_min: "int64_t", start_max: "int64_t", duration_min: "int64_t", duration_max: "int64_t", end_min: "int64_t", end_max: "int64_t", optional: "bool", name: "std::string const &") -> "operations_research::IntervalVar *":
-        r"""
-        Creates an interval var by specifying the bounds on start,
-        duration, and end.
-        """
-        return _pywrapcp.Solver_IntervalVar(self, start_min, start_max, duration_min, duration_max, end_min, end_max, optional, name)
-
-    def MirrorInterval(self, interval_var: "IntervalVar") -> "operations_research::IntervalVar *":
-        r"""
-        Creates an interval var that is the mirror image of the given one, that
-        is, the interval var obtained by reversing the axis.
-        """
-        return _pywrapcp.Solver_MirrorInterval(self, interval_var)
-
-    def FixedDurationStartSyncedOnStartIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
-        r"""
-        Creates an interval var with a fixed duration whose start is
-        synchronized with the start of another interval, with a given
-        offset. The performed status is also in sync with the performed
-        status of the given interval variable.
-        """
-        return _pywrapcp.Solver_FixedDurationStartSyncedOnStartIntervalVar(self, interval_var, duration, offset)
-
-    def FixedDurationStartSyncedOnEndIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
-        r"""
-        Creates an interval var with a fixed duration whose start is
-        synchronized with the end of another interval, with a given
-        offset. The performed status is also in sync with the performed
-        status of the given interval variable.
-        """
-        return _pywrapcp.Solver_FixedDurationStartSyncedOnEndIntervalVar(self, interval_var, duration, offset)
-
-    def FixedDurationEndSyncedOnStartIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
-        r"""
-        Creates an interval var with a fixed duration whose end is
-        synchronized with the start of another interval, with a given
-        offset. The performed status is also in sync with the performed
-        status of the given interval variable.
-        """
-        return _pywrapcp.Solver_FixedDurationEndSyncedOnStartIntervalVar(self, interval_var, duration, offset)
-
-    def FixedDurationEndSyncedOnEndIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
-        r"""
-        Creates an interval var with a fixed duration whose end is
-        synchronized with the end of another interval, with a given
-        offset. The performed status is also in sync with the performed
-        status of the given interval variable.
-        """
-        return _pywrapcp.Solver_FixedDurationEndSyncedOnEndIntervalVar(self, interval_var, duration, offset)
-
-    def IntervalRelaxedMin(self, interval_var: "IntervalVar") -> "operations_research::IntervalVar *":
-        r"""
-         Creates and returns an interval variable that wraps around the given one,
-         relaxing the min start and end. Relaxing means making unbounded when
-         optional. If the variable is non-optional, this method returns
-         interval_var.
-
-         More precisely, such an interval variable behaves as follows:
-        When the underlying must be performed, the returned interval variable
-             behaves exactly as the underlying;
-        When the underlying may or may not be performed, the returned interval
-             variable behaves like the underlying, except that it is unbounded on
-             the min side;
-        When the underlying cannot be performed, the returned interval variable
-             is of duration 0 and must be performed in an interval unbounded on
-             both sides.
-
-         This is very useful to implement propagators that may only modify
-         the start max or end max.
-        """
-        return _pywrapcp.Solver_IntervalRelaxedMin(self, interval_var)
-
-    def IntervalRelaxedMax(self, interval_var: "IntervalVar") -> "operations_research::IntervalVar *":
-        r"""
-         Creates and returns an interval variable that wraps around the given one,
-         relaxing the max start and end. Relaxing means making unbounded when
-         optional. If the variable is non optional, this method returns
-         interval_var.
-
-         More precisely, such an interval variable behaves as follows:
-        When the underlying must be performed, the returned interval variable
-             behaves exactly as the underlying;
-        When the underlying may or may not be performed, the returned interval
-             variable behaves like the underlying, except that it is unbounded on
-             the max side;
-        When the underlying cannot be performed, the returned interval variable
-             is of duration 0 and must be performed in an interval unbounded on
-             both sides.
-
-         This is very useful for implementing propagators that may only modify
-         the start min or end min.
-        """
-        return _pywrapcp.Solver_IntervalRelaxedMax(self, interval_var)
-
-    def TemporalDisjunction(self, *args) -> "operations_research::Constraint *":
-        r"""
-        *Overload 1:*
-        This constraint implements a temporal disjunction between two
-        interval vars t1 and t2. 'alt' indicates which alternative was
-        chosen (alt == 0 is equivalent to t1 before t2).
-
-        |
-
-        *Overload 2:*
-        This constraint implements a temporal disjunction between two
-        interval vars.
-        """
-        return _pywrapcp.Solver_TemporalDisjunction(self, *args)
-
-    def DisjunctiveConstraint(self, intervals: "std::vector< operations_research::IntervalVar * > const &", name: "std::string const &") -> "operations_research::DisjunctiveConstraint *":
-        r"""
-        This constraint forces all interval vars into an non-overlapping
-        sequence. Intervals with zero duration can be scheduled anywhere.
-        """
-        return _pywrapcp.Solver_DisjunctiveConstraint(self, intervals, name)
-
-    def Cumulative(self, *args) -> "operations_research::Constraint *":
-        r"""
-        *Overload 1:*
-        This constraint forces that, for any integer t, the sum of the demands
-        corresponding to an interval containing t does not exceed the given
-        capacity.
-
-        Intervals and demands should be vectors of equal size.
-
-        Demands should only contain non-negative values. Zero values are
-        supported, and the corresponding intervals are filtered out, as they
-        neither impact nor are impacted by this constraint.
-
-        |
-
-        *Overload 2:*
-        This constraint forces that, for any integer t, the sum of the demands
-        corresponding to an interval containing t does not exceed the given
-        capacity.
-
-        Intervals and demands should be vectors of equal size.
-
-        Demands should only contain non-negative values. Zero values are
-        supported, and the corresponding intervals are filtered out, as they
-        neither impact nor are impacted by this constraint.
-
-        |
-
-        *Overload 3:*
-        This constraint forces that, for any integer t, the sum of the demands
-        corresponding to an interval containing t does not exceed the given
-        capacity.
-
-        Intervals and demands should be vectors of equal size.
-
-        Demands should only contain non-negative values. Zero values are
-        supported, and the corresponding intervals are filtered out, as they
-        neither impact nor are impacted by this constraint.
-
-        |
-
-        *Overload 4:*
-        This constraint enforces that, for any integer t, the sum of the demands
-        corresponding to an interval containing t does not exceed the given
-        capacity.
-
-        Intervals and demands should be vectors of equal size.
-
-        Demands should only contain non-negative values. Zero values are
-        supported, and the corresponding intervals are filtered out, as they
-        neither impact nor are impacted by this constraint.
-
-        |
-
-        *Overload 5:*
-        This constraint enforces that, for any integer t, the sum of demands
-        corresponding to an interval containing t does not exceed the given
-        capacity.
-
-        Intervals and demands should be vectors of equal size.
-
-        Demands should be positive.
-
-        |
-
-        *Overload 6:*
-        This constraint enforces that, for any integer t, the sum of demands
-        corresponding to an interval containing t does not exceed the given
-        capacity.
-
-        Intervals and demands should be vectors of equal size.
-
-        Demands should be positive.
-        """
-        return _pywrapcp.Solver_Cumulative(self, *args)
-
-    def Cover(self, vars: "std::vector< operations_research::IntervalVar * > const &", target_var: "IntervalVar") -> "operations_research::Constraint *":
-        r"""
-        This constraint states that the target_var is the convex hull of
-        the intervals. If none of the interval variables is performed,
-        then the target var is unperformed too. Also, if the target
-        variable is unperformed, then all the intervals variables are
-        unperformed too.
-        """
-        return _pywrapcp.Solver_Cover(self, vars, target_var)
-
-    def Assignment(self, *args) -> "operations_research::Assignment *":
-        r"""
-        *Overload 1:*
-        This method creates an empty assignment.
-
-        |
-
-        *Overload 2:*
-        This method creates an assignment which is a copy of 'a'.
-        """
-        return _pywrapcp.Solver_Assignment(self, *args)
-
-    def FirstSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
-        r"""
-        *Overload 1:*
-        Collect the first solution of the search.
+    def MemberCt(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_MemberCt(self, *args)
 
-        |
+    def NotMemberCt(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        expr not in set.
 
-        *Overload 2:*
-        Collect the first solution of the search. The variables will need to
-        be added later.
-        """
-        return _pywrapcp.Solver_FirstSolutionCollector(self, *args)
-
-    def LastSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
-        r"""
-        *Overload 1:*
-        Collect the last solution of the search.
-
-        |
-
-        *Overload 2:*
-        Collect the last solution of the search. The variables will need to
-        be added later.
-        """
-        return _pywrapcp.Solver_LastSolutionCollector(self, *args)
-
-    def BestValueSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
-        r"""
-        *Overload 1:*
-        Collect the solution corresponding to the optimal value of the objective
-        of 'assignment'; if 'assignment' does not have an objective no solution is
-        collected. This collector only collects one solution corresponding to the
-        best objective value (the first one found).
-
-        |
-
-        *Overload 2:*
-        Collect the solution corresponding to the optimal value of the
-        objective of 'assignment'; if 'assignment' does not have an objective no
-        solution is collected. This collector only collects one solution
-        corresponding to the best objective value (the first one
-        found). The variables will need to be added later.
-        """
-        return _pywrapcp.Solver_BestValueSolutionCollector(self, *args)
-
-    def AllSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
-        r"""
-        *Overload 1:*
-        Collect all solutions of the search.
-
-        |
-
-        *Overload 2:*
-        Collect all solutions of the search. The variables will need to
-        be added later.
-        """
-        return _pywrapcp.Solver_AllSolutionCollector(self, *args)
-
-    def Minimize(self, v: "IntVar", step: "int64_t") -> "operations_research::OptimizeVar *":
-        r""" Creates a minimization objective."""
-        return _pywrapcp.Solver_Minimize(self, v, step)
-
-    def Maximize(self, v: "IntVar", step: "int64_t") -> "operations_research::OptimizeVar *":
-        r""" Creates a maximization objective."""
-        return _pywrapcp.Solver_Maximize(self, v, step)
-
-    def Optimize(self, maximize: "bool", v: "IntVar", step: "int64_t") -> "operations_research::OptimizeVar *":
-        r""" Creates a objective with a given sense (true = maximization)."""
-        return _pywrapcp.Solver_Optimize(self, maximize, v, step)
-
-    def WeightedMinimize(self, *args) -> "operations_research::OptimizeVar *":
-        r"""
-        *Overload 1:*
-        Creates a minimization weighted objective. The actual objective is
-        scalar_prod(sub_objectives, weights).
-
-        |
-
-        *Overload 2:*
-        Creates a minimization weighted objective. The actual objective is
-        scalar_prod(sub_objectives, weights).
-        """
-        return _pywrapcp.Solver_WeightedMinimize(self, *args)
-
-    def WeightedMaximize(self, *args) -> "operations_research::OptimizeVar *":
-        r"""
-        *Overload 1:*
-        Creates a maximization weigthed objective.
-
-        |
-
-        *Overload 2:*
-        Creates a maximization weigthed objective.
-        """
-        return _pywrapcp.Solver_WeightedMaximize(self, *args)
-
-    def WeightedOptimize(self, *args) -> "operations_research::OptimizeVar *":
-        r"""
-        *Overload 1:*
-        Creates a weighted objective with a given sense (true = maximization).
-
-        |
-
-        *Overload 2:*
-        Creates a weighted objective with a given sense (true = maximization).
-        """
-        return _pywrapcp.Solver_WeightedOptimize(self, *args)
-
-    def TabuSearch(self, maximize: "bool", v: "IntVar", step: "int64_t", vars: "std::vector< operations_research::IntVar * > const &", keep_tenure: "int64_t", forbid_tenure: "int64_t", tabu_factor: "double") -> "operations_research::SearchMonitor *":
-        r"""
-        MetaHeuristics which try to get the search out of local optima.
-        Creates a Tabu Search monitor.
-        In the context of local search the behavior is similar to MakeOptimize(),
-        creating an objective in a given sense. The behavior differs once a local
-        optimum is reached: thereafter solutions which degrade the value of the
-        objective are allowed if they are not "tabu". A solution is "tabu" if it
-        doesn't respect the following rules:
-        - improving the best solution found so far
-        - variables in the "keep" list must keep their value, variables in the
-        "forbid" list must not take the value they have in the list.
-        Variables with new values enter the tabu lists after each new solution
-        found and leave the lists after a given number of iterations (called
-        tenure). Only the variables passed to the method can enter the lists.
-        The tabu criterion is softened by the tabu factor which gives the number
-        of "tabu" violations which is tolerated; a factor of 1 means no violations
-        allowed; a factor of 0 means all violations are allowed.
-        """
-        return _pywrapcp.Solver_TabuSearch(self, maximize, v, step, vars, keep_tenure, forbid_tenure, tabu_factor)
-
-    def SimulatedAnnealing(self, maximize: "bool", v: "IntVar", step: "int64_t", initial_temperature: "int64_t") -> "operations_research::SearchMonitor *":
-        r""" Creates a Simulated Annealing monitor."""
-        return _pywrapcp.Solver_SimulatedAnnealing(self, maximize, v, step, initial_temperature)
-
-    def LubyRestart(self, scale_factor: "int") -> "operations_research::SearchMonitor *":
-        r"""
-        This search monitor will restart the search periodically.
-        At the iteration n, it will restart after scale_factor * Luby(n) failures
-        where Luby is the Luby Strategy (i.e. 1 1 2 1 1 2 4 1 1 2 1 1 2 4 8...).
-        """
-        return _pywrapcp.Solver_LubyRestart(self, scale_factor)
-
-    def ConstantRestart(self, frequency: "int") -> "operations_research::SearchMonitor *":
-        r"""
-        This search monitor will restart the search periodically after 'frequency'
-        failures.
-        """
-        return _pywrapcp.Solver_ConstantRestart(self, frequency)
-
-    def TimeLimit(self, *args) -> "operations_research::RegularLimit *":
-        return _pywrapcp.Solver_TimeLimit(self, *args)
-
-    def BranchesLimit(self, branches: "int64_t") -> "operations_research::RegularLimit *":
-        r"""
-        Creates a search limit that constrains the number of branches
-        explored in the search tree.
-        """
-        return _pywrapcp.Solver_BranchesLimit(self, branches)
-
-    def FailuresLimit(self, failures: "int64_t") -> "operations_research::RegularLimit *":
-        r"""
-        Creates a search limit that constrains the number of failures
-        that can happen when exploring the search tree.
-        """
-        return _pywrapcp.Solver_FailuresLimit(self, failures)
-
-    def SolutionsLimit(self, solutions: "int64_t") -> "operations_research::RegularLimit *":
-        r"""
-        Creates a search limit that constrains the number of solutions found
-        during the search.
-        """
-        return _pywrapcp.Solver_SolutionsLimit(self, solutions)
-
-    def Limit(self, *args) -> "operations_research::SearchLimit *":
-        r"""
-        *Overload 1:*
-        Limits the search with the 'time', 'branches', 'failures' and
-        'solutions' limits. 'smart_time_check' reduces the calls to the wall
-
-        |
-
-        *Overload 2:*
-        Creates a search limit from its protobuf description
-
-        |
-
-        *Overload 3:*
-        Creates a search limit that is reached when either of the underlying limit
-        is reached. That is, the returned limit is more stringent than both
-        argument limits.
-        """
-        return _pywrapcp.Solver_Limit(self, *args)
-
-    def CustomLimit(self, limiter: "std::function< bool () >") -> "operations_research::SearchLimit *":
-        r"""
-        Callback-based search limit. Search stops when limiter returns true; if
-        this happens at a leaf the corresponding solution will be rejected.
-        """
-        return _pywrapcp.Solver_CustomLimit(self, limiter)
-
-    def SearchLog(self, *args) -> "operations_research::SearchMonitor *":
-        return _pywrapcp.Solver_SearchLog(self, *args)
-
-    def SearchTrace(self, prefix: "std::string const &") -> "operations_research::SearchMonitor *":
-        r"""
-        Creates a search monitor that will trace precisely the behavior of the
-        search. Use this only for low level debugging.
-        """
-        return _pywrapcp.Solver_SearchTrace(self, prefix)
-
-    def PrintModelVisitor(self) -> "operations_research::ModelVisitor *":
-        r""" Prints the model."""
-        return _pywrapcp.Solver_PrintModelVisitor(self)
-
-    def StatisticsModelVisitor(self) -> "operations_research::ModelVisitor *":
-        r""" Displays some nice statistics on the model."""
-        return _pywrapcp.Solver_StatisticsModelVisitor(self)
-
-    def AssignVariableValue(self, var: "IntVar", val: "int64_t") -> "operations_research::Decision *":
-        r""" Decisions."""
-        return _pywrapcp.Solver_AssignVariableValue(self, var, val)
-
-    def VariableLessOrEqualValue(self, var: "IntVar", value: "int64_t") -> "operations_research::Decision *":
-        return _pywrapcp.Solver_VariableLessOrEqualValue(self, var, value)
-
-    def VariableGreaterOrEqualValue(self, var: "IntVar", value: "int64_t") -> "operations_research::Decision *":
-        return _pywrapcp.Solver_VariableGreaterOrEqualValue(self, var, value)
-
-    def SplitVariableDomain(self, var: "IntVar", val: "int64_t", start_with_lower_half: "bool") -> "operations_research::Decision *":
-        return _pywrapcp.Solver_SplitVariableDomain(self, var, val, start_with_lower_half)
-
-    def AssignVariableValueOrFail(self, var: "IntVar", value: "int64_t") -> "operations_research::Decision *":
-        return _pywrapcp.Solver_AssignVariableValueOrFail(self, var, value)
-
-    def AssignVariablesValues(self, vars: "std::vector< operations_research::IntVar * > const &", values: "std::vector< int64_t > const &") -> "operations_research::Decision *":
-        return _pywrapcp.Solver_AssignVariablesValues(self, vars, values)
-
-    def FailDecision(self) -> "operations_research::Decision *":
-        return _pywrapcp.Solver_FailDecision(self)
-
-    def Decision(self, apply: "operations_research::Solver::Action", refute: "operations_research::Solver::Action") -> "operations_research::Decision *":
-        return _pywrapcp.Solver_Decision(self, apply, refute)
-
-    def Compose(self, dbs: "std::vector< operations_research::DecisionBuilder * > const &") -> "operations_research::DecisionBuilder *":
-        return _pywrapcp.Solver_Compose(self, dbs)
-
-    def Try(self, dbs: "std::vector< operations_research::DecisionBuilder * > const &") -> "operations_research::DecisionBuilder *":
-        return _pywrapcp.Solver_Try(self, dbs)
-
-    def DefaultPhase(self, *args) -> "operations_research::DecisionBuilder *":
-        return _pywrapcp.Solver_DefaultPhase(self, *args)
-
-    def ScheduleOrPostpone(self, var: "IntervalVar", est: "int64_t", marker: "int64_t *const") -> "operations_research::Decision *":
-        r"""
-        Returns a decision that tries to schedule a task at a given time.
-        On the Apply branch, it will set that interval var as performed and set
-        its start to 'est'. On the Refute branch, it will just update the
-        'marker' to 'est' + 1. This decision is used in the
-        INTERVAL_SET_TIMES_FORWARD strategy.
-        """
-        return _pywrapcp.Solver_ScheduleOrPostpone(self, var, est, marker)
-
-    def ScheduleOrExpedite(self, var: "IntervalVar", est: "int64_t", marker: "int64_t *const") -> "operations_research::Decision *":
-        r"""
-        Returns a decision that tries to schedule a task at a given time.
-        On the Apply branch, it will set that interval var as performed and set
-        its end to 'est'. On the Refute branch, it will just update the
-        'marker' to 'est' - 1. This decision is used in the
-        INTERVAL_SET_TIMES_BACKWARD strategy.
-        """
-        return _pywrapcp.Solver_ScheduleOrExpedite(self, var, est, marker)
-
-    def RankFirstInterval(self, sequence: "SequenceVar", index: "int") -> "operations_research::Decision *":
-        r"""
-        Returns a decision that tries to rank first the ith interval var
-        in the sequence variable.
-        """
-        return _pywrapcp.Solver_RankFirstInterval(self, sequence, index)
-
-    def RankLastInterval(self, sequence: "SequenceVar", index: "int") -> "operations_research::Decision *":
-        r"""
-        Returns a decision that tries to rank last the ith interval var
-        in the sequence variable.
-        """
-        return _pywrapcp.Solver_RankLastInterval(self, sequence, index)
-
-    def Phase(self, *args) -> "operations_research::DecisionBuilder *":
-        return _pywrapcp.Solver_Phase(self, *args)
-
-    def DecisionBuilderFromAssignment(self, assignment: "Assignment", db: "DecisionBuilder", vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::DecisionBuilder *":
-        r"""
-        Returns a decision builder for which the left-most leaf corresponds
-        to assignment, the rest of the tree being explored using 'db'.
-        """
-        return _pywrapcp.Solver_DecisionBuilderFromAssignment(self, assignment, db, vars)
-
-    def ConstraintAdder(self, ct: "Constraint") -> "operations_research::DecisionBuilder *":
-        r"""
-        Returns a decision builder that will add the given constraint to
-        the model.
-        """
-        return _pywrapcp.Solver_ConstraintAdder(self, ct)
-
-    def SolveOnce(self, db: "DecisionBuilder", monitors: "std::vector< operations_research::SearchMonitor * > const &") -> "operations_research::DecisionBuilder *":
-        return _pywrapcp.Solver_SolveOnce(self, db, monitors)
-
-    def NestedOptimize(self, *args) -> "operations_research::DecisionBuilder *":
-        return _pywrapcp.Solver_NestedOptimize(self, *args)
-
-    def RestoreAssignment(self, assignment: "Assignment") -> "operations_research::DecisionBuilder *":
-        r"""
-        Returns a DecisionBuilder which restores an Assignment
-        (calls void Assignment::Restore())
-        """
-        return _pywrapcp.Solver_RestoreAssignment(self, assignment)
-
-    def StoreAssignment(self, assignment: "Assignment") -> "operations_research::DecisionBuilder *":
-        r"""
-        Returns a DecisionBuilder which stores an Assignment
-        (calls void Assignment::Store())
-        """
-        return _pywrapcp.Solver_StoreAssignment(self, assignment)
-
-    def Operator(self, *args) -> "operations_research::LocalSearchOperator *":
-        return _pywrapcp.Solver_Operator(self, *args)
-
-    def RandomLnsOperator(self, *args) -> "operations_research::LocalSearchOperator *":
-        return _pywrapcp.Solver_RandomLnsOperator(self, *args)
-
-    def MoveTowardTargetOperator(self, *args) -> "operations_research::LocalSearchOperator *":
-        r"""
-        *Overload 1:*
-        Creates a local search operator that tries to move the assignment of some
-        variables toward a target. The target is given as an Assignment. This
-        operator generates neighbors in which the only difference compared to the
-        current state is that one variable that belongs to the target assignment
-        is set to its target value.
-
-        |
-
-        *Overload 2:*
-        Creates a local search operator that tries to move the assignment of some
-        variables toward a target. The target is given either as two vectors: a
-        vector of variables and a vector of associated target values. The two
-        vectors should be of the same length. This operator generates neighbors in
-        which the only difference compared to the current state is that one
-        variable that belongs to the given vector is set to its target value.
-        """
-        return _pywrapcp.Solver_MoveTowardTargetOperator(self, *args)
-
-    def ConcatenateOperators(self, *args) -> "operations_research::LocalSearchOperator *":
-        return _pywrapcp.Solver_ConcatenateOperators(self, *args)
-
-    def RandomConcatenateOperators(self, *args) -> "operations_research::LocalSearchOperator *":
-        r"""
-        *Overload 1:*
-        Randomized version of local search concatenator; calls a random operator
-        at each call to MakeNextNeighbor().
-
-        |
-
-        *Overload 2:*
-        Randomized version of local search concatenator; calls a random operator
-        at each call to MakeNextNeighbor(). The provided seed is used to
-        initialize the random number generator.
-        """
-        return _pywrapcp.Solver_RandomConcatenateOperators(self, *args)
-
-    def NeighborhoodLimit(self, op: "LocalSearchOperator", limit: "int64_t") -> "operations_research::LocalSearchOperator *":
-        r"""
-        Creates a local search operator that wraps another local search
-        operator and limits the number of neighbors explored (i.e., calls
-        to MakeNextNeighbor from the current solution (between two calls
-        to Start()). When this limit is reached, MakeNextNeighbor()
-        returns false. The counter is cleared when Start() is called.
-        """
-        return _pywrapcp.Solver_NeighborhoodLimit(self, op, limit)
-
-    def LocalSearchPhase(self, *args) -> "operations_research::DecisionBuilder *":
-        return _pywrapcp.Solver_LocalSearchPhase(self, *args)
-
-    def LocalSearchPhaseParameters(self, *args) -> "operations_research::LocalSearchPhaseParameters *":
-        return _pywrapcp.Solver_LocalSearchPhaseParameters(self, *args)
-
-    def SearchDepth(self) -> "int":
-        r"""
-        Gets the search depth of the current active search. Returns -1 if
-        there is no active search opened.
-        """
-        return _pywrapcp.Solver_SearchDepth(self)
-
-    def SearchLeftDepth(self) -> "int":
-        r"""
-        Gets the search left depth of the current active search. Returns -1 if
-        there is no active search opened.
-        """
-        return _pywrapcp.Solver_SearchLeftDepth(self)
-
-    def SolveDepth(self) -> "int":
-        r"""
-        Gets the number of nested searches. It returns 0 outside search,
-        1 during the top level search, 2 or more in case of nested searches.
-        """
-        return _pywrapcp.Solver_SolveDepth(self)
-
-    def Rand64(self, size: "int64_t") -> "int64_t":
-        r""" Returns a random value between 0 and 'size' - 1;"""
-        return _pywrapcp.Solver_Rand64(self, size)
-
-    def Rand32(self, size: "int32_t") -> "int32_t":
-        r""" Returns a random value between 0 and 'size' - 1;"""
-        return _pywrapcp.Solver_Rand32(self, size)
-
-    def ReSeed(self, seed: "int32_t") -> "void":
-        r""" Reseed the solver random generator."""
-        return _pywrapcp.Solver_ReSeed(self, seed)
-
-    def LocalSearchProfile(self) -> "std::string":
-        r""" Returns local search profiling information in a human readable format."""
-        return _pywrapcp.Solver_LocalSearchProfile(self)
-
-    def Constraints(self) -> "int":
-        r"""
-        Counts the number of constraints that have been added
-        to the solver before the search.
-        """
-        return _pywrapcp.Solver_Constraints(self)
-
-    def Accept(self, visitor: "operations_research::ModelVisitor *const") -> "void":
-        r""" Accepts the given model visitor."""
-        return _pywrapcp.Solver_Accept(self, visitor)
-
-    def FinishCurrentSearch(self) -> "void":
-        r""" Tells the solver to kill or restart the current search."""
-        return _pywrapcp.Solver_FinishCurrentSearch(self)
-
-    def RestartCurrentSearch(self) -> "void":
-        return _pywrapcp.Solver_RestartCurrentSearch(self)
-
-    def ShouldFail(self) -> "void":
-        r"""
-        These methods are only useful for the SWIG wrappers, which need a way
-        to externally cause the Solver to fail.
-        """
-        return _pywrapcp.Solver_ShouldFail(self)
-
-    def __str__(self) -> "std::string":
-        return _pywrapcp.Solver___str__(self)
-
-    def Add(self, ct):
-      if isinstance(ct, PyConstraint):
-        self.__python_constraints.append(ct)
-      self.AddConstraint(ct)
-
-
-    def TreeNoCycle(self, nexts: "std::vector< operations_research::IntVar * > const &", active: "std::vector< operations_research::IntVar * > const &", callback: "operations_research::Solver::IndexFilter1"=0) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_TreeNoCycle(self, nexts, active, callback)
-
-    def SearchLogWithCallback(self, period: "int", callback: "std::function< std::string () >") -> "operations_research::SearchMonitor *":
-        return _pywrapcp.Solver_SearchLogWithCallback(self, period, callback)
-
-    def ElementFunction(self, values: "std::function< int64_t (int64_t) >", index: "IntVar") -> "operations_research::IntExpr *":
-        return _pywrapcp.Solver_ElementFunction(self, values, index)
-
-    def VarEvalValStrPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_evaluator: "std::function< int64_t (int64_t) >", val_str: "operations_research::Solver::IntValueStrategy") -> "operations_research::DecisionBuilder *":
-        return _pywrapcp.Solver_VarEvalValStrPhase(self, vars, var_evaluator, val_str)
-
-    def VarStrValEvalPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_str: "operations_research::Solver::IntVarStrategy", val_eval: "operations_research::Solver::IndexEvaluator2") -> "operations_research::DecisionBuilder *":
-        return _pywrapcp.Solver_VarStrValEvalPhase(self, vars, var_str, val_eval)
-
-    def VarEvalValEvalPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_eval: "std::function< int64_t (int64_t) >", val_eval: "operations_research::Solver::IndexEvaluator2") -> "operations_research::DecisionBuilder *":
-        return _pywrapcp.Solver_VarEvalValEvalPhase(self, vars, var_eval, val_eval)
-
-    def VarStrValEvalTieBreakPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_str: "operations_research::Solver::IntVarStrategy", val_eval: "operations_research::Solver::IndexEvaluator2", tie_breaker: "std::function< int64_t (int64_t) >") -> "operations_research::DecisionBuilder *":
-        return _pywrapcp.Solver_VarStrValEvalTieBreakPhase(self, vars, var_str, val_eval, tie_breaker)
-
-    def VarEvalValEvalTieBreakPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_eval: "std::function< int64_t (int64_t) >", val_eval: "operations_research::Solver::IndexEvaluator2", tie_breaker: "std::function< int64_t (int64_t) >") -> "operations_research::DecisionBuilder *":
-        return _pywrapcp.Solver_VarEvalValEvalTieBreakPhase(self, vars, var_eval, val_eval, tie_breaker)
-
-    def EvalEvalStrPhase(self, vars: "std::vector< operations_research::IntVar * > const &", evaluator: "operations_research::Solver::IndexEvaluator2", str: "operations_research::Solver::EvaluatorStrategy") -> "operations_research::DecisionBuilder *":
-        return _pywrapcp.Solver_EvalEvalStrPhase(self, vars, evaluator, str)
-
-    def EvalEvalStrTieBreakPhase(self, vars: "std::vector< operations_research::IntVar * > const &", evaluator: "operations_research::Solver::IndexEvaluator2", tie_breaker: "operations_research::Solver::IndexEvaluator1", str: "operations_research::Solver::EvaluatorStrategy") -> "operations_research::DecisionBuilder *":
-        return _pywrapcp.Solver_EvalEvalStrTieBreakPhase(self, vars, evaluator, tie_breaker, str)
-
-    def GuidedLocalSearch(self, *args) -> "operations_research::SearchMonitor *":
-        return _pywrapcp.Solver_GuidedLocalSearch(self, *args)
-
-    def SumObjectiveFilter(self, vars: "std::vector< operations_research::IntVar * > const &", values: "operations_research::Solver::IndexEvaluator2", filter_enum: "operations_research::Solver::LocalSearchFilterBound") -> "operations_research::LocalSearchFilter *":
-        return _pywrapcp.Solver_SumObjectiveFilter(self, vars, values, filter_enum)
-
-# Register Solver in _pywrapcp:
-_pywrapcp.Solver_swigregister(Solver)
-
-def Solver_DefaultSolverParameters() -> "operations_research::ConstraintSolverParameters":
-    r""" Create a ConstraintSolverParameters proto with all the default values."""
-    return _pywrapcp.Solver_DefaultSolverParameters()
-
-def Solver_MemoryUsage() -> "int64_t":
-    r""" Current memory usage in bytes"""
-    return _pywrapcp.Solver_MemoryUsage()
-
-class BaseObject(object):
-    r"""
-    A BaseObject is the root of all reversibly allocated objects.
-    A DebugString method and the associated << operator are implemented
-    as a convenience.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self):
-        if self.__class__ == BaseObject:
-            _self = None
-        else:
-            _self = self
-        _pywrapcp.BaseObject_swiginit(self, _pywrapcp.new_BaseObject(_self, ))
-    __swig_destroy__ = _pywrapcp.delete_BaseObject
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.BaseObject_DebugString(self)
-
-    def __str__(self) -> "std::string":
-        return _pywrapcp.BaseObject___str__(self)
-
-    def __repr__(self) -> "std::string":
-        return _pywrapcp.BaseObject___repr__(self)
-    def __disown__(self):
-        self.this.disown()
-        _pywrapcp.disown_BaseObject(self)
-        return weakref.proxy(self)
-
-# Register BaseObject in _pywrapcp:
-_pywrapcp.BaseObject_swigregister(BaseObject)
-
-class PropagationBaseObject(BaseObject):
-    r"""
-    NOLINT
-    The PropagationBaseObject is a subclass of BaseObject that is also
-    friend to the Solver class. It allows accessing methods useful when
-    writing new constraints or new expressions.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self, s: "Solver"):
-        if self.__class__ == PropagationBaseObject:
-            _self = None
-        else:
-            _self = self
-        _pywrapcp.PropagationBaseObject_swiginit(self, _pywrapcp.new_PropagationBaseObject(_self, s))
-    __swig_destroy__ = _pywrapcp.delete_PropagationBaseObject
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.PropagationBaseObject_DebugString(self)
-
-    def solver(self) -> "operations_research::Solver *":
-        return _pywrapcp.PropagationBaseObject_solver(self)
-
-    def Name(self) -> "std::string":
-        r""" Object naming."""
-        return _pywrapcp.PropagationBaseObject_Name(self)
-    def __disown__(self):
-        self.this.disown()
-        _pywrapcp.disown_PropagationBaseObject(self)
-        return weakref.proxy(self)
-
-# Register PropagationBaseObject in _pywrapcp:
-_pywrapcp.PropagationBaseObject_swigregister(PropagationBaseObject)
-
-class Decision(BaseObject):
-    r"""
-    A Decision represents a choice point in the search tree. The two main
-    methods are Apply() to go left, or Refute() to go right.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self):
-        if self.__class__ == Decision:
-            _self = None
-        else:
-            _self = self
-        _pywrapcp.Decision_swiginit(self, _pywrapcp.new_Decision(_self, ))
-    __swig_destroy__ = _pywrapcp.delete_Decision
-
-    def ApplyWrapper(self, s: "Solver") -> "void":
-        r""" Apply will be called first when the decision is executed."""
-        return _pywrapcp.Decision_ApplyWrapper(self, s)
-
-    def RefuteWrapper(self, s: "Solver") -> "void":
-        r""" Refute will be called after a backtrack."""
-        return _pywrapcp.Decision_RefuteWrapper(self, s)
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.Decision_DebugString(self)
-
-    def __repr__(self) -> "std::string":
-        return _pywrapcp.Decision___repr__(self)
-
-    def __str__(self) -> "std::string":
-        return _pywrapcp.Decision___str__(self)
-    def __disown__(self):
-        self.this.disown()
-        _pywrapcp.disown_Decision(self)
-        return weakref.proxy(self)
-
-# Register Decision in _pywrapcp:
-_pywrapcp.Decision_swigregister(Decision)
-
-class DecisionBuilder(BaseObject):
-    r"""
-    A DecisionBuilder is responsible for creating the search tree. The
-    important method is Next(), which returns the next decision to execute.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self):
-        if self.__class__ == DecisionBuilder:
-            _self = None
-        else:
-            _self = self
-        _pywrapcp.DecisionBuilder_swiginit(self, _pywrapcp.new_DecisionBuilder(_self, ))
-    __swig_destroy__ = _pywrapcp.delete_DecisionBuilder
-
-    def NextWrapper(self, s: "Solver") -> "operations_research::Decision *":
-        r"""
-        This is the main method of the decision builder class. It must
-        return a decision (an instance of the class Decision). If it
-        returns nullptr, this means that the decision builder has finished
-        its work.
-        """
-        return _pywrapcp.DecisionBuilder_NextWrapper(self, s)
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.DecisionBuilder_DebugString(self)
-
-    def __repr__(self) -> "std::string":
-        return _pywrapcp.DecisionBuilder___repr__(self)
-
-    def __str__(self) -> "std::string":
-        return _pywrapcp.DecisionBuilder___str__(self)
-    def __disown__(self):
-        self.this.disown()
-        _pywrapcp.disown_DecisionBuilder(self)
-        return weakref.proxy(self)
-
-# Register DecisionBuilder in _pywrapcp:
-_pywrapcp.DecisionBuilder_swigregister(DecisionBuilder)
-
-class Demon(BaseObject):
-    r"""
-    A Demon is the base element of a propagation queue. It is the main
-      object responsible for implementing the actual propagation
-      of the constraint and pruning the inconsistent values in the domains
-      of the variables. The main concept is that demons are listeners that are
-      attached to the variables and listen to their modifications.
-    There are two methods:
-     - Run() is the actual method called when the demon is processed.
-     - priority() returns its priority. Standard priorities are slow, normal
-       or fast. "immediate" is reserved for variables and is treated separately.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self):
-        r"""
-        This indicates the priority of a demon. Immediate demons are treated
-        separately and corresponds to variables.
-        """
-        if self.__class__ == Demon:
-            _self = None
-        else:
-            _self = self
-        _pywrapcp.Demon_swiginit(self, _pywrapcp.new_Demon(_self, ))
-    __swig_destroy__ = _pywrapcp.delete_Demon
-
-    def RunWrapper(self, s: "Solver") -> "void":
-        r""" This is the main callback of the demon."""
-        return _pywrapcp.Demon_RunWrapper(self, s)
-
-    def Priority(self) -> "operations_research::Solver::DemonPriority":
-        r"""
-        This method returns the priority of the demon. Usually a demon is
-        fast, slow or normal. Immediate demons are reserved for internal
-        use to maintain variables.
-        """
-        return _pywrapcp.Demon_Priority(self)
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.Demon_DebugString(self)
-
-    def Inhibit(self, s: "Solver") -> "void":
-        r"""
-        This method inhibits the demon in the search tree below the
-        current position.
-        """
-        return _pywrapcp.Demon_Inhibit(self, s)
-
-    def Desinhibit(self, s: "Solver") -> "void":
-        r""" This method un-inhibits the demon that was previously inhibited."""
-        return _pywrapcp.Demon_Desinhibit(self, s)
-    def __disown__(self):
-        self.this.disown()
-        _pywrapcp.disown_Demon(self)
-        return weakref.proxy(self)
-
-# Register Demon in _pywrapcp:
-_pywrapcp.Demon_swigregister(Demon)
-
-class Constraint(PropagationBaseObject):
-    r"""
-    A constraint is the main modeling object. It provides two methods:
-      - Post() is responsible for creating the demons and attaching them to
-        immediate demons().
-      - InitialPropagate() is called once just after Post and performs
-        the initial propagation. The subsequent propagations will be performed
-        by the demons Posted during the post() method.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, solver: "Solver"):
-        if self.__class__ == Constraint:
-            _self = None
-        else:
-            _self = self
-        _pywrapcp.Constraint_swiginit(self, _pywrapcp.new_Constraint(_self, solver))
-    __swig_destroy__ = _pywrapcp.delete_Constraint
-
-    def Post(self) -> "void":
-        r"""
-        This method is called when the constraint is processed by the
-        solver. Its main usage is to attach demons to variables.
-        """
-        return _pywrapcp.Constraint_Post(self)
-
-    def InitialPropagateWrapper(self) -> "void":
-        r"""
-        This method performs the initial propagation of the
-        constraint. It is called just after the post.
-        """
-        return _pywrapcp.Constraint_InitialPropagateWrapper(self)
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.Constraint_DebugString(self)
-
-    def Var(self) -> "operations_research::IntVar *":
-        r"""
-        Creates a Boolean variable representing the status of the constraint
-        (false = constraint is violated, true = constraint is satisfied). It
-        returns nullptr if the constraint does not support this API.
-        """
-        return _pywrapcp.Constraint_Var(self)
-
-    def __repr__(self) -> "std::string":
-        return _pywrapcp.Constraint___repr__(self)
-
-    def __str__(self) -> "std::string":
-        return _pywrapcp.Constraint___str__(self)
-
-    def __add__(self, *args) -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint___add__(self, *args)
-
-    def __radd__(self, v: "int64_t") -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint___radd__(self, v)
-
-    def __sub__(self, *args) -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint___sub__(self, *args)
-
-    def __rsub__(self, v: "int64_t") -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint___rsub__(self, v)
-
-    def __mul__(self, *args) -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint___mul__(self, *args)
-
-    def __rmul__(self, v: "int64_t") -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint___rmul__(self, v)
-
-    def __floordiv__(self, v: "int64_t") -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint___floordiv__(self, v)
-
-    def __neg__(self) -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint___neg__(self)
-
-    def __abs__(self) -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint___abs__(self)
-
-    def Square(self) -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint_Square(self)
-
-    def __eq__(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Constraint___eq__(self, *args)
-
-    def __ne__(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Constraint___ne__(self, *args)
-
-    def __ge__(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Constraint___ge__(self, *args)
-
-    def __gt__(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Constraint___gt__(self, *args)
-
-    def __le__(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Constraint___le__(self, *args)
-
-    def __lt__(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Constraint___lt__(self, *args)
-
-    def MapTo(self, vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-        return _pywrapcp.Constraint_MapTo(self, vars)
-
-    def IndexOf(self, *args) -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint_IndexOf(self, *args)
-    def __disown__(self):
-        self.this.disown()
-        _pywrapcp.disown_Constraint(self)
-        return weakref.proxy(self)
-
-# Register Constraint in _pywrapcp:
-_pywrapcp.Constraint_swigregister(Constraint)
-
-class SearchMonitor(BaseObject):
-    r""" A search monitor is a simple set of callbacks to monitor all search events"""
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, s: "Solver"):
-        if self.__class__ == SearchMonitor:
-            _self = None
-        else:
-            _self = self
-        _pywrapcp.SearchMonitor_swiginit(self, _pywrapcp.new_SearchMonitor(_self, s))
-    __swig_destroy__ = _pywrapcp.delete_SearchMonitor
-
-    def EnterSearch(self) -> "void":
-        r""" Beginning of the search."""
-        return _pywrapcp.SearchMonitor_EnterSearch(self)
-
-    def RestartSearch(self) -> "void":
-        r""" Restart the search."""
-        return _pywrapcp.SearchMonitor_RestartSearch(self)
+        |
 
-    def ExitSearch(self) -> "void":
-        r""" End of the search."""
-        return _pywrapcp.SearchMonitor_ExitSearch(self)
+        *Overload 2:*
+        expr should not be in the list of forbidden intervals [start[i]..end[i]].
 
-    def BeginNextDecision(self, b: "DecisionBuilder") -> "void":
-        r""" Before calling DecisionBuilder::Next."""
-        return _pywrapcp.SearchMonitor_BeginNextDecision(self, b)
+        |
 
-    def EndNextDecision(self, b: "DecisionBuilder", d: "Decision") -> "void":
-        r""" After calling DecisionBuilder::Next, along with the returned decision."""
-        return _pywrapcp.SearchMonitor_EndNextDecision(self, b, d)
+        *Overload 3:*
+        expr should not be in the list of forbidden intervals [start[i]..end[i]].
+        """
+        return _pywrapcp.Solver_NotMemberCt(self, *args)
 
-    def ApplyDecision(self, d: "Decision") -> "void":
-        r""" Before applying the decision."""
-        return _pywrapcp.SearchMonitor_ApplyDecision(self, d)
+    def IsMemberCt(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_IsMemberCt(self, *args)
 
-    def RefuteDecision(self, d: "Decision") -> "void":
-        r""" Before refuting the decision."""
-        return _pywrapcp.SearchMonitor_RefuteDecision(self, d)
+    def IsMemberVar(self, *args) -> "operations_research::IntVar *":
+        return _pywrapcp.Solver_IsMemberVar(self, *args)
 
-    def AfterDecision(self, d: "Decision", apply: "bool") -> "void":
-        r"""
-        Just after refuting or applying the decision, apply is true after Apply.
-        This is called only if the Apply() or Refute() methods have not failed.
-        """
-        return _pywrapcp.SearchMonitor_AfterDecision(self, d, apply)
+    def Count(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        |{i | vars[i] == value}| == max_count
+
+        |
+
+        *Overload 2:*
+        |{i | vars[i] == value}| == max_count
+        """
+        return _pywrapcp.Solver_Count(self, *args)
+
+    def Distribute(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        Aggregated version of count:  |{i | v[i] == values[j]}| == cards[j]
+
+        |
+
+        *Overload 2:*
+        Aggregated version of count:  |{i | v[i] == values[j]}| == cards[j]
+
+        |
+
+        *Overload 3:*
+        Aggregated version of count:  |{i | v[i] == j}| == cards[j]
+
+        |
+
+        *Overload 4:*
+        Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1: card_min <= |{i | v[i] == j}| <= card_max
+
+        |
+
+        *Overload 5:*
+        Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1:    card_min[j] <= |{i | v[i] == j}| <= card_max[j]
+
+        |
+
+        *Overload 6:*
+        Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1:    card_min[j] <= |{i | v[i] == j}| <= card_max[j]
+
+        |
+
+        *Overload 7:*
+        Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1:    card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j]
+
+        |
+
+        *Overload 8:*
+        Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1:    card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j]
+        """
+        return _pywrapcp.Solver_Distribute(self, *args)
+
+    def Deviation(self, vars: "std::vector< operations_research::IntVar * > const &", deviation_var: "IntVar", total_sum: "int64_t") -> "operations_research::Constraint *":
+        r""" Deviation constraint: sum_i |n * vars[i] - total_sum| <= deviation_var and sum_i vars[i] == total_sum n = #vars"""
+        return _pywrapcp.Solver_Deviation(self, vars, deviation_var, total_sum)
+
+    def AllDifferent(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        All variables are pairwise different. This corresponds to the stronger version of the propagation algorithm.
+
+        |
+
+        *Overload 2:*
+        All variables are pairwise different.  If 'stronger_propagation' is true, stronger, and potentially slower propagation will occur. This API will be deprecated in the future.
+        """
+        return _pywrapcp.Solver_AllDifferent(self, *args)
+
+    def AllDifferentExcept(self, vars: "std::vector< operations_research::IntVar * > const &", escape_value: "int64_t") -> "operations_research::Constraint *":
+        r""" All variables are pairwise different, unless they are assigned to the escape value."""
+        return _pywrapcp.Solver_AllDifferentExcept(self, vars, escape_value)
+
+    def SortingConstraint(self, vars: "std::vector< operations_research::IntVar * > const &", sorted: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Creates a constraint binding the arrays of variables "vars" and "sorted_vars": sorted_vars[0] must be equal to the minimum of all variables in vars, and so on: the value of sorted_vars[i] must be equal to the i-th value of variables invars. This constraint propagates in both directions: from "vars" to "sorted_vars" and vice-versa. Behind the scenes, this constraint maintains that:   - sorted is always increasing.   - whatever the values of vars, there exists a permutation that     injects its values into the sorted variables. For more info, please have a look at:   https://mpi-inf.mpg.de/~mehlhorn/ftp/Mehlhorn-Thiel.pdf"""
+        return _pywrapcp.Solver_SortingConstraint(self, vars, sorted)
+
+    def LexicalLess(self, left: "std::vector< operations_research::IntVar * > const &", right: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Creates a constraint that enforces that left is lexicographically less than right."""
+        return _pywrapcp.Solver_LexicalLess(self, left, right)
+
+    def LexicalLessOrEqual(self, left: "std::vector< operations_research::IntVar * > const &", right: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Creates a constraint that enforces that left is lexicographically less than or equal to right."""
+        return _pywrapcp.Solver_LexicalLessOrEqual(self, left, right)
+
+    def InversePermutationConstraint(self, left: "std::vector< operations_research::IntVar * > const &", right: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Creates a constraint that enforces that 'left' and 'right' both represent permutations of [0..left.size()-1], and that 'right' is the inverse permutation of 'left', i.e. for all i in [0..left.size()-1], right[left[i]] = i."""
+        return _pywrapcp.Solver_InversePermutationConstraint(self, left, right)
+
+    def NullIntersect(self, first_vars: "std::vector< operations_research::IntVar * > const &", second_vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Creates a constraint that states that all variables in the first vector are different from all variables in the second group. Thus the set of values in the first vector does not intersect with the set of values in the second vector."""
+        return _pywrapcp.Solver_NullIntersect(self, first_vars, second_vars)
+
+    def NullIntersectExcept(self, first_vars: "std::vector< operations_research::IntVar * > const &", second_vars: "std::vector< operations_research::IntVar * > const &", escape_value: "int64_t") -> "operations_research::Constraint *":
+        r""" Creates a constraint that states that all variables in the first vector are different from all variables from the second group, unless they are assigned to the escape value. Thus the set of values in the first vector minus the escape value does not intersect with the set of values in the second vector."""
+        return _pywrapcp.Solver_NullIntersectExcept(self, first_vars, second_vars, escape_value)
+
+    def Circuit(self, nexts: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Force the "nexts" variable to create a complete Hamiltonian path."""
+        return _pywrapcp.Solver_Circuit(self, nexts)
+
+    def SubCircuit(self, nexts: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Force the "nexts" variable to create a complete Hamiltonian path for those that do not loop upon themselves."""
+        return _pywrapcp.Solver_SubCircuit(self, nexts)
+
+    def DelayedPathCumul(self, nexts: "std::vector< operations_research::IntVar * > const &", active: "std::vector< operations_research::IntVar * > const &", cumuls: "std::vector< operations_research::IntVar * > const &", transits: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Delayed version of the same constraint: propagation on the nexts variables is delayed until all constraints have propagated."""
+        return _pywrapcp.Solver_DelayedPathCumul(self, nexts, active, cumuls, transits)
+
+    def PathCumul(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        Creates a constraint which accumulates values along a path such that: cumuls[next[i]] = cumuls[i] + transits[i]. Active variables indicate if the corresponding next variable is active; this could be useful to model unperformed nodes in a routing problem.
+
+        |
+
+        *Overload 2:*
+        Creates a constraint which accumulates values along a path such that: cumuls[next[i]] = cumuls[i] + transit_evaluator(i, next[i]). Active variables indicate if the corresponding next variable is active; this could be useful to model unperformed nodes in a routing problem. Ownership of transit_evaluator is taken and it must be a repeatable callback.
+
+        |
+
+        *Overload 3:*
+        Creates a constraint which accumulates values along a path such that: cumuls[next[i]] = cumuls[i] + transit_evaluator(i, next[i]) + slacks[i]. Active variables indicate if the corresponding next variable is active; this could be useful to model unperformed nodes in a routing problem. Ownership of transit_evaluator is taken and it must be a repeatable callback.
+        """
+        return _pywrapcp.Solver_PathCumul(self, *args)
+
+    def AllowedAssignments(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        This method creates a constraint where the graph of the relation between the variables is given in extension. There are 'arity' variables involved in the relation and the graph is given by a integer tuple set.
+
+        |
+
+        *Overload 2:*
+        Compatibility layer for Python API.
+        """
+        return _pywrapcp.Solver_AllowedAssignments(self, *args)
+
+    def TransitionConstraint(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_TransitionConstraint(self, *args)
+
+    def NonOverlappingBoxesConstraint(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_NonOverlappingBoxesConstraint(self, *args)
+
+    def Pack(self, vars: "std::vector< operations_research::IntVar * > const &", number_of_bins: "int") -> "operations_research::Pack *":
+        r""" This constraint packs all variables onto 'number_of_bins' variables.  For any given variable, a value of 'number_of_bins' indicates that the variable is not assigned to any bin. Dimensions, i.e., cumulative constraints on this packing, can be added directly from the pack class."""
+        return _pywrapcp.Solver_Pack(self, vars, number_of_bins)
+
+    def FixedDurationIntervalVar(self, *args) -> "operations_research::IntervalVar *":
+        r"""
+        *Overload 1:*
+        Creates an interval var with a fixed duration. The duration must be greater than 0. If optional is true, then the interval can be performed or unperformed. If optional is false, then the interval is always performed.
+
+        |
+
+        *Overload 2:*
+        Creates a performed interval var with a fixed duration. The duration must be greater than 0.
+
+        |
+
+        *Overload 3:*
+        Creates an interval var with a fixed duration, and performed_variable. The duration must be greater than 0.
+        """
+        return _pywrapcp.Solver_FixedDurationIntervalVar(self, *args)
+
+    def FixedInterval(self, start: "int64_t", duration: "int64_t", name: "std::string const &") -> "operations_research::IntervalVar *":
+        r""" Creates a fixed and performed interval."""
+        return _pywrapcp.Solver_FixedInterval(self, start, duration, name)
+
+    def IntervalVar(self, start_min: "int64_t", start_max: "int64_t", duration_min: "int64_t", duration_max: "int64_t", end_min: "int64_t", end_max: "int64_t", optional: "bool", name: "std::string const &") -> "operations_research::IntervalVar *":
+        r""" Creates an interval var by specifying the bounds on start, duration, and end."""
+        return _pywrapcp.Solver_IntervalVar(self, start_min, start_max, duration_min, duration_max, end_min, end_max, optional, name)
+
+    def MirrorInterval(self, interval_var: "IntervalVar") -> "operations_research::IntervalVar *":
+        r""" Creates an interval var that is the mirror image of the given one, that is, the interval var obtained by reversing the axis."""
+        return _pywrapcp.Solver_MirrorInterval(self, interval_var)
+
+    def FixedDurationStartSyncedOnStartIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
+        r""" Creates an interval var with a fixed duration whose start is synchronized with the start of another interval, with a given offset. The performed status is also in sync with the performed status of the given interval variable."""
+        return _pywrapcp.Solver_FixedDurationStartSyncedOnStartIntervalVar(self, interval_var, duration, offset)
+
+    def FixedDurationStartSyncedOnEndIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
+        r""" Creates an interval var with a fixed duration whose start is synchronized with the end of another interval, with a given offset. The performed status is also in sync with the performed status of the given interval variable."""
+        return _pywrapcp.Solver_FixedDurationStartSyncedOnEndIntervalVar(self, interval_var, duration, offset)
+
+    def FixedDurationEndSyncedOnStartIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
+        r""" Creates an interval var with a fixed duration whose end is synchronized with the start of another interval, with a given offset. The performed status is also in sync with the performed status of the given interval variable."""
+        return _pywrapcp.Solver_FixedDurationEndSyncedOnStartIntervalVar(self, interval_var, duration, offset)
+
+    def FixedDurationEndSyncedOnEndIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
+        r""" Creates an interval var with a fixed duration whose end is synchronized with the end of another interval, with a given offset. The performed status is also in sync with the performed status of the given interval variable."""
+        return _pywrapcp.Solver_FixedDurationEndSyncedOnEndIntervalVar(self, interval_var, duration, offset)
+
+    def IntervalRelaxedMin(self, interval_var: "IntervalVar") -> "operations_research::IntervalVar *":
+        r""" Creates and returns an interval variable that wraps around the given one, relaxing the min start and end. Relaxing means making unbounded when optional. If the variable is non-optional, this method returns interval_var. More precisely, such an interval variable behaves as follows: * When the underlying must be performed, the returned interval variable     behaves exactly as the underlying; * When the underlying may or may not be performed, the returned interval     variable behaves like the underlying, except that it is unbounded on     the min side; * When the underlying cannot be performed, the returned interval variable     is of duration 0 and must be performed in an interval unbounded on     both sides. This is very useful to implement propagators that may only modify the start max or end max."""
+        return _pywrapcp.Solver_IntervalRelaxedMin(self, interval_var)
+
+    def IntervalRelaxedMax(self, interval_var: "IntervalVar") -> "operations_research::IntervalVar *":
+        r""" Creates and returns an interval variable that wraps around the given one, relaxing the max start and end. Relaxing means making unbounded when optional. If the variable is non optional, this method returns interval_var. More precisely, such an interval variable behaves as follows: * When the underlying must be performed, the returned interval variable     behaves exactly as the underlying; * When the underlying may or may not be performed, the returned interval     variable behaves like the underlying, except that it is unbounded on     the max side; * When the underlying cannot be performed, the returned interval variable     is of duration 0 and must be performed in an interval unbounded on     both sides. This is very useful for implementing propagators that may only modify the start min or end min."""
+        return _pywrapcp.Solver_IntervalRelaxedMax(self, interval_var)
+
+    def TemporalDisjunction(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        This constraint implements a temporal disjunction between two interval vars t1 and t2. 'alt' indicates which alternative was chosen (alt == 0 is equivalent to t1 before t2).
+
+        |
+
+        *Overload 2:*
+        This constraint implements a temporal disjunction between two interval vars.
+        """
+        return _pywrapcp.Solver_TemporalDisjunction(self, *args)
+
+    def DisjunctiveConstraint(self, intervals: "std::vector< operations_research::IntervalVar * > const &", name: "std::string const &") -> "operations_research::DisjunctiveConstraint *":
+        r""" This constraint forces all interval vars into an non-overlapping sequence. Intervals with zero duration can be scheduled anywhere."""
+        return _pywrapcp.Solver_DisjunctiveConstraint(self, intervals, name)
+
+    def Cumulative(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        This constraint forces that, for any integer t, the sum of the demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should only contain non-negative values. Zero values are supported, and the corresponding intervals are filtered out, as they neither impact nor are impacted by this constraint.
+
+        |
+
+        *Overload 2:*
+        This constraint forces that, for any integer t, the sum of the demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should only contain non-negative values. Zero values are supported, and the corresponding intervals are filtered out, as they neither impact nor are impacted by this constraint.
+
+        |
+
+        *Overload 3:*
+        This constraint forces that, for any integer t, the sum of the demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should only contain non-negative values. Zero values are supported, and the corresponding intervals are filtered out, as they neither impact nor are impacted by this constraint.
+
+        |
+
+        *Overload 4:*
+        This constraint enforces that, for any integer t, the sum of the demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should only contain non-negative values. Zero values are supported, and the corresponding intervals are filtered out, as they neither impact nor are impacted by this constraint.
+
+        |
+
+        *Overload 5:*
+        This constraint enforces that, for any integer t, the sum of demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should be positive.
+
+        |
+
+        *Overload 6:*
+        This constraint enforces that, for any integer t, the sum of demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should be positive.
+        """
+        return _pywrapcp.Solver_Cumulative(self, *args)
+
+    def Cover(self, vars: "std::vector< operations_research::IntervalVar * > const &", target_var: "IntervalVar") -> "operations_research::Constraint *":
+        r""" This constraint states that the target_var is the convex hull of the intervals. If none of the interval variables is performed, then the target var is unperformed too. Also, if the target variable is unperformed, then all the intervals variables are unperformed too."""
+        return _pywrapcp.Solver_Cover(self, vars, target_var)
+
+    def Assignment(self, *args) -> "operations_research::Assignment *":
+        r"""
+        *Overload 1:*
+        This method creates an empty assignment.
+
+        |
+
+        *Overload 2:*
+        This method creates an assignment which is a copy of 'a'.
+        """
+        return _pywrapcp.Solver_Assignment(self, *args)
+
+    def FirstSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
+        r"""
+        *Overload 1:*
+        Collect the first solution of the search.
+
+        |
+
+        *Overload 2:*
+        Collect the first solution of the search. The variables will need to be added later.
+        """
+        return _pywrapcp.Solver_FirstSolutionCollector(self, *args)
+
+    def LastSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
+        r"""
+        *Overload 1:*
+        Collect the last solution of the search.
+
+        |
+
+        *Overload 2:*
+        Collect the last solution of the search. The variables will need to be added later.
+        """
+        return _pywrapcp.Solver_LastSolutionCollector(self, *args)
+
+    def BestValueSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
+        r"""
+        *Overload 1:*
+        Collect the solution corresponding to the optimal value of the objective of 'assignment'; if 'assignment' does not have an objective no solution is collected. This collector only collects one solution corresponding to the best objective value (the first one found).
+
+        |
+
+        *Overload 2:*
+        Collect the solution corresponding to the optimal value of the objective of 'assignment'; if 'assignment' does not have an objective no solution is collected. This collector only collects one solution corresponding to the best objective value (the first one found). The variables will need to be added later.
+        """
+        return _pywrapcp.Solver_BestValueSolutionCollector(self, *args)
+
+    def AllSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
+        r"""
+        *Overload 1:*
+        Collect all solutions of the search.
+
+        |
+
+        *Overload 2:*
+        Collect all solutions of the search. The variables will need to be added later.
+        """
+        return _pywrapcp.Solver_AllSolutionCollector(self, *args)
+
+    def Minimize(self, v: "IntVar", step: "int64_t") -> "operations_research::OptimizeVar *":
+        r""" Creates a minimization objective."""
+        return _pywrapcp.Solver_Minimize(self, v, step)
+
+    def Maximize(self, v: "IntVar", step: "int64_t") -> "operations_research::OptimizeVar *":
+        r""" Creates a maximization objective."""
+        return _pywrapcp.Solver_Maximize(self, v, step)
+
+    def Optimize(self, maximize: "bool", v: "IntVar", step: "int64_t") -> "operations_research::OptimizeVar *":
+        r""" Creates a objective with a given sense (true = maximization)."""
+        return _pywrapcp.Solver_Optimize(self, maximize, v, step)
+
+    def WeightedMinimize(self, *args) -> "operations_research::OptimizeVar *":
+        r"""
+        *Overload 1:*
+        Creates a minimization weighted objective. The actual objective is scalar_prod(sub_objectives, weights).
+
+        |
+
+        *Overload 2:*
+        Creates a minimization weighted objective. The actual objective is scalar_prod(sub_objectives, weights).
+        """
+        return _pywrapcp.Solver_WeightedMinimize(self, *args)
+
+    def WeightedMaximize(self, *args) -> "operations_research::OptimizeVar *":
+        r"""
+        *Overload 1:*
+        Creates a maximization weigthed objective.
+
+        |
+
+        *Overload 2:*
+        Creates a maximization weigthed objective.
+        """
+        return _pywrapcp.Solver_WeightedMaximize(self, *args)
+
+    def WeightedOptimize(self, *args) -> "operations_research::OptimizeVar *":
+        r"""
+        *Overload 1:*
+        Creates a weighted objective with a given sense (true = maximization).
+
+        |
+
+        *Overload 2:*
+        Creates a weighted objective with a given sense (true = maximization).
+        """
+        return _pywrapcp.Solver_WeightedOptimize(self, *args)
+
+    def TabuSearch(self, maximize: "bool", v: "IntVar", step: "int64_t", vars: "std::vector< operations_research::IntVar * > const &", keep_tenure: "int64_t", forbid_tenure: "int64_t", tabu_factor: "double") -> "operations_research::SearchMonitor *":
+        r""" MetaHeuristics which try to get the search out of local optima. Creates a Tabu Search monitor. In the context of local search the behavior is similar to MakeOptimize(), creating an objective in a given sense. The behavior differs once a local optimum is reached: thereafter solutions which degrade the value of the objective are allowed if they are not "tabu". A solution is "tabu" if it doesn't respect the following rules: - improving the best solution found so far - variables in the "keep" list must keep their value, variables in the "forbid" list must not take the value they have in the list. Variables with new values enter the tabu lists after each new solution found and leave the lists after a given number of iterations (called tenure). Only the variables passed to the method can enter the lists. The tabu criterion is softened by the tabu factor which gives the number of "tabu" violations which is tolerated; a factor of 1 means no violations allowed; a factor of 0 means all violations are allowed."""
+        return _pywrapcp.Solver_TabuSearch(self, maximize, v, step, vars, keep_tenure, forbid_tenure, tabu_factor)
+
+    def SimulatedAnnealing(self, maximize: "bool", v: "IntVar", step: "int64_t", initial_temperature: "int64_t") -> "operations_research::SearchMonitor *":
+        r""" Creates a Simulated Annealing monitor."""
+        return _pywrapcp.Solver_SimulatedAnnealing(self, maximize, v, step, initial_temperature)
+
+    def LubyRestart(self, scale_factor: "int") -> "operations_research::SearchMonitor *":
+        r""" This search monitor will restart the search periodically. At the iteration n, it will restart after scale_factor * Luby(n) failures where Luby is the Luby Strategy (i.e. 1 1 2 1 1 2 4 1 1 2 1 1 2 4 8...)."""
+        return _pywrapcp.Solver_LubyRestart(self, scale_factor)
+
+    def ConstantRestart(self, frequency: "int") -> "operations_research::SearchMonitor *":
+        r""" This search monitor will restart the search periodically after 'frequency' failures."""
+        return _pywrapcp.Solver_ConstantRestart(self, frequency)
+
+    def TimeLimit(self, *args) -> "operations_research::RegularLimit *":
+        return _pywrapcp.Solver_TimeLimit(self, *args)
+
+    def BranchesLimit(self, branches: "int64_t") -> "operations_research::RegularLimit *":
+        r""" Creates a search limit that constrains the number of branches explored in the search tree."""
+        return _pywrapcp.Solver_BranchesLimit(self, branches)
+
+    def FailuresLimit(self, failures: "int64_t") -> "operations_research::RegularLimit *":
+        r""" Creates a search limit that constrains the number of failures that can happen when exploring the search tree."""
+        return _pywrapcp.Solver_FailuresLimit(self, failures)
+
+    def SolutionsLimit(self, solutions: "int64_t") -> "operations_research::RegularLimit *":
+        r""" Creates a search limit that constrains the number of solutions found during the search."""
+        return _pywrapcp.Solver_SolutionsLimit(self, solutions)
+
+    def Limit(self, *args) -> "operations_research::SearchLimit *":
+        r"""
+        *Overload 1:*
+        Limits the search with the 'time', 'branches', 'failures' and 'solutions' limits. 'smart_time_check' reduces the calls to the wall
+
+        |
+
+        *Overload 2:*
+        Creates a search limit from its protobuf description
+
+        |
+
+        *Overload 3:*
+        Creates a search limit that is reached when either of the underlying limit is reached. That is, the returned limit is more stringent than both argument limits.
+        """
+        return _pywrapcp.Solver_Limit(self, *args)
+
+    def CustomLimit(self, limiter: "std::function< bool () >") -> "operations_research::SearchLimit *":
+        r""" Callback-based search limit. Search stops when limiter returns true; if this happens at a leaf the corresponding solution will be rejected."""
+        return _pywrapcp.Solver_CustomLimit(self, limiter)
+
+    def SearchLog(self, *args) -> "operations_research::SearchMonitor *":
+        return _pywrapcp.Solver_SearchLog(self, *args)
+
+    def SearchTrace(self, prefix: "std::string const &") -> "operations_research::SearchMonitor *":
+        r""" Creates a search monitor that will trace precisely the behavior of the search. Use this only for low level debugging."""
+        return _pywrapcp.Solver_SearchTrace(self, prefix)
+
+    def PrintModelVisitor(self) -> "operations_research::ModelVisitor *":
+        r""" Prints the model."""
+        return _pywrapcp.Solver_PrintModelVisitor(self)
+
+    def StatisticsModelVisitor(self) -> "operations_research::ModelVisitor *":
+        r""" Displays some nice statistics on the model."""
+        return _pywrapcp.Solver_StatisticsModelVisitor(self)
+
+    def AssignVariableValue(self, var: "IntVar", val: "int64_t") -> "operations_research::Decision *":
+        r""" Decisions."""
+        return _pywrapcp.Solver_AssignVariableValue(self, var, val)
+
+    def VariableLessOrEqualValue(self, var: "IntVar", value: "int64_t") -> "operations_research::Decision *":
+        return _pywrapcp.Solver_VariableLessOrEqualValue(self, var, value)
+
+    def VariableGreaterOrEqualValue(self, var: "IntVar", value: "int64_t") -> "operations_research::Decision *":
+        return _pywrapcp.Solver_VariableGreaterOrEqualValue(self, var, value)
+
+    def SplitVariableDomain(self, var: "IntVar", val: "int64_t", start_with_lower_half: "bool") -> "operations_research::Decision *":
+        return _pywrapcp.Solver_SplitVariableDomain(self, var, val, start_with_lower_half)
+
+    def AssignVariableValueOrFail(self, var: "IntVar", value: "int64_t") -> "operations_research::Decision *":
+        return _pywrapcp.Solver_AssignVariableValueOrFail(self, var, value)
+
+    def AssignVariablesValues(self, vars: "std::vector< operations_research::IntVar * > const &", values: "std::vector< int64_t > const &") -> "operations_research::Decision *":
+        return _pywrapcp.Solver_AssignVariablesValues(self, vars, values)
+
+    def FailDecision(self) -> "operations_research::Decision *":
+        return _pywrapcp.Solver_FailDecision(self)
+
+    def Decision(self, apply: "operations_research::Solver::Action", refute: "operations_research::Solver::Action") -> "operations_research::Decision *":
+        return _pywrapcp.Solver_Decision(self, apply, refute)
+
+    def Compose(self, dbs: "std::vector< operations_research::DecisionBuilder * > const &") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_Compose(self, dbs)
+
+    def Try(self, dbs: "std::vector< operations_research::DecisionBuilder * > const &") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_Try(self, dbs)
+
+    def DefaultPhase(self, *args) -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_DefaultPhase(self, *args)
+
+    def ScheduleOrPostpone(self, var: "IntervalVar", est: "int64_t", marker: "int64_t *const") -> "operations_research::Decision *":
+        r""" Returns a decision that tries to schedule a task at a given time. On the Apply branch, it will set that interval var as performed and set its start to 'est'. On the Refute branch, it will just update the 'marker' to 'est' + 1. This decision is used in the INTERVAL_SET_TIMES_FORWARD strategy."""
+        return _pywrapcp.Solver_ScheduleOrPostpone(self, var, est, marker)
+
+    def ScheduleOrExpedite(self, var: "IntervalVar", est: "int64_t", marker: "int64_t *const") -> "operations_research::Decision *":
+        r""" Returns a decision that tries to schedule a task at a given time. On the Apply branch, it will set that interval var as performed and set its end to 'est'. On the Refute branch, it will just update the 'marker' to 'est' - 1. This decision is used in the INTERVAL_SET_TIMES_BACKWARD strategy."""
+        return _pywrapcp.Solver_ScheduleOrExpedite(self, var, est, marker)
+
+    def RankFirstInterval(self, sequence: "SequenceVar", index: "int") -> "operations_research::Decision *":
+        r""" Returns a decision that tries to rank first the ith interval var in the sequence variable."""
+        return _pywrapcp.Solver_RankFirstInterval(self, sequence, index)
+
+    def RankLastInterval(self, sequence: "SequenceVar", index: "int") -> "operations_research::Decision *":
+        r""" Returns a decision that tries to rank last the ith interval var in the sequence variable."""
+        return _pywrapcp.Solver_RankLastInterval(self, sequence, index)
+
+    def Phase(self, *args) -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_Phase(self, *args)
+
+    def DecisionBuilderFromAssignment(self, assignment: "Assignment", db: "DecisionBuilder", vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::DecisionBuilder *":
+        r""" Returns a decision builder for which the left-most leaf corresponds to assignment, the rest of the tree being explored using 'db'."""
+        return _pywrapcp.Solver_DecisionBuilderFromAssignment(self, assignment, db, vars)
+
+    def ConstraintAdder(self, ct: "Constraint") -> "operations_research::DecisionBuilder *":
+        r""" Returns a decision builder that will add the given constraint to the model."""
+        return _pywrapcp.Solver_ConstraintAdder(self, ct)
+
+    def SolveOnce(self, db: "DecisionBuilder", monitors: "std::vector< operations_research::SearchMonitor * > const &") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_SolveOnce(self, db, monitors)
+
+    def NestedOptimize(self, *args) -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_NestedOptimize(self, *args)
+
+    def RestoreAssignment(self, assignment: "Assignment") -> "operations_research::DecisionBuilder *":
+        r""" Returns a DecisionBuilder which restores an Assignment (calls void Assignment::Restore())"""
+        return _pywrapcp.Solver_RestoreAssignment(self, assignment)
+
+    def StoreAssignment(self, assignment: "Assignment") -> "operations_research::DecisionBuilder *":
+        r""" Returns a DecisionBuilder which stores an Assignment (calls void Assignment::Store())"""
+        return _pywrapcp.Solver_StoreAssignment(self, assignment)
+
+    def Operator(self, *args) -> "operations_research::LocalSearchOperator *":
+        return _pywrapcp.Solver_Operator(self, *args)
+
+    def RandomLnsOperator(self, *args) -> "operations_research::LocalSearchOperator *":
+        return _pywrapcp.Solver_RandomLnsOperator(self, *args)
+
+    def MoveTowardTargetOperator(self, *args) -> "operations_research::LocalSearchOperator *":
+        r"""
+        *Overload 1:*
+        Creates a local search operator that tries to move the assignment of some variables toward a target. The target is given as an Assignment. This operator generates neighbors in which the only difference compared to the current state is that one variable that belongs to the target assignment is set to its target value.
+
+        |
+
+        *Overload 2:*
+        Creates a local search operator that tries to move the assignment of some variables toward a target. The target is given either as two vectors: a vector of variables and a vector of associated target values. The two vectors should be of the same length. This operator generates neighbors in which the only difference compared to the current state is that one variable that belongs to the given vector is set to its target value.
+        """
+        return _pywrapcp.Solver_MoveTowardTargetOperator(self, *args)
+
+    def ConcatenateOperators(self, *args) -> "operations_research::LocalSearchOperator *":
+        return _pywrapcp.Solver_ConcatenateOperators(self, *args)
+
+    def RandomConcatenateOperators(self, *args) -> "operations_research::LocalSearchOperator *":
+        r"""
+        *Overload 1:*
+        Randomized version of local search concatenator; calls a random operator at each call to MakeNextNeighbor().
+
+        |
+
+        *Overload 2:*
+        Randomized version of local search concatenator; calls a random operator at each call to MakeNextNeighbor(). The provided seed is used to initialize the random number generator.
+        """
+        return _pywrapcp.Solver_RandomConcatenateOperators(self, *args)
+
+    def NeighborhoodLimit(self, op: "LocalSearchOperator", limit: "int64_t") -> "operations_research::LocalSearchOperator *":
+        r""" Creates a local search operator that wraps another local search operator and limits the number of neighbors explored (i.e., calls to MakeNextNeighbor from the current solution (between two calls to Start()). When this limit is reached, MakeNextNeighbor() returns false. The counter is cleared when Start() is called."""
+        return _pywrapcp.Solver_NeighborhoodLimit(self, op, limit)
+
+    def LocalSearchPhase(self, *args) -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_LocalSearchPhase(self, *args)
+
+    def LocalSearchPhaseParameters(self, *args) -> "operations_research::LocalSearchPhaseParameters *":
+        return _pywrapcp.Solver_LocalSearchPhaseParameters(self, *args)
+
+    def SearchDepth(self) -> "int":
+        r""" Gets the search depth of the current active search. Returns -1 if there is no active search opened."""
+        return _pywrapcp.Solver_SearchDepth(self)
+
+    def SearchLeftDepth(self) -> "int":
+        r""" Gets the search left depth of the current active search. Returns -1 if there is no active search opened."""
+        return _pywrapcp.Solver_SearchLeftDepth(self)
+
+    def SolveDepth(self) -> "int":
+        r""" Gets the number of nested searches. It returns 0 outside search, 1 during the top level search, 2 or more in case of nested searches."""
+        return _pywrapcp.Solver_SolveDepth(self)
+
+    def Rand64(self, size: "int64_t") -> "int64_t":
+        r""" Returns a random value between 0 and 'size' - 1;"""
+        return _pywrapcp.Solver_Rand64(self, size)
+
+    def Rand32(self, size: "int32_t") -> "int32_t":
+        r""" Returns a random value between 0 and 'size' - 1;"""
+        return _pywrapcp.Solver_Rand32(self, size)
+
+    def ReSeed(self, seed: "int32_t") -> "void":
+        r""" Reseed the solver random generator."""
+        return _pywrapcp.Solver_ReSeed(self, seed)
+
+    def LocalSearchProfile(self) -> "std::string":
+        r""" Returns local search profiling information in a human readable format."""
+        return _pywrapcp.Solver_LocalSearchProfile(self)
+
+    def Constraints(self) -> "int":
+        r""" Counts the number of constraints that have been added to the solver before the search."""
+        return _pywrapcp.Solver_Constraints(self)
+
+    def Accept(self, visitor: "operations_research::ModelVisitor *const") -> "void":
+        r""" Accepts the given model visitor."""
+        return _pywrapcp.Solver_Accept(self, visitor)
+
+    def FinishCurrentSearch(self) -> "void":
+        r""" Tells the solver to kill or restart the current search."""
+        return _pywrapcp.Solver_FinishCurrentSearch(self)
+
+    def RestartCurrentSearch(self) -> "void":
+        return _pywrapcp.Solver_RestartCurrentSearch(self)
+
+    def ShouldFail(self) -> "void":
+        r""" These methods are only useful for the SWIG wrappers, which need a way to externally cause the Solver to fail."""
+        return _pywrapcp.Solver_ShouldFail(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.Solver___str__(self)
+
+    def Add(self, ct):
+      if isinstance(ct, PyConstraint):
+        self.__python_constraints.append(ct)
+      self.AddConstraint(ct)
+
+
+    def TreeNoCycle(self, nexts: "std::vector< operations_research::IntVar * > const &", active: "std::vector< operations_research::IntVar * > const &", callback: "operations_research::Solver::IndexFilter1"=0) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_TreeNoCycle(self, nexts, active, callback)
+
+    def SearchLogWithCallback(self, period: "int", callback: "std::function< std::string () >") -> "operations_research::SearchMonitor *":
+        return _pywrapcp.Solver_SearchLogWithCallback(self, period, callback)
+
+    def ElementFunction(self, values: "std::function< int64_t (int64_t) >", index: "IntVar") -> "operations_research::IntExpr *":
+        return _pywrapcp.Solver_ElementFunction(self, values, index)
+
+    def VarEvalValStrPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_evaluator: "std::function< int64_t (int64_t) >", val_str: "operations_research::Solver::IntValueStrategy") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_VarEvalValStrPhase(self, vars, var_evaluator, val_str)
+
+    def VarStrValEvalPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_str: "operations_research::Solver::IntVarStrategy", val_eval: "operations_research::Solver::IndexEvaluator2") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_VarStrValEvalPhase(self, vars, var_str, val_eval)
+
+    def VarEvalValEvalPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_eval: "std::function< int64_t (int64_t) >", val_eval: "operations_research::Solver::IndexEvaluator2") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_VarEvalValEvalPhase(self, vars, var_eval, val_eval)
+
+    def VarStrValEvalTieBreakPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_str: "operations_research::Solver::IntVarStrategy", val_eval: "operations_research::Solver::IndexEvaluator2", tie_breaker: "std::function< int64_t (int64_t) >") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_VarStrValEvalTieBreakPhase(self, vars, var_str, val_eval, tie_breaker)
+
+    def VarEvalValEvalTieBreakPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_eval: "std::function< int64_t (int64_t) >", val_eval: "operations_research::Solver::IndexEvaluator2", tie_breaker: "std::function< int64_t (int64_t) >") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_VarEvalValEvalTieBreakPhase(self, vars, var_eval, val_eval, tie_breaker)
+
+    def EvalEvalStrPhase(self, vars: "std::vector< operations_research::IntVar * > const &", evaluator: "operations_research::Solver::IndexEvaluator2", str: "operations_research::Solver::EvaluatorStrategy") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_EvalEvalStrPhase(self, vars, evaluator, str)
+
+    def EvalEvalStrTieBreakPhase(self, vars: "std::vector< operations_research::IntVar * > const &", evaluator: "operations_research::Solver::IndexEvaluator2", tie_breaker: "operations_research::Solver::IndexEvaluator1", str: "operations_research::Solver::EvaluatorStrategy") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_EvalEvalStrTieBreakPhase(self, vars, evaluator, tie_breaker, str)
+
+    def GuidedLocalSearch(self, *args) -> "operations_research::SearchMonitor *":
+        return _pywrapcp.Solver_GuidedLocalSearch(self, *args)
+
+    def SumObjectiveFilter(self, vars: "std::vector< operations_research::IntVar * > const &", values: "operations_research::Solver::IndexEvaluator2", filter_enum: "operations_research::Solver::LocalSearchFilterBound") -> "operations_research::LocalSearchFilter *":
+        return _pywrapcp.Solver_SumObjectiveFilter(self, vars, values, filter_enum)
+
+# Register Solver in _pywrapcp:
+_pywrapcp.Solver_swigregister(Solver)
+
+def Solver_DefaultSolverParameters() -> "operations_research::ConstraintSolverParameters":
+    r""" Create a ConstraintSolverParameters proto with all the default values."""
+    return _pywrapcp.Solver_DefaultSolverParameters()
+
+def Solver_MemoryUsage() -> "int64_t":
+    r""" Current memory usage in bytes"""
+    return _pywrapcp.Solver_MemoryUsage()
+
+class BaseObject(object):
+    r""" A BaseObject is the root of all reversibly allocated objects. A DebugString method and the associated << operator are implemented as a convenience."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self):
+        if self.__class__ == BaseObject:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.BaseObject_swiginit(self, _pywrapcp.new_BaseObject(_self, ))
+    __swig_destroy__ = _pywrapcp.delete_BaseObject
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.BaseObject_DebugString(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.BaseObject___str__(self)
+
+    def __repr__(self) -> "std::string":
+        return _pywrapcp.BaseObject___repr__(self)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_BaseObject(self)
+        return weakref.proxy(self)
+
+# Register BaseObject in _pywrapcp:
+_pywrapcp.BaseObject_swigregister(BaseObject)
+
+class PropagationBaseObject(BaseObject):
+    r""" NOLINT The PropagationBaseObject is a subclass of BaseObject that is also friend to the Solver class. It allows accessing methods useful when writing new constraints or new expressions."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, s: "Solver"):
+        if self.__class__ == PropagationBaseObject:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.PropagationBaseObject_swiginit(self, _pywrapcp.new_PropagationBaseObject(_self, s))
+    __swig_destroy__ = _pywrapcp.delete_PropagationBaseObject
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.PropagationBaseObject_DebugString(self)
+
+    def solver(self) -> "operations_research::Solver *":
+        return _pywrapcp.PropagationBaseObject_solver(self)
+
+    def Name(self) -> "std::string":
+        r""" Object naming."""
+        return _pywrapcp.PropagationBaseObject_Name(self)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_PropagationBaseObject(self)
+        return weakref.proxy(self)
+
+# Register PropagationBaseObject in _pywrapcp:
+_pywrapcp.PropagationBaseObject_swigregister(PropagationBaseObject)
+
+class Decision(BaseObject):
+    r""" A Decision represents a choice point in the search tree. The two main methods are Apply() to go left, or Refute() to go right."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self):
+        if self.__class__ == Decision:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.Decision_swiginit(self, _pywrapcp.new_Decision(_self, ))
+    __swig_destroy__ = _pywrapcp.delete_Decision
+
+    def ApplyWrapper(self, s: "Solver") -> "void":
+        r""" Apply will be called first when the decision is executed."""
+        return _pywrapcp.Decision_ApplyWrapper(self, s)
+
+    def RefuteWrapper(self, s: "Solver") -> "void":
+        r""" Refute will be called after a backtrack."""
+        return _pywrapcp.Decision_RefuteWrapper(self, s)
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.Decision_DebugString(self)
+
+    def __repr__(self) -> "std::string":
+        return _pywrapcp.Decision___repr__(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.Decision___str__(self)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_Decision(self)
+        return weakref.proxy(self)
+
+# Register Decision in _pywrapcp:
+_pywrapcp.Decision_swigregister(Decision)
+
+class DecisionBuilder(BaseObject):
+    r""" A DecisionBuilder is responsible for creating the search tree. The important method is Next(), which returns the next decision to execute."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self):
+        if self.__class__ == DecisionBuilder:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.DecisionBuilder_swiginit(self, _pywrapcp.new_DecisionBuilder(_self, ))
+    __swig_destroy__ = _pywrapcp.delete_DecisionBuilder
+
+    def NextWrapper(self, s: "Solver") -> "operations_research::Decision *":
+        r""" This is the main method of the decision builder class. It must return a decision (an instance of the class Decision). If it returns nullptr, this means that the decision builder has finished its work."""
+        return _pywrapcp.DecisionBuilder_NextWrapper(self, s)
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.DecisionBuilder_DebugString(self)
+
+    def __repr__(self) -> "std::string":
+        return _pywrapcp.DecisionBuilder___repr__(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.DecisionBuilder___str__(self)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_DecisionBuilder(self)
+        return weakref.proxy(self)
+
+# Register DecisionBuilder in _pywrapcp:
+_pywrapcp.DecisionBuilder_swigregister(DecisionBuilder)
+
+class Demon(BaseObject):
+    r""" A Demon is the base element of a propagation queue. It is the main   object responsible for implementing the actual propagation   of the constraint and pruning the inconsistent values in the domains   of the variables. The main concept is that demons are listeners that are   attached to the variables and listen to their modifications. There are two methods:  - Run() is the actual method called when the demon is processed.  - priority() returns its priority. Standard priorities are slow, normal    or fast. "immediate" is reserved for variables and is treated separately."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self):
+        r""" This indicates the priority of a demon. Immediate demons are treated separately and corresponds to variables."""
+        if self.__class__ == Demon:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.Demon_swiginit(self, _pywrapcp.new_Demon(_self, ))
+    __swig_destroy__ = _pywrapcp.delete_Demon
+
+    def RunWrapper(self, s: "Solver") -> "void":
+        r""" This is the main callback of the demon."""
+        return _pywrapcp.Demon_RunWrapper(self, s)
+
+    def Priority(self) -> "operations_research::Solver::DemonPriority":
+        r""" This method returns the priority of the demon. Usually a demon is fast, slow or normal. Immediate demons are reserved for internal use to maintain variables."""
+        return _pywrapcp.Demon_Priority(self)
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.Demon_DebugString(self)
+
+    def Inhibit(self, s: "Solver") -> "void":
+        r""" This method inhibits the demon in the search tree below the current position."""
+        return _pywrapcp.Demon_Inhibit(self, s)
+
+    def Desinhibit(self, s: "Solver") -> "void":
+        r""" This method un-inhibits the demon that was previously inhibited."""
+        return _pywrapcp.Demon_Desinhibit(self, s)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_Demon(self)
+        return weakref.proxy(self)
+
+# Register Demon in _pywrapcp:
+_pywrapcp.Demon_swigregister(Demon)
+
+class Constraint(PropagationBaseObject):
+    r""" A constraint is the main modeling object. It provides two methods:   - Post() is responsible for creating the demons and attaching them to     immediate demons().   - InitialPropagate() is called once just after Post and performs     the initial propagation. The subsequent propagations will be performed     by the demons Posted during the post() method."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, solver: "Solver"):
+        if self.__class__ == Constraint:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.Constraint_swiginit(self, _pywrapcp.new_Constraint(_self, solver))
+    __swig_destroy__ = _pywrapcp.delete_Constraint
+
+    def Post(self) -> "void":
+        r""" This method is called when the constraint is processed by the solver. Its main usage is to attach demons to variables."""
+        return _pywrapcp.Constraint_Post(self)
+
+    def InitialPropagateWrapper(self) -> "void":
+        r""" This method performs the initial propagation of the constraint. It is called just after the post."""
+        return _pywrapcp.Constraint_InitialPropagateWrapper(self)
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.Constraint_DebugString(self)
+
+    def Var(self) -> "operations_research::IntVar *":
+        r""" Creates a Boolean variable representing the status of the constraint (false = constraint is violated, true = constraint is satisfied). It returns nullptr if the constraint does not support this API."""
+        return _pywrapcp.Constraint_Var(self)
+
+    def __repr__(self) -> "std::string":
+        return _pywrapcp.Constraint___repr__(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.Constraint___str__(self)
+
+    def __add__(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint___add__(self, *args)
+
+    def __radd__(self, v: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint___radd__(self, v)
+
+    def __sub__(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint___sub__(self, *args)
+
+    def __rsub__(self, v: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint___rsub__(self, v)
+
+    def __mul__(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint___mul__(self, *args)
+
+    def __rmul__(self, v: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint___rmul__(self, v)
+
+    def __floordiv__(self, v: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint___floordiv__(self, v)
+
+    def __neg__(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint___neg__(self)
+
+    def __abs__(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint___abs__(self)
+
+    def Square(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint_Square(self)
+
+    def __eq__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Constraint___eq__(self, *args)
+
+    def __ne__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Constraint___ne__(self, *args)
+
+    def __ge__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Constraint___ge__(self, *args)
+
+    def __gt__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Constraint___gt__(self, *args)
+
+    def __le__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Constraint___le__(self, *args)
+
+    def __lt__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Constraint___lt__(self, *args)
+
+    def MapTo(self, vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        return _pywrapcp.Constraint_MapTo(self, vars)
+
+    def IndexOf(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint_IndexOf(self, *args)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_Constraint(self)
+        return weakref.proxy(self)
+
+# Register Constraint in _pywrapcp:
+_pywrapcp.Constraint_swigregister(Constraint)
+
+class SearchMonitor(BaseObject):
+    r""" A search monitor is a simple set of callbacks to monitor all search events"""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, s: "Solver"):
+        if self.__class__ == SearchMonitor:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.SearchMonitor_swiginit(self, _pywrapcp.new_SearchMonitor(_self, s))
+    __swig_destroy__ = _pywrapcp.delete_SearchMonitor
+
+    def EnterSearch(self) -> "void":
+        r""" Beginning of the search."""
+        return _pywrapcp.SearchMonitor_EnterSearch(self)
+
+    def RestartSearch(self) -> "void":
+        r""" Restart the search."""
+        return _pywrapcp.SearchMonitor_RestartSearch(self)
+
+    def ExitSearch(self) -> "void":
+        r""" End of the search."""
+        return _pywrapcp.SearchMonitor_ExitSearch(self)
+
+    def BeginNextDecision(self, b: "DecisionBuilder") -> "void":
+        r""" Before calling DecisionBuilder::Next."""
+        return _pywrapcp.SearchMonitor_BeginNextDecision(self, b)
+
+    def EndNextDecision(self, b: "DecisionBuilder", d: "Decision") -> "void":
+        r""" After calling DecisionBuilder::Next, along with the returned decision."""
+        return _pywrapcp.SearchMonitor_EndNextDecision(self, b, d)
+
+    def ApplyDecision(self, d: "Decision") -> "void":
+        r""" Before applying the decision."""
+        return _pywrapcp.SearchMonitor_ApplyDecision(self, d)
+
+    def RefuteDecision(self, d: "Decision") -> "void":
+        r""" Before refuting the decision."""
+        return _pywrapcp.SearchMonitor_RefuteDecision(self, d)
+
+    def AfterDecision(self, d: "Decision", apply: "bool") -> "void":
+        r""" Just after refuting or applying the decision, apply is true after Apply. This is called only if the Apply() or Refute() methods have not failed."""
+        return _pywrapcp.SearchMonitor_AfterDecision(self, d, apply)
+
+    def BeginFail(self) -> "void":
+        r""" Just when the failure occurs."""
+        return _pywrapcp.SearchMonitor_BeginFail(self)
+
+    def EndFail(self) -> "void":
+        r""" After completing the backtrack."""
+        return _pywrapcp.SearchMonitor_EndFail(self)
+
+    def BeginInitialPropagation(self) -> "void":
+        r""" Before the initial propagation."""
+        return _pywrapcp.SearchMonitor_BeginInitialPropagation(self)
+
+    def EndInitialPropagation(self) -> "void":
+        r""" After the initial propagation."""
+        return _pywrapcp.SearchMonitor_EndInitialPropagation(self)
+
+    def AcceptSolution(self) -> "bool":
+        r""" This method is called when a solution is found. It asserts whether the solution is valid. A value of false indicates that the solution should be discarded."""
+        return _pywrapcp.SearchMonitor_AcceptSolution(self)
+
+    def AtSolution(self) -> "bool":
+        r""" This method is called when a valid solution is found. If the return value is true, then search will resume after. If the result is false, then search will stop there."""
+        return _pywrapcp.SearchMonitor_AtSolution(self)
+
+    def NoMoreSolutions(self) -> "void":
+        r""" When the search tree is finished."""
+        return _pywrapcp.SearchMonitor_NoMoreSolutions(self)
+
+    def LocalOptimum(self) -> "bool":
+        r""" When a local optimum is reached. If 'true' is returned, the last solution is discarded and the search proceeds with the next one."""
+        return _pywrapcp.SearchMonitor_LocalOptimum(self)
+
+    def AcceptDelta(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
+        return _pywrapcp.SearchMonitor_AcceptDelta(self, delta, deltadelta)
+
+    def AcceptNeighbor(self) -> "void":
+        r""" After accepting a neighbor during local search."""
+        return _pywrapcp.SearchMonitor_AcceptNeighbor(self)
+
+    def solver(self) -> "operations_research::Solver *":
+        return _pywrapcp.SearchMonitor_solver(self)
+
+    def __repr__(self) -> "std::string":
+        return _pywrapcp.SearchMonitor___repr__(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.SearchMonitor___str__(self)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_SearchMonitor(self)
+        return weakref.proxy(self)
+
+# Register SearchMonitor in _pywrapcp:
+_pywrapcp.SearchMonitor_swigregister(SearchMonitor)
+
+class IntExpr(PropagationBaseObject):
+    r""" The class IntExpr is the base of all integer expressions in constraint programming. It contains the basic protocol for an expression:   - setting and modifying its bound   - querying if it is bound   - listening to events modifying its bounds   - casting it into a variable (instance of IntVar)"""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+    def Min(self) -> "int64_t":
+        return _pywrapcp.IntExpr_Min(self)
+
+    def SetMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntExpr_SetMin(self, m)
+
+    def Max(self) -> "int64_t":
+        return _pywrapcp.IntExpr_Max(self)
+
+    def SetMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntExpr_SetMax(self, m)
+
+    def SetRange(self, l: "int64_t", u: "int64_t") -> "void":
+        r""" This method sets both the min and the max of the expression."""
+        return _pywrapcp.IntExpr_SetRange(self, l, u)
+
+    def SetValue(self, v: "int64_t") -> "void":
+        r""" This method sets the value of the expression."""
+        return _pywrapcp.IntExpr_SetValue(self, v)
+
+    def Bound(self) -> "bool":
+        r""" Returns true if the min and the max of the expression are equal."""
+        return _pywrapcp.IntExpr_Bound(self)
+
+    def IsVar(self) -> "bool":
+        r""" Returns true if the expression is indeed a variable."""
+        return _pywrapcp.IntExpr_IsVar(self)
+
+    def Var(self) -> "operations_research::IntVar *":
+        r""" Creates a variable from the expression."""
+        return _pywrapcp.IntExpr_Var(self)
+
+    def VarWithName(self, name: "std::string const &") -> "operations_research::IntVar *":
+        r""" Creates a variable from the expression and set the name of the resulting var. If the expression is already a variable, then it will set the name of the expression, possibly overwriting it. This is just a shortcut to Var() followed by set_name()."""
+        return _pywrapcp.IntExpr_VarWithName(self, name)
+
+    def WhenRange(self, *args) -> "void":
+        r"""
+        *Overload 1:*
+        Attach a demon that will watch the min or the max of the expression.
+
+        |
+
+        *Overload 2:*
+        Attach a demon that will watch the min or the max of the expression.
+        """
+        return _pywrapcp.IntExpr_WhenRange(self, *args)
+
+    def __repr__(self) -> "std::string":
+        return _pywrapcp.IntExpr___repr__(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.IntExpr___str__(self)
+
+    def __add__(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___add__(self, *args)
+
+    def __radd__(self, v: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___radd__(self, v)
+
+    def __sub__(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___sub__(self, *args)
+
+    def __rsub__(self, v: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___rsub__(self, v)
+
+    def __mul__(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___mul__(self, *args)
+
+    def __rmul__(self, v: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___rmul__(self, v)
+
+    def __floordiv__(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___floordiv__(self, *args)
+
+    def __mod__(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___mod__(self, *args)
+
+    def __neg__(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___neg__(self)
+
+    def __abs__(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___abs__(self)
+
+    def Square(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr_Square(self)
+
+    def __eq__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr___eq__(self, *args)
+
+    def __ne__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr___ne__(self, *args)
+
+    def __ge__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr___ge__(self, *args)
+
+    def __gt__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr___gt__(self, *args)
+
+    def __le__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr___le__(self, *args)
+
+    def __lt__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr___lt__(self, *args)
+
+    def MapTo(self, vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr_MapTo(self, vars)
+
+    def IndexOf(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr_IndexOf(self, *args)
+
+    def IsMember(self, values: "std::vector< int64_t > const &") -> "operations_research::IntVar *":
+        return _pywrapcp.IntExpr_IsMember(self, values)
+
+    def Member(self, values: "std::vector< int64_t > const &") -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr_Member(self, values)
+
+    def NotMember(self, starts: "std::vector< int64_t > const &", ends: "std::vector< int64_t > const &") -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr_NotMember(self, starts, ends)
+
+# Register IntExpr in _pywrapcp:
+_pywrapcp.IntExpr_swigregister(IntExpr)
+
+class IntVarIterator(BaseObject):
+    r""" The class Iterator has two direct subclasses. HoleIterators iterates over all holes, that is value removed between the current min and max of the variable since the last time the variable was processed in the queue. DomainIterators iterates over all elements of the variable domain. Both iterators are not robust to domain changes. Hole iterators can also report values outside the current min and max of the variable. HoleIterators should only be called from a demon attached to the variable that has created this iterator. IntVar* current_var; std::unique_ptr<IntVarIterator> it(current_var->MakeHoleIterator(false)); for (const int64_t hole : InitAndGetValues(it)) {   /// use the hole }"""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+
+    def Init(self) -> "void":
+        r""" This method must be called before each loop."""
+        return _pywrapcp.IntVarIterator_Init(self)
+
+    def Ok(self) -> "bool":
+        r""" This method indicates if we can call Value() or not."""
+        return _pywrapcp.IntVarIterator_Ok(self)
+
+    def Value(self) -> "int64_t":
+        r""" This method returns the current value of the iterator."""
+        return _pywrapcp.IntVarIterator_Value(self)
+
+    def Next(self) -> "void":
+        r""" This method moves the iterator to the next value."""
+        return _pywrapcp.IntVarIterator_Next(self)
+
+    def DebugString(self) -> "std::string":
+        r""" Pretty Print."""
+        return _pywrapcp.IntVarIterator_DebugString(self)
+
+    def __iter__(self):
+      self.Init()
+      return self
+
+    def next(self):
+      if self.Ok():
+        result = self.Value()
+        self.Next()
+        return result
+      else:
+        raise StopIteration()
+
+    def __next__(self):
+      return self.next()
+
+
+# Register IntVarIterator in _pywrapcp:
+_pywrapcp.IntVarIterator_swigregister(IntVarIterator)
+
+class IntVar(IntExpr):
+    r""" The class IntVar is a subset of IntExpr. In addition to the IntExpr protocol, it offers persistence, removing values from the domains, and a finer model for events."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+    def IsVar(self) -> "bool":
+        return _pywrapcp.IntVar_IsVar(self)
+
+    def Var(self) -> "operations_research::IntVar *":
+        return _pywrapcp.IntVar_Var(self)
+
+    def Value(self) -> "int64_t":
+        r""" This method returns the value of the variable. This method checks before that the variable is bound."""
+        return _pywrapcp.IntVar_Value(self)
+
+    def RemoveValue(self, v: "int64_t") -> "void":
+        r""" This method removes the value 'v' from the domain of the variable."""
+        return _pywrapcp.IntVar_RemoveValue(self, v)
+
+    def RemoveInterval(self, l: "int64_t", u: "int64_t") -> "void":
+        r""" This method removes the interval 'l' .. 'u' from the domain of the variable. It assumes that 'l' <= 'u'."""
+        return _pywrapcp.IntVar_RemoveInterval(self, l, u)
+
+    def RemoveValues(self, values: "std::vector< int64_t > const &") -> "void":
+        r""" This method remove the values from the domain of the variable."""
+        return _pywrapcp.IntVar_RemoveValues(self, values)
+
+    def SetValues(self, values: "std::vector< int64_t > const &") -> "void":
+        r""" This method intersects the current domain with the values in the array."""
+        return _pywrapcp.IntVar_SetValues(self, values)
+
+    def WhenBound(self, *args) -> "void":
+        r"""
+        *Overload 1:*
+        This method attaches a demon that will be awakened when the variable is bound.
+
+        |
+
+        *Overload 2:*
+        This method attaches a closure that will be awakened when the variable is bound.
+        """
+        return _pywrapcp.IntVar_WhenBound(self, *args)
+
+    def WhenDomain(self, *args) -> "void":
+        r"""
+        *Overload 1:*
+        This method attaches a demon that will watch any domain modification of the domain of the variable.
+
+        |
+
+        *Overload 2:*
+        This method attaches a closure that will watch any domain modification of the domain of the variable.
+        """
+        return _pywrapcp.IntVar_WhenDomain(self, *args)
+
+    def Size(self) -> "uint64_t":
+        r""" This method returns the number of values in the domain of the variable."""
+        return _pywrapcp.IntVar_Size(self)
+
+    def Contains(self, v: "int64_t") -> "bool":
+        r""" This method returns whether the value 'v' is in the domain of the variable."""
+        return _pywrapcp.IntVar_Contains(self, v)
+
+    def HoleIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *":
+        r""" Creates a hole iterator. When 'reversible' is false, the returned object is created on the normal C++ heap and the solver does NOT take ownership of the object."""
+        return _pywrapcp.IntVar_HoleIteratorAux(self, reversible)
+
+    def DomainIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *":
+        r""" Creates a domain iterator. When 'reversible' is false, the returned object is created on the normal C++ heap and the solver does NOT take ownership of the object."""
+        return _pywrapcp.IntVar_DomainIteratorAux(self, reversible)
+
+    def OldMin(self) -> "int64_t":
+        r""" Returns the previous min."""
+        return _pywrapcp.IntVar_OldMin(self)
+
+    def OldMax(self) -> "int64_t":
+        r""" Returns the previous max."""
+        return _pywrapcp.IntVar_OldMax(self)
+
+    def __repr__(self) -> "std::string":
+        return _pywrapcp.IntVar___repr__(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.IntVar___str__(self)
+
+    def DomainIterator(self):
+      return iter(self.DomainIteratorAux(False))
+
+    def HoleIterator(self):
+      return iter(self.HoleIteratorAux(False))
+
+
+# Register IntVar in _pywrapcp:
+_pywrapcp.IntVar_swigregister(IntVar)
+
+class SolutionCollector(SearchMonitor):
+    r""" This class is the root class of all solution collectors. It implements a basic query API to be used independently of the collector used."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.SolutionCollector_DebugString(self)
+
+    def Add(self, *args) -> "void":
+        return _pywrapcp.SolutionCollector_Add(self, *args)
+
+    def AddObjective(self, objective: "IntVar") -> "void":
+        return _pywrapcp.SolutionCollector_AddObjective(self, objective)
+
+    def EnterSearch(self) -> "void":
+        r""" Beginning of the search."""
+        return _pywrapcp.SolutionCollector_EnterSearch(self)
+
+    def SolutionCount(self) -> "int":
+        r""" Returns how many solutions were stored during the search."""
+        return _pywrapcp.SolutionCollector_SolutionCount(self)
+
+    def Solution(self, n: "int") -> "operations_research::Assignment *":
+        r""" Returns the nth solution."""
+        return _pywrapcp.SolutionCollector_Solution(self, n)
+
+    def WallTime(self, n: "int") -> "int64_t":
+        r""" Returns the wall time in ms for the nth solution."""
+        return _pywrapcp.SolutionCollector_WallTime(self, n)
+
+    def Branches(self, n: "int") -> "int64_t":
+        r""" Returns the number of branches when the nth solution was found."""
+        return _pywrapcp.SolutionCollector_Branches(self, n)
+
+    def Failures(self, n: "int") -> "int64_t":
+        r""" Returns the number of failures encountered at the time of the nth solution."""
+        return _pywrapcp.SolutionCollector_Failures(self, n)
+
+    def ObjectiveValue(self, n: "int") -> "int64_t":
+        r""" Returns the objective value of the nth solution."""
+        return _pywrapcp.SolutionCollector_ObjectiveValue(self, n)
+
+    def Value(self, n: "int", var: "IntVar") -> "int64_t":
+        r""" This is a shortcut to get the Value of 'var' in the nth solution."""
+        return _pywrapcp.SolutionCollector_Value(self, n, var)
+
+    def StartValue(self, n: "int", var: "IntervalVar") -> "int64_t":
+        r""" This is a shortcut to get the StartValue of 'var' in the nth solution."""
+        return _pywrapcp.SolutionCollector_StartValue(self, n, var)
+
+    def EndValue(self, n: "int", var: "IntervalVar") -> "int64_t":
+        r""" This is a shortcut to get the EndValue of 'var' in the nth solution."""
+        return _pywrapcp.SolutionCollector_EndValue(self, n, var)
+
+    def DurationValue(self, n: "int", var: "IntervalVar") -> "int64_t":
+        r""" This is a shortcut to get the DurationValue of 'var' in the nth solution."""
+        return _pywrapcp.SolutionCollector_DurationValue(self, n, var)
+
+    def PerformedValue(self, n: "int", var: "IntervalVar") -> "int64_t":
+        r""" This is a shortcut to get the PerformedValue of 'var' in the nth solution."""
+        return _pywrapcp.SolutionCollector_PerformedValue(self, n, var)
+
+    def ForwardSequence(self, n: "int", var: "SequenceVar") -> "std::vector< int > const &":
+        r""" This is a shortcut to get the ForwardSequence of 'var' in the nth solution. The forward sequence is the list of ranked interval variables starting from the start of the sequence."""
+        return _pywrapcp.SolutionCollector_ForwardSequence(self, n, var)
+
+    def BackwardSequence(self, n: "int", var: "SequenceVar") -> "std::vector< int > const &":
+        r""" This is a shortcut to get the BackwardSequence of 'var' in the nth solution. The backward sequence is the list of ranked interval variables starting from the end of the sequence."""
+        return _pywrapcp.SolutionCollector_BackwardSequence(self, n, var)
+
+    def Unperformed(self, n: "int", var: "SequenceVar") -> "std::vector< int > const &":
+        r""" This is a shortcut to get the list of unperformed of 'var' in the nth solution."""
+        return _pywrapcp.SolutionCollector_Unperformed(self, n, var)
+
+# Register SolutionCollector in _pywrapcp:
+_pywrapcp.SolutionCollector_swigregister(SolutionCollector)
+
+class OptimizeVar(SearchMonitor):
+    r""" This class encapsulates an objective. It requires the direction (minimize or maximize), the variable to optimize, and the improvement step."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Best(self) -> "int64_t":
+        r""" Returns the best value found during search."""
+        return _pywrapcp.OptimizeVar_Best(self)
+
+    def Var(self) -> "operations_research::IntVar *":
+        r""" Returns the variable that is optimized."""
+        return _pywrapcp.OptimizeVar_Var(self)
+
+    def AcceptDelta(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
+        r""" Internal methods."""
+        return _pywrapcp.OptimizeVar_AcceptDelta(self, delta, deltadelta)
+
+    def EnterSearch(self) -> "void":
+        return _pywrapcp.OptimizeVar_EnterSearch(self)
+
+    def BeginNextDecision(self, db: "DecisionBuilder") -> "void":
+        return _pywrapcp.OptimizeVar_BeginNextDecision(self, db)
+
+    def RefuteDecision(self, d: "Decision") -> "void":
+        return _pywrapcp.OptimizeVar_RefuteDecision(self, d)
+
+    def AtSolution(self) -> "bool":
+        return _pywrapcp.OptimizeVar_AtSolution(self)
+
+    def AcceptSolution(self) -> "bool":
+        return _pywrapcp.OptimizeVar_AcceptSolution(self)
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.OptimizeVar_DebugString(self)
+
+# Register OptimizeVar in _pywrapcp:
+_pywrapcp.OptimizeVar_swigregister(OptimizeVar)
+
+class SearchLimit(SearchMonitor):
+    r""" Base class of all search limits."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+    __swig_destroy__ = _pywrapcp.delete_SearchLimit
+
+    def Crossed(self) -> "bool":
+        r""" Returns true if the limit has been crossed."""
+        return _pywrapcp.SearchLimit_Crossed(self)
+
+    def Check(self) -> "bool":
+        r""" This method is called to check the status of the limit. A return value of true indicates that we have indeed crossed the limit. In that case, this method will not be called again and the remaining search will be discarded."""
+        return _pywrapcp.SearchLimit_Check(self)
+
+    def Init(self) -> "void":
+        r""" This method is called when the search limit is initialized."""
+        return _pywrapcp.SearchLimit_Init(self)
+
+    def EnterSearch(self) -> "void":
+        r""" Internal methods."""
+        return _pywrapcp.SearchLimit_EnterSearch(self)
+
+    def BeginNextDecision(self, b: "DecisionBuilder") -> "void":
+        return _pywrapcp.SearchLimit_BeginNextDecision(self, b)
+
+    def RefuteDecision(self, d: "Decision") -> "void":
+        return _pywrapcp.SearchLimit_RefuteDecision(self, d)
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.SearchLimit_DebugString(self)
+
+# Register SearchLimit in _pywrapcp:
+_pywrapcp.SearchLimit_swigregister(SearchLimit)
+
+class IntervalVar(PropagationBaseObject):
+    r""" Interval variables are often used in scheduling. The main characteristics of an IntervalVar are the start position, duration, and end date. All these characteristics can be queried and set, and demons can be posted on their modifications. An important aspect is optionality: an IntervalVar can be performed or not. If unperformed, then it simply does not exist, and its characteristics cannot be accessed any more. An interval var is automatically marked as unperformed when it is not consistent anymore (start greater than end, duration < 0...)"""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+    def StartMin(self) -> "int64_t":
+        r""" These methods query, set, and watch the start position of the interval var."""
+        return _pywrapcp.IntervalVar_StartMin(self)
+
+    def StartMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_StartMax(self)
+
+    def SetStartMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetStartMin(self, m)
+
+    def SetStartMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetStartMax(self, m)
+
+    def SetStartRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetStartRange(self, mi, ma)
+
+    def OldStartMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_OldStartMin(self)
+
+    def OldStartMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_OldStartMax(self)
+
+    def WhenStartRange(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenStartRange(self, *args)
+
+    def WhenStartBound(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenStartBound(self, *args)
+
+    def DurationMin(self) -> "int64_t":
+        r""" These methods query, set, and watch the duration of the interval var."""
+        return _pywrapcp.IntervalVar_DurationMin(self)
+
+    def DurationMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_DurationMax(self)
+
+    def SetDurationMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetDurationMin(self, m)
+
+    def SetDurationMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetDurationMax(self, m)
+
+    def SetDurationRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetDurationRange(self, mi, ma)
+
+    def OldDurationMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_OldDurationMin(self)
+
+    def OldDurationMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_OldDurationMax(self)
+
+    def WhenDurationRange(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenDurationRange(self, *args)
+
+    def WhenDurationBound(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenDurationBound(self, *args)
+
+    def EndMin(self) -> "int64_t":
+        r""" These methods query, set, and watch the end position of the interval var."""
+        return _pywrapcp.IntervalVar_EndMin(self)
+
+    def EndMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_EndMax(self)
+
+    def SetEndMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetEndMin(self, m)
+
+    def SetEndMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetEndMax(self, m)
+
+    def SetEndRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetEndRange(self, mi, ma)
+
+    def OldEndMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_OldEndMin(self)
+
+    def OldEndMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_OldEndMax(self)
+
+    def WhenEndRange(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenEndRange(self, *args)
+
+    def WhenEndBound(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenEndBound(self, *args)
+
+    def MustBePerformed(self) -> "bool":
+        r""" These methods query, set, and watch the performed status of the interval var."""
+        return _pywrapcp.IntervalVar_MustBePerformed(self)
+
+    def MayBePerformed(self) -> "bool":
+        return _pywrapcp.IntervalVar_MayBePerformed(self)
+
+    def CannotBePerformed(self) -> "bool":
+        return _pywrapcp.IntervalVar_CannotBePerformed(self)
+
+    def IsPerformedBound(self) -> "bool":
+        return _pywrapcp.IntervalVar_IsPerformedBound(self)
+
+    def SetPerformed(self, val: "bool") -> "void":
+        return _pywrapcp.IntervalVar_SetPerformed(self, val)
+
+    def WasPerformedBound(self) -> "bool":
+        return _pywrapcp.IntervalVar_WasPerformedBound(self)
+
+    def WhenPerformedBound(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenPerformedBound(self, *args)
+
+    def WhenAnything(self, *args) -> "void":
+        r"""
+        *Overload 1:*
+        Attaches a demon awakened when anything about this interval changes.
+
+        |
+
+        *Overload 2:*
+        Attaches a closure awakened when anything about this interval changes.
+        """
+        return _pywrapcp.IntervalVar_WhenAnything(self, *args)
+
+    def StartExpr(self) -> "operations_research::IntExpr *":
+        r""" These methods create expressions encapsulating the start, end and duration of the interval var. Please note that these must not be used if the interval var is unperformed."""
+        return _pywrapcp.IntervalVar_StartExpr(self)
+
+    def DurationExpr(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntervalVar_DurationExpr(self)
+
+    def EndExpr(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntervalVar_EndExpr(self)
+
+    def PerformedExpr(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntervalVar_PerformedExpr(self)
+
+    def SafeStartExpr(self, unperformed_value: "int64_t") -> "operations_research::IntExpr *":
+        r""" These methods create expressions encapsulating the start, end and duration of the interval var. If the interval var is unperformed, they will return the unperformed_value."""
+        return _pywrapcp.IntervalVar_SafeStartExpr(self, unperformed_value)
+
+    def SafeDurationExpr(self, unperformed_value: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.IntervalVar_SafeDurationExpr(self, unperformed_value)
+
+    def SafeEndExpr(self, unperformed_value: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.IntervalVar_SafeEndExpr(self, unperformed_value)
+
+    def EndsAfterEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAfterEnd(self, other)
+
+    def EndsAfterEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAfterEndWithDelay(self, other, delay)
+
+    def EndsAfterStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAfterStart(self, other)
+
+    def EndsAfterStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAfterStartWithDelay(self, other, delay)
+
+    def EndsAtEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAtEnd(self, other)
+
+    def EndsAtEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAtEndWithDelay(self, other, delay)
+
+    def EndsAtStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAtStart(self, other)
+
+    def EndsAtStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAtStartWithDelay(self, other, delay)
+
+    def StartsAfterEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAfterEnd(self, other)
+
+    def StartsAfterEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAfterEndWithDelay(self, other, delay)
+
+    def StartsAfterStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAfterStart(self, other)
+
+    def StartsAfterStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAfterStartWithDelay(self, other, delay)
+
+    def StartsAtEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAtEnd(self, other)
+
+    def StartsAtEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAtEndWithDelay(self, other, delay)
+
+    def StartsAtStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAtStart(self, other)
+
+    def StartsAtStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAtStartWithDelay(self, other, delay)
+
+    def StaysInSync(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StaysInSync(self, other)
+
+    def StaysInSyncWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StaysInSyncWithDelay(self, other, delay)
+
+    def EndsAfter(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAfter(self, date)
+
+    def EndsAt(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAt(self, date)
+
+    def EndsBefore(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsBefore(self, date)
+
+    def StartsAfter(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAfter(self, date)
+
+    def StartsAt(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAt(self, date)
+
+    def StartsBefore(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsBefore(self, date)
+
+    def CrossesDate(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_CrossesDate(self, date)
+
+    def AvoidsDate(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_AvoidsDate(self, date)
+
+    def __repr__(self) -> "std::string":
+        return _pywrapcp.IntervalVar___repr__(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.IntervalVar___str__(self)
+
+# Register IntervalVar in _pywrapcp:
+_pywrapcp.IntervalVar_swigregister(IntervalVar)
+
+class SequenceVar(PropagationBaseObject):
+    r""" A sequence variable is a variable whose domain is a set of possible orderings of the interval variables. It allows ordering of tasks. It has two sets of methods: ComputePossibleFirstsAndLasts(), which returns the list of interval variables that can be ranked first or last; and RankFirst/RankNotFirst/RankLast/RankNotLast, which can be used to create the search decision."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.SequenceVar_DebugString(self)
+
+    def RankFirst(self, index: "int") -> "void":
+        r""" Ranks the index_th interval var first of all unranked interval vars. After that, it will no longer be considered ranked."""
+        return _pywrapcp.SequenceVar_RankFirst(self, index)
+
+    def RankNotFirst(self, index: "int") -> "void":
+        r""" Indicates that the index_th interval var will not be ranked first of all currently unranked interval vars."""
+        return _pywrapcp.SequenceVar_RankNotFirst(self, index)
+
+    def RankLast(self, index: "int") -> "void":
+        r""" Ranks the index_th interval var first of all unranked interval vars. After that, it will no longer be considered ranked."""
+        return _pywrapcp.SequenceVar_RankLast(self, index)
+
+    def RankNotLast(self, index: "int") -> "void":
+        r""" Indicates that the index_th interval var will not be ranked first of all currently unranked interval vars."""
+        return _pywrapcp.SequenceVar_RankNotLast(self, index)
+
+    def Interval(self, index: "int") -> "operations_research::IntervalVar *":
+        r""" Returns the index_th interval of the sequence."""
+        return _pywrapcp.SequenceVar_Interval(self, index)
+
+    def Next(self, index: "int") -> "operations_research::IntVar *":
+        r""" Returns the next of the index_th interval of the sequence."""
+        return _pywrapcp.SequenceVar_Next(self, index)
+
+    def Size(self) -> "int64_t":
+        r""" Returns the number of interval vars in the sequence."""
+        return _pywrapcp.SequenceVar_Size(self)
+
+    def __repr__(self) -> "std::string":
+        return _pywrapcp.SequenceVar___repr__(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.SequenceVar___str__(self)
+
+# Register SequenceVar in _pywrapcp:
+_pywrapcp.SequenceVar_swigregister(SequenceVar)
+
+class AssignmentElement(object):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Activate(self) -> "void":
+        return _pywrapcp.AssignmentElement_Activate(self)
+
+    def Deactivate(self) -> "void":
+        return _pywrapcp.AssignmentElement_Deactivate(self)
+
+    def Activated(self) -> "bool":
+        return _pywrapcp.AssignmentElement_Activated(self)
+    __swig_destroy__ = _pywrapcp.delete_AssignmentElement
+
+# Register AssignmentElement in _pywrapcp:
+_pywrapcp.AssignmentElement_swigregister(AssignmentElement)
+
+class IntVarElement(AssignmentElement):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Var(self) -> "operations_research::IntVar *":
+        return _pywrapcp.IntVarElement_Var(self)
+
+    def Min(self) -> "int64_t":
+        return _pywrapcp.IntVarElement_Min(self)
+
+    def SetMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntVarElement_SetMin(self, m)
+
+    def Max(self) -> "int64_t":
+        return _pywrapcp.IntVarElement_Max(self)
+
+    def SetMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntVarElement_SetMax(self, m)
+
+    def Value(self) -> "int64_t":
+        return _pywrapcp.IntVarElement_Value(self)
+
+    def Bound(self) -> "bool":
+        return _pywrapcp.IntVarElement_Bound(self)
+
+    def SetRange(self, l: "int64_t", u: "int64_t") -> "void":
+        return _pywrapcp.IntVarElement_SetRange(self, l, u)
+
+    def SetValue(self, v: "int64_t") -> "void":
+        return _pywrapcp.IntVarElement_SetValue(self, v)
+
+    def __eq__(self, element: "IntVarElement") -> "bool":
+        return _pywrapcp.IntVarElement___eq__(self, element)
+
+    def __ne__(self, element: "IntVarElement") -> "bool":
+        return _pywrapcp.IntVarElement___ne__(self, element)
+    __swig_destroy__ = _pywrapcp.delete_IntVarElement
+
+# Register IntVarElement in _pywrapcp:
+_pywrapcp.IntVarElement_swigregister(IntVarElement)
+
+class IntervalVarElement(AssignmentElement):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Var(self) -> "operations_research::IntervalVar *":
+        return _pywrapcp.IntervalVarElement_Var(self)
+
+    def StartMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_StartMin(self)
+
+    def StartMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_StartMax(self)
+
+    def StartValue(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_StartValue(self)
+
+    def DurationMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_DurationMin(self)
+
+    def DurationMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_DurationMax(self)
+
+    def DurationValue(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_DurationValue(self)
+
+    def EndMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_EndMin(self)
+
+    def EndMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_EndMax(self)
+
+    def EndValue(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_EndValue(self)
+
+    def PerformedMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_PerformedMin(self)
+
+    def PerformedMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_PerformedMax(self)
+
+    def PerformedValue(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_PerformedValue(self)
+
+    def SetStartMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetStartMin(self, m)
+
+    def SetStartMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetStartMax(self, m)
+
+    def SetStartRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetStartRange(self, mi, ma)
+
+    def SetStartValue(self, v: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetStartValue(self, v)
+
+    def SetDurationMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetDurationMin(self, m)
+
+    def SetDurationMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetDurationMax(self, m)
+
+    def SetDurationRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetDurationRange(self, mi, ma)
+
+    def SetDurationValue(self, v: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetDurationValue(self, v)
+
+    def SetEndMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetEndMin(self, m)
+
+    def SetEndMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetEndMax(self, m)
+
+    def SetEndRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetEndRange(self, mi, ma)
+
+    def SetEndValue(self, v: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetEndValue(self, v)
+
+    def SetPerformedMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetPerformedMin(self, m)
+
+    def SetPerformedMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetPerformedMax(self, m)
+
+    def SetPerformedRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetPerformedRange(self, mi, ma)
+
+    def SetPerformedValue(self, v: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetPerformedValue(self, v)
+
+    def __eq__(self, element: "IntervalVarElement") -> "bool":
+        return _pywrapcp.IntervalVarElement___eq__(self, element)
+
+    def __ne__(self, element: "IntervalVarElement") -> "bool":
+        return _pywrapcp.IntervalVarElement___ne__(self, element)
+    __swig_destroy__ = _pywrapcp.delete_IntervalVarElement
+
+# Register IntervalVarElement in _pywrapcp:
+_pywrapcp.IntervalVarElement_swigregister(IntervalVarElement)
+
+class SequenceVarElement(AssignmentElement):
+    r""" The SequenceVarElement stores a partial representation of ranked interval variables in the underlying sequence variable. This representation consists of three vectors:   - the forward sequence. That is the list of interval variables     ranked first in the sequence.  The first element of the backward     sequence is the first interval in the sequence variable.   - the backward sequence. That is the list of interval variables     ranked last in the sequence. The first element of the backward     sequence is the last interval in the sequence variable.   - The list of unperformed interval variables.  Furthermore, if all performed variables are ranked, then by  convention, the forward_sequence will contain all such variables  and the backward_sequence will be empty."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Var(self) -> "operations_research::SequenceVar *":
+        return _pywrapcp.SequenceVarElement_Var(self)
+
+    def ForwardSequence(self) -> "std::vector< int > const &":
+        return _pywrapcp.SequenceVarElement_ForwardSequence(self)
+
+    def BackwardSequence(self) -> "std::vector< int > const &":
+        return _pywrapcp.SequenceVarElement_BackwardSequence(self)
+
+    def Unperformed(self) -> "std::vector< int > const &":
+        return _pywrapcp.SequenceVarElement_Unperformed(self)
+
+    def SetSequence(self, forward_sequence: "std::vector< int > const &", backward_sequence: "std::vector< int > const &", unperformed: "std::vector< int > const &") -> "void":
+        return _pywrapcp.SequenceVarElement_SetSequence(self, forward_sequence, backward_sequence, unperformed)
+
+    def SetForwardSequence(self, forward_sequence: "std::vector< int > const &") -> "void":
+        return _pywrapcp.SequenceVarElement_SetForwardSequence(self, forward_sequence)
+
+    def SetBackwardSequence(self, backward_sequence: "std::vector< int > const &") -> "void":
+        return _pywrapcp.SequenceVarElement_SetBackwardSequence(self, backward_sequence)
+
+    def SetUnperformed(self, unperformed: "std::vector< int > const &") -> "void":
+        return _pywrapcp.SequenceVarElement_SetUnperformed(self, unperformed)
+
+    def __eq__(self, element: "SequenceVarElement") -> "bool":
+        return _pywrapcp.SequenceVarElement___eq__(self, element)
+
+    def __ne__(self, element: "SequenceVarElement") -> "bool":
+        return _pywrapcp.SequenceVarElement___ne__(self, element)
+    __swig_destroy__ = _pywrapcp.delete_SequenceVarElement
+
+# Register SequenceVarElement in _pywrapcp:
+_pywrapcp.SequenceVarElement_swigregister(SequenceVarElement)
+
+class Assignment(PropagationBaseObject):
+    r""" An Assignment is a variable -> domains mapping, used to report solutions to the user."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Clear(self) -> "void":
+        return _pywrapcp.Assignment_Clear(self)
+
+    def Empty(self) -> "bool":
+        return _pywrapcp.Assignment_Empty(self)
+
+    def Size(self) -> "int":
+        return _pywrapcp.Assignment_Size(self)
+
+    def NumIntVars(self) -> "int":
+        return _pywrapcp.Assignment_NumIntVars(self)
+
+    def NumIntervalVars(self) -> "int":
+        return _pywrapcp.Assignment_NumIntervalVars(self)
+
+    def NumSequenceVars(self) -> "int":
+        return _pywrapcp.Assignment_NumSequenceVars(self)
+
+    def Store(self) -> "void":
+        return _pywrapcp.Assignment_Store(self)
+
+    def Restore(self) -> "void":
+        return _pywrapcp.Assignment_Restore(self)
+
+    def Load(self, *args) -> "void":
+        return _pywrapcp.Assignment_Load(self, *args)
+
+    def Save(self, *args) -> "void":
+        return _pywrapcp.Assignment_Save(self, *args)
+
+    def AddObjective(self, v: "IntVar") -> "void":
+        return _pywrapcp.Assignment_AddObjective(self, v)
+
+    def Objective(self) -> "operations_research::IntVar *":
+        return _pywrapcp.Assignment_Objective(self)
+
+    def HasObjective(self) -> "bool":
+        return _pywrapcp.Assignment_HasObjective(self)
+
+    def ObjectiveMin(self) -> "int64_t":
+        return _pywrapcp.Assignment_ObjectiveMin(self)
+
+    def ObjectiveMax(self) -> "int64_t":
+        return _pywrapcp.Assignment_ObjectiveMax(self)
+
+    def ObjectiveValue(self) -> "int64_t":
+        return _pywrapcp.Assignment_ObjectiveValue(self)
+
+    def ObjectiveBound(self) -> "bool":
+        return _pywrapcp.Assignment_ObjectiveBound(self)
+
+    def SetObjectiveMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetObjectiveMin(self, m)
+
+    def SetObjectiveMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetObjectiveMax(self, m)
+
+    def SetObjectiveValue(self, value: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetObjectiveValue(self, value)
+
+    def SetObjectiveRange(self, l: "int64_t", u: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetObjectiveRange(self, l, u)
+
+    def Min(self, var: "IntVar") -> "int64_t":
+        return _pywrapcp.Assignment_Min(self, var)
+
+    def Max(self, var: "IntVar") -> "int64_t":
+        return _pywrapcp.Assignment_Max(self, var)
+
+    def Value(self, var: "IntVar") -> "int64_t":
+        return _pywrapcp.Assignment_Value(self, var)
+
+    def Bound(self, var: "IntVar") -> "bool":
+        return _pywrapcp.Assignment_Bound(self, var)
+
+    def SetMin(self, var: "IntVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetMin(self, var, m)
+
+    def SetMax(self, var: "IntVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetMax(self, var, m)
+
+    def SetRange(self, var: "IntVar", l: "int64_t", u: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetRange(self, var, l, u)
+
+    def SetValue(self, var: "IntVar", value: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetValue(self, var, value)
+
+    def StartMin(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_StartMin(self, var)
+
+    def StartMax(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_StartMax(self, var)
+
+    def StartValue(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_StartValue(self, var)
+
+    def DurationMin(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_DurationMin(self, var)
+
+    def DurationMax(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_DurationMax(self, var)
+
+    def DurationValue(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_DurationValue(self, var)
+
+    def EndMin(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_EndMin(self, var)
+
+    def EndMax(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_EndMax(self, var)
+
+    def EndValue(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_EndValue(self, var)
+
+    def PerformedMin(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_PerformedMin(self, var)
+
+    def PerformedMax(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_PerformedMax(self, var)
+
+    def PerformedValue(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_PerformedValue(self, var)
+
+    def SetStartMin(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetStartMin(self, var, m)
+
+    def SetStartMax(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetStartMax(self, var, m)
+
+    def SetStartRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetStartRange(self, var, mi, ma)
+
+    def SetStartValue(self, var: "IntervalVar", value: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetStartValue(self, var, value)
+
+    def SetDurationMin(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetDurationMin(self, var, m)
+
+    def SetDurationMax(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetDurationMax(self, var, m)
+
+    def SetDurationRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetDurationRange(self, var, mi, ma)
+
+    def SetDurationValue(self, var: "IntervalVar", value: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetDurationValue(self, var, value)
+
+    def SetEndMin(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetEndMin(self, var, m)
+
+    def SetEndMax(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetEndMax(self, var, m)
+
+    def SetEndRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetEndRange(self, var, mi, ma)
+
+    def SetEndValue(self, var: "IntervalVar", value: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetEndValue(self, var, value)
+
+    def SetPerformedMin(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetPerformedMin(self, var, m)
+
+    def SetPerformedMax(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetPerformedMax(self, var, m)
+
+    def SetPerformedRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetPerformedRange(self, var, mi, ma)
+
+    def SetPerformedValue(self, var: "IntervalVar", value: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetPerformedValue(self, var, value)
+
+    def Add(self, *args) -> "void":
+        return _pywrapcp.Assignment_Add(self, *args)
+
+    def ForwardSequence(self, var: "SequenceVar") -> "std::vector< int > const &":
+        return _pywrapcp.Assignment_ForwardSequence(self, var)
+
+    def BackwardSequence(self, var: "SequenceVar") -> "std::vector< int > const &":
+        return _pywrapcp.Assignment_BackwardSequence(self, var)
+
+    def Unperformed(self, var: "SequenceVar") -> "std::vector< int > const &":
+        return _pywrapcp.Assignment_Unperformed(self, var)
+
+    def SetSequence(self, var: "SequenceVar", forward_sequence: "std::vector< int > const &", backward_sequence: "std::vector< int > const &", unperformed: "std::vector< int > const &") -> "void":
+        return _pywrapcp.Assignment_SetSequence(self, var, forward_sequence, backward_sequence, unperformed)
+
+    def SetForwardSequence(self, var: "SequenceVar", forward_sequence: "std::vector< int > const &") -> "void":
+        return _pywrapcp.Assignment_SetForwardSequence(self, var, forward_sequence)
+
+    def SetBackwardSequence(self, var: "SequenceVar", backward_sequence: "std::vector< int > const &") -> "void":
+        return _pywrapcp.Assignment_SetBackwardSequence(self, var, backward_sequence)
+
+    def SetUnperformed(self, var: "SequenceVar", unperformed: "std::vector< int > const &") -> "void":
+        return _pywrapcp.Assignment_SetUnperformed(self, var, unperformed)
+
+    def Activate(self, *args) -> "void":
+        return _pywrapcp.Assignment_Activate(self, *args)
+
+    def Deactivate(self, *args) -> "void":
+        return _pywrapcp.Assignment_Deactivate(self, *args)
+
+    def Activated(self, *args) -> "bool":
+        return _pywrapcp.Assignment_Activated(self, *args)
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.Assignment_DebugString(self)
+
+    def IntVarContainer(self) -> "operations_research::Assignment::IntContainer const &":
+        return _pywrapcp.Assignment_IntVarContainer(self)
+
+    def MutableIntVarContainer(self) -> "operations_research::Assignment::IntContainer *":
+        return _pywrapcp.Assignment_MutableIntVarContainer(self)
+
+    def IntervalVarContainer(self) -> "operations_research::Assignment::IntervalContainer const &":
+        return _pywrapcp.Assignment_IntervalVarContainer(self)
+
+    def MutableIntervalVarContainer(self) -> "operations_research::Assignment::IntervalContainer *":
+        return _pywrapcp.Assignment_MutableIntervalVarContainer(self)
+
+    def SequenceVarContainer(self) -> "operations_research::Assignment::SequenceContainer const &":
+        return _pywrapcp.Assignment_SequenceVarContainer(self)
+
+    def MutableSequenceVarContainer(self) -> "operations_research::Assignment::SequenceContainer *":
+        return _pywrapcp.Assignment_MutableSequenceVarContainer(self)
+
+    def __eq__(self, assignment: "Assignment") -> "bool":
+        return _pywrapcp.Assignment___eq__(self, assignment)
+
+    def __ne__(self, assignment: "Assignment") -> "bool":
+        return _pywrapcp.Assignment___ne__(self, assignment)
+
+# Register Assignment in _pywrapcp:
+_pywrapcp.Assignment_swigregister(Assignment)
+
+
+def __lshift__(*args) -> "std::ostream &":
+    return _pywrapcp.__lshift__(*args)
+class Pack(Constraint):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def AddWeightedSumLessOrEqualConstantDimension(self, *args) -> "void":
+        r"""
+        *Overload 1:*
+        Dimensions are additional constraints than can restrict what is possible with the pack constraint. It can be used to set capacity limits, to count objects per bin, to compute unassigned penalties... This dimension imposes that for all bins b, the weighted sum (weights[i]) of all objects i assigned to 'b' is less or equal 'bounds[b]'.
+
+        |
+
+        *Overload 2:*
+        This dimension imposes that for all bins b, the weighted sum (weights->Run(i)) of all objects i assigned to 'b' is less or equal to 'bounds[b]'. Ownership of the callback is transferred to the pack constraint.
+
+        |
+
+        *Overload 3:*
+        This dimension imposes that for all bins b, the weighted sum (weights->Run(i, b) of all objects i assigned to 'b' is less or equal to 'bounds[b]'. Ownership of the callback is transferred to the pack constraint.
+        """
+        return _pywrapcp.Pack_AddWeightedSumLessOrEqualConstantDimension(self, *args)
+
+    def AddWeightedSumEqualVarDimension(self, *args) -> "void":
+        r"""
+        *Overload 1:*
+        This dimension imposes that for all bins b, the weighted sum (weights[i]) of all objects i assigned to 'b' is equal to loads[b].
+
+        |
+
+        *Overload 2:*
+        This dimension imposes that for all bins b, the weighted sum (weights->Run(i, b)) of all objects i assigned to 'b' is equal to loads[b].
+        """
+        return _pywrapcp.Pack_AddWeightedSumEqualVarDimension(self, *args)
+
+    def AddSumVariableWeightsLessOrEqualConstantDimension(self, usage: "std::vector< operations_research::IntVar * > const &", capacity: "std::vector< int64_t > const &") -> "void":
+        r""" This dimension imposes: forall b in bins,    sum (i in items: usage[i] * is_assigned(i, b)) <= capacity[b] where is_assigned(i, b) is true if and only if item i is assigned to the bin b. This can be used to model shapes of items by linking variables of the same item on parallel dimensions with an allowed assignment constraint."""
+        return _pywrapcp.Pack_AddSumVariableWeightsLessOrEqualConstantDimension(self, usage, capacity)
+
+    def AddWeightedSumOfAssignedDimension(self, weights: "std::vector< int64_t > const &", cost_var: "IntVar") -> "void":
+        r""" This dimension enforces that cost_var == sum of weights[i] for all objects 'i' assigned to a bin."""
+        return _pywrapcp.Pack_AddWeightedSumOfAssignedDimension(self, weights, cost_var)
+
+    def AddCountUsedBinDimension(self, count_var: "IntVar") -> "void":
+        r""" This dimension links 'count_var' to the actual number of bins used in the pack."""
+        return _pywrapcp.Pack_AddCountUsedBinDimension(self, count_var)
+
+    def AddCountAssignedItemsDimension(self, count_var: "IntVar") -> "void":
+        r""" This dimension links 'count_var' to the actual number of items assigned to a bin in the pack."""
+        return _pywrapcp.Pack_AddCountAssignedItemsDimension(self, count_var)
+
+    def Post(self) -> "void":
+        return _pywrapcp.Pack_Post(self)
+
+    def InitialPropagateWrapper(self) -> "void":
+        return _pywrapcp.Pack_InitialPropagateWrapper(self)
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.Pack_DebugString(self)
+
+# Register Pack in _pywrapcp:
+_pywrapcp.Pack_swigregister(Pack)
+
+class DisjunctiveConstraint(Constraint):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+
+    def SequenceVar(self) -> "operations_research::SequenceVar *":
+        r""" Creates a sequence variable from the constraint."""
+        return _pywrapcp.DisjunctiveConstraint_SequenceVar(self)
+
+    def SetTransitionTime(self, transition_time: "operations_research::Solver::IndexEvaluator2") -> "void":
+        r""" Add a transition time between intervals.  It forces the distance between the end of interval a and start of interval b that follows it to be at least transition_time(a, b). This function must always return a positive or null value."""
+        return _pywrapcp.DisjunctiveConstraint_SetTransitionTime(self, transition_time)
+
+    def TransitionTime(self, before_index: "int", after_index: "int") -> "int64_t":
+        return _pywrapcp.DisjunctiveConstraint_TransitionTime(self, before_index, after_index)
+
+# Register DisjunctiveConstraint in _pywrapcp:
+_pywrapcp.DisjunctiveConstraint_swigregister(DisjunctiveConstraint)
+
+class RevInteger(object):
+    r""" This class adds reversibility to a POD type. It contains the stamp optimization. i.e. the SaveValue call is done only once per node of the search tree.  Please note that actual stamps always starts at 1, thus an initial value of 0 will always trigger the first SaveValue."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, val: "long const &"):
+        _pywrapcp.RevInteger_swiginit(self, _pywrapcp.new_RevInteger(val))
+
+    def Value(self) -> "long const &":
+        return _pywrapcp.RevInteger_Value(self)
+
+    def SetValue(self, s: "Solver", val: "long const &") -> "void":
+        return _pywrapcp.RevInteger_SetValue(self, s, val)
+    __swig_destroy__ = _pywrapcp.delete_RevInteger
+
+# Register RevInteger in _pywrapcp:
+_pywrapcp.RevInteger_swigregister(RevInteger)
+
+class NumericalRevInteger(RevInteger):
+    r""" Subclass of Rev<T> which adds numerical operations."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, val: "long const &"):
+        _pywrapcp.NumericalRevInteger_swiginit(self, _pywrapcp.new_NumericalRevInteger(val))
+
+    def Add(self, s: "Solver", to_add: "long const &") -> "void":
+        return _pywrapcp.NumericalRevInteger_Add(self, s, to_add)
+
+    def Incr(self, s: "Solver") -> "void":
+        return _pywrapcp.NumericalRevInteger_Incr(self, s)
+
+    def Decr(self, s: "Solver") -> "void":
+        return _pywrapcp.NumericalRevInteger_Decr(self, s)
+    __swig_destroy__ = _pywrapcp.delete_NumericalRevInteger
+
+# Register NumericalRevInteger in _pywrapcp:
+_pywrapcp.NumericalRevInteger_swigregister(NumericalRevInteger)
+
+class RevBool(object):
+    r""" This class adds reversibility to a POD type. It contains the stamp optimization. i.e. the SaveValue call is done only once per node of the search tree.  Please note that actual stamps always starts at 1, thus an initial value of 0 will always trigger the first SaveValue."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, val: "bool const &"):
+        _pywrapcp.RevBool_swiginit(self, _pywrapcp.new_RevBool(val))
+
+    def Value(self) -> "bool const &":
+        return _pywrapcp.RevBool_Value(self)
+
+    def SetValue(self, s: "Solver", val: "bool const &") -> "void":
+        return _pywrapcp.RevBool_SetValue(self, s, val)
+    __swig_destroy__ = _pywrapcp.delete_RevBool
+
+# Register RevBool in _pywrapcp:
+_pywrapcp.RevBool_swigregister(RevBool)
+
+class IntVarContainer(object):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Contains(self, var: "IntVar") -> "bool":
+        return _pywrapcp.IntVarContainer_Contains(self, var)
+
+    def Element(self, index: "int") -> "operations_research::IntVarElement *":
+        return _pywrapcp.IntVarContainer_Element(self, index)
+
+    def Size(self) -> "int":
+        return _pywrapcp.IntVarContainer_Size(self)
+
+    def Store(self) -> "void":
+        return _pywrapcp.IntVarContainer_Store(self)
+
+    def Restore(self) -> "void":
+        return _pywrapcp.IntVarContainer_Restore(self)
+
+    def __eq__(self, container: "IntVarContainer") -> "bool":
+        r""" Returns true if this and 'container' both represent the same V* -> E map. Runs in linear time; requires that the == operator on the type E is well defined."""
+        return _pywrapcp.IntVarContainer___eq__(self, container)
+
+    def __ne__(self, container: "IntVarContainer") -> "bool":
+        return _pywrapcp.IntVarContainer___ne__(self, container)
+    __swig_destroy__ = _pywrapcp.delete_IntVarContainer
+
+# Register IntVarContainer in _pywrapcp:
+_pywrapcp.IntVarContainer_swigregister(IntVarContainer)
+
+class IntervalVarContainer(object):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Contains(self, var: "IntervalVar") -> "bool":
+        return _pywrapcp.IntervalVarContainer_Contains(self, var)
+
+    def Element(self, index: "int") -> "operations_research::IntervalVarElement *":
+        return _pywrapcp.IntervalVarContainer_Element(self, index)
+
+    def Size(self) -> "int":
+        return _pywrapcp.IntervalVarContainer_Size(self)
+
+    def Store(self) -> "void":
+        return _pywrapcp.IntervalVarContainer_Store(self)
+
+    def Restore(self) -> "void":
+        return _pywrapcp.IntervalVarContainer_Restore(self)
+
+    def __eq__(self, container: "IntervalVarContainer") -> "bool":
+        r""" Returns true if this and 'container' both represent the same V* -> E map. Runs in linear time; requires that the == operator on the type E is well defined."""
+        return _pywrapcp.IntervalVarContainer___eq__(self, container)
+
+    def __ne__(self, container: "IntervalVarContainer") -> "bool":
+        return _pywrapcp.IntervalVarContainer___ne__(self, container)
+    __swig_destroy__ = _pywrapcp.delete_IntervalVarContainer
+
+# Register IntervalVarContainer in _pywrapcp:
+_pywrapcp.IntervalVarContainer_swigregister(IntervalVarContainer)
+
+class SequenceVarContainer(object):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Contains(self, var: "SequenceVar") -> "bool":
+        return _pywrapcp.SequenceVarContainer_Contains(self, var)
+
+    def Element(self, index: "int") -> "operations_research::SequenceVarElement *":
+        return _pywrapcp.SequenceVarContainer_Element(self, index)
+
+    def Size(self) -> "int":
+        return _pywrapcp.SequenceVarContainer_Size(self)
+
+    def Store(self) -> "void":
+        return _pywrapcp.SequenceVarContainer_Store(self)
+
+    def Restore(self) -> "void":
+        return _pywrapcp.SequenceVarContainer_Restore(self)
+
+    def __eq__(self, container: "SequenceVarContainer") -> "bool":
+        r""" Returns true if this and 'container' both represent the same V* -> E map. Runs in linear time; requires that the == operator on the type E is well defined."""
+        return _pywrapcp.SequenceVarContainer___eq__(self, container)
+
+    def __ne__(self, container: "SequenceVarContainer") -> "bool":
+        return _pywrapcp.SequenceVarContainer___ne__(self, container)
+    __swig_destroy__ = _pywrapcp.delete_SequenceVarContainer
+
+# Register SequenceVarContainer in _pywrapcp:
+_pywrapcp.SequenceVarContainer_swigregister(SequenceVarContainer)
+
+class LocalSearchOperator(BaseObject):
+    r""" This class represent a reversible FIFO structure. The main difference w.r.t a standard FIFO structure is that a Solver is given as parameter to the modifiers such that the solver can store the backtrack information Iterator's traversing order should not be changed, as some algorithm depend on it to be consistent. It's main use is to store a list of demons in the various classes of variables. The base class for all local search operators. A local search operator is an object that defines the neighborhood of a solution. In other words, a neighborhood is the set of solutions which can be reached from a given solution using an operator. The behavior of the LocalSearchOperator class is similar to iterators. The operator is synchronized with an assignment (gives the current values of the variables); this is done in the Start() method. Then one can iterate over the neighbors using the MakeNextNeighbor method. This method returns an assignment which represents the incremental changes to the current solution. It also returns a second assignment representing the changes to the last solution defined by the neighborhood operator; this assignment is empty if the neighborhood operator cannot track this information."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+
+    def NextNeighbor(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
+        return _pywrapcp.LocalSearchOperator_NextNeighbor(self, delta, deltadelta)
+
+    def Start(self, assignment: "Assignment") -> "void":
+        return _pywrapcp.LocalSearchOperator_Start(self, assignment)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_LocalSearchOperator(self)
+        return weakref.proxy(self)
+
+# Register LocalSearchOperator in _pywrapcp:
+_pywrapcp.LocalSearchOperator_swigregister(LocalSearchOperator)
+
+class IntVarLocalSearchOperatorTemplate(LocalSearchOperator):
+    r""" Base operator class for operators manipulating variables."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+
+    def Start(self, assignment: "Assignment") -> "void":
+        r""" This method should not be overridden. Override OnStart() instead which is called before exiting this method."""
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_Start(self, assignment)
+
+    def IsIncremental(self) -> "bool":
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_IsIncremental(self)
+
+    def Size(self) -> "int":
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_Size(self)
+
+    def Value(self, index: "int64_t") -> "long const &":
+        r""" Returns the value in the current assignment of the variable of given index."""
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_Value(self, index)
+
+    def OldValue(self, index: "int64_t") -> "long const &":
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_OldValue(self, index)
+
+    def SetValue(self, index: "int64_t", value: "long const &") -> "void":
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_SetValue(self, index, value)
+
+    def OnStart(self) -> "void":
+        r""" Called by Start() after synchronizing the operator with the current assignment. Should be overridden instead of Start() to avoid calling VarLocalSearchOperator::Start explicitly."""
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_OnStart(self)
+
+# Register IntVarLocalSearchOperatorTemplate in _pywrapcp:
+_pywrapcp.IntVarLocalSearchOperatorTemplate_swigregister(IntVarLocalSearchOperatorTemplate)
+
+class IntVarLocalSearchOperator(IntVarLocalSearchOperatorTemplate):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, *args):
+        if self.__class__ == IntVarLocalSearchOperator:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.IntVarLocalSearchOperator_swiginit(self, _pywrapcp.new_IntVarLocalSearchOperator(_self, *args))
+    __swig_destroy__ = _pywrapcp.delete_IntVarLocalSearchOperator
+
+    def NextNeighbor(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
+        r""" Redefines MakeNextNeighbor to export a simpler interface. The calls to ApplyChanges() and RevertChanges() are factored in this method, hiding both delta and deltadelta from subclasses which only need to override MakeOneNeighbor(). Therefore this method should not be overridden. Override MakeOneNeighbor() instead."""
+        return _pywrapcp.IntVarLocalSearchOperator_NextNeighbor(self, delta, deltadelta)
+
+    def OneNeighbor(self) -> "bool":
+        r""" Creates a new neighbor. It returns false when the neighborhood is completely explored. MakeNextNeighbor() in a subclass of IntVarLocalSearchOperator."""
+        return _pywrapcp.IntVarLocalSearchOperator_OneNeighbor(self)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_IntVarLocalSearchOperator(self)
+        return weakref.proxy(self)
+
+# Register IntVarLocalSearchOperator in _pywrapcp:
+_pywrapcp.IntVarLocalSearchOperator_swigregister(IntVarLocalSearchOperator)
+
+class SequenceVarLocalSearchOperatorTemplate(LocalSearchOperator):
+    r""" Base operator class for operators manipulating variables."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+
+    def Start(self, assignment: "Assignment") -> "void":
+        r""" This method should not be overridden. Override OnStart() instead which is called before exiting this method."""
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_Start(self, assignment)
+
+    def IsIncremental(self) -> "bool":
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_IsIncremental(self)
+
+    def Size(self) -> "int":
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_Size(self)
+
+    def Value(self, index: "int64_t") -> "std::vector< int > const &":
+        r""" Returns the value in the current assignment of the variable of given index."""
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_Value(self, index)
+
+    def OldValue(self, index: "int64_t") -> "std::vector< int > const &":
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_OldValue(self, index)
+
+    def SetValue(self, index: "int64_t", value: "std::vector< int > const &") -> "void":
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_SetValue(self, index, value)
+
+    def OnStart(self) -> "void":
+        r""" Called by Start() after synchronizing the operator with the current assignment. Should be overridden instead of Start() to avoid calling VarLocalSearchOperator::Start explicitly."""
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_OnStart(self)
+
+# Register SequenceVarLocalSearchOperatorTemplate in _pywrapcp:
+_pywrapcp.SequenceVarLocalSearchOperatorTemplate_swigregister(SequenceVarLocalSearchOperatorTemplate)
+
+class SequenceVarLocalSearchOperator(SequenceVarLocalSearchOperatorTemplate):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+
+# Register SequenceVarLocalSearchOperator in _pywrapcp:
+_pywrapcp.SequenceVarLocalSearchOperator_swigregister(SequenceVarLocalSearchOperator)
+
+class BaseLns(IntVarLocalSearchOperator):
+    r""" This is the base class for building an Lns operator. An Lns fragment is a collection of variables which will be relaxed. Fragments are built with NextFragment(), which returns false if there are no more fragments to build. Optionally one can override InitFragments, which is called from LocalSearchOperator::Start to initialize fragment data. Here's a sample relaxing one variable at a time: class OneVarLns : public BaseLns {  public:   OneVarLns(const std::vector<IntVar*>& vars) : BaseLns(vars), index_(0) {}   virtual ~OneVarLns() {}   virtual void InitFragments() { index_ = 0; }   virtual bool NextFragment() {     const int size = Size();     if (index_ < size) {       AppendToFragment(index_);       ++index_;       return true;     } else {       return false;     }   }  private:   int index_; };"""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, vars: "std::vector< operations_research::IntVar * > const &"):
+        if self.__class__ == BaseLns:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.BaseLns_swiginit(self, _pywrapcp.new_BaseLns(_self, vars))
+    __swig_destroy__ = _pywrapcp.delete_BaseLns
+
+    def InitFragments(self) -> "void":
+        return _pywrapcp.BaseLns_InitFragments(self)
+
+    def NextFragment(self) -> "bool":
+        return _pywrapcp.BaseLns_NextFragment(self)
+
+    def AppendToFragment(self, index: "int") -> "void":
+        return _pywrapcp.BaseLns_AppendToFragment(self, index)
+
+    def FragmentSize(self) -> "int":
+        return _pywrapcp.BaseLns_FragmentSize(self)
+
+    def __getitem__(self, index: "int") -> "int64_t":
+        return _pywrapcp.BaseLns___getitem__(self, index)
+
+    def __len__(self) -> "int":
+        return _pywrapcp.BaseLns___len__(self)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_BaseLns(self)
+        return weakref.proxy(self)
+
+# Register BaseLns in _pywrapcp:
+_pywrapcp.BaseLns_swigregister(BaseLns)
+
+class ChangeValue(IntVarLocalSearchOperator):
+    r""" Defines operators which change the value of variables; each neighbor corresponds to *one* modified variable. Sub-classes have to define ModifyValue which determines what the new variable value is going to be (given the current value and the variable)."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, vars: "std::vector< operations_research::IntVar * > const &"):
+        if self.__class__ == ChangeValue:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.ChangeValue_swiginit(self, _pywrapcp.new_ChangeValue(_self, vars))
+    __swig_destroy__ = _pywrapcp.delete_ChangeValue
+
+    def ModifyValue(self, index: "int64_t", value: "int64_t") -> "int64_t":
+        return _pywrapcp.ChangeValue_ModifyValue(self, index, value)
+
+    def OneNeighbor(self) -> "bool":
+        r""" This method should not be overridden. Override ModifyValue() instead."""
+        return _pywrapcp.ChangeValue_OneNeighbor(self)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_ChangeValue(self)
+        return weakref.proxy(self)
+
+# Register ChangeValue in _pywrapcp:
+_pywrapcp.ChangeValue_swigregister(ChangeValue)
+
+class PathOperator(IntVarLocalSearchOperator):
+    r""" Base class of the local search operators dedicated to path modifications (a path is a set of nodes linked together by arcs). This family of neighborhoods supposes they are handling next variables representing the arcs (var[i] represents the node immediately after i on a path). Several services are provided: - arc manipulators (SetNext(), ReverseChain(), MoveChain()) - path inspectors (Next(), Prev(), IsPathEnd()) - path iterators: operators need a given number of nodes to define a   neighbor; this class provides the iteration on a given number of (base)   nodes which can be used to define a neighbor (through the BaseNode method) Subclasses only need to override MakeNeighbor to create neighbors using the services above (no direct manipulation of assignments)."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+
+    def Neighbor(self) -> "bool":
+        return _pywrapcp.PathOperator_Neighbor(self)
+
+# Register PathOperator in _pywrapcp:
+_pywrapcp.PathOperator_swigregister(PathOperator)
+
+class LocalSearchFilter(BaseObject):
+    r""" Classes to which this template function can be applied to as of 04/2014. Usage: LocalSearchOperator* op = MakeLocalSearchOperator<Relocate>(...); class TwoOpt; class Relocate; class Exchange; class Cross; class MakeActiveOperator; class MakeInactiveOperator; class MakeChainInactiveOperator; class SwapActiveOperator; class ExtendedSwapActiveOperator; class MakeActiveAndRelocate; class RelocateAndMakeActiveOperator; class RelocateAndMakeInactiveOperator; Local Search Filters are used for fast neighbor pruning. Filtering a move is done in several phases: - in the Relax phase, filters determine which parts of their internals   will be changed by the candidate, and modify intermediary State - in the Accept phase, filters check that the candidate is feasible, - if the Accept phase succeeds, the solver may decide to trigger a   Synchronize phase that makes filters change their internal representation   to the last candidate, - otherwise (Accept fails or the solver does not want to synchronize),   a Revert phase makes filters erase any intermediary State generated by the   Relax and Accept phases. A given filter has phases called with the following pattern: (Relax.Accept.Synchronize | Relax.Accept.Revert | Relax.Revert)*. Filters's Revert() is always called in the reverse order their Accept() was called, to allow late filters to use state done/undone by early filters' Accept()/Revert()."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+
+    def Accept(self, delta: "Assignment", deltadelta: "Assignment", objective_min: "int64_t", objective_max: "int64_t") -> "bool":
+        r""" Accepts a "delta" given the assignment with which the filter has been synchronized; the delta holds the variables which have been modified and their new value. If the filter represents a part of the global objective, its contribution must be between objective_min and objective_max. Sample: supposing one wants to maintain a[0,1] + b[0,1] <= 1, for the assignment (a,1), (b,0), the delta (b,1) will be rejected but the delta (a,0) will be accepted. TODO(user): Remove arguments when there are no more need for those."""
+        return _pywrapcp.LocalSearchFilter_Accept(self, delta, deltadelta, objective_min, objective_max)
+
+    def IsIncremental(self) -> "bool":
+        return _pywrapcp.LocalSearchFilter_IsIncremental(self)
+
+    def Synchronize(self, assignment: "Assignment", delta: "Assignment") -> "void":
+        r""" Synchronizes the filter with the current solution, delta being the difference with the solution passed to the previous call to Synchronize() or IncrementalSynchronize(). 'delta' can be used to incrementally synchronizing the filter with the new solution by only considering the changes in delta."""
+        return _pywrapcp.LocalSearchFilter_Synchronize(self, assignment, delta)
+    __swig_destroy__ = _pywrapcp.delete_LocalSearchFilter
+
+# Register LocalSearchFilter in _pywrapcp:
+_pywrapcp.LocalSearchFilter_swigregister(LocalSearchFilter)
+
+class LocalSearchFilterManager(BaseObject):
+    r""" Filter manager: when a move is made, filters are executed to decide whether the solution is feasible and compute parts of the new cost. This class schedules filter execution and composes costs as a sum."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.LocalSearchFilterManager_DebugString(self)
+
+    def __init__(self, *args):
+        _pywrapcp.LocalSearchFilterManager_swiginit(self, _pywrapcp.new_LocalSearchFilterManager(*args))
+
+    def Accept(self, monitor: "operations_research::LocalSearchMonitor *const", delta: "Assignment", deltadelta: "Assignment", objective_min: "int64_t", objective_max: "int64_t") -> "bool":
+        r""" Returns true iff all filters return true, and the sum of their accepted objectives is between objective_min and objective_max. The monitor has its Begin/EndFiltering events triggered."""
+        return _pywrapcp.LocalSearchFilterManager_Accept(self, monitor, delta, deltadelta, objective_min, objective_max)
+
+    def Synchronize(self, assignment: "Assignment", delta: "Assignment") -> "void":
+        r""" Synchronizes all filters to assignment."""
+        return _pywrapcp.LocalSearchFilterManager_Synchronize(self, assignment, delta)
+    __swig_destroy__ = _pywrapcp.delete_LocalSearchFilterManager
+
+# Register LocalSearchFilterManager in _pywrapcp:
+_pywrapcp.LocalSearchFilterManager_swigregister(LocalSearchFilterManager)
+
+class IntVarLocalSearchFilter(LocalSearchFilter):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, vars: "std::vector< operations_research::IntVar * > const &"):
+        if self.__class__ == IntVarLocalSearchFilter:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.IntVarLocalSearchFilter_swiginit(self, _pywrapcp.new_IntVarLocalSearchFilter(_self, vars))
+    __swig_destroy__ = _pywrapcp.delete_IntVarLocalSearchFilter
+
+    def Synchronize(self, assignment: "Assignment", delta: "Assignment") -> "void":
+        r""" This method should not be overridden. Override OnSynchronize() instead which is called before exiting this method."""
+        return _pywrapcp.IntVarLocalSearchFilter_Synchronize(self, assignment, delta)
+
+    def Size(self) -> "int":
+        return _pywrapcp.IntVarLocalSearchFilter_Size(self)
+
+    def Value(self, index: "int") -> "int64_t":
+        return _pywrapcp.IntVarLocalSearchFilter_Value(self, index)
+
+    def IndexFromVar(self, var: "IntVar") -> "int64_t":
+        return _pywrapcp.IntVarLocalSearchFilter_IndexFromVar(self, var)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_IntVarLocalSearchFilter(self)
+        return weakref.proxy(self)
+
+# Register IntVarLocalSearchFilter in _pywrapcp:
+_pywrapcp.IntVarLocalSearchFilter_swigregister(IntVarLocalSearchFilter)
+
+class BooleanVar(IntVar):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+
+    def Min(self) -> "int64_t":
+        return _pywrapcp.BooleanVar_Min(self)
+
+    def SetMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.BooleanVar_SetMin(self, m)
+
+    def Max(self) -> "int64_t":
+        return _pywrapcp.BooleanVar_Max(self)
+
+    def SetMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.BooleanVar_SetMax(self, m)
+
+    def SetRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.BooleanVar_SetRange(self, mi, ma)
+
+    def Bound(self) -> "bool":
+        return _pywrapcp.BooleanVar_Bound(self)
+
+    def Value(self) -> "int64_t":
+        return _pywrapcp.BooleanVar_Value(self)
+
+    def RemoveValue(self, v: "int64_t") -> "void":
+        return _pywrapcp.BooleanVar_RemoveValue(self, v)
+
+    def RemoveInterval(self, l: "int64_t", u: "int64_t") -> "void":
+        return _pywrapcp.BooleanVar_RemoveInterval(self, l, u)
+
+    def WhenBound(self, d: "Demon") -> "void":
+        return _pywrapcp.BooleanVar_WhenBound(self, d)
+
+    def WhenRange(self, d: "Demon") -> "void":
+        return _pywrapcp.BooleanVar_WhenRange(self, d)
+
+    def WhenDomain(self, d: "Demon") -> "void":
+        return _pywrapcp.BooleanVar_WhenDomain(self, d)
+
+    def Size(self) -> "uint64_t":
+        return _pywrapcp.BooleanVar_Size(self)
+
+    def Contains(self, v: "int64_t") -> "bool":
+        return _pywrapcp.BooleanVar_Contains(self, v)
+
+    def HoleIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *":
+        return _pywrapcp.BooleanVar_HoleIteratorAux(self, reversible)
+
+    def DomainIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *":
+        return _pywrapcp.BooleanVar_DomainIteratorAux(self, reversible)
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.BooleanVar_DebugString(self)
+
+# Register BooleanVar in _pywrapcp:
+_pywrapcp.BooleanVar_swigregister(BooleanVar)
+
+
+class PyDecision(Decision):
+
+  def __init__(self):
+    Decision.__init__(self)
+
+  def ApplyWrapper(self, solver):
+    try:
+       self.Apply(solver)
+    except Exception as e:
+      if 'CP Solver fail' in str(e):
+        solver.ShouldFail()
+      else:
+        raise
+
+  def RefuteWrapper(self, solver):
+    try:
+       self.Refute(solver)
+    except Exception as e:
+      if 'CP Solver fail' in str(e):
+        solver.ShouldFail()
+      else:
+        raise
+
+  def DebugString(self):
+    return "PyDecision"
+
+
+class PyDecisionBuilder(DecisionBuilder):
+
+  def __init__(self):
+    DecisionBuilder.__init__(self)
+
+  def NextWrapper(self, solver):
+    try:
+      return self.Next(solver)
+    except Exception as e:
+      if 'CP Solver fail' in str(e):
+        return solver.FailDecision()
+      else:
+        raise
+
+  def DebugString(self):
+    return "PyDecisionBuilder"
+
+
+class PyDemon(Demon):
+
+  def RunWrapper(self, solver):
+    try:
+      self.Run(solver)
+    except Exception as e:
+      if 'CP Solver fail' in str(e):
+        solver.ShouldFail()
+      else:
+        raise
+
+  def DebugString(self):
+    return "PyDemon"
+
+
+class PyConstraintDemon(PyDemon):
+
+  def __init__(self, ct, method, delayed, *args):
+    PyDemon.__init__(self)
+    self.__constraint = ct
+    self.__method = method
+    self.__delayed = delayed
+    self.__args = args
+
+  def Run(self, solver):
+    self.__method(self.__constraint, *self.__args)
+
+  def Priority(self):
+    return Solver.DELAYED_PRIORITY if self.__delayed else Solver.NORMAL_PRIORITY
+
+  def DebugString(self):
+    return 'PyConstraintDemon'
+
+
+class PyConstraint(Constraint):
+
+  def __init__(self, solver):
+    Constraint.__init__(self, solver)
+    self.__demons = []
+
+  def Demon(self, method, *args):
+    demon = PyConstraintDemon(self, method, False, *args)
+    self.__demons.append(demon)
+    return demon
+
+  def DelayedDemon(self, method, *args):
+    demon = PyConstraintDemon(self, method, True, *args)
+    self.__demons.append(demon)
+    return demon
+
+  def InitialPropagateDemon(self):
+    return self.solver().ConstraintInitialPropagateCallback(self)
+
+  def DelayedInitialPropagateDemon(self):
+    return self.solver().DelayedConstraintInitialPropagateCallback(self)
+
+  def InitialPropagateWrapper(self):
+    try:
+      self.InitialPropagate()
+    except Exception as e:
+      if 'CP Solver fail' in str(e):
+        self.solver().ShouldFail()
+      else:
+        raise
+
+  def DebugString(self):
+    return "PyConstraint"
+
+
+
+class RoutingIndexManager(object):
+    r""" Manager for any NodeIndex <-> variable index conversion. The routing solver uses variable indices internally and through its API. These variable indices are tricky to manage directly because one Node can correspond to a multitude of variables, depending on the number of times they appear in the model, and if they're used as start and/or end points. This class aims to simplify variable index usage, allowing users to use NodeIndex instead. Usage:   .cpp}   auto starts_ends = ...;  /// These are NodeIndex.   RoutingIndexManager manager(10, 4, starts_ends);  // 10 nodes, 4 vehicles.   RoutingModel model(manager);"""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, *args):
+        _pywrapcp.RoutingIndexManager_swiginit(self, _pywrapcp.new_RoutingIndexManager(*args))
+    __swig_destroy__ = _pywrapcp.delete_RoutingIndexManager
+
+    def GetNumberOfNodes(self) -> "int":
+        return _pywrapcp.RoutingIndexManager_GetNumberOfNodes(self)
+
+    def GetNumberOfVehicles(self) -> "int":
+        return _pywrapcp.RoutingIndexManager_GetNumberOfVehicles(self)
+
+    def GetNumberOfIndices(self) -> "int":
+        return _pywrapcp.RoutingIndexManager_GetNumberOfIndices(self)
+
+    def GetStartIndex(self, vehicle: "int") -> "int64_t":
+        return _pywrapcp.RoutingIndexManager_GetStartIndex(self, vehicle)
+
+    def GetEndIndex(self, vehicle: "int") -> "int64_t":
+        return _pywrapcp.RoutingIndexManager_GetEndIndex(self, vehicle)
+
+    def NodeToIndex(self, node: "operations_research::RoutingIndexManager::NodeIndex") -> "int64_t":
+        return _pywrapcp.RoutingIndexManager_NodeToIndex(self, node)
+
+    def IndexToNode(self, index: "int64_t") -> "operations_research::RoutingIndexManager::NodeIndex":
+        return _pywrapcp.RoutingIndexManager_IndexToNode(self, index)
+
+# Register RoutingIndexManager in _pywrapcp:
+_pywrapcp.RoutingIndexManager_swigregister(RoutingIndexManager)
+
+
+def DefaultRoutingModelParameters() -> "operations_research::RoutingModelParameters":
+    return _pywrapcp.DefaultRoutingModelParameters()
+
+def DefaultRoutingSearchParameters() -> "operations_research::RoutingSearchParameters":
+    return _pywrapcp.DefaultRoutingSearchParameters()
+
+def FindErrorInRoutingSearchParameters(search_parameters: "operations_research::RoutingSearchParameters const &") -> "std::string":
+    r""" Returns an empty std::string if the routing search parameters are valid, and a non-empty, human readable error description if they're not."""
+    return _pywrapcp.FindErrorInRoutingSearchParameters(search_parameters)
+BOOL_UNSPECIFIED = _pywrapcp.BOOL_UNSPECIFIED
+BOOL_FALSE = _pywrapcp.BOOL_FALSE
+BOOL_TRUE = _pywrapcp.BOOL_TRUE
+class RoutingModel(object):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+    ROUTING_NOT_SOLVED = _pywrapcp.RoutingModel_ROUTING_NOT_SOLVED
+    r""" Problem not solved yet (before calling RoutingModel::Solve())."""
+    ROUTING_SUCCESS = _pywrapcp.RoutingModel_ROUTING_SUCCESS
+    r""" Problem solved successfully after calling RoutingModel::Solve()."""
+    ROUTING_FAIL = _pywrapcp.RoutingModel_ROUTING_FAIL
+    r""" No solution found to the problem after calling RoutingModel::Solve()."""
+    ROUTING_FAIL_TIMEOUT = _pywrapcp.RoutingModel_ROUTING_FAIL_TIMEOUT
+    r""" Time limit reached before finding a solution with RoutingModel::Solve()."""
+    ROUTING_INVALID = _pywrapcp.RoutingModel_ROUTING_INVALID
+    r""" Model, model parameters or flags are not valid."""
+    PICKUP_AND_DELIVERY_NO_ORDER = _pywrapcp.RoutingModel_PICKUP_AND_DELIVERY_NO_ORDER
+    r""" Any precedence is accepted."""
+    PICKUP_AND_DELIVERY_LIFO = _pywrapcp.RoutingModel_PICKUP_AND_DELIVERY_LIFO
+    r""" Deliveries must be performed in reverse order of pickups."""
+    PICKUP_AND_DELIVERY_FIFO = _pywrapcp.RoutingModel_PICKUP_AND_DELIVERY_FIFO
+    r""" Deliveries must be performed in the same order as pickups."""
+
+    def __init__(self, *args):
+        _pywrapcp.RoutingModel_swiginit(self, _pywrapcp.new_RoutingModel(*args))
+    __swig_destroy__ = _pywrapcp.delete_RoutingModel
+
+    def RegisterUnaryTransitVector(self, values: "std::vector< int64_t >") -> "int":
+        r""" Registers 'callback' and returns its index."""
+        return _pywrapcp.RoutingModel_RegisterUnaryTransitVector(self, values)
+
+    def RegisterUnaryTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback1") -> "int":
+        return _pywrapcp.RoutingModel_RegisterUnaryTransitCallback(self, callback)
+
+    def RegisterPositiveUnaryTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback1") -> "int":
+        return _pywrapcp.RoutingModel_RegisterPositiveUnaryTransitCallback(self, callback)
+
+    def RegisterTransitMatrix(self, values: "std::vector< std::vector< int64_t > >") -> "int":
+        return _pywrapcp.RoutingModel_RegisterTransitMatrix(self, values)
+
+    def RegisterTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback2") -> "int":
+        return _pywrapcp.RoutingModel_RegisterTransitCallback(self, callback)
+
+    def RegisterPositiveTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback2") -> "int":
+        return _pywrapcp.RoutingModel_RegisterPositiveTransitCallback(self, callback)
+
+    def TransitCallback(self, callback_index: "int") -> "operations_research::RoutingModel::TransitCallback2 const &":
+        return _pywrapcp.RoutingModel_TransitCallback(self, callback_index)
+
+    def UnaryTransitCallbackOrNull(self, callback_index: "int") -> "operations_research::RoutingModel::TransitCallback1 const &":
+        return _pywrapcp.RoutingModel_UnaryTransitCallbackOrNull(self, callback_index)
+
+    def AddDimension(self, evaluator_index: "int", slack_max: "int64_t", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
+        r""" Model creation Methods to add dimensions to routes; dimensions represent quantities accumulated at nodes along the routes. They represent quantities such as weights or volumes carried along the route, or distance or times. Quantities at a node are represented by "cumul" variables and the increase or decrease of quantities between nodes are represented by "transit" variables. These variables are linked as follows: if j == next(i), cumul(j) = cumul(i) + transit(i) + slack(i) where slack is a positive slack variable (can represent waiting times for a time dimension). Setting the value of fix_start_cumul_to_zero to true will force the "cumul" variable of the start node of all vehicles to be equal to 0. Creates a dimension where the transit variable is constrained to be equal to evaluator(i, next(i)); 'slack_max' is the upper bound of the slack variable and 'capacity' is the upper bound of the cumul variables. 'name' is the name used to reference the dimension; this name is used to get cumul and transit variables from the routing model. Returns false if a dimension with the same name has already been created (and doesn't create the new dimension). Takes ownership of the callback 'evaluator'."""
+        return _pywrapcp.RoutingModel_AddDimension(self, evaluator_index, slack_max, capacity, fix_start_cumul_to_zero, name)
+
+    def AddDimensionWithVehicleTransits(self, evaluator_indices: "std::vector< int > const &", slack_max: "int64_t", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
+        return _pywrapcp.RoutingModel_AddDimensionWithVehicleTransits(self, evaluator_indices, slack_max, capacity, fix_start_cumul_to_zero, name)
+
+    def AddDimensionWithVehicleCapacity(self, evaluator_index: "int", slack_max: "int64_t", vehicle_capacities: "std::vector< int64_t >", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
+        return _pywrapcp.RoutingModel_AddDimensionWithVehicleCapacity(self, evaluator_index, slack_max, vehicle_capacities, fix_start_cumul_to_zero, name)
+
+    def AddDimensionWithVehicleTransitAndCapacity(self, evaluator_indices: "std::vector< int > const &", slack_max: "int64_t", vehicle_capacities: "std::vector< int64_t >", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
+        return _pywrapcp.RoutingModel_AddDimensionWithVehicleTransitAndCapacity(self, evaluator_indices, slack_max, vehicle_capacities, fix_start_cumul_to_zero, name)
+
+    def AddConstantDimensionWithSlack(self, value: "int64_t", capacity: "int64_t", slack_max: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
+        r""" Creates a dimension where the transit variable is constrained to be equal to 'value'; 'capacity' is the upper bound of the cumul variables. 'name' is the name used to reference the dimension; this name is used to get cumul and transit variables from the routing model. Returns a pair consisting of an index to the registered unary transit callback and a bool denoting whether the dimension has been created. It is false if a dimension with the same name has already been created (and doesn't create the new dimension but still register a new callback)."""
+        return _pywrapcp.RoutingModel_AddConstantDimensionWithSlack(self, value, capacity, slack_max, fix_start_cumul_to_zero, name)
+
+    def AddConstantDimension(self, value: "int64_t", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
+        return _pywrapcp.RoutingModel_AddConstantDimension(self, value, capacity, fix_start_cumul_to_zero, name)
+
+    def AddVectorDimension(self, values: "std::vector< int64_t >", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
+        r""" Creates a dimension where the transit variable is constrained to be equal to 'values[i]' for node i; 'capacity' is the upper bound of the cumul variables. 'name' is the name used to reference the dimension; this name is used to get cumul and transit variables from the routing model. Returns a pair consisting of an index to the registered unary transit callback and a bool denoting whether the dimension has been created. It is false if a dimension with the same name has already been created (and doesn't create the new dimension but still register a new callback)."""
+        return _pywrapcp.RoutingModel_AddVectorDimension(self, values, capacity, fix_start_cumul_to_zero, name)
+
+    def AddMatrixDimension(self, values: "std::vector< std::vector< int64_t > >", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
+        r""" Creates a dimension where the transit variable is constrained to be equal to 'values[i][next(i)]' for node i; 'capacity' is the upper bound of the cumul variables. 'name' is the name used to reference the dimension; this name is used to get cumul and transit variables from the routing model. Returns a pair consisting of an index to the registered transit callback and a bool denoting whether the dimension has been created. It is false if a dimension with the same name has already been created (and doesn't create the new dimension but still register a new callback)."""
+        return _pywrapcp.RoutingModel_AddMatrixDimension(self, values, capacity, fix_start_cumul_to_zero, name)
+
+    def MakePathSpansAndTotalSlacks(self, dimension: "RoutingDimension", spans: "std::vector< operations_research::IntVar * >", total_slacks: "std::vector< operations_research::IntVar * >") -> "operations_research::Constraint *":
+        r""" For every vehicle of the routing model: - if total_slacks[vehicle] is not nullptr, constrains it to be the sum of   slacks on that vehicle, that is,   dimension->CumulVar(end) - dimension->CumulVar(start) -   sum_{node in path of vehicle} dimension->FixedTransitVar(node). - if spans[vehicle] is not nullptr, constrains it to be   dimension->CumulVar(end) - dimension->CumulVar(start) This does stronger propagation than a decomposition, and takes breaks into account."""
+        return _pywrapcp.RoutingModel_MakePathSpansAndTotalSlacks(self, dimension, spans, total_slacks)
+
+    def GetAllDimensionNames(self) -> "std::vector< std::string >":
+        r""" Outputs the names of all dimensions added to the routing engine."""
+        return _pywrapcp.RoutingModel_GetAllDimensionNames(self)
+
+    def GetDimensions(self) -> "std::vector< operations_research::RoutingDimension * > const &":
+        r""" Returns all dimensions of the model."""
+        return _pywrapcp.RoutingModel_GetDimensions(self)
+
+    def GetDimensionsWithSoftOrSpanCosts(self) -> "std::vector< operations_research::RoutingDimension * >":
+        r""" Returns dimensions with soft or vehicle span costs."""
+        return _pywrapcp.RoutingModel_GetDimensionsWithSoftOrSpanCosts(self)
+
+    def GetGlobalDimensionCumulOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::GlobalDimensionCumulOptimizer > > const &":
+        r""" Returns [global|local]_dimension_optimizers_, which are empty if the model has not been closed."""
+        return _pywrapcp.RoutingModel_GetGlobalDimensionCumulOptimizers(self)
+
+    def GetGlobalDimensionCumulMPOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::GlobalDimensionCumulOptimizer > > const &":
+        return _pywrapcp.RoutingModel_GetGlobalDimensionCumulMPOptimizers(self)
+
+    def GetLocalDimensionCumulOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::LocalDimensionCumulOptimizer > > const &":
+        return _pywrapcp.RoutingModel_GetLocalDimensionCumulOptimizers(self)
+
+    def GetLocalDimensionCumulMPOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::LocalDimensionCumulOptimizer > > const &":
+        return _pywrapcp.RoutingModel_GetLocalDimensionCumulMPOptimizers(self)
+
+    def GetMutableGlobalCumulOptimizer(self, dimension: "RoutingDimension") -> "operations_research::GlobalDimensionCumulOptimizer *":
+        r""" Returns the global/local dimension cumul optimizer for a given dimension, or nullptr if there is none."""
+        return _pywrapcp.RoutingModel_GetMutableGlobalCumulOptimizer(self, dimension)
+
+    def GetMutableGlobalCumulMPOptimizer(self, dimension: "RoutingDimension") -> "operations_research::GlobalDimensionCumulOptimizer *":
+        return _pywrapcp.RoutingModel_GetMutableGlobalCumulMPOptimizer(self, dimension)
+
+    def GetMutableLocalCumulOptimizer(self, dimension: "RoutingDimension") -> "operations_research::LocalDimensionCumulOptimizer *":
+        return _pywrapcp.RoutingModel_GetMutableLocalCumulOptimizer(self, dimension)
+
+    def GetMutableLocalCumulMPOptimizer(self, dimension: "RoutingDimension") -> "operations_research::LocalDimensionCumulOptimizer *":
+        return _pywrapcp.RoutingModel_GetMutableLocalCumulMPOptimizer(self, dimension)
+
+    def HasDimension(self, dimension_name: "std::string const &") -> "bool":
+        r""" Returns true if a dimension exists for a given dimension name."""
+        return _pywrapcp.RoutingModel_HasDimension(self, dimension_name)
+
+    def GetDimensionOrDie(self, dimension_name: "std::string const &") -> "operations_research::RoutingDimension const &":
+        r""" Returns a dimension from its name. Dies if the dimension does not exist."""
+        return _pywrapcp.RoutingModel_GetDimensionOrDie(self, dimension_name)
+
+    def GetMutableDimension(self, dimension_name: "std::string const &") -> "operations_research::RoutingDimension *":
+        r""" Returns a dimension from its name. Returns nullptr if the dimension does not exist."""
+        return _pywrapcp.RoutingModel_GetMutableDimension(self, dimension_name)
+
+    def SetPrimaryConstrainedDimension(self, dimension_name: "std::string const &") -> "void":
+        r""" Set the given dimension as "primary constrained". As of August 2013, this is only used by ArcIsMoreConstrainedThanArc(). "dimension" must be the name of an existing dimension, or be empty, in which case there will not be a primary dimension after this call."""
+        return _pywrapcp.RoutingModel_SetPrimaryConstrainedDimension(self, dimension_name)
+
+    def GetPrimaryConstrainedDimension(self) -> "std::string const &":
+        r""" Get the primary constrained dimension, or an empty string if it is unset."""
+        return _pywrapcp.RoutingModel_GetPrimaryConstrainedDimension(self)
+
+    def GetDimensionResourceGroupIndices(self, dimension: "RoutingDimension") -> "std::vector< int > const &":
+        r""" Returns the indices of resource groups for this dimension. This method can only be called after the model has been closed."""
+        return _pywrapcp.RoutingModel_GetDimensionResourceGroupIndices(self, dimension)
+
+    def AddDisjunction(self, *args) -> "operations_research::RoutingModel::DisjunctionIndex":
+        r""" Adds a disjunction constraint on the indices: exactly 'max_cardinality' of the indices are active. Start and end indices of any vehicle cannot be part of a disjunction. If a penalty is given, at most 'max_cardinality' of the indices can be active, and if less are active, 'penalty' is payed per inactive index. This is equivalent to adding the constraint:     p + Sum(i)active[i] == max_cardinality where p is an integer variable, and the following cost to the cost function:     p * penalty. 'penalty' must be positive to make the disjunction optional; a negative penalty will force 'max_cardinality' indices of the disjunction to be performed, and therefore p == 0. Note: passing a vector with a single index will model an optional index with a penalty cost if it is not visited."""
+        return _pywrapcp.RoutingModel_AddDisjunction(self, *args)
+
+    def GetDisjunctionIndices(self, index: "int64_t") -> "std::vector< operations_research::RoutingModel::DisjunctionIndex > const &":
+        r""" Returns the indices of the disjunctions to which an index belongs."""
+        return _pywrapcp.RoutingModel_GetDisjunctionIndices(self, index)
+
+    def GetDisjunctionPenalty(self, index: "operations_research::RoutingModel::DisjunctionIndex") -> "int64_t":
+        r""" Returns the penalty of the node disjunction of index 'index'."""
+        return _pywrapcp.RoutingModel_GetDisjunctionPenalty(self, index)
+
+    def GetDisjunctionMaxCardinality(self, index: "operations_research::RoutingModel::DisjunctionIndex") -> "int64_t":
+        r""" Returns the maximum number of possible active nodes of the node disjunction of index 'index'."""
+        return _pywrapcp.RoutingModel_GetDisjunctionMaxCardinality(self, index)
+
+    def GetNumberOfDisjunctions(self) -> "int":
+        r""" Returns the number of node disjunctions in the model."""
+        return _pywrapcp.RoutingModel_GetNumberOfDisjunctions(self)
+
+    def GetPerfectBinaryDisjunctions(self) -> "std::vector< std::pair< int64_t,int64_t > >":
+        r""" Returns the list of all perfect binary disjunctions, as pairs of variable indices: a disjunction is "perfect" when its variables do not appear in any other disjunction. Each pair is sorted (lowest variable index first), and the output vector is also sorted (lowest pairs first)."""
+        return _pywrapcp.RoutingModel_GetPerfectBinaryDisjunctions(self)
+
+    def IgnoreDisjunctionsAlreadyForcedToZero(self) -> "void":
+        r""" SPECIAL: Makes the solver ignore all the disjunctions whose active variables are all trivially zero (i.e. Max() == 0), by setting their max_cardinality to 0. This can be useful when using the BaseBinaryDisjunctionNeighborhood operators, in the context of arc-based routing."""
+        return _pywrapcp.RoutingModel_IgnoreDisjunctionsAlreadyForcedToZero(self)
+
+    def AddSoftSameVehicleConstraint(self, indices: "std::vector< int64_t > const &", cost: "int64_t") -> "void":
+        r""" Adds a soft constraint to force a set of variable indices to be on the same vehicle. If all nodes are not on the same vehicle, each extra vehicle used adds 'cost' to the cost function."""
+        return _pywrapcp.RoutingModel_AddSoftSameVehicleConstraint(self, indices, cost)
+
+    def SetAllowedVehiclesForIndex(self, vehicles: "std::vector< int > const &", index: "int64_t") -> "void":
+        r""" Sets the vehicles which can visit a given node. If the node is in a disjunction, this will not prevent it from being unperformed. Specifying an empty vector of vehicles has no effect (all vehicles will be allowed to visit the node)."""
+        return _pywrapcp.RoutingModel_SetAllowedVehiclesForIndex(self, vehicles, index)
+
+    def IsVehicleAllowedForIndex(self, vehicle: "int", index: "int64_t") -> "bool":
+        r""" Returns true if a vehicle is allowed to visit a given node."""
+        return _pywrapcp.RoutingModel_IsVehicleAllowedForIndex(self, vehicle, index)
+
+    def AddPickupAndDelivery(self, pickup: "int64_t", delivery: "int64_t") -> "void":
+        r""" Notifies that index1 and index2 form a pair of nodes which should belong to the same route. This methods helps the search find better solutions, especially in the local search phase. It should be called each time you have an equality constraint linking the vehicle variables of two node (including for instance pickup and delivery problems):     Solver* const solver = routing.solver();     int64_t index1 = manager.NodeToIndex(node1);     int64_t index2 = manager.NodeToIndex(node2);     solver->AddConstraint(solver->MakeEquality(         routing.VehicleVar(index1),         routing.VehicleVar(index2)));     routing.AddPickupAndDelivery(index1, index2);"""
+        return _pywrapcp.RoutingModel_AddPickupAndDelivery(self, pickup, delivery)
+
+    def AddPickupAndDeliverySets(self, pickup_disjunction: "operations_research::RoutingModel::DisjunctionIndex", delivery_disjunction: "operations_research::RoutingModel::DisjunctionIndex") -> "void":
+        r""" Same as AddPickupAndDelivery but notifying that the performed node from the disjunction of index 'pickup_disjunction' is on the same route as the performed node from the disjunction of index 'delivery_disjunction'."""
+        return _pywrapcp.RoutingModel_AddPickupAndDeliverySets(self, pickup_disjunction, delivery_disjunction)
+
+    def GetPickupIndexPairs(self, node_index: "int64_t") -> "std::vector< std::pair< int,int > > const &":
+        r""" Returns pairs for which the node is a pickup; the first element of each pair is the index in the pickup and delivery pairs list in which the pickup appears, the second element is its index in the pickups list."""
+        return _pywrapcp.RoutingModel_GetPickupIndexPairs(self, node_index)
+
+    def GetDeliveryIndexPairs(self, node_index: "int64_t") -> "std::vector< std::pair< int,int > > const &":
+        r""" Same as above for deliveries."""
+        return _pywrapcp.RoutingModel_GetDeliveryIndexPairs(self, node_index)
+
+    def SetPickupAndDeliveryPolicyOfAllVehicles(self, policy: "operations_research::RoutingModel::PickupAndDeliveryPolicy") -> "void":
+        r""" Sets the Pickup and delivery policy of all vehicles. It is equivalent to calling SetPickupAndDeliveryPolicyOfVehicle on all vehicles."""
+        return _pywrapcp.RoutingModel_SetPickupAndDeliveryPolicyOfAllVehicles(self, policy)
+
+    def SetPickupAndDeliveryPolicyOfVehicle(self, policy: "operations_research::RoutingModel::PickupAndDeliveryPolicy", vehicle: "int") -> "void":
+        return _pywrapcp.RoutingModel_SetPickupAndDeliveryPolicyOfVehicle(self, policy, vehicle)
+
+    def GetPickupAndDeliveryPolicyOfVehicle(self, vehicle: "int") -> "operations_research::RoutingModel::PickupAndDeliveryPolicy":
+        return _pywrapcp.RoutingModel_GetPickupAndDeliveryPolicyOfVehicle(self, vehicle)
+
+    def GetNumOfSingletonNodes(self) -> "int":
+        r""" Returns the number of non-start/end nodes which do not appear in a pickup/delivery pair."""
+        return _pywrapcp.RoutingModel_GetNumOfSingletonNodes(self)
+    TYPE_ADDED_TO_VEHICLE = _pywrapcp.RoutingModel_TYPE_ADDED_TO_VEHICLE
+    r""" When visited, the number of types 'T' on the vehicle increases by one."""
+    ADDED_TYPE_REMOVED_FROM_VEHICLE = _pywrapcp.RoutingModel_ADDED_TYPE_REMOVED_FROM_VEHICLE
+    r""" When visited, one instance of type 'T' previously added to the route (TYPE_ADDED_TO_VEHICLE), if any, is removed from the vehicle. If the type was not previously added to the route or all added instances have already been removed, this visit has no effect on the types."""
+    TYPE_ON_VEHICLE_UP_TO_VISIT = _pywrapcp.RoutingModel_TYPE_ON_VEHICLE_UP_TO_VISIT
+    r""" With the following policy, the visit enforces that type 'T' is considered on the route from its start until this node is visited."""
+    TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED = _pywrapcp.RoutingModel_TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED
+    r""" The visit doesn't have an impact on the number of types 'T' on the route, as it's (virtually) added and removed directly. This policy can be used for visits which are part of an incompatibility or requirement set without affecting the type count on the route."""
+
+    def SetVisitType(self, index: "int64_t", type: "int", type_policy: "operations_research::RoutingModel::VisitTypePolicy") -> "void":
+        return _pywrapcp.RoutingModel_SetVisitType(self, index, type, type_policy)
+
+    def GetVisitType(self, index: "int64_t") -> "int":
+        return _pywrapcp.RoutingModel_GetVisitType(self, index)
+
+    def GetSingleNodesOfType(self, type: "int") -> "std::vector< int > const &":
+        return _pywrapcp.RoutingModel_GetSingleNodesOfType(self, type)
+
+    def GetPairIndicesOfType(self, type: "int") -> "std::vector< int > const &":
+        return _pywrapcp.RoutingModel_GetPairIndicesOfType(self, type)
+
+    def GetVisitTypePolicy(self, index: "int64_t") -> "operations_research::RoutingModel::VisitTypePolicy":
+        return _pywrapcp.RoutingModel_GetVisitTypePolicy(self, index)
+
+    def CloseVisitTypes(self) -> "void":
+        r""" This function should be called once all node visit types have been set and prior to adding any incompatibilities/requirements. "close" types."""
+        return _pywrapcp.RoutingModel_CloseVisitTypes(self)
+
+    def GetNumberOfVisitTypes(self) -> "int":
+        return _pywrapcp.RoutingModel_GetNumberOfVisitTypes(self)
+
+    def AddHardTypeIncompatibility(self, type1: "int", type2: "int") -> "void":
+        r""" Incompatibilities: Two nodes with "hard" incompatible types cannot share the same route at all, while with a "temporal" incompatibility they can't be on the same route at the same time."""
+        return _pywrapcp.RoutingModel_AddHardTypeIncompatibility(self, type1, type2)
+
+    def AddTemporalTypeIncompatibility(self, type1: "int", type2: "int") -> "void":
+        return _pywrapcp.RoutingModel_AddTemporalTypeIncompatibility(self, type1, type2)
+
+    def GetHardTypeIncompatibilitiesOfType(self, type: "int") -> "absl::flat_hash_set< int > const &":
+        r""" Returns visit types incompatible with a given type."""
+        return _pywrapcp.RoutingModel_GetHardTypeIncompatibilitiesOfType(self, type)
+
+    def GetTemporalTypeIncompatibilitiesOfType(self, type: "int") -> "absl::flat_hash_set< int > const &":
+        return _pywrapcp.RoutingModel_GetTemporalTypeIncompatibilitiesOfType(self, type)
+
+    def HasHardTypeIncompatibilities(self) -> "bool":
+        r""" Returns true iff any hard (resp. temporal) type incompatibilities have been added to the model."""
+        return _pywrapcp.RoutingModel_HasHardTypeIncompatibilities(self)
+
+    def HasTemporalTypeIncompatibilities(self) -> "bool":
+        return _pywrapcp.RoutingModel_HasTemporalTypeIncompatibilities(self)
+
+    def AddSameVehicleRequiredTypeAlternatives(self, dependent_type: "int", required_type_alternatives: "absl::flat_hash_set< int >") -> "void":
+        r""" Requirements: NOTE: As of 2019-04, cycles in the requirement graph are not supported, and lead to the dependent nodes being skipped if possible (otherwise the model is considered infeasible). The following functions specify that "dependent_type" requires at least one of the types in "required_type_alternatives". For same-vehicle requirements, a node of dependent type type_D requires at least one node of type type_R among the required alternatives on the same route."""
+        return _pywrapcp.RoutingModel_AddSameVehicleRequiredTypeAlternatives(self, dependent_type, required_type_alternatives)
+
+    def AddRequiredTypeAlternativesWhenAddingType(self, dependent_type: "int", required_type_alternatives: "absl::flat_hash_set< int >") -> "void":
+        r""" If type_D depends on type_R when adding type_D, any node_D of type_D and VisitTypePolicy TYPE_ADDED_TO_VEHICLE or TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED requires at least one type_R on its vehicle at the time node_D is visited."""
+        return _pywrapcp.RoutingModel_AddRequiredTypeAlternativesWhenAddingType(self, dependent_type, required_type_alternatives)
+
+    def AddRequiredTypeAlternativesWhenRemovingType(self, dependent_type: "int", required_type_alternatives: "absl::flat_hash_set< int >") -> "void":
+        r""" The following requirements apply when visiting dependent nodes that remove their type from the route, i.e. type_R must be on the vehicle when type_D of VisitTypePolicy ADDED_TYPE_REMOVED_FROM_VEHICLE, TYPE_ON_VEHICLE_UP_TO_VISIT or TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED is visited."""
+        return _pywrapcp.RoutingModel_AddRequiredTypeAlternativesWhenRemovingType(self, dependent_type, required_type_alternatives)
+
+    def GetSameVehicleRequiredTypeAlternativesOfType(self, type: "int") -> "std::vector< absl::flat_hash_set< int > > const &":
+        r""" Returns the set of same-vehicle requirement alternatives for the given type."""
+        return _pywrapcp.RoutingModel_GetSameVehicleRequiredTypeAlternativesOfType(self, type)
+
+    def GetRequiredTypeAlternativesWhenAddingType(self, type: "int") -> "std::vector< absl::flat_hash_set< int > > const &":
+        r""" Returns the set of requirement alternatives when adding the given type."""
+        return _pywrapcp.RoutingModel_GetRequiredTypeAlternativesWhenAddingType(self, type)
+
+    def GetRequiredTypeAlternativesWhenRemovingType(self, type: "int") -> "std::vector< absl::flat_hash_set< int > > const &":
+        r""" Returns the set of requirement alternatives when removing the given type."""
+        return _pywrapcp.RoutingModel_GetRequiredTypeAlternativesWhenRemovingType(self, type)
+
+    def HasSameVehicleTypeRequirements(self) -> "bool":
+        r""" Returns true iff any same-route (resp. temporal) type requirements have been added to the model."""
+        return _pywrapcp.RoutingModel_HasSameVehicleTypeRequirements(self)
+
+    def HasTemporalTypeRequirements(self) -> "bool":
+        return _pywrapcp.RoutingModel_HasTemporalTypeRequirements(self)
+
+    def HasTypeRegulations(self) -> "bool":
+        r""" Returns true iff the model has any incompatibilities or requirements set on node types."""
+        return _pywrapcp.RoutingModel_HasTypeRegulations(self)
+
+    def UnperformedPenalty(self, var_index: "int64_t") -> "int64_t":
+        r""" Get the "unperformed" penalty of a node. This is only well defined if the node is only part of a single Disjunction, and that disjunction has a penalty. For forced active nodes returns max int64_t. In all other cases, this returns 0."""
+        return _pywrapcp.RoutingModel_UnperformedPenalty(self, var_index)
+
+    def UnperformedPenaltyOrValue(self, default_value: "int64_t", var_index: "int64_t") -> "int64_t":
+        r""" Same as above except that it returns default_value instead of 0 when penalty is not well defined (default value is passed as first argument to simplify the usage of the method in a callback)."""
+        return _pywrapcp.RoutingModel_UnperformedPenaltyOrValue(self, default_value, var_index)
+
+    def GetDepot(self) -> "int64_t":
+        r""" Returns the variable index of the first starting or ending node of all routes. If all routes start  and end at the same node (single depot), this is the node returned."""
+        return _pywrapcp.RoutingModel_GetDepot(self)
+
+    def SetMaximumNumberOfActiveVehicles(self, max_active_vehicles: "int") -> "void":
+        r""" Constrains the maximum number of active vehicles, aka the number of vehicles which do not have an empty route. For instance, this can be used to limit the number of routes in the case where there are fewer drivers than vehicles and that the fleet of vehicle is heterogeneous."""
+        return _pywrapcp.RoutingModel_SetMaximumNumberOfActiveVehicles(self, max_active_vehicles)
+
+    def GetMaximumNumberOfActiveVehicles(self) -> "int":
+        r""" Returns the maximum number of active vehicles."""
+        return _pywrapcp.RoutingModel_GetMaximumNumberOfActiveVehicles(self)
+
+    def SetArcCostEvaluatorOfAllVehicles(self, evaluator_index: "int") -> "void":
+        r""" Sets the cost function of the model such that the cost of a segment of a route between node 'from' and 'to' is evaluator(from, to), whatever the route or vehicle performing the route."""
+        return _pywrapcp.RoutingModel_SetArcCostEvaluatorOfAllVehicles(self, evaluator_index)
+
+    def SetArcCostEvaluatorOfVehicle(self, evaluator_index: "int", vehicle: "int") -> "void":
+        r""" Sets the cost function for a given vehicle route."""
+        return _pywrapcp.RoutingModel_SetArcCostEvaluatorOfVehicle(self, evaluator_index, vehicle)
+
+    def SetFixedCostOfAllVehicles(self, cost: "int64_t") -> "void":
+        r""" Sets the fixed cost of all vehicle routes. It is equivalent to calling SetFixedCostOfVehicle on all vehicle routes."""
+        return _pywrapcp.RoutingModel_SetFixedCostOfAllVehicles(self, cost)
+
+    def SetFixedCostOfVehicle(self, cost: "int64_t", vehicle: "int") -> "void":
+        r""" Sets the fixed cost of one vehicle route."""
+        return _pywrapcp.RoutingModel_SetFixedCostOfVehicle(self, cost, vehicle)
+
+    def GetFixedCostOfVehicle(self, vehicle: "int") -> "int64_t":
+        r""" Returns the route fixed cost taken into account if the route of the vehicle is not empty, aka there's at least one node on the route other than the first and last nodes."""
+        return _pywrapcp.RoutingModel_GetFixedCostOfVehicle(self, vehicle)
+
+    def SetAmortizedCostFactorsOfAllVehicles(self, linear_cost_factor: "int64_t", quadratic_cost_factor: "int64_t") -> "void":
+        r""" The following methods set the linear and quadratic cost factors of vehicles (must be positive values). The default value of these parameters is zero for all vehicles. When set, the cost_ of the model will contain terms aiming at reducing the number of vehicles used in the model, by adding the following to the objective for every vehicle v: INDICATOR(v used in the model) *   [linear_cost_factor_of_vehicle_[v]    - quadratic_cost_factor_of_vehicle_[v]*(square of length of route v)] i.e. for every used vehicle, we add the linear factor as fixed cost, and subtract the square of the route length multiplied by the quadratic factor. This second term aims at making the routes as dense as possible. Sets the linear and quadratic cost factor of all vehicles."""
+        return _pywrapcp.RoutingModel_SetAmortizedCostFactorsOfAllVehicles(self, linear_cost_factor, quadratic_cost_factor)
+
+    def SetAmortizedCostFactorsOfVehicle(self, linear_cost_factor: "int64_t", quadratic_cost_factor: "int64_t", vehicle: "int") -> "void":
+        r""" Sets the linear and quadratic cost factor of the given vehicle."""
+        return _pywrapcp.RoutingModel_SetAmortizedCostFactorsOfVehicle(self, linear_cost_factor, quadratic_cost_factor, vehicle)
+
+    def GetAmortizedLinearCostFactorOfVehicles(self) -> "std::vector< int64_t > const &":
+        return _pywrapcp.RoutingModel_GetAmortizedLinearCostFactorOfVehicles(self)
+
+    def GetAmortizedQuadraticCostFactorOfVehicles(self) -> "std::vector< int64_t > const &":
+        return _pywrapcp.RoutingModel_GetAmortizedQuadraticCostFactorOfVehicles(self)
+
+    def ConsiderEmptyRouteCostsForVehicle(self, consider_costs: "bool", vehicle: "int") -> "void":
+        return _pywrapcp.RoutingModel_ConsiderEmptyRouteCostsForVehicle(self, consider_costs, vehicle)
+
+    def AreEmptyRouteCostsConsideredForVehicle(self, vehicle: "int") -> "bool":
+        return _pywrapcp.RoutingModel_AreEmptyRouteCostsConsideredForVehicle(self, vehicle)
+
+    def SetFirstSolutionEvaluator(self, evaluator: "operations_research::Solver::IndexEvaluator2") -> "void":
+        r""" Gets/sets the evaluator used during the search. Only relevant when RoutingSearchParameters.first_solution_strategy = EVALUATOR_STRATEGY. Takes ownership of evaluator."""
+        return _pywrapcp.RoutingModel_SetFirstSolutionEvaluator(self, evaluator)
+
+    def AddLocalSearchOperator(self, ls_operator: "LocalSearchOperator") -> "void":
+        r""" Adds a local search operator to the set of operators used to solve the vehicle routing problem."""
+        return _pywrapcp.RoutingModel_AddLocalSearchOperator(self, ls_operator)
+
+    def AddSearchMonitor(self, monitor: "SearchMonitor") -> "void":
+        r""" Adds a search monitor to the search used to solve the routing model."""
+        return _pywrapcp.RoutingModel_AddSearchMonitor(self, monitor)
+
+    def AddAtSolutionCallback(self, callback: "std::function< void () >") -> "void":
+        r""" Adds a callback called each time a solution is found during the search. This is a shortcut to creating a monitor to call the callback on AtSolution() and adding it with AddSearchMonitor."""
+        return _pywrapcp.RoutingModel_AddAtSolutionCallback(self, callback)
+
+    def AddVariableMinimizedByFinalizer(self, var: "IntVar") -> "void":
+        r""" Adds a variable to minimize in the solution finalizer. The solution finalizer is called each time a solution is found during the search and allows to instantiate secondary variables (such as dimension cumul variables)."""
+        return _pywrapcp.RoutingModel_AddVariableMinimizedByFinalizer(self, var)
+
+    def AddVariableMaximizedByFinalizer(self, var: "IntVar") -> "void":
+        r""" Adds a variable to maximize in the solution finalizer (see above for information on the solution finalizer)."""
+        return _pywrapcp.RoutingModel_AddVariableMaximizedByFinalizer(self, var)
+
+    def AddWeightedVariableMinimizedByFinalizer(self, var: "IntVar", cost: "int64_t") -> "void":
+        r""" Adds a variable to minimize in the solution finalizer, with a weighted priority: the higher the more priority it has."""
+        return _pywrapcp.RoutingModel_AddWeightedVariableMinimizedByFinalizer(self, var, cost)
+
+    def AddVariableTargetToFinalizer(self, var: "IntVar", target: "int64_t") -> "void":
+        r""" Add a variable to set the closest possible to the target value in the solution finalizer."""
+        return _pywrapcp.RoutingModel_AddVariableTargetToFinalizer(self, var, target)
+
+    def CloseModel(self) -> "void":
+        r""" Closes the current routing model; after this method is called, no modification to the model can be done, but RoutesToAssignment becomes available. Note that CloseModel() is automatically called by Solve() and other methods that produce solution. This is equivalent to calling CloseModelWithParameters(DefaultRoutingSearchParameters())."""
+        return _pywrapcp.RoutingModel_CloseModel(self)
+
+    def CloseModelWithParameters(self, search_parameters: "operations_research::RoutingSearchParameters const &") -> "void":
+        r""" Same as above taking search parameters (as of 10/2015 some the parameters have to be set when closing the model)."""
+        return _pywrapcp.RoutingModel_CloseModelWithParameters(self, search_parameters)
+
+    def Solve(self, assignment: "Assignment"=None) -> "operations_research::Assignment const *":
+        r""" Solves the current routing model; closes the current model. This is equivalent to calling SolveWithParameters(DefaultRoutingSearchParameters()) or SolveFromAssignmentWithParameters(assignment,                                   DefaultRoutingSearchParameters())."""
+        return _pywrapcp.RoutingModel_Solve(self, assignment)
+
+    def SolveWithParameters(self, search_parameters: "operations_research::RoutingSearchParameters const &", solutions: "std::vector< operations_research::Assignment const * > *"=None) -> "operations_research::Assignment const *":
+        r""" Solves the current routing model with the given parameters. If 'solutions' is specified, it will contain the k best solutions found during the search (from worst to best, including the one returned by this method), where k corresponds to the 'number_of_solutions_to_collect' in 'search_parameters'. Note that the Assignment returned by the method and the ones in solutions are owned by the underlying solver and should not be deleted."""
+        return _pywrapcp.RoutingModel_SolveWithParameters(self, search_parameters, solutions)
+
+    def SolveFromAssignmentWithParameters(self, assignment: "Assignment", search_parameters: "operations_research::RoutingSearchParameters const &", solutions: "std::vector< operations_research::Assignment const * > *"=None) -> "operations_research::Assignment const *":
+        r""" Same as above, except that if assignment is not null, it will be used as the initial solution."""
+        return _pywrapcp.RoutingModel_SolveFromAssignmentWithParameters(self, assignment, search_parameters, solutions)
+
+    def SolveFromAssignmentsWithParameters(self, assignments: "std::vector< operations_research::Assignment const * > const &", search_parameters: "operations_research::RoutingSearchParameters const &", solutions: "std::vector< operations_research::Assignment const * > *"=None) -> "operations_research::Assignment const *":
+        r""" Same as above but will try all assignments in order as first solutions until one succeeds."""
+        return _pywrapcp.RoutingModel_SolveFromAssignmentsWithParameters(self, assignments, search_parameters, solutions)
+
+    def SetAssignmentFromOtherModelAssignment(self, target_assignment: "Assignment", source_model: "RoutingModel", source_assignment: "Assignment") -> "void":
+        r""" Given a "source_model" and its "source_assignment", resets "target_assignment" with the IntVar variables (nexts_, and vehicle_vars_ if costs aren't homogeneous across vehicles) of "this" model, with the values set according to those in "other_assignment". The objective_element of target_assignment is set to this->cost_."""
+        return _pywrapcp.RoutingModel_SetAssignmentFromOtherModelAssignment(self, target_assignment, source_model, source_assignment)
+
+    def ComputeLowerBound(self) -> "int64_t":
+        r""" Computes a lower bound to the routing problem solving a linear assignment problem. The routing model must be closed before calling this method. Note that problems with node disjunction constraints (including optional nodes) and non-homogenous costs are not supported (the method returns 0 in these cases)."""
+        return _pywrapcp.RoutingModel_ComputeLowerBound(self)
+
+    def status(self) -> "operations_research::RoutingModel::Status":
+        r""" Returns the current status of the routing model."""
+        return _pywrapcp.RoutingModel_status(self)
+
+    def ApplyLocks(self, locks: "std::vector< int64_t > const &") -> "operations_research::IntVar *":
+        r""" Applies a lock chain to the next search. 'locks' represents an ordered vector of nodes representing a partial route which will be fixed during the next search; it will constrain next variables such that: next[locks[i]] == locks[i+1]. Returns the next variable at the end of the locked chain; this variable is not locked. An assignment containing the locks can be obtained by calling PreAssignment()."""
+        return _pywrapcp.RoutingModel_ApplyLocks(self, locks)
+
+    def ApplyLocksToAllVehicles(self, locks: "std::vector< std::vector< int64_t > > const &", close_routes: "bool") -> "bool":
+        r""" Applies lock chains to all vehicles to the next search, such that locks[p] is the lock chain for route p. Returns false if the locks do not contain valid routes; expects that the routes do not contain the depots, i.e. there are empty vectors in place of empty routes. If close_routes is set to true, adds the end nodes to the route of each vehicle and deactivates other nodes. An assignment containing the locks can be obtained by calling PreAssignment()."""
+        return _pywrapcp.RoutingModel_ApplyLocksToAllVehicles(self, locks, close_routes)
+
+    def PreAssignment(self) -> "operations_research::Assignment const *const":
+        r""" Returns an assignment used to fix some of the variables of the problem. In practice, this assignment locks partial routes of the problem. This can be used in the context of locking the parts of the routes which have already been driven in online routing problems."""
+        return _pywrapcp.RoutingModel_PreAssignment(self)
+
+    def MutablePreAssignment(self) -> "operations_research::Assignment *":
+        return _pywrapcp.RoutingModel_MutablePreAssignment(self)
+
+    def WriteAssignment(self, file_name: "std::string const &") -> "bool":
+        r""" Writes the current solution to a file containing an AssignmentProto. Returns false if the file cannot be opened or if there is no current solution."""
+        return _pywrapcp.RoutingModel_WriteAssignment(self, file_name)
+
+    def ReadAssignment(self, file_name: "std::string const &") -> "operations_research::Assignment *":
+        r""" Reads an assignment from a file and returns the current solution. Returns nullptr if the file cannot be opened or if the assignment is not valid."""
+        return _pywrapcp.RoutingModel_ReadAssignment(self, file_name)
+
+    def RestoreAssignment(self, solution: "Assignment") -> "operations_research::Assignment *":
+        r""" Restores an assignment as a solution in the routing model and returns the new solution. Returns nullptr if the assignment is not valid."""
+        return _pywrapcp.RoutingModel_RestoreAssignment(self, solution)
+
+    def ReadAssignmentFromRoutes(self, routes: "std::vector< std::vector< int64_t > > const &", ignore_inactive_indices: "bool") -> "operations_research::Assignment *":
+        r""" Restores the routes as the current solution. Returns nullptr if the solution cannot be restored (routes do not contain a valid solution). Note that calling this method will run the solver to assign values to the dimension variables; this may take considerable amount of time, especially when using dimensions with slack."""
+        return _pywrapcp.RoutingModel_ReadAssignmentFromRoutes(self, routes, ignore_inactive_indices)
+
+    def RoutesToAssignment(self, routes: "std::vector< std::vector< int64_t > > const &", ignore_inactive_indices: "bool", close_routes: "bool", assignment: "Assignment") -> "bool":
+        r""" Fills an assignment from a specification of the routes of the vehicles. The routes are specified as lists of variable indices that appear on the routes of the vehicles. The indices of the outer vector in 'routes' correspond to vehicles IDs, the inner vector contains the variable indices on the routes for the given vehicle. The inner vectors must not contain the start and end indices, as these are determined by the routing model.  Sets the value of NextVars in the assignment, adding the variables to the assignment if necessary. The method does not touch other variables in the assignment. The method can only be called after the model is closed.  With ignore_inactive_indices set to false, this method will fail (return nullptr) in case some of the route contain indices that are deactivated in the model; when set to true, these indices will be skipped.  Returns true if routes were successfully loaded. However, such assignment still might not be a valid solution to the routing problem due to more complex constraints; it is advisible to call solver()->CheckSolution() afterwards."""
+        return _pywrapcp.RoutingModel_RoutesToAssignment(self, routes, ignore_inactive_indices, close_routes, assignment)
+
+    def AssignmentToRoutes(self, assignment: "Assignment", routes: "std::vector< std::vector< int64_t > > *const") -> "void":
+        r""" Converts the solution in the given assignment to routes for all vehicles. Expects that assignment contains a valid solution (i.e. routes for all vehicles end with an end index for that vehicle)."""
+        return _pywrapcp.RoutingModel_AssignmentToRoutes(self, assignment, routes)
+
+    def CompactAssignment(self, assignment: "Assignment") -> "operations_research::Assignment *":
+        r""" Converts the solution in the given assignment to routes for all vehicles. If the returned vector is route_indices, route_indices[i][j] is the index for jth location visited on route i. Note that contrary to AssignmentToRoutes, the vectors do include start and end locations. Returns a compacted version of the given assignment, in which all vehicles with id lower or equal to some N have non-empty routes, and all vehicles with id greater than N have empty routes. Does not take ownership of the returned object. If found, the cost of the compact assignment is the same as in the original assignment and it preserves the values of 'active' variables. Returns nullptr if a compact assignment was not found. This method only works in homogenous mode, and it only swaps equivalent vehicles (vehicles with the same start and end nodes). When creating the compact assignment, the empty plan is replaced by the route assigned to the compatible vehicle with the highest id. Note that with more complex constraints on vehicle variables, this method might fail even if a compact solution exists. This method changes the vehicle and dimension variables as necessary. While compacting the solution, only basic checks on vehicle variables are performed; if one of these checks fails no attempts to repair it are made (instead, the method returns nullptr)."""
+        return _pywrapcp.RoutingModel_CompactAssignment(self, assignment)
+
+    def CompactAndCheckAssignment(self, assignment: "Assignment") -> "operations_research::Assignment *":
+        r""" Same as CompactAssignment() but also checks the validity of the final compact solution; if it is not valid, no attempts to repair it are made (instead, the method returns nullptr)."""
+        return _pywrapcp.RoutingModel_CompactAndCheckAssignment(self, assignment)
+
+    def AddToAssignment(self, var: "IntVar") -> "void":
+        r""" Adds an extra variable to the vehicle routing assignment."""
+        return _pywrapcp.RoutingModel_AddToAssignment(self, var)
+
+    def AddIntervalToAssignment(self, interval: "IntervalVar") -> "void":
+        return _pywrapcp.RoutingModel_AddIntervalToAssignment(self, interval)
+
+    def PackCumulsOfOptimizerDimensionsFromAssignment(self, original_assignment: "Assignment", duration_limit: "absl::Duration") -> "operations_research::Assignment const *":
+        r""" For every dimension in the model with an optimizer in local/global_dimension_optimizers_, this method tries to pack the cumul values of the dimension, such that: - The cumul costs (span costs, soft lower and upper bound costs, etc) are   minimized. - The cumuls of the ends of the routes are minimized for this given   minimal cumul cost. - Given these minimal end cumuls, the route start cumuls are maximized. Returns the assignment resulting from allocating these packed cumuls with the solver, and nullptr if these cumuls could not be set by the solver."""
+        return _pywrapcp.RoutingModel_PackCumulsOfOptimizerDimensionsFromAssignment(self, original_assignment, duration_limit)
+
+    def AddLocalSearchFilter(self, filter: "LocalSearchFilter") -> "void":
+        r""" Adds a custom local search filter to the list of filters used to speed up local search by pruning unfeasible variable assignments. Calling this method after the routing model has been closed (CloseModel() or Solve() has been called) has no effect. The routing model does not take ownership of the filter."""
+        return _pywrapcp.RoutingModel_AddLocalSearchFilter(self, filter)
+
+    def Start(self, vehicle: "int") -> "int64_t":
+        r""" Model inspection. Returns the variable index of the starting node of a vehicle route."""
+        return _pywrapcp.RoutingModel_Start(self, vehicle)
+
+    def End(self, vehicle: "int") -> "int64_t":
+        r""" Returns the variable index of the ending node of a vehicle route."""
+        return _pywrapcp.RoutingModel_End(self, vehicle)
+
+    def IsStart(self, index: "int64_t") -> "bool":
+        r""" Returns true if 'index' represents the first node of a route."""
+        return _pywrapcp.RoutingModel_IsStart(self, index)
+
+    def IsEnd(self, index: "int64_t") -> "bool":
+        r""" Returns true if 'index' represents the last node of a route."""
+        return _pywrapcp.RoutingModel_IsEnd(self, index)
+
+    def VehicleIndex(self, index: "int64_t") -> "int":
+        r""" Returns the vehicle of the given start/end index, and -1 if the given index is not a vehicle start/end."""
+        return _pywrapcp.RoutingModel_VehicleIndex(self, index)
+
+    def Next(self, assignment: "Assignment", index: "int64_t") -> "int64_t":
+        r""" Assignment inspection Returns the variable index of the node directly after the node corresponding to 'index' in 'assignment'."""
+        return _pywrapcp.RoutingModel_Next(self, assignment, index)
+
+    def IsVehicleUsed(self, assignment: "Assignment", vehicle: "int") -> "bool":
+        r""" Returns true if the route of 'vehicle' is non empty in 'assignment'."""
+        return _pywrapcp.RoutingModel_IsVehicleUsed(self, assignment, vehicle)
+
+    def NextVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        r""" Returns the next variable of the node corresponding to index. Note that NextVar(index) == index is equivalent to ActiveVar(index) == 0."""
+        return _pywrapcp.RoutingModel_NextVar(self, index)
+
+    def ActiveVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        r""" Returns the active variable of the node corresponding to index."""
+        return _pywrapcp.RoutingModel_ActiveVar(self, index)
+
+    def ActiveVehicleVar(self, vehicle: "int") -> "operations_research::IntVar *":
+        r""" Returns the active variable of the vehicle. It will be equal to 1 iff the route of the vehicle is not empty, 0 otherwise."""
+        return _pywrapcp.RoutingModel_ActiveVehicleVar(self, vehicle)
+
+    def VehicleCostsConsideredVar(self, vehicle: "int") -> "operations_research::IntVar *":
+        r""" Returns the variable specifying whether or not costs are considered for vehicle."""
+        return _pywrapcp.RoutingModel_VehicleCostsConsideredVar(self, vehicle)
+
+    def VehicleVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        r""" Returns the vehicle variable of the node corresponding to index. Note that VehicleVar(index) == -1 is equivalent to ActiveVar(index) == 0."""
+        return _pywrapcp.RoutingModel_VehicleVar(self, index)
+
+    def CostVar(self) -> "operations_research::IntVar *":
+        r""" Returns the global cost variable which is being minimized."""
+        return _pywrapcp.RoutingModel_CostVar(self)
+
+    def GetArcCostForVehicle(self, from_index: "int64_t", to_index: "int64_t", vehicle: "int64_t") -> "int64_t":
+        r""" Returns the cost of the transit arc between two nodes for a given vehicle. Input are variable indices of node. This returns 0 if vehicle < 0."""
+        return _pywrapcp.RoutingModel_GetArcCostForVehicle(self, from_index, to_index, vehicle)
+
+    def CostsAreHomogeneousAcrossVehicles(self) -> "bool":
+        r""" Whether costs are homogeneous across all vehicles."""
+        return _pywrapcp.RoutingModel_CostsAreHomogeneousAcrossVehicles(self)
+
+    def GetHomogeneousCost(self, from_index: "int64_t", to_index: "int64_t") -> "int64_t":
+        r""" Returns the cost of the segment between two nodes supposing all vehicle costs are the same (returns the cost for the first vehicle otherwise)."""
+        return _pywrapcp.RoutingModel_GetHomogeneousCost(self, from_index, to_index)
+
+    def GetArcCostForFirstSolution(self, from_index: "int64_t", to_index: "int64_t") -> "int64_t":
+        r""" Returns the cost of the arc in the context of the first solution strategy. This is typically a simplification of the actual cost; see the .cc."""
+        return _pywrapcp.RoutingModel_GetArcCostForFirstSolution(self, from_index, to_index)
+
+    def GetArcCostForClass(self, from_index: "int64_t", to_index: "int64_t", cost_class_index: "int64_t") -> "int64_t":
+        r""" Returns the cost of the segment between two nodes for a given cost class. Input are variable indices of nodes and the cost class. Unlike GetArcCostForVehicle(), if cost_class is kNoCost, then the returned cost won't necessarily be zero: only some of the components of the cost that depend on the cost class will be omited. See the code for details."""
+        return _pywrapcp.RoutingModel_GetArcCostForClass(self, from_index, to_index, cost_class_index)
+
+    def GetCostClassIndexOfVehicle(self, vehicle: "int64_t") -> "operations_research::RoutingModel::CostClassIndex":
+        r""" Get the cost class index of the given vehicle."""
+        return _pywrapcp.RoutingModel_GetCostClassIndexOfVehicle(self, vehicle)
+
+    def HasVehicleWithCostClassIndex(self, cost_class_index: "operations_research::RoutingModel::CostClassIndex") -> "bool":
+        r""" Returns true iff the model contains a vehicle with the given cost_class_index."""
+        return _pywrapcp.RoutingModel_HasVehicleWithCostClassIndex(self, cost_class_index)
+
+    def GetCostClassesCount(self) -> "int":
+        r""" Returns the number of different cost classes in the model."""
+        return _pywrapcp.RoutingModel_GetCostClassesCount(self)
+
+    def GetNonZeroCostClassesCount(self) -> "int":
+        r""" Ditto, minus the 'always zero', built-in cost class."""
+        return _pywrapcp.RoutingModel_GetNonZeroCostClassesCount(self)
+
+    def GetVehicleClassIndexOfVehicle(self, vehicle: "int64_t") -> "operations_research::RoutingModel::VehicleClassIndex":
+        return _pywrapcp.RoutingModel_GetVehicleClassIndexOfVehicle(self, vehicle)
+
+    def GetVehicleOfClass(self, vehicle_class: "operations_research::RoutingModel::VehicleClassIndex") -> "int":
+        r""" Returns a vehicle of the given vehicle class, and -1 if there are no vehicles for this class."""
+        return _pywrapcp.RoutingModel_GetVehicleOfClass(self, vehicle_class)
+
+    def GetVehicleClassesCount(self) -> "int":
+        r""" Returns the number of different vehicle classes in the model."""
+        return _pywrapcp.RoutingModel_GetVehicleClassesCount(self)
+
+    def GetSameVehicleIndicesOfIndex(self, node: "int") -> "std::vector< int > const &":
+        r""" Returns variable indices of nodes constrained to be on the same route."""
+        return _pywrapcp.RoutingModel_GetSameVehicleIndicesOfIndex(self, node)
+
+    def GetVehicleTypeContainer(self) -> "operations_research::RoutingModel::VehicleTypeContainer const &":
+        return _pywrapcp.RoutingModel_GetVehicleTypeContainer(self)
+
+    def ArcIsMoreConstrainedThanArc(self, _from: "int64_t", to1: "int64_t", to2: "int64_t") -> "bool":
+        r""" Returns whether the arc from->to1 is more constrained than from->to2, taking into account, in order: - whether the destination node isn't an end node - whether the destination node is mandatory - whether the destination node is bound to the same vehicle as the source - the "primary constrained" dimension (see SetPrimaryConstrainedDimension) It then breaks ties using, in order: - the arc cost (taking unperformed penalties into account) - the size of the vehicle vars of "to1" and "to2" (lowest size wins) - the value: the lowest value of the indices to1 and to2 wins. See the .cc for details. The more constrained arc is typically preferable when building a first solution. This method is intended to be used as a callback for the BestValueByComparisonSelector value selector. Args:   from: the variable index of the source node   to1: the variable index of the first candidate destination node.   to2: the variable index of the second candidate destination node."""
+        return _pywrapcp.RoutingModel_ArcIsMoreConstrainedThanArc(self, _from, to1, to2)
+
+    def DebugOutputAssignment(self, solution_assignment: "Assignment", dimension_to_print: "std::string const &") -> "std::string":
+        r""" Print some debugging information about an assignment, including the feasible intervals of the CumulVar for dimension "dimension_to_print" at each step of the routes. If "dimension_to_print" is omitted, all dimensions will be printed."""
+        return _pywrapcp.RoutingModel_DebugOutputAssignment(self, solution_assignment, dimension_to_print)
+
+    def solver(self) -> "operations_research::Solver *":
+        r""" Returns a vector cumul_bounds, for which cumul_bounds[i][j] is a pair containing the minimum and maximum of the CumulVar of the jth node on route i. - cumul_bounds[i][j].first is the minimum. - cumul_bounds[i][j].second is the maximum. Returns the underlying constraint solver. Can be used to add extra constraints and/or modify search algorithms."""
+        return _pywrapcp.RoutingModel_solver(self)
+
+    def CheckLimit(self) -> "bool":
+        r""" Returns true if the search limit has been crossed."""
+        return _pywrapcp.RoutingModel_CheckLimit(self)
+
+    def RemainingTime(self) -> "absl::Duration":
+        r""" Returns the time left in the search limit."""
+        return _pywrapcp.RoutingModel_RemainingTime(self)
+
+    def nodes(self) -> "int":
+        r""" Sizes and indices Returns the number of nodes in the model."""
+        return _pywrapcp.RoutingModel_nodes(self)
+
+    def vehicles(self) -> "int":
+        r""" Returns the number of vehicle routes in the model."""
+        return _pywrapcp.RoutingModel_vehicles(self)
+
+    def Size(self) -> "int64_t":
+        r""" Returns the number of next variables in the model."""
+        return _pywrapcp.RoutingModel_Size(self)
+
+    def GetNumberOfDecisionsInFirstSolution(self, search_parameters: "operations_research::RoutingSearchParameters const &") -> "int64_t":
+        r""" Returns statistics on first solution search, number of decisions sent to filters, number of decisions rejected by filters."""
+        return _pywrapcp.RoutingModel_GetNumberOfDecisionsInFirstSolution(self, search_parameters)
+
+    def GetNumberOfRejectsInFirstSolution(self, search_parameters: "operations_research::RoutingSearchParameters const &") -> "int64_t":
+        return _pywrapcp.RoutingModel_GetNumberOfRejectsInFirstSolution(self, search_parameters)
+
+    def GetAutomaticFirstSolutionStrategy(self) -> "operations_research::FirstSolutionStrategy::Value":
+        r""" Returns the automatic first solution strategy selected."""
+        return _pywrapcp.RoutingModel_GetAutomaticFirstSolutionStrategy(self)
+
+    def IsMatchingModel(self) -> "bool":
+        r""" Returns true if a vehicle/node matching problem is detected."""
+        return _pywrapcp.RoutingModel_IsMatchingModel(self)
+
+    def MakeGuidedSlackFinalizer(self, dimension: "RoutingDimension", initializer: "std::function< int64_t (int64_t) >") -> "operations_research::DecisionBuilder *":
+        r""" The next few members are in the public section only for testing purposes. MakeGuidedSlackFinalizer creates a DecisionBuilder for the slacks of a dimension using a callback to choose which values to start with. The finalizer works only when all next variables in the model have been fixed. It has the following two characteristics: 1. It follows the routes defined by the nexts variables when choosing a    variable to make a decision on. 2. When it comes to choose a value for the slack of node i, the decision    builder first calls the callback with argument i, and supposingly the    returned value is x it creates decisions slack[i] = x, slack[i] = x +    1, slack[i] = x - 1, slack[i] = x + 2, etc."""
+        return _pywrapcp.RoutingModel_MakeGuidedSlackFinalizer(self, dimension, initializer)
+
+    def MakeSelfDependentDimensionFinalizer(self, dimension: "RoutingDimension") -> "operations_research::DecisionBuilder *":
+        r""" MakeSelfDependentDimensionFinalizer is a finalizer for the slacks of a self-dependent dimension. It makes an extensive use of the caches of the state dependent transits. In detail, MakeSelfDependentDimensionFinalizer returns a composition of a local search decision builder with a greedy descent operator for the cumul of the start of each route and a guided slack finalizer. Provided there are no time windows and the maximum slacks are large enough, once the cumul of the start of route is fixed, the guided finalizer can find optimal values of the slacks for the rest of the route in time proportional to the length of the route. Therefore the composed finalizer generally works in time O(log(t)*n*m), where t is the latest possible departute time, n is the number of nodes in the network and m is the number of vehicles."""
+        return _pywrapcp.RoutingModel_MakeSelfDependentDimensionFinalizer(self, dimension)
+
+# Register RoutingModel in _pywrapcp:
+_pywrapcp.RoutingModel_swigregister(RoutingModel)
+cvar = _pywrapcp.cvar
+RoutingModel.kNoPenalty = _pywrapcp.cvar.RoutingModel_kNoPenalty
+RoutingModel.kNoDisjunction = _pywrapcp.cvar.RoutingModel_kNoDisjunction
+RoutingModel.kNoDimension = _pywrapcp.cvar.RoutingModel_kNoDimension
+
+class RoutingModelVisitor(BaseObject):
+    r""" Routing model visitor."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self):
+        _pywrapcp.RoutingModelVisitor_swiginit(self, _pywrapcp.new_RoutingModelVisitor())
+    __swig_destroy__ = _pywrapcp.delete_RoutingModelVisitor
+
+# Register RoutingModelVisitor in _pywrapcp:
+_pywrapcp.RoutingModelVisitor_swigregister(RoutingModelVisitor)
+RoutingModelVisitor.kLightElement = _pywrapcp.cvar.RoutingModelVisitor_kLightElement
+RoutingModelVisitor.kLightElement2 = _pywrapcp.cvar.RoutingModelVisitor_kLightElement2
+RoutingModelVisitor.kRemoveValues = _pywrapcp.cvar.RoutingModelVisitor_kRemoveValues
+
+class GlobalVehicleBreaksConstraint(Constraint):
+    r""" GlobalVehicleBreaksConstraint ensures breaks constraints are enforced on all vehicles in the dimension passed to its constructor. It is intended to be used for dimensions representing time. A break constraint ensures break intervals fit on the route of a vehicle. For a given vehicle, it forces break intervals to be disjoint from visit intervals, where visit intervals start at CumulVar(node) and last for node_visit_transit[node]. Moreover, it ensures that there is enough time between two consecutive nodes of a route to do transit and vehicle breaks, i.e. if Next(nodeA) = nodeB, CumulVar(nodeA) = tA and CumulVar(nodeB) = tB, then SlackVar(nodeA) >= sum_{breaks [tA, tB)} duration(break)."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, dimension: "RoutingDimension"):
+        _pywrapcp.GlobalVehicleBreaksConstraint_swiginit(self, _pywrapcp.new_GlobalVehicleBreaksConstraint(dimension))
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.GlobalVehicleBreaksConstraint_DebugString(self)
+
+    def Post(self) -> "void":
+        return _pywrapcp.GlobalVehicleBreaksConstraint_Post(self)
+
+    def InitialPropagateWrapper(self) -> "void":
+        return _pywrapcp.GlobalVehicleBreaksConstraint_InitialPropagateWrapper(self)
+    __swig_destroy__ = _pywrapcp.delete_GlobalVehicleBreaksConstraint
+
+# Register GlobalVehicleBreaksConstraint in _pywrapcp:
+_pywrapcp.GlobalVehicleBreaksConstraint_swigregister(GlobalVehicleBreaksConstraint)
+
+class TypeRegulationsChecker(object):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+    __swig_destroy__ = _pywrapcp.delete_TypeRegulationsChecker
+
+    def CheckVehicle(self, vehicle: "int", next_accessor: "std::function< int64_t (int64_t) > const &") -> "bool":
+        return _pywrapcp.TypeRegulationsChecker_CheckVehicle(self, vehicle, next_accessor)
+
+# Register TypeRegulationsChecker in _pywrapcp:
+_pywrapcp.TypeRegulationsChecker_swigregister(TypeRegulationsChecker)
+
+class TypeIncompatibilityChecker(TypeRegulationsChecker):
+    r""" Checker for type incompatibilities."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, model: "RoutingModel", check_hard_incompatibilities: "bool"):
+        _pywrapcp.TypeIncompatibilityChecker_swiginit(self, _pywrapcp.new_TypeIncompatibilityChecker(model, check_hard_incompatibilities))
+    __swig_destroy__ = _pywrapcp.delete_TypeIncompatibilityChecker
+
+# Register TypeIncompatibilityChecker in _pywrapcp:
+_pywrapcp.TypeIncompatibilityChecker_swigregister(TypeIncompatibilityChecker)
+
+class TypeRequirementChecker(TypeRegulationsChecker):
+    r""" Checker for type requirements."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, model: "RoutingModel"):
+        _pywrapcp.TypeRequirementChecker_swiginit(self, _pywrapcp.new_TypeRequirementChecker(model))
+    __swig_destroy__ = _pywrapcp.delete_TypeRequirementChecker
+
+# Register TypeRequirementChecker in _pywrapcp:
+_pywrapcp.TypeRequirementChecker_swigregister(TypeRequirementChecker)
+
+class TypeRegulationsConstraint(Constraint):
+    r""" The following constraint ensures that incompatibilities and requirements between types are respected. It verifies both "hard" and "temporal" incompatibilities. Two nodes with hard incompatible types cannot be served by the same vehicle at all, while with a temporal incompatibility they can't be on the same route at the same time. The VisitTypePolicy of a node determines how visiting it impacts the type count on the route. For example, for - three temporally incompatible types T1 T2 and T3 - 2 pairs of nodes a1/r1 and a2/r2 of type T1 and T2 respectively, with     - a1 and a2 of VisitTypePolicy TYPE_ADDED_TO_VEHICLE     - r1 and r2 of policy ADDED_TYPE_REMOVED_FROM_VEHICLE - 3 nodes A, UV and AR of type T3, respectively with type policies   TYPE_ADDED_TO_VEHICLE, TYPE_ON_VEHICLE_UP_TO_VISIT and   TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED the configurations UV --> a1 --> r1 --> a2 --> r2,   a1 --> r1 --> a2 --> r2 --> A and a1 --> r1 --> AR --> a2 --> r2 are acceptable, whereas the configurations a1 --> a2 --> r1 --> ..., or A --> a1 --> r1 --> ..., or a1 --> r1 --> UV --> ... are not feasible. It also verifies same-vehicle and temporal type requirements. A node of type T_d with a same-vehicle requirement for type T_r needs to be served by the same vehicle as a node of type T_r. Temporal requirements, on the other hand, can take effect either when the dependent type is being added to the route or when it's removed from it, which is determined by the dependent node's VisitTypePolicy. In the above example: - If T3 is required on the same vehicle as T1, A, AR or UV must be on the   same vehicle as a1. - If T2 is required when adding T1, a2 must be visited *before* a1, and if   r2 is also visited on the route, it must be *after* a1, i.e. T2 must be on   the vehicle when a1 is visited:   ... --> a2 --> ... --> a1 --> ... --> r2 --> ... - If T3 is required when removing T1, T3 needs to be on the vehicle when   r1 is visited:   ... --> A --> ... --> r1 --> ...   OR   ... --> r1 --> ... --> UV --> ..."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, model: "RoutingModel"):
+        _pywrapcp.TypeRegulationsConstraint_swiginit(self, _pywrapcp.new_TypeRegulationsConstraint(model))
+
+    def Post(self) -> "void":
+        return _pywrapcp.TypeRegulationsConstraint_Post(self)
+
+    def InitialPropagateWrapper(self) -> "void":
+        return _pywrapcp.TypeRegulationsConstraint_InitialPropagateWrapper(self)
+    __swig_destroy__ = _pywrapcp.delete_TypeRegulationsConstraint
+
+# Register TypeRegulationsConstraint in _pywrapcp:
+_pywrapcp.TypeRegulationsConstraint_swigregister(TypeRegulationsConstraint)
+
+class RoutingDimension(object):
+    r""" Dimensions represent quantities accumulated at nodes along the routes. They represent quantities such as weights or volumes carried along the route, or distance or times. Quantities at a node are represented by "cumul" variables and the increase or decrease of quantities between nodes are represented by "transit" variables. These variables are linked as follows: if j == next(i), cumuls(j) = cumuls(i) + transits(i) + slacks(i) +             state_dependent_transits(i) where slack is a positive slack variable (can represent waiting times for a time dimension), and state_dependent_transits is a non-purely functional version of transits_. Favour transits over state_dependent_transits when possible, because purely functional callbacks allow more optimisations and make the model faster and easier to solve. for a given vehicle, it is passed as an external vector, it would be better to have this information here."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+    __swig_destroy__ = _pywrapcp.delete_RoutingDimension
+
+    def model(self) -> "operations_research::RoutingModel *":
+        r""" Returns the model on which the dimension was created."""
+        return _pywrapcp.RoutingDimension_model(self)
+
+    def GetTransitValue(self, from_index: "int64_t", to_index: "int64_t", vehicle: "int64_t") -> "int64_t":
+        r""" Returns the transition value for a given pair of nodes (as var index); this value is the one taken by the corresponding transit variable when the 'next' variable for 'from_index' is bound to 'to_index'."""
+        return _pywrapcp.RoutingDimension_GetTransitValue(self, from_index, to_index, vehicle)
+
+    def GetTransitValueFromClass(self, from_index: "int64_t", to_index: "int64_t", vehicle_class: "int64_t") -> "int64_t":
+        r""" Same as above but taking a vehicle class of the dimension instead of a vehicle (the class of a vehicle can be obtained with vehicle_to_class())."""
+        return _pywrapcp.RoutingDimension_GetTransitValueFromClass(self, from_index, to_index, vehicle_class)
+
+    def CumulVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        r""" Get the cumul, transit and slack variables for the given node (given as int64_t var index)."""
+        return _pywrapcp.RoutingDimension_CumulVar(self, index)
+
+    def TransitVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        return _pywrapcp.RoutingDimension_TransitVar(self, index)
+
+    def FixedTransitVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        return _pywrapcp.RoutingDimension_FixedTransitVar(self, index)
+
+    def SlackVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        return _pywrapcp.RoutingDimension_SlackVar(self, index)
+
+    def SetSpanUpperBoundForVehicle(self, upper_bound: "int64_t", vehicle: "int") -> "void":
+        r""" Sets an upper bound on the dimension span on a given vehicle. This is the preferred way to limit the "length" of the route of a vehicle according to a dimension."""
+        return _pywrapcp.RoutingDimension_SetSpanUpperBoundForVehicle(self, upper_bound, vehicle)
+
+    def SetSpanCostCoefficientForVehicle(self, coefficient: "int64_t", vehicle: "int") -> "void":
+        r""" Sets a cost proportional to the dimension span on a given vehicle, or on all vehicles at once. "coefficient" must be nonnegative. This is handy to model costs proportional to idle time when the dimension represents time. The cost for a vehicle is   span_cost = coefficient * (dimension end value - dimension start value)."""
+        return _pywrapcp.RoutingDimension_SetSpanCostCoefficientForVehicle(self, coefficient, vehicle)
+
+    def SetSpanCostCoefficientForAllVehicles(self, coefficient: "int64_t") -> "void":
+        return _pywrapcp.RoutingDimension_SetSpanCostCoefficientForAllVehicles(self, coefficient)
+
+    def SetGlobalSpanCostCoefficient(self, coefficient: "int64_t") -> "void":
+        r""" Sets a cost proportional to the *global* dimension span, that is the difference between the largest value of route end cumul variables and the smallest value of route start cumul variables. In other words: global_span_cost =   coefficient * (Max(dimension end value) - Min(dimension start value))."""
+        return _pywrapcp.RoutingDimension_SetGlobalSpanCostCoefficient(self, coefficient)
+
+    def SetCumulVarSoftUpperBound(self, index: "int64_t", upper_bound: "int64_t", coefficient: "int64_t") -> "void":
+        r""" Sets a soft upper bound to the cumul variable of a given variable index. If the value of the cumul variable is greater than the bound, a cost proportional to the difference between this value and the bound is added to the cost function of the model:   cumulVar <= upper_bound -> cost = 0    cumulVar > upper_bound -> cost = coefficient * (cumulVar - upper_bound) This is also handy to model tardiness costs when the dimension represents time."""
+        return _pywrapcp.RoutingDimension_SetCumulVarSoftUpperBound(self, index, upper_bound, coefficient)
+
+    def HasCumulVarSoftUpperBound(self, index: "int64_t") -> "bool":
+        r""" Returns true if a soft upper bound has been set for a given variable index."""
+        return _pywrapcp.RoutingDimension_HasCumulVarSoftUpperBound(self, index)
+
+    def GetCumulVarSoftUpperBound(self, index: "int64_t") -> "int64_t":
+        r""" Returns the soft upper bound of a cumul variable for a given variable index. The "hard" upper bound of the variable is returned if no soft upper bound has been set."""
+        return _pywrapcp.RoutingDimension_GetCumulVarSoftUpperBound(self, index)
+
+    def GetCumulVarSoftUpperBoundCoefficient(self, index: "int64_t") -> "int64_t":
+        r""" Returns the cost coefficient of the soft upper bound of a cumul variable for a given variable index. If no soft upper bound has been set, 0 is returned."""
+        return _pywrapcp.RoutingDimension_GetCumulVarSoftUpperBoundCoefficient(self, index)
+
+    def SetCumulVarSoftLowerBound(self, index: "int64_t", lower_bound: "int64_t", coefficient: "int64_t") -> "void":
+        r""" Sets a soft lower bound to the cumul variable of a given variable index. If the value of the cumul variable is less than the bound, a cost proportional to the difference between this value and the bound is added to the cost function of the model:   cumulVar > lower_bound -> cost = 0   cumulVar <= lower_bound -> cost = coefficient * (lower_bound -               cumulVar). This is also handy to model earliness costs when the dimension represents time."""
+        return _pywrapcp.RoutingDimension_SetCumulVarSoftLowerBound(self, index, lower_bound, coefficient)
+
+    def HasCumulVarSoftLowerBound(self, index: "int64_t") -> "bool":
+        r""" Returns true if a soft lower bound has been set for a given variable index."""
+        return _pywrapcp.RoutingDimension_HasCumulVarSoftLowerBound(self, index)
+
+    def GetCumulVarSoftLowerBound(self, index: "int64_t") -> "int64_t":
+        r""" Returns the soft lower bound of a cumul variable for a given variable index. The "hard" lower bound of the variable is returned if no soft lower bound has been set."""
+        return _pywrapcp.RoutingDimension_GetCumulVarSoftLowerBound(self, index)
+
+    def GetCumulVarSoftLowerBoundCoefficient(self, index: "int64_t") -> "int64_t":
+        r""" Returns the cost coefficient of the soft lower bound of a cumul variable for a given variable index. If no soft lower bound has been set, 0 is returned."""
+        return _pywrapcp.RoutingDimension_GetCumulVarSoftLowerBoundCoefficient(self, index)
+
+    def SetBreakIntervalsOfVehicle(self, breaks: "std::vector< operations_research::IntervalVar * >", vehicle: "int", node_visit_transits: "std::vector< int64_t >") -> "void":
+        r""" Sets the breaks for a given vehicle. Breaks are represented by IntervalVars. They may interrupt transits between nodes and increase the value of corresponding slack variables. A break may take place before the start of a vehicle, after the end of a vehicle, or during a travel i -> j. In that case, the interval [break.Start(), break.End()) must be a subset of [CumulVar(i) + pre_travel(i, j), CumulVar(j) - post_travel(i, j)). In other words, a break may not overlap any node n's visit, given by [CumulVar(n) - post_travel(_, n), CumulVar(n) + pre_travel(n, _)). This formula considers post_travel(_, start) and pre_travel(end, _) to be 0; pre_travel will never be called on any (_, start) and post_travel will never we called on any (end, _). If pre_travel_evaluator or post_travel_evaluator is -1, it will be taken as a function that always returns 0. Deprecated, sets pre_travel(i, j) = node_visit_transit[i]."""
+        return _pywrapcp.RoutingDimension_SetBreakIntervalsOfVehicle(self, breaks, vehicle, node_visit_transits)
+
+    def SetBreakDistanceDurationOfVehicle(self, distance: "int64_t", duration: "int64_t", vehicle: "int") -> "void":
+        r""" With breaks supposed to be consecutive, this forces the distance between breaks of size at least minimum_break_duration to be at most distance. This supposes that the time until route start and after route end are infinite breaks."""
+        return _pywrapcp.RoutingDimension_SetBreakDistanceDurationOfVehicle(self, distance, duration, vehicle)
+
+    def InitializeBreaks(self) -> "void":
+        r""" Sets up vehicle_break_intervals_, vehicle_break_distance_duration_, pre_travel_evaluators and post_travel_evaluators."""
+        return _pywrapcp.RoutingDimension_InitializeBreaks(self)
+
+    def HasBreakConstraints(self) -> "bool":
+        r""" Returns true if any break interval or break distance was defined."""
+        return _pywrapcp.RoutingDimension_HasBreakConstraints(self)
+
+    def GetPreTravelEvaluatorOfVehicle(self, vehicle: "int") -> "int":
+        return _pywrapcp.RoutingDimension_GetPreTravelEvaluatorOfVehicle(self, vehicle)
+
+    def GetPostTravelEvaluatorOfVehicle(self, vehicle: "int") -> "int":
+        return _pywrapcp.RoutingDimension_GetPostTravelEvaluatorOfVehicle(self, vehicle)
+
+    def base_dimension(self) -> "operations_research::RoutingDimension const *":
+        r""" Returns the parent in the dependency tree if any or nullptr otherwise."""
+        return _pywrapcp.RoutingDimension_base_dimension(self)
+
+    def ShortestTransitionSlack(self, node: "int64_t") -> "int64_t":
+        r""" It makes sense to use the function only for self-dependent dimension. For such dimensions the value of the slack of a node determines the transition cost of the next transit. Provided that   1. cumul[node] is fixed,   2. next[node] and next[next[node]] (if exists) are fixed, the value of slack[node] for which cumul[next[node]] + transit[next[node]] is minimized can be found in O(1) using this function."""
+        return _pywrapcp.RoutingDimension_ShortestTransitionSlack(self, node)
+
+    def name(self) -> "std::string const &":
+        r""" Returns the name of the dimension."""
+        return _pywrapcp.RoutingDimension_name(self)
+
+    def SetPickupToDeliveryLimitFunctionForPair(self, limit_function: "operations_research::RoutingDimension::PickupToDeliveryLimitFunction", pair_index: "int") -> "void":
+        return _pywrapcp.RoutingDimension_SetPickupToDeliveryLimitFunctionForPair(self, limit_function, pair_index)
+
+    def HasPickupToDeliveryLimits(self) -> "bool":
+        return _pywrapcp.RoutingDimension_HasPickupToDeliveryLimits(self)
+
+    def AddNodePrecedence(self, first_node: "int64_t", second_node: "int64_t", offset: "int64_t") -> "void":
+        return _pywrapcp.RoutingDimension_AddNodePrecedence(self, first_node, second_node, offset)
+
+    def GetSpanUpperBoundForVehicle(self, vehicle: "int") -> "int64_t":
+        return _pywrapcp.RoutingDimension_GetSpanUpperBoundForVehicle(self, vehicle)
+
+    def GetSpanCostCoefficientForVehicle(self, vehicle: "int") -> "int64_t":
+        return _pywrapcp.RoutingDimension_GetSpanCostCoefficientForVehicle(self, vehicle)
+
+    def global_span_cost_coefficient(self) -> "int64_t":
+        return _pywrapcp.RoutingDimension_global_span_cost_coefficient(self)
+
+    def GetGlobalOptimizerOffset(self) -> "int64_t":
+        return _pywrapcp.RoutingDimension_GetGlobalOptimizerOffset(self)
+
+    def GetLocalOptimizerOffsetForVehicle(self, vehicle: "int") -> "int64_t":
+        return _pywrapcp.RoutingDimension_GetLocalOptimizerOffsetForVehicle(self, vehicle)
+
+# Register RoutingDimension in _pywrapcp:
+_pywrapcp.RoutingDimension_swigregister(RoutingDimension)
+
+
+def MakeSetValuesFromTargets(solver: "Solver", variables: "std::vector< operations_research::IntVar * >", targets: "std::vector< int64_t >") -> "operations_research::DecisionBuilder *":
+    r""" A decision builder which tries to assign values to variables as close as possible to target values first."""
+    return _pywrapcp.MakeSetValuesFromTargets(solver, variables, targets)
+
+def SolveModelWithSat(model: "RoutingModel", search_parameters: "operations_research::RoutingSearchParameters const &", initial_solution: "Assignment", solution: "Assignment") -> "bool":
+    r""" Attempts to solve the model using the cp-sat solver. As of 5/2019, will solve the TSP corresponding to the model if it has a single vehicle. Therefore the resulting solution might not actually be feasible. Will return false if a solution could not be found."""
+    return _pywrapcp.SolveModelWithSat(model, search_parameters, initial_solution, solution)
+
+ +
+ +
+
+
+ #   - def BeginFail(self) -> "void": - r""" Just when the failure occurs.""" - return _pywrapcp.SearchMonitor_BeginFail(self) - - def EndFail(self) -> "void": - r""" After completing the backtrack.""" - return _pywrapcp.SearchMonitor_EndFail(self) - - def BeginInitialPropagation(self) -> "void": - r""" Before the initial propagation.""" - return _pywrapcp.SearchMonitor_BeginInitialPropagation(self) - - def EndInitialPropagation(self) -> "void": - r""" After the initial propagation.""" - return _pywrapcp.SearchMonitor_EndInitialPropagation(self) - - def AcceptSolution(self) -> "bool": - r""" - This method is called when a solution is found. It asserts whether the - solution is valid. A value of false indicates that the solution - should be discarded. - """ - return _pywrapcp.SearchMonitor_AcceptSolution(self) - - def AtSolution(self) -> "bool": - r""" - This method is called when a valid solution is found. If the - return value is true, then search will resume after. If the result - is false, then search will stop there. - """ - return _pywrapcp.SearchMonitor_AtSolution(self) - - def NoMoreSolutions(self) -> "void": - r""" When the search tree is finished.""" - return _pywrapcp.SearchMonitor_NoMoreSolutions(self) - - def LocalOptimum(self) -> "bool": - r""" - When a local optimum is reached. If 'true' is returned, the last solution - is discarded and the search proceeds with the next one. - """ - return _pywrapcp.SearchMonitor_LocalOptimum(self) - - def AcceptDelta(self, delta: "Assignment", deltadelta: "Assignment") -> "bool": - return _pywrapcp.SearchMonitor_AcceptDelta(self, delta, deltadelta) + class + DefaultPhaseParameters: +
+ +
+ View Source +
class DefaultPhaseParameters(object):
+    r""" This struct holds all parameters for the default search. DefaultPhaseParameters is only used by Solver::MakeDefaultPhase methods. Note this is for advanced users only."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+    CHOOSE_MAX_SUM_IMPACT = _pywrapcp.DefaultPhaseParameters_CHOOSE_MAX_SUM_IMPACT
+    CHOOSE_MAX_AVERAGE_IMPACT = _pywrapcp.DefaultPhaseParameters_CHOOSE_MAX_AVERAGE_IMPACT
+    CHOOSE_MAX_VALUE_IMPACT = _pywrapcp.DefaultPhaseParameters_CHOOSE_MAX_VALUE_IMPACT
+    SELECT_MIN_IMPACT = _pywrapcp.DefaultPhaseParameters_SELECT_MIN_IMPACT
+    SELECT_MAX_IMPACT = _pywrapcp.DefaultPhaseParameters_SELECT_MAX_IMPACT
+    NONE = _pywrapcp.DefaultPhaseParameters_NONE
+    NORMAL = _pywrapcp.DefaultPhaseParameters_NORMAL
+    VERBOSE = _pywrapcp.DefaultPhaseParameters_VERBOSE
+    var_selection_schema = property(_pywrapcp.DefaultPhaseParameters_var_selection_schema_get, _pywrapcp.DefaultPhaseParameters_var_selection_schema_set, doc=r""" This parameter describes how the next variable to instantiate will be chosen.""")
+    value_selection_schema = property(_pywrapcp.DefaultPhaseParameters_value_selection_schema_get, _pywrapcp.DefaultPhaseParameters_value_selection_schema_set, doc=r""" This parameter describes which value to select for a given var.""")
+    initialization_splits = property(_pywrapcp.DefaultPhaseParameters_initialization_splits_get, _pywrapcp.DefaultPhaseParameters_initialization_splits_set, doc=r""" Maximum number of intervals that the initialization of impacts will scan per variable.""")
+    run_all_heuristics = property(_pywrapcp.DefaultPhaseParameters_run_all_heuristics_get, _pywrapcp.DefaultPhaseParameters_run_all_heuristics_set, doc=r""" The default phase will run heuristics periodically. This parameter indicates if we should run all heuristics, or a randomly selected one.""")
+    heuristic_period = property(_pywrapcp.DefaultPhaseParameters_heuristic_period_get, _pywrapcp.DefaultPhaseParameters_heuristic_period_set, doc=r""" The distance in nodes between each run of the heuristics. A negative or null value will mean that we will not run heuristics at all.""")
+    heuristic_num_failures_limit = property(_pywrapcp.DefaultPhaseParameters_heuristic_num_failures_limit_get, _pywrapcp.DefaultPhaseParameters_heuristic_num_failures_limit_set, doc=r""" The failure limit for each heuristic that we run.""")
+    persistent_impact = property(_pywrapcp.DefaultPhaseParameters_persistent_impact_get, _pywrapcp.DefaultPhaseParameters_persistent_impact_set, doc=r""" Whether to keep the impact from the first search for other searches, or to recompute the impact for each new search.""")
+    random_seed = property(_pywrapcp.DefaultPhaseParameters_random_seed_get, _pywrapcp.DefaultPhaseParameters_random_seed_set, doc=r""" Seed used to initialize the random part in some heuristics.""")
+    display_level = property(_pywrapcp.DefaultPhaseParameters_display_level_get, _pywrapcp.DefaultPhaseParameters_display_level_set, doc=r""" This represents the amount of information displayed by the default search. NONE means no display, VERBOSE means extra information.""")
+    decision_builder = property(_pywrapcp.DefaultPhaseParameters_decision_builder_get, _pywrapcp.DefaultPhaseParameters_decision_builder_set, doc=r""" When defined, this overrides the default impact based decision builder.""")
+
+    def __init__(self):
+        _pywrapcp.DefaultPhaseParameters_swiginit(self, _pywrapcp.new_DefaultPhaseParameters())
+    __swig_destroy__ = _pywrapcp.delete_DefaultPhaseParameters
+
+ +
+ +

This struct holds all parameters for the default search. DefaultPhaseParameters is only used by Solver::MakeDefaultPhase methods. Note this is for advanced users only.

+
+ + +
+
#   - def AcceptNeighbor(self) -> "void": - r""" After accepting a neighbor during local search.""" - return _pywrapcp.SearchMonitor_AcceptNeighbor(self) - - def solver(self) -> "operations_research::Solver *": - return _pywrapcp.SearchMonitor_solver(self) - - def __repr__(self) -> "std::string": - return _pywrapcp.SearchMonitor___repr__(self) - - def __str__(self) -> "std::string": - return _pywrapcp.SearchMonitor___str__(self) - def __disown__(self): - self.this.disown() - _pywrapcp.disown_SearchMonitor(self) - return weakref.proxy(self) - -# Register SearchMonitor in _pywrapcp: -_pywrapcp.SearchMonitor_swigregister(SearchMonitor) - -class IntExpr(PropagationBaseObject): - r""" - The class IntExpr is the base of all integer expressions in - constraint programming. - It contains the basic protocol for an expression: - - setting and modifying its bound - - querying if it is bound - - listening to events modifying its bounds - - casting it into a variable (instance of IntVar) - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined - class is abstract") - - def Min(self) -> "int64_t": - return _pywrapcp.IntExpr_Min(self) - - def SetMin(self, m: "int64_t") -> "void": - return _pywrapcp.IntExpr_SetMin(self, m) - - def Max(self) -> "int64_t": - return _pywrapcp.IntExpr_Max(self) - - def SetMax(self, m: "int64_t") -> "void": - return _pywrapcp.IntExpr_SetMax(self, m) - - def SetRange(self, l: "int64_t", u: "int64_t") -> "void": - r""" This method sets both the min and the max of the expression.""" - return _pywrapcp.IntExpr_SetRange(self, l, u) - - def SetValue(self, v: "int64_t") -> "void": - r""" This method sets the value of the expression.""" - return _pywrapcp.IntExpr_SetValue(self, v) - - def Bound(self) -> "bool": - r""" Returns true if the min and the max of the expression are equal.""" - return _pywrapcp.IntExpr_Bound(self) - - def IsVar(self) -> "bool": - r""" Returns true if the expression is indeed a variable.""" - return _pywrapcp.IntExpr_IsVar(self) - - def Var(self) -> "operations_research::IntVar *": - r""" Creates a variable from the expression.""" - return _pywrapcp.IntExpr_Var(self) - - def VarWithName(self, name: "std::string const &") -> "operations_research::IntVar *": - r""" - Creates a variable from the expression and set the name of the - resulting var. If the expression is already a variable, then it - will set the name of the expression, possibly overwriting it. - This is just a shortcut to Var() followed by set_name(). - """ - return _pywrapcp.IntExpr_VarWithName(self, name) - - def WhenRange(self, *args) -> "void": - r""" - *Overload 1:* - Attach a demon that will watch the min or the max of the expression. - - | - - *Overload 2:* - Attach a demon that will watch the min or the max of the expression. - """ - return _pywrapcp.IntExpr_WhenRange(self, *args) - - def __repr__(self) -> "std::string": - return _pywrapcp.IntExpr___repr__(self) - - def __str__(self) -> "std::string": - return _pywrapcp.IntExpr___str__(self) - - def __add__(self, *args) -> "operations_research::IntExpr *": - return _pywrapcp.IntExpr___add__(self, *args) - - def __radd__(self, v: "int64_t") -> "operations_research::IntExpr *": - return _pywrapcp.IntExpr___radd__(self, v) - - def __sub__(self, *args) -> "operations_research::IntExpr *": - return _pywrapcp.IntExpr___sub__(self, *args) - - def __rsub__(self, v: "int64_t") -> "operations_research::IntExpr *": - return _pywrapcp.IntExpr___rsub__(self, v) - - def __mul__(self, *args) -> "operations_research::IntExpr *": - return _pywrapcp.IntExpr___mul__(self, *args) - - def __rmul__(self, v: "int64_t") -> "operations_research::IntExpr *": - return _pywrapcp.IntExpr___rmul__(self, v) - - def __floordiv__(self, *args) -> "operations_research::IntExpr *": - return _pywrapcp.IntExpr___floordiv__(self, *args) - - def __mod__(self, *args) -> "operations_research::IntExpr *": - return _pywrapcp.IntExpr___mod__(self, *args) - - def __neg__(self) -> "operations_research::IntExpr *": - return _pywrapcp.IntExpr___neg__(self) - - def __abs__(self) -> "operations_research::IntExpr *": - return _pywrapcp.IntExpr___abs__(self) - - def Square(self) -> "operations_research::IntExpr *": - return _pywrapcp.IntExpr_Square(self) - - def __eq__(self, *args) -> "operations_research::Constraint *": - return _pywrapcp.IntExpr___eq__(self, *args) - - def __ne__(self, *args) -> "operations_research::Constraint *": - return _pywrapcp.IntExpr___ne__(self, *args) - - def __ge__(self, *args) -> "operations_research::Constraint *": - return _pywrapcp.IntExpr___ge__(self, *args) - - def __gt__(self, *args) -> "operations_research::Constraint *": - return _pywrapcp.IntExpr___gt__(self, *args) - - def __le__(self, *args) -> "operations_research::Constraint *": - return _pywrapcp.IntExpr___le__(self, *args) - - def __lt__(self, *args) -> "operations_research::Constraint *": - return _pywrapcp.IntExpr___lt__(self, *args) - - def MapTo(self, vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *": - return _pywrapcp.IntExpr_MapTo(self, vars) - - def IndexOf(self, *args) -> "operations_research::IntExpr *": - return _pywrapcp.IntExpr_IndexOf(self, *args) - - def IsMember(self, values: "std::vector< int64_t > const &") -> "operations_research::IntVar *": - return _pywrapcp.IntExpr_IsMember(self, values) - - def Member(self, values: "std::vector< int64_t > const &") -> "operations_research::Constraint *": - return _pywrapcp.IntExpr_Member(self, values) - - def NotMember(self, starts: "std::vector< int64_t > const &", ends: "std::vector< int64_t > const &") -> "operations_research::Constraint *": - return _pywrapcp.IntExpr_NotMember(self, starts, ends) - -# Register IntExpr in _pywrapcp: -_pywrapcp.IntExpr_swigregister(IntExpr) - -class IntVarIterator(BaseObject): - r""" - The class Iterator has two direct subclasses. HoleIterators - iterates over all holes, that is value removed between the - current min and max of the variable since the last time the - variable was processed in the queue. DomainIterators iterates - over all elements of the variable domain. Both iterators are not - robust to domain changes. Hole iterators can also report values outside - the current min and max of the variable. - HoleIterators should only be called from a demon attached to the - variable that has created this iterator. - IntVar* current_var; - std::unique_ptr<IntVarIterator> it(current_var->MakeHoleIterator(false)); - for (const int64_t hole : InitAndGetValues(it)) { - use the hole - } - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - - def Init(self) -> "void": - r""" This method must be called before each loop.""" - return _pywrapcp.IntVarIterator_Init(self) - - def Ok(self) -> "bool": - r""" This method indicates if we can call Value() or not.""" - return _pywrapcp.IntVarIterator_Ok(self) - - def Value(self) -> "int64_t": - r""" This method returns the current value of the iterator.""" - return _pywrapcp.IntVarIterator_Value(self) - - def Next(self) -> "void": - r""" This method moves the iterator to the next value.""" - return _pywrapcp.IntVarIterator_Next(self) - - def DebugString(self) -> "std::string": - r""" Pretty Print.""" - return _pywrapcp.IntVarIterator_DebugString(self) - - def __iter__(self): - self.Init() - return self - - def next(self): - if self.Ok(): - result = self.Value() - self.Next() - return result - else: - raise StopIteration() - - def __next__(self): - return self.next() - - -# Register IntVarIterator in _pywrapcp: -_pywrapcp.IntVarIterator_swigregister(IntVarIterator) - -class IntVar(IntExpr): - r""" - The class IntVar is a subset of IntExpr. In addition to the - IntExpr protocol, it offers persistence, removing values from the domains, - and a finer model for events. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined - class is abstract") - - def IsVar(self) -> "bool": - return _pywrapcp.IntVar_IsVar(self) - - def Var(self) -> "operations_research::IntVar *": - return _pywrapcp.IntVar_Var(self) - - def Value(self) -> "int64_t": - r""" - This method returns the value of the variable. This method checks - before that the variable is bound. - """ - return _pywrapcp.IntVar_Value(self) - - def RemoveValue(self, v: "int64_t") -> "void": - r""" This method removes the value 'v' from the domain of the variable.""" - return _pywrapcp.IntVar_RemoveValue(self, v) - - def RemoveInterval(self, l: "int64_t", u: "int64_t") -> "void": - r""" - This method removes the interval 'l' .. 'u' from the domain of - the variable. It assumes that 'l' <= 'u'. - """ - return _pywrapcp.IntVar_RemoveInterval(self, l, u) - - def RemoveValues(self, values: "std::vector< int64_t > const &") -> "void": - r""" This method remove the values from the domain of the variable.""" - return _pywrapcp.IntVar_RemoveValues(self, values) - - def SetValues(self, values: "std::vector< int64_t > const &") -> "void": - r""" This method intersects the current domain with the values in the array.""" - return _pywrapcp.IntVar_SetValues(self, values) - - def WhenBound(self, *args) -> "void": - r""" - *Overload 1:* - This method attaches a demon that will be awakened when the - variable is bound. - - | - - *Overload 2:* - This method attaches a closure that will be awakened when the - variable is bound. - """ - return _pywrapcp.IntVar_WhenBound(self, *args) - - def WhenDomain(self, *args) -> "void": - r""" - *Overload 1:* - This method attaches a demon that will watch any domain - modification of the domain of the variable. - - | - - *Overload 2:* - This method attaches a closure that will watch any domain - modification of the domain of the variable. - """ - return _pywrapcp.IntVar_WhenDomain(self, *args) - - def Size(self) -> "uint64_t": - r""" This method returns the number of values in the domain of the variable.""" - return _pywrapcp.IntVar_Size(self) - - def Contains(self, v: "int64_t") -> "bool": - r""" - This method returns whether the value 'v' is in the domain of the - variable. - """ - return _pywrapcp.IntVar_Contains(self, v) - - def HoleIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *": - r""" - Creates a hole iterator. When 'reversible' is false, the returned - object is created on the normal C++ heap and the solver does NOT - take ownership of the object. - """ - return _pywrapcp.IntVar_HoleIteratorAux(self, reversible) - - def DomainIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *": - r""" - Creates a domain iterator. When 'reversible' is false, the - returned object is created on the normal C++ heap and the solver - does NOT take ownership of the object. - """ - return _pywrapcp.IntVar_DomainIteratorAux(self, reversible) - - def OldMin(self) -> "int64_t": - r""" Returns the previous min.""" - return _pywrapcp.IntVar_OldMin(self) - - def OldMax(self) -> "int64_t": - r""" Returns the previous max.""" - return _pywrapcp.IntVar_OldMax(self) - - def __repr__(self) -> "std::string": - return _pywrapcp.IntVar___repr__(self) - - def __str__(self) -> "std::string": - return _pywrapcp.IntVar___str__(self) - - def DomainIterator(self): - return iter(self.DomainIteratorAux(False)) - - def HoleIterator(self): - return iter(self.HoleIteratorAux(False)) - - -# Register IntVar in _pywrapcp: -_pywrapcp.IntVar_swigregister(IntVar) - -class SolutionCollector(SearchMonitor): - r""" - This class is the root class of all solution collectors. - It implements a basic query API to be used independently - of the collector used. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined") - __repr__ = _swig_repr - - def DebugString(self) -> "std::string": - return _pywrapcp.SolutionCollector_DebugString(self) - - def Add(self, *args) -> "void": - return _pywrapcp.SolutionCollector_Add(self, *args) - - def AddObjective(self, objective: "IntVar") -> "void": - return _pywrapcp.SolutionCollector_AddObjective(self, objective) - - def EnterSearch(self) -> "void": - r""" Beginning of the search.""" - return _pywrapcp.SolutionCollector_EnterSearch(self) - - def SolutionCount(self) -> "int": - r""" Returns how many solutions were stored during the search.""" - return _pywrapcp.SolutionCollector_SolutionCount(self) - - def Solution(self, n: "int") -> "operations_research::Assignment *": - r""" Returns the nth solution.""" - return _pywrapcp.SolutionCollector_Solution(self, n) - - def WallTime(self, n: "int") -> "int64_t": - r""" Returns the wall time in ms for the nth solution.""" - return _pywrapcp.SolutionCollector_WallTime(self, n) - - def Branches(self, n: "int") -> "int64_t": - r""" Returns the number of branches when the nth solution was found.""" - return _pywrapcp.SolutionCollector_Branches(self, n) - - def Failures(self, n: "int") -> "int64_t": - r""" - Returns the number of failures encountered at the time of the nth - solution. - """ - return _pywrapcp.SolutionCollector_Failures(self, n) - - def ObjectiveValue(self, n: "int") -> "int64_t": - r""" Returns the objective value of the nth solution.""" - return _pywrapcp.SolutionCollector_ObjectiveValue(self, n) - - def Value(self, n: "int", var: "IntVar") -> "int64_t": - r""" This is a shortcut to get the Value of 'var' in the nth solution.""" - return _pywrapcp.SolutionCollector_Value(self, n, var) - - def StartValue(self, n: "int", var: "IntervalVar") -> "int64_t": - r""" This is a shortcut to get the StartValue of 'var' in the nth solution.""" - return _pywrapcp.SolutionCollector_StartValue(self, n, var) - - def EndValue(self, n: "int", var: "IntervalVar") -> "int64_t": - r""" This is a shortcut to get the EndValue of 'var' in the nth solution.""" - return _pywrapcp.SolutionCollector_EndValue(self, n, var) - - def DurationValue(self, n: "int", var: "IntervalVar") -> "int64_t": - r""" This is a shortcut to get the DurationValue of 'var' in the nth solution.""" - return _pywrapcp.SolutionCollector_DurationValue(self, n, var) - - def PerformedValue(self, n: "int", var: "IntervalVar") -> "int64_t": - r""" This is a shortcut to get the PerformedValue of 'var' in the nth solution.""" - return _pywrapcp.SolutionCollector_PerformedValue(self, n, var) - - def ForwardSequence(self, n: "int", var: "SequenceVar") -> "std::vector< int > const &": - r""" - This is a shortcut to get the ForwardSequence of 'var' in the - nth solution. The forward sequence is the list of ranked interval - variables starting from the start of the sequence. - """ - return _pywrapcp.SolutionCollector_ForwardSequence(self, n, var) - - def BackwardSequence(self, n: "int", var: "SequenceVar") -> "std::vector< int > const &": - r""" - This is a shortcut to get the BackwardSequence of 'var' in the - nth solution. The backward sequence is the list of ranked interval - variables starting from the end of the sequence. - """ - return _pywrapcp.SolutionCollector_BackwardSequence(self, n, var) - - def Unperformed(self, n: "int", var: "SequenceVar") -> "std::vector< int > const &": - r""" - This is a shortcut to get the list of unperformed of 'var' in the - nth solution. - """ - return _pywrapcp.SolutionCollector_Unperformed(self, n, var) - -# Register SolutionCollector in _pywrapcp: -_pywrapcp.SolutionCollector_swigregister(SolutionCollector) - -class OptimizeVar(SearchMonitor): - r""" - This class encapsulates an objective. It requires the direction - (minimize or maximize), the variable to optimize, and the - improvement step. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined") - __repr__ = _swig_repr - - def Best(self) -> "int64_t": - r""" Returns the best value found during search.""" - return _pywrapcp.OptimizeVar_Best(self) - - def Var(self) -> "operations_research::IntVar *": - r""" Returns the variable that is optimized.""" - return _pywrapcp.OptimizeVar_Var(self) - - def AcceptDelta(self, delta: "Assignment", deltadelta: "Assignment") -> "bool": - r""" Internal methods.""" - return _pywrapcp.OptimizeVar_AcceptDelta(self, delta, deltadelta) - - def EnterSearch(self) -> "void": - return _pywrapcp.OptimizeVar_EnterSearch(self) - - def BeginNextDecision(self, db: "DecisionBuilder") -> "void": - return _pywrapcp.OptimizeVar_BeginNextDecision(self, db) - - def RefuteDecision(self, d: "Decision") -> "void": - return _pywrapcp.OptimizeVar_RefuteDecision(self, d) - - def AtSolution(self) -> "bool": - return _pywrapcp.OptimizeVar_AtSolution(self) - - def AcceptSolution(self) -> "bool": - return _pywrapcp.OptimizeVar_AcceptSolution(self) - - def DebugString(self) -> "std::string": - return _pywrapcp.OptimizeVar_DebugString(self) - -# Register OptimizeVar in _pywrapcp: -_pywrapcp.OptimizeVar_swigregister(OptimizeVar) - -class SearchLimit(SearchMonitor): - r""" Base class of all search limits.""" - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - __swig_destroy__ = _pywrapcp.delete_SearchLimit - - def Crossed(self) -> "bool": - r""" Returns true if the limit has been crossed.""" - return _pywrapcp.SearchLimit_Crossed(self) - - def Check(self) -> "bool": - r""" - This method is called to check the status of the limit. A return - value of true indicates that we have indeed crossed the limit. In - that case, this method will not be called again and the remaining - search will be discarded. - """ - return _pywrapcp.SearchLimit_Check(self) - - def Init(self) -> "void": - r""" This method is called when the search limit is initialized.""" - return _pywrapcp.SearchLimit_Init(self) - - def EnterSearch(self) -> "void": - r""" Internal methods.""" - return _pywrapcp.SearchLimit_EnterSearch(self) - - def BeginNextDecision(self, b: "DecisionBuilder") -> "void": - return _pywrapcp.SearchLimit_BeginNextDecision(self, b) - - def RefuteDecision(self, d: "Decision") -> "void": - return _pywrapcp.SearchLimit_RefuteDecision(self, d) - - def DebugString(self) -> "std::string": - return _pywrapcp.SearchLimit_DebugString(self) - -# Register SearchLimit in _pywrapcp: -_pywrapcp.SearchLimit_swigregister(SearchLimit) - -class IntervalVar(PropagationBaseObject): - r""" - Interval variables are often used in scheduling. The main characteristics - of an IntervalVar are the start position, duration, and end - date. All these characteristics can be queried and set, and demons can - be posted on their modifications. - - An important aspect is optionality: an IntervalVar can be performed or not. - If unperformed, then it simply does not exist, and its characteristics - cannot be accessed any more. An interval var is automatically marked - as unperformed when it is not consistent anymore (start greater - than end, duration < 0...) - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined - class is abstract") - - def StartMin(self) -> "int64_t": - r""" - These methods query, set, and watch the start position of the - interval var. - """ - return _pywrapcp.IntervalVar_StartMin(self) - - def StartMax(self) -> "int64_t": - return _pywrapcp.IntervalVar_StartMax(self) - - def SetStartMin(self, m: "int64_t") -> "void": - return _pywrapcp.IntervalVar_SetStartMin(self, m) - - def SetStartMax(self, m: "int64_t") -> "void": - return _pywrapcp.IntervalVar_SetStartMax(self, m) - - def SetStartRange(self, mi: "int64_t", ma: "int64_t") -> "void": - return _pywrapcp.IntervalVar_SetStartRange(self, mi, ma) - - def OldStartMin(self) -> "int64_t": - return _pywrapcp.IntervalVar_OldStartMin(self) - - def OldStartMax(self) -> "int64_t": - return _pywrapcp.IntervalVar_OldStartMax(self) - - def WhenStartRange(self, *args) -> "void": - return _pywrapcp.IntervalVar_WhenStartRange(self, *args) - - def WhenStartBound(self, *args) -> "void": - return _pywrapcp.IntervalVar_WhenStartBound(self, *args) - - def DurationMin(self) -> "int64_t": - r""" These methods query, set, and watch the duration of the interval var.""" - return _pywrapcp.IntervalVar_DurationMin(self) - - def DurationMax(self) -> "int64_t": - return _pywrapcp.IntervalVar_DurationMax(self) - - def SetDurationMin(self, m: "int64_t") -> "void": - return _pywrapcp.IntervalVar_SetDurationMin(self, m) - - def SetDurationMax(self, m: "int64_t") -> "void": - return _pywrapcp.IntervalVar_SetDurationMax(self, m) - - def SetDurationRange(self, mi: "int64_t", ma: "int64_t") -> "void": - return _pywrapcp.IntervalVar_SetDurationRange(self, mi, ma) - - def OldDurationMin(self) -> "int64_t": - return _pywrapcp.IntervalVar_OldDurationMin(self) - - def OldDurationMax(self) -> "int64_t": - return _pywrapcp.IntervalVar_OldDurationMax(self) - - def WhenDurationRange(self, *args) -> "void": - return _pywrapcp.IntervalVar_WhenDurationRange(self, *args) - - def WhenDurationBound(self, *args) -> "void": - return _pywrapcp.IntervalVar_WhenDurationBound(self, *args) - - def EndMin(self) -> "int64_t": - r""" These methods query, set, and watch the end position of the interval var.""" - return _pywrapcp.IntervalVar_EndMin(self) - - def EndMax(self) -> "int64_t": - return _pywrapcp.IntervalVar_EndMax(self) - - def SetEndMin(self, m: "int64_t") -> "void": - return _pywrapcp.IntervalVar_SetEndMin(self, m) - - def SetEndMax(self, m: "int64_t") -> "void": - return _pywrapcp.IntervalVar_SetEndMax(self, m) - - def SetEndRange(self, mi: "int64_t", ma: "int64_t") -> "void": - return _pywrapcp.IntervalVar_SetEndRange(self, mi, ma) - - def OldEndMin(self) -> "int64_t": - return _pywrapcp.IntervalVar_OldEndMin(self) - - def OldEndMax(self) -> "int64_t": - return _pywrapcp.IntervalVar_OldEndMax(self) - - def WhenEndRange(self, *args) -> "void": - return _pywrapcp.IntervalVar_WhenEndRange(self, *args) - - def WhenEndBound(self, *args) -> "void": - return _pywrapcp.IntervalVar_WhenEndBound(self, *args) - - def MustBePerformed(self) -> "bool": - r""" - These methods query, set, and watch the performed status of the - interval var. - """ - return _pywrapcp.IntervalVar_MustBePerformed(self) - - def MayBePerformed(self) -> "bool": - return _pywrapcp.IntervalVar_MayBePerformed(self) - - def CannotBePerformed(self) -> "bool": - return _pywrapcp.IntervalVar_CannotBePerformed(self) - - def IsPerformedBound(self) -> "bool": - return _pywrapcp.IntervalVar_IsPerformedBound(self) - - def SetPerformed(self, val: "bool") -> "void": - return _pywrapcp.IntervalVar_SetPerformed(self, val) - - def WasPerformedBound(self) -> "bool": - return _pywrapcp.IntervalVar_WasPerformedBound(self) - - def WhenPerformedBound(self, *args) -> "void": - return _pywrapcp.IntervalVar_WhenPerformedBound(self, *args) - - def WhenAnything(self, *args) -> "void": - r""" - *Overload 1:* - Attaches a demon awakened when anything about this interval changes. - - | - - *Overload 2:* - Attaches a closure awakened when anything about this interval changes. - """ - return _pywrapcp.IntervalVar_WhenAnything(self, *args) - - def StartExpr(self) -> "operations_research::IntExpr *": - r""" - These methods create expressions encapsulating the start, end - and duration of the interval var. Please note that these must not - be used if the interval var is unperformed. - """ - return _pywrapcp.IntervalVar_StartExpr(self) - - def DurationExpr(self) -> "operations_research::IntExpr *": - return _pywrapcp.IntervalVar_DurationExpr(self) - - def EndExpr(self) -> "operations_research::IntExpr *": - return _pywrapcp.IntervalVar_EndExpr(self) - - def PerformedExpr(self) -> "operations_research::IntExpr *": - return _pywrapcp.IntervalVar_PerformedExpr(self) - - def SafeStartExpr(self, unperformed_value: "int64_t") -> "operations_research::IntExpr *": - r""" - These methods create expressions encapsulating the start, end - and duration of the interval var. If the interval var is - unperformed, they will return the unperformed_value. - """ - return _pywrapcp.IntervalVar_SafeStartExpr(self, unperformed_value) - - def SafeDurationExpr(self, unperformed_value: "int64_t") -> "operations_research::IntExpr *": - return _pywrapcp.IntervalVar_SafeDurationExpr(self, unperformed_value) - - def SafeEndExpr(self, unperformed_value: "int64_t") -> "operations_research::IntExpr *": - return _pywrapcp.IntervalVar_SafeEndExpr(self, unperformed_value) - - def EndsAfterEnd(self, other: "IntervalVar") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_EndsAfterEnd(self, other) - - def EndsAfterEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_EndsAfterEndWithDelay(self, other, delay) - - def EndsAfterStart(self, other: "IntervalVar") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_EndsAfterStart(self, other) - - def EndsAfterStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_EndsAfterStartWithDelay(self, other, delay) - - def EndsAtEnd(self, other: "IntervalVar") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_EndsAtEnd(self, other) - - def EndsAtEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_EndsAtEndWithDelay(self, other, delay) - - def EndsAtStart(self, other: "IntervalVar") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_EndsAtStart(self, other) - - def EndsAtStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_EndsAtStartWithDelay(self, other, delay) - - def StartsAfterEnd(self, other: "IntervalVar") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_StartsAfterEnd(self, other) - - def StartsAfterEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_StartsAfterEndWithDelay(self, other, delay) - - def StartsAfterStart(self, other: "IntervalVar") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_StartsAfterStart(self, other) - - def StartsAfterStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_StartsAfterStartWithDelay(self, other, delay) - - def StartsAtEnd(self, other: "IntervalVar") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_StartsAtEnd(self, other) - - def StartsAtEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_StartsAtEndWithDelay(self, other, delay) - - def StartsAtStart(self, other: "IntervalVar") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_StartsAtStart(self, other) - - def StartsAtStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_StartsAtStartWithDelay(self, other, delay) - - def StaysInSync(self, other: "IntervalVar") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_StaysInSync(self, other) - - def StaysInSyncWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_StaysInSyncWithDelay(self, other, delay) - - def EndsAfter(self, date: "int64_t") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_EndsAfter(self, date) - - def EndsAt(self, date: "int64_t") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_EndsAt(self, date) - - def EndsBefore(self, date: "int64_t") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_EndsBefore(self, date) - - def StartsAfter(self, date: "int64_t") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_StartsAfter(self, date) - - def StartsAt(self, date: "int64_t") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_StartsAt(self, date) - - def StartsBefore(self, date: "int64_t") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_StartsBefore(self, date) - - def CrossesDate(self, date: "int64_t") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_CrossesDate(self, date) - - def AvoidsDate(self, date: "int64_t") -> "operations_research::Constraint *": - return _pywrapcp.IntervalVar_AvoidsDate(self, date) - - def __repr__(self) -> "std::string": - return _pywrapcp.IntervalVar___repr__(self) - - def __str__(self) -> "std::string": - return _pywrapcp.IntervalVar___str__(self) - -# Register IntervalVar in _pywrapcp: -_pywrapcp.IntervalVar_swigregister(IntervalVar) - -class SequenceVar(PropagationBaseObject): - r""" - A sequence variable is a variable whose domain is a set of possible - orderings of the interval variables. It allows ordering of tasks. It - has two sets of methods: ComputePossibleFirstsAndLasts(), which - returns the list of interval variables that can be ranked first or - last; and RankFirst/RankNotFirst/RankLast/RankNotLast, which can be - used to create the search decision. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined") - - def DebugString(self) -> "std::string": - return _pywrapcp.SequenceVar_DebugString(self) - - def RankFirst(self, index: "int") -> "void": - r""" - Ranks the index_th interval var first of all unranked interval - vars. After that, it will no longer be considered ranked. - """ - return _pywrapcp.SequenceVar_RankFirst(self, index) - - def RankNotFirst(self, index: "int") -> "void": - r""" - Indicates that the index_th interval var will not be ranked first - of all currently unranked interval vars. - """ - return _pywrapcp.SequenceVar_RankNotFirst(self, index) - - def RankLast(self, index: "int") -> "void": - r""" - Ranks the index_th interval var first of all unranked interval - vars. After that, it will no longer be considered ranked. - """ - return _pywrapcp.SequenceVar_RankLast(self, index) - - def RankNotLast(self, index: "int") -> "void": - r""" - Indicates that the index_th interval var will not be ranked first - of all currently unranked interval vars. - """ - return _pywrapcp.SequenceVar_RankNotLast(self, index) - - def Interval(self, index: "int") -> "operations_research::IntervalVar *": - r""" Returns the index_th interval of the sequence.""" - return _pywrapcp.SequenceVar_Interval(self, index) - - def Next(self, index: "int") -> "operations_research::IntVar *": - r""" Returns the next of the index_th interval of the sequence.""" - return _pywrapcp.SequenceVar_Next(self, index) - - def Size(self) -> "int64_t": - r""" Returns the number of interval vars in the sequence.""" - return _pywrapcp.SequenceVar_Size(self) - - def __repr__(self) -> "std::string": - return _pywrapcp.SequenceVar___repr__(self) - - def __str__(self) -> "std::string": - return _pywrapcp.SequenceVar___str__(self) - -# Register SequenceVar in _pywrapcp: -_pywrapcp.SequenceVar_swigregister(SequenceVar) - -class AssignmentElement(object): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined") - __repr__ = _swig_repr - - def Activate(self) -> "void": - return _pywrapcp.AssignmentElement_Activate(self) - - def Deactivate(self) -> "void": - return _pywrapcp.AssignmentElement_Deactivate(self) - - def Activated(self) -> "bool": - return _pywrapcp.AssignmentElement_Activated(self) - __swig_destroy__ = _pywrapcp.delete_AssignmentElement - -# Register AssignmentElement in _pywrapcp: -_pywrapcp.AssignmentElement_swigregister(AssignmentElement) - -class IntVarElement(AssignmentElement): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined") - __repr__ = _swig_repr - - def Var(self) -> "operations_research::IntVar *": - return _pywrapcp.IntVarElement_Var(self) - - def Min(self) -> "int64_t": - return _pywrapcp.IntVarElement_Min(self) - - def SetMin(self, m: "int64_t") -> "void": - return _pywrapcp.IntVarElement_SetMin(self, m) - - def Max(self) -> "int64_t": - return _pywrapcp.IntVarElement_Max(self) - - def SetMax(self, m: "int64_t") -> "void": - return _pywrapcp.IntVarElement_SetMax(self, m) - - def Value(self) -> "int64_t": - return _pywrapcp.IntVarElement_Value(self) - - def Bound(self) -> "bool": - return _pywrapcp.IntVarElement_Bound(self) - - def SetRange(self, l: "int64_t", u: "int64_t") -> "void": - return _pywrapcp.IntVarElement_SetRange(self, l, u) - - def SetValue(self, v: "int64_t") -> "void": - return _pywrapcp.IntVarElement_SetValue(self, v) - - def __eq__(self, element: "IntVarElement") -> "bool": - return _pywrapcp.IntVarElement___eq__(self, element) - - def __ne__(self, element: "IntVarElement") -> "bool": - return _pywrapcp.IntVarElement___ne__(self, element) - __swig_destroy__ = _pywrapcp.delete_IntVarElement - -# Register IntVarElement in _pywrapcp: -_pywrapcp.IntVarElement_swigregister(IntVarElement) - -class IntervalVarElement(AssignmentElement): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined") - __repr__ = _swig_repr - - def Var(self) -> "operations_research::IntervalVar *": - return _pywrapcp.IntervalVarElement_Var(self) - - def StartMin(self) -> "int64_t": - return _pywrapcp.IntervalVarElement_StartMin(self) - - def StartMax(self) -> "int64_t": - return _pywrapcp.IntervalVarElement_StartMax(self) - - def StartValue(self) -> "int64_t": - return _pywrapcp.IntervalVarElement_StartValue(self) - - def DurationMin(self) -> "int64_t": - return _pywrapcp.IntervalVarElement_DurationMin(self) - - def DurationMax(self) -> "int64_t": - return _pywrapcp.IntervalVarElement_DurationMax(self) - - def DurationValue(self) -> "int64_t": - return _pywrapcp.IntervalVarElement_DurationValue(self) - - def EndMin(self) -> "int64_t": - return _pywrapcp.IntervalVarElement_EndMin(self) - - def EndMax(self) -> "int64_t": - return _pywrapcp.IntervalVarElement_EndMax(self) - - def EndValue(self) -> "int64_t": - return _pywrapcp.IntervalVarElement_EndValue(self) - - def PerformedMin(self) -> "int64_t": - return _pywrapcp.IntervalVarElement_PerformedMin(self) - - def PerformedMax(self) -> "int64_t": - return _pywrapcp.IntervalVarElement_PerformedMax(self) - - def PerformedValue(self) -> "int64_t": - return _pywrapcp.IntervalVarElement_PerformedValue(self) - - def SetStartMin(self, m: "int64_t") -> "void": - return _pywrapcp.IntervalVarElement_SetStartMin(self, m) - - def SetStartMax(self, m: "int64_t") -> "void": - return _pywrapcp.IntervalVarElement_SetStartMax(self, m) - - def SetStartRange(self, mi: "int64_t", ma: "int64_t") -> "void": - return _pywrapcp.IntervalVarElement_SetStartRange(self, mi, ma) - - def SetStartValue(self, v: "int64_t") -> "void": - return _pywrapcp.IntervalVarElement_SetStartValue(self, v) - - def SetDurationMin(self, m: "int64_t") -> "void": - return _pywrapcp.IntervalVarElement_SetDurationMin(self, m) - - def SetDurationMax(self, m: "int64_t") -> "void": - return _pywrapcp.IntervalVarElement_SetDurationMax(self, m) - - def SetDurationRange(self, mi: "int64_t", ma: "int64_t") -> "void": - return _pywrapcp.IntervalVarElement_SetDurationRange(self, mi, ma) - - def SetDurationValue(self, v: "int64_t") -> "void": - return _pywrapcp.IntervalVarElement_SetDurationValue(self, v) - - def SetEndMin(self, m: "int64_t") -> "void": - return _pywrapcp.IntervalVarElement_SetEndMin(self, m) - - def SetEndMax(self, m: "int64_t") -> "void": - return _pywrapcp.IntervalVarElement_SetEndMax(self, m) - - def SetEndRange(self, mi: "int64_t", ma: "int64_t") -> "void": - return _pywrapcp.IntervalVarElement_SetEndRange(self, mi, ma) - - def SetEndValue(self, v: "int64_t") -> "void": - return _pywrapcp.IntervalVarElement_SetEndValue(self, v) - - def SetPerformedMin(self, m: "int64_t") -> "void": - return _pywrapcp.IntervalVarElement_SetPerformedMin(self, m) - - def SetPerformedMax(self, m: "int64_t") -> "void": - return _pywrapcp.IntervalVarElement_SetPerformedMax(self, m) - - def SetPerformedRange(self, mi: "int64_t", ma: "int64_t") -> "void": - return _pywrapcp.IntervalVarElement_SetPerformedRange(self, mi, ma) - - def SetPerformedValue(self, v: "int64_t") -> "void": - return _pywrapcp.IntervalVarElement_SetPerformedValue(self, v) - - def __eq__(self, element: "IntervalVarElement") -> "bool": - return _pywrapcp.IntervalVarElement___eq__(self, element) - - def __ne__(self, element: "IntervalVarElement") -> "bool": - return _pywrapcp.IntervalVarElement___ne__(self, element) - __swig_destroy__ = _pywrapcp.delete_IntervalVarElement - -# Register IntervalVarElement in _pywrapcp: -_pywrapcp.IntervalVarElement_swigregister(IntervalVarElement) - -class SequenceVarElement(AssignmentElement): - r""" - The SequenceVarElement stores a partial representation of ranked - interval variables in the underlying sequence variable. - This representation consists of three vectors: - - the forward sequence. That is the list of interval variables - ranked first in the sequence. The first element of the backward - sequence is the first interval in the sequence variable. - - the backward sequence. That is the list of interval variables - ranked last in the sequence. The first element of the backward - sequence is the last interval in the sequence variable. - - The list of unperformed interval variables. - Furthermore, if all performed variables are ranked, then by - convention, the forward_sequence will contain all such variables - and the backward_sequence will be empty. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined") - __repr__ = _swig_repr - - def Var(self) -> "operations_research::SequenceVar *": - return _pywrapcp.SequenceVarElement_Var(self) - - def ForwardSequence(self) -> "std::vector< int > const &": - return _pywrapcp.SequenceVarElement_ForwardSequence(self) - - def BackwardSequence(self) -> "std::vector< int > const &": - return _pywrapcp.SequenceVarElement_BackwardSequence(self) - - def Unperformed(self) -> "std::vector< int > const &": - return _pywrapcp.SequenceVarElement_Unperformed(self) - - def SetSequence(self, forward_sequence: "std::vector< int > const &", backward_sequence: "std::vector< int > const &", unperformed: "std::vector< int > const &") -> "void": - return _pywrapcp.SequenceVarElement_SetSequence(self, forward_sequence, backward_sequence, unperformed) - - def SetForwardSequence(self, forward_sequence: "std::vector< int > const &") -> "void": - return _pywrapcp.SequenceVarElement_SetForwardSequence(self, forward_sequence) - - def SetBackwardSequence(self, backward_sequence: "std::vector< int > const &") -> "void": - return _pywrapcp.SequenceVarElement_SetBackwardSequence(self, backward_sequence) - - def SetUnperformed(self, unperformed: "std::vector< int > const &") -> "void": - return _pywrapcp.SequenceVarElement_SetUnperformed(self, unperformed) - - def __eq__(self, element: "SequenceVarElement") -> "bool": - return _pywrapcp.SequenceVarElement___eq__(self, element) - - def __ne__(self, element: "SequenceVarElement") -> "bool": - return _pywrapcp.SequenceVarElement___ne__(self, element) - __swig_destroy__ = _pywrapcp.delete_SequenceVarElement - -# Register SequenceVarElement in _pywrapcp: -_pywrapcp.SequenceVarElement_swigregister(SequenceVarElement) - -class Assignment(PropagationBaseObject): - r""" - An Assignment is a variable -> domains mapping, used - to report solutions to the user. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined") - __repr__ = _swig_repr - - def Clear(self) -> "void": - return _pywrapcp.Assignment_Clear(self) - - def Empty(self) -> "bool": - return _pywrapcp.Assignment_Empty(self) - - def Size(self) -> "int": - return _pywrapcp.Assignment_Size(self) - - def NumIntVars(self) -> "int": - return _pywrapcp.Assignment_NumIntVars(self) - - def NumIntervalVars(self) -> "int": - return _pywrapcp.Assignment_NumIntervalVars(self) - - def NumSequenceVars(self) -> "int": - return _pywrapcp.Assignment_NumSequenceVars(self) - - def Store(self) -> "void": - return _pywrapcp.Assignment_Store(self) - - def Restore(self) -> "void": - return _pywrapcp.Assignment_Restore(self) - - def Load(self, *args) -> "void": - return _pywrapcp.Assignment_Load(self, *args) - - def Save(self, *args) -> "void": - return _pywrapcp.Assignment_Save(self, *args) - - def AddObjective(self, v: "IntVar") -> "void": - return _pywrapcp.Assignment_AddObjective(self, v) - - def Objective(self) -> "operations_research::IntVar *": - return _pywrapcp.Assignment_Objective(self) - - def HasObjective(self) -> "bool": - return _pywrapcp.Assignment_HasObjective(self) - - def ObjectiveMin(self) -> "int64_t": - return _pywrapcp.Assignment_ObjectiveMin(self) - - def ObjectiveMax(self) -> "int64_t": - return _pywrapcp.Assignment_ObjectiveMax(self) - - def ObjectiveValue(self) -> "int64_t": - return _pywrapcp.Assignment_ObjectiveValue(self) - - def ObjectiveBound(self) -> "bool": - return _pywrapcp.Assignment_ObjectiveBound(self) - - def SetObjectiveMin(self, m: "int64_t") -> "void": - return _pywrapcp.Assignment_SetObjectiveMin(self, m) - - def SetObjectiveMax(self, m: "int64_t") -> "void": - return _pywrapcp.Assignment_SetObjectiveMax(self, m) - - def SetObjectiveValue(self, value: "int64_t") -> "void": - return _pywrapcp.Assignment_SetObjectiveValue(self, value) - - def SetObjectiveRange(self, l: "int64_t", u: "int64_t") -> "void": - return _pywrapcp.Assignment_SetObjectiveRange(self, l, u) - - def Min(self, var: "IntVar") -> "int64_t": - return _pywrapcp.Assignment_Min(self, var) - - def Max(self, var: "IntVar") -> "int64_t": - return _pywrapcp.Assignment_Max(self, var) - - def Value(self, var: "IntVar") -> "int64_t": - return _pywrapcp.Assignment_Value(self, var) - - def Bound(self, var: "IntVar") -> "bool": - return _pywrapcp.Assignment_Bound(self, var) - - def SetMin(self, var: "IntVar", m: "int64_t") -> "void": - return _pywrapcp.Assignment_SetMin(self, var, m) - - def SetMax(self, var: "IntVar", m: "int64_t") -> "void": - return _pywrapcp.Assignment_SetMax(self, var, m) - - def SetRange(self, var: "IntVar", l: "int64_t", u: "int64_t") -> "void": - return _pywrapcp.Assignment_SetRange(self, var, l, u) - - def SetValue(self, var: "IntVar", value: "int64_t") -> "void": - return _pywrapcp.Assignment_SetValue(self, var, value) - - def StartMin(self, var: "IntervalVar") -> "int64_t": - return _pywrapcp.Assignment_StartMin(self, var) - - def StartMax(self, var: "IntervalVar") -> "int64_t": - return _pywrapcp.Assignment_StartMax(self, var) - - def StartValue(self, var: "IntervalVar") -> "int64_t": - return _pywrapcp.Assignment_StartValue(self, var) - - def DurationMin(self, var: "IntervalVar") -> "int64_t": - return _pywrapcp.Assignment_DurationMin(self, var) - - def DurationMax(self, var: "IntervalVar") -> "int64_t": - return _pywrapcp.Assignment_DurationMax(self, var) - - def DurationValue(self, var: "IntervalVar") -> "int64_t": - return _pywrapcp.Assignment_DurationValue(self, var) - - def EndMin(self, var: "IntervalVar") -> "int64_t": - return _pywrapcp.Assignment_EndMin(self, var) - - def EndMax(self, var: "IntervalVar") -> "int64_t": - return _pywrapcp.Assignment_EndMax(self, var) - - def EndValue(self, var: "IntervalVar") -> "int64_t": - return _pywrapcp.Assignment_EndValue(self, var) - - def PerformedMin(self, var: "IntervalVar") -> "int64_t": - return _pywrapcp.Assignment_PerformedMin(self, var) - - def PerformedMax(self, var: "IntervalVar") -> "int64_t": - return _pywrapcp.Assignment_PerformedMax(self, var) - - def PerformedValue(self, var: "IntervalVar") -> "int64_t": - return _pywrapcp.Assignment_PerformedValue(self, var) - - def SetStartMin(self, var: "IntervalVar", m: "int64_t") -> "void": - return _pywrapcp.Assignment_SetStartMin(self, var, m) - - def SetStartMax(self, var: "IntervalVar", m: "int64_t") -> "void": - return _pywrapcp.Assignment_SetStartMax(self, var, m) - - def SetStartRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void": - return _pywrapcp.Assignment_SetStartRange(self, var, mi, ma) - - def SetStartValue(self, var: "IntervalVar", value: "int64_t") -> "void": - return _pywrapcp.Assignment_SetStartValue(self, var, value) - - def SetDurationMin(self, var: "IntervalVar", m: "int64_t") -> "void": - return _pywrapcp.Assignment_SetDurationMin(self, var, m) - - def SetDurationMax(self, var: "IntervalVar", m: "int64_t") -> "void": - return _pywrapcp.Assignment_SetDurationMax(self, var, m) - - def SetDurationRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void": - return _pywrapcp.Assignment_SetDurationRange(self, var, mi, ma) - - def SetDurationValue(self, var: "IntervalVar", value: "int64_t") -> "void": - return _pywrapcp.Assignment_SetDurationValue(self, var, value) - - def SetEndMin(self, var: "IntervalVar", m: "int64_t") -> "void": - return _pywrapcp.Assignment_SetEndMin(self, var, m) - - def SetEndMax(self, var: "IntervalVar", m: "int64_t") -> "void": - return _pywrapcp.Assignment_SetEndMax(self, var, m) - - def SetEndRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void": - return _pywrapcp.Assignment_SetEndRange(self, var, mi, ma) - - def SetEndValue(self, var: "IntervalVar", value: "int64_t") -> "void": - return _pywrapcp.Assignment_SetEndValue(self, var, value) - - def SetPerformedMin(self, var: "IntervalVar", m: "int64_t") -> "void": - return _pywrapcp.Assignment_SetPerformedMin(self, var, m) - - def SetPerformedMax(self, var: "IntervalVar", m: "int64_t") -> "void": - return _pywrapcp.Assignment_SetPerformedMax(self, var, m) - - def SetPerformedRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void": - return _pywrapcp.Assignment_SetPerformedRange(self, var, mi, ma) - - def SetPerformedValue(self, var: "IntervalVar", value: "int64_t") -> "void": - return _pywrapcp.Assignment_SetPerformedValue(self, var, value) - - def Add(self, *args) -> "void": - return _pywrapcp.Assignment_Add(self, *args) - - def ForwardSequence(self, var: "SequenceVar") -> "std::vector< int > const &": - return _pywrapcp.Assignment_ForwardSequence(self, var) - - def BackwardSequence(self, var: "SequenceVar") -> "std::vector< int > const &": - return _pywrapcp.Assignment_BackwardSequence(self, var) - - def Unperformed(self, var: "SequenceVar") -> "std::vector< int > const &": - return _pywrapcp.Assignment_Unperformed(self, var) - - def SetSequence(self, var: "SequenceVar", forward_sequence: "std::vector< int > const &", backward_sequence: "std::vector< int > const &", unperformed: "std::vector< int > const &") -> "void": - return _pywrapcp.Assignment_SetSequence(self, var, forward_sequence, backward_sequence, unperformed) - - def SetForwardSequence(self, var: "SequenceVar", forward_sequence: "std::vector< int > const &") -> "void": - return _pywrapcp.Assignment_SetForwardSequence(self, var, forward_sequence) - - def SetBackwardSequence(self, var: "SequenceVar", backward_sequence: "std::vector< int > const &") -> "void": - return _pywrapcp.Assignment_SetBackwardSequence(self, var, backward_sequence) - - def SetUnperformed(self, var: "SequenceVar", unperformed: "std::vector< int > const &") -> "void": - return _pywrapcp.Assignment_SetUnperformed(self, var, unperformed) - - def Activate(self, *args) -> "void": - return _pywrapcp.Assignment_Activate(self, *args) - - def Deactivate(self, *args) -> "void": - return _pywrapcp.Assignment_Deactivate(self, *args) - - def Activated(self, *args) -> "bool": - return _pywrapcp.Assignment_Activated(self, *args) - - def DebugString(self) -> "std::string": - return _pywrapcp.Assignment_DebugString(self) - - def IntVarContainer(self) -> "operations_research::Assignment::IntContainer const &": - return _pywrapcp.Assignment_IntVarContainer(self) - - def MutableIntVarContainer(self) -> "operations_research::Assignment::IntContainer *": - return _pywrapcp.Assignment_MutableIntVarContainer(self) - - def IntervalVarContainer(self) -> "operations_research::Assignment::IntervalContainer const &": - return _pywrapcp.Assignment_IntervalVarContainer(self) - - def MutableIntervalVarContainer(self) -> "operations_research::Assignment::IntervalContainer *": - return _pywrapcp.Assignment_MutableIntervalVarContainer(self) - - def SequenceVarContainer(self) -> "operations_research::Assignment::SequenceContainer const &": - return _pywrapcp.Assignment_SequenceVarContainer(self) - - def MutableSequenceVarContainer(self) -> "operations_research::Assignment::SequenceContainer *": - return _pywrapcp.Assignment_MutableSequenceVarContainer(self) - - def __eq__(self, assignment: "Assignment") -> "bool": - return _pywrapcp.Assignment___eq__(self, assignment) - - def __ne__(self, assignment: "Assignment") -> "bool": - return _pywrapcp.Assignment___ne__(self, assignment) - -# Register Assignment in _pywrapcp: -_pywrapcp.Assignment_swigregister(Assignment) - - -def __lshift__(*args) -> "std::ostream &": - return _pywrapcp.__lshift__(*args) -class Pack(Constraint): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined") - __repr__ = _swig_repr - - def AddWeightedSumLessOrEqualConstantDimension(self, *args) -> "void": - r""" - *Overload 1:* - Dimensions are additional constraints than can restrict what is - possible with the pack constraint. It can be used to set capacity - limits, to count objects per bin, to compute unassigned - penalties... - This dimension imposes that for all bins b, the weighted sum - (weights[i]) of all objects i assigned to 'b' is less or equal - 'bounds[b]'. - - | - - *Overload 2:* - This dimension imposes that for all bins b, the weighted sum - (weights->Run(i)) of all objects i assigned to 'b' is less or - equal to 'bounds[b]'. Ownership of the callback is transferred to - the pack constraint. - - | - - *Overload 3:* - This dimension imposes that for all bins b, the weighted sum - (weights->Run(i, b) of all objects i assigned to 'b' is less or - equal to 'bounds[b]'. Ownership of the callback is transferred to - the pack constraint. - """ - return _pywrapcp.Pack_AddWeightedSumLessOrEqualConstantDimension(self, *args) - - def AddWeightedSumEqualVarDimension(self, *args) -> "void": - r""" - *Overload 1:* - This dimension imposes that for all bins b, the weighted sum - (weights[i]) of all objects i assigned to 'b' is equal to loads[b]. - - | - - *Overload 2:* - This dimension imposes that for all bins b, the weighted sum - (weights->Run(i, b)) of all objects i assigned to 'b' is equal to - loads[b]. - """ - return _pywrapcp.Pack_AddWeightedSumEqualVarDimension(self, *args) - - def AddSumVariableWeightsLessOrEqualConstantDimension(self, usage: "std::vector< operations_research::IntVar * > const &", capacity: "std::vector< int64_t > const &") -> "void": - r""" - This dimension imposes: - forall b in bins, - sum (i in items: usage[i] * is_assigned(i, b)) <= capacity[b] - where is_assigned(i, b) is true if and only if item i is assigned - to the bin b. - - This can be used to model shapes of items by linking variables of - the same item on parallel dimensions with an allowed assignment - constraint. - """ - return _pywrapcp.Pack_AddSumVariableWeightsLessOrEqualConstantDimension(self, usage, capacity) - - def AddWeightedSumOfAssignedDimension(self, weights: "std::vector< int64_t > const &", cost_var: "IntVar") -> "void": - r""" - This dimension enforces that cost_var == sum of weights[i] for - all objects 'i' assigned to a bin. - """ - return _pywrapcp.Pack_AddWeightedSumOfAssignedDimension(self, weights, cost_var) - - def AddCountUsedBinDimension(self, count_var: "IntVar") -> "void": - r""" - This dimension links 'count_var' to the actual number of bins used in the - pack. - """ - return _pywrapcp.Pack_AddCountUsedBinDimension(self, count_var) - - def AddCountAssignedItemsDimension(self, count_var: "IntVar") -> "void": - r""" - This dimension links 'count_var' to the actual number of items - assigned to a bin in the pack. - """ - return _pywrapcp.Pack_AddCountAssignedItemsDimension(self, count_var) - - def Post(self) -> "void": - return _pywrapcp.Pack_Post(self) - - def InitialPropagateWrapper(self) -> "void": - return _pywrapcp.Pack_InitialPropagateWrapper(self) - - def DebugString(self) -> "std::string": - return _pywrapcp.Pack_DebugString(self) - -# Register Pack in _pywrapcp: -_pywrapcp.Pack_swigregister(Pack) - -class DisjunctiveConstraint(Constraint): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - - def SequenceVar(self) -> "operations_research::SequenceVar *": - r""" Creates a sequence variable from the constraint.""" - return _pywrapcp.DisjunctiveConstraint_SequenceVar(self) - - def SetTransitionTime(self, transition_time: "operations_research::Solver::IndexEvaluator2") -> "void": - r""" - Add a transition time between intervals. It forces the distance between - the end of interval a and start of interval b that follows it to be at - least transition_time(a, b). This function must always return - a positive or null value. - """ - return _pywrapcp.DisjunctiveConstraint_SetTransitionTime(self, transition_time) - - def TransitionTime(self, before_index: "int", after_index: "int") -> "int64_t": - return _pywrapcp.DisjunctiveConstraint_TransitionTime(self, before_index, after_index) - -# Register DisjunctiveConstraint in _pywrapcp: -_pywrapcp.DisjunctiveConstraint_swigregister(DisjunctiveConstraint) - -class RevInteger(object): - r""" - This class adds reversibility to a POD type. - It contains the stamp optimization. i.e. the SaveValue call is done - only once per node of the search tree. Please note that actual - stamps always starts at 1, thus an initial value of 0 will always - trigger the first SaveValue. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - - def __init__(self, val: "long const &"): - _pywrapcp.RevInteger_swiginit(self, _pywrapcp.new_RevInteger(val)) - - def Value(self) -> "long const &": - return _pywrapcp.RevInteger_Value(self) - - def SetValue(self, s: "Solver", val: "long const &") -> "void": - return _pywrapcp.RevInteger_SetValue(self, s, val) - __swig_destroy__ = _pywrapcp.delete_RevInteger - -# Register RevInteger in _pywrapcp: -_pywrapcp.RevInteger_swigregister(RevInteger) - -class NumericalRevInteger(RevInteger): - r""" Subclass of Rev<T> which adds numerical operations.""" - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - - def __init__(self, val: "long const &"): - _pywrapcp.NumericalRevInteger_swiginit(self, _pywrapcp.new_NumericalRevInteger(val)) - - def Add(self, s: "Solver", to_add: "long const &") -> "void": - return _pywrapcp.NumericalRevInteger_Add(self, s, to_add) - - def Incr(self, s: "Solver") -> "void": - return _pywrapcp.NumericalRevInteger_Incr(self, s) - - def Decr(self, s: "Solver") -> "void": - return _pywrapcp.NumericalRevInteger_Decr(self, s) - __swig_destroy__ = _pywrapcp.delete_NumericalRevInteger - -# Register NumericalRevInteger in _pywrapcp: -_pywrapcp.NumericalRevInteger_swigregister(NumericalRevInteger) - -class RevBool(object): - r""" - This class adds reversibility to a POD type. - It contains the stamp optimization. i.e. the SaveValue call is done - only once per node of the search tree. Please note that actual - stamps always starts at 1, thus an initial value of 0 will always - trigger the first SaveValue. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - - def __init__(self, val: "bool const &"): - _pywrapcp.RevBool_swiginit(self, _pywrapcp.new_RevBool(val)) - - def Value(self) -> "bool const &": - return _pywrapcp.RevBool_Value(self) - - def SetValue(self, s: "Solver", val: "bool const &") -> "void": - return _pywrapcp.RevBool_SetValue(self, s, val) - __swig_destroy__ = _pywrapcp.delete_RevBool - -# Register RevBool in _pywrapcp: -_pywrapcp.RevBool_swigregister(RevBool) - -class IntVarContainer(object): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined") - __repr__ = _swig_repr - - def Contains(self, var: "IntVar") -> "bool": - return _pywrapcp.IntVarContainer_Contains(self, var) - - def Element(self, index: "int") -> "operations_research::IntVarElement *": - return _pywrapcp.IntVarContainer_Element(self, index) - - def Size(self) -> "int": - return _pywrapcp.IntVarContainer_Size(self) - - def Store(self) -> "void": - return _pywrapcp.IntVarContainer_Store(self) - - def Restore(self) -> "void": - return _pywrapcp.IntVarContainer_Restore(self) - - def __eq__(self, container: "IntVarContainer") -> "bool": - r""" - Returns true if this and 'container' both represent the same V* -> E map. - Runs in linear time; requires that the == operator on the type E is well - defined. - """ - return _pywrapcp.IntVarContainer___eq__(self, container) - - def __ne__(self, container: "IntVarContainer") -> "bool": - return _pywrapcp.IntVarContainer___ne__(self, container) - __swig_destroy__ = _pywrapcp.delete_IntVarContainer - -# Register IntVarContainer in _pywrapcp: -_pywrapcp.IntVarContainer_swigregister(IntVarContainer) - -class IntervalVarContainer(object): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined") - __repr__ = _swig_repr - - def Contains(self, var: "IntervalVar") -> "bool": - return _pywrapcp.IntervalVarContainer_Contains(self, var) - - def Element(self, index: "int") -> "operations_research::IntervalVarElement *": - return _pywrapcp.IntervalVarContainer_Element(self, index) - - def Size(self) -> "int": - return _pywrapcp.IntervalVarContainer_Size(self) - - def Store(self) -> "void": - return _pywrapcp.IntervalVarContainer_Store(self) - - def Restore(self) -> "void": - return _pywrapcp.IntervalVarContainer_Restore(self) - - def __eq__(self, container: "IntervalVarContainer") -> "bool": - r""" - Returns true if this and 'container' both represent the same V* -> E map. - Runs in linear time; requires that the == operator on the type E is well - defined. - """ - return _pywrapcp.IntervalVarContainer___eq__(self, container) - - def __ne__(self, container: "IntervalVarContainer") -> "bool": - return _pywrapcp.IntervalVarContainer___ne__(self, container) - __swig_destroy__ = _pywrapcp.delete_IntervalVarContainer - -# Register IntervalVarContainer in _pywrapcp: -_pywrapcp.IntervalVarContainer_swigregister(IntervalVarContainer) - -class SequenceVarContainer(object): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined") - __repr__ = _swig_repr - - def Contains(self, var: "SequenceVar") -> "bool": - return _pywrapcp.SequenceVarContainer_Contains(self, var) - - def Element(self, index: "int") -> "operations_research::SequenceVarElement *": - return _pywrapcp.SequenceVarContainer_Element(self, index) - - def Size(self) -> "int": - return _pywrapcp.SequenceVarContainer_Size(self) - - def Store(self) -> "void": - return _pywrapcp.SequenceVarContainer_Store(self) - - def Restore(self) -> "void": - return _pywrapcp.SequenceVarContainer_Restore(self) - - def __eq__(self, container: "SequenceVarContainer") -> "bool": - r""" - Returns true if this and 'container' both represent the same V* -> E map. - Runs in linear time; requires that the == operator on the type E is well - defined. - """ - return _pywrapcp.SequenceVarContainer___eq__(self, container) - - def __ne__(self, container: "SequenceVarContainer") -> "bool": - return _pywrapcp.SequenceVarContainer___ne__(self, container) - __swig_destroy__ = _pywrapcp.delete_SequenceVarContainer - -# Register SequenceVarContainer in _pywrapcp: -_pywrapcp.SequenceVarContainer_swigregister(SequenceVarContainer) - -class LocalSearchOperator(BaseObject): - r""" - This class represent a reversible FIFO structure. - The main difference w.r.t a standard FIFO structure is that a Solver is - given as parameter to the modifiers such that the solver can store the - backtrack information - Iterator's traversing order should not be changed, as some algorithm - depend on it to be consistent. - It's main use is to store a list of demons in the various classes of - variables. - The base class for all local search operators. - - A local search operator is an object that defines the neighborhood of a - solution. In other words, a neighborhood is the set of solutions which can - be reached from a given solution using an operator. - - The behavior of the LocalSearchOperator class is similar to iterators. - The operator is synchronized with an assignment (gives the - current values of the variables); this is done in the Start() method. - - Then one can iterate over the neighbors using the MakeNextNeighbor method. - This method returns an assignment which represents the incremental changes - to the current solution. It also returns a second assignment representing - the changes to the last solution defined by the neighborhood operator; this - assignment is empty if the neighborhood operator cannot track this - information. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - - def NextNeighbor(self, delta: "Assignment", deltadelta: "Assignment") -> "bool": - return _pywrapcp.LocalSearchOperator_NextNeighbor(self, delta, deltadelta) - - def Start(self, assignment: "Assignment") -> "void": - return _pywrapcp.LocalSearchOperator_Start(self, assignment) - def __disown__(self): - self.this.disown() - _pywrapcp.disown_LocalSearchOperator(self) - return weakref.proxy(self) - -# Register LocalSearchOperator in _pywrapcp: -_pywrapcp.LocalSearchOperator_swigregister(LocalSearchOperator) - -class IntVarLocalSearchOperatorTemplate(LocalSearchOperator): - r""" Base operator class for operators manipulating variables.""" - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - - def Start(self, assignment: "Assignment") -> "void": - r""" - This method should not be overridden. Override OnStart() instead which is - called before exiting this method. - """ - return _pywrapcp.IntVarLocalSearchOperatorTemplate_Start(self, assignment) - - def IsIncremental(self) -> "bool": - return _pywrapcp.IntVarLocalSearchOperatorTemplate_IsIncremental(self) - - def Size(self) -> "int": - return _pywrapcp.IntVarLocalSearchOperatorTemplate_Size(self) - - def Value(self, index: "int64_t") -> "long const &": - r""" - Returns the value in the current assignment of the variable of given - index. - """ - return _pywrapcp.IntVarLocalSearchOperatorTemplate_Value(self, index) - - def OldValue(self, index: "int64_t") -> "long const &": - return _pywrapcp.IntVarLocalSearchOperatorTemplate_OldValue(self, index) - - def SetValue(self, index: "int64_t", value: "long const &") -> "void": - return _pywrapcp.IntVarLocalSearchOperatorTemplate_SetValue(self, index, value) - - def OnStart(self) -> "void": - r""" - Called by Start() after synchronizing the operator with the current - assignment. Should be overridden instead of Start() to avoid calling - VarLocalSearchOperator::Start explicitly. - """ - return _pywrapcp.IntVarLocalSearchOperatorTemplate_OnStart(self) - -# Register IntVarLocalSearchOperatorTemplate in _pywrapcp: -_pywrapcp.IntVarLocalSearchOperatorTemplate_swigregister(IntVarLocalSearchOperatorTemplate) - -class IntVarLocalSearchOperator(IntVarLocalSearchOperatorTemplate): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - - def __init__(self, *args): - if self.__class__ == IntVarLocalSearchOperator: - _self = None - else: - _self = self - _pywrapcp.IntVarLocalSearchOperator_swiginit(self, _pywrapcp.new_IntVarLocalSearchOperator(_self, *args)) - __swig_destroy__ = _pywrapcp.delete_IntVarLocalSearchOperator - - def NextNeighbor(self, delta: "Assignment", deltadelta: "Assignment") -> "bool": - r""" - Redefines MakeNextNeighbor to export a simpler interface. The calls to - ApplyChanges() and RevertChanges() are factored in this method, hiding - both delta and deltadelta from subclasses which only need to override - MakeOneNeighbor(). - Therefore this method should not be overridden. Override MakeOneNeighbor() - instead. - """ - return _pywrapcp.IntVarLocalSearchOperator_NextNeighbor(self, delta, deltadelta) - - def OneNeighbor(self) -> "bool": - r""" - Creates a new neighbor. It returns false when the neighborhood is - completely explored. - MakeNextNeighbor() in a subclass of IntVarLocalSearchOperator. - """ - return _pywrapcp.IntVarLocalSearchOperator_OneNeighbor(self) - def __disown__(self): - self.this.disown() - _pywrapcp.disown_IntVarLocalSearchOperator(self) - return weakref.proxy(self) - -# Register IntVarLocalSearchOperator in _pywrapcp: -_pywrapcp.IntVarLocalSearchOperator_swigregister(IntVarLocalSearchOperator) - -class SequenceVarLocalSearchOperatorTemplate(LocalSearchOperator): - r""" Base operator class for operators manipulating variables.""" - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - - def Start(self, assignment: "Assignment") -> "void": - r""" - This method should not be overridden. Override OnStart() instead which is - called before exiting this method. - """ - return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_Start(self, assignment) - - def IsIncremental(self) -> "bool": - return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_IsIncremental(self) - - def Size(self) -> "int": - return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_Size(self) - - def Value(self, index: "int64_t") -> "std::vector< int > const &": - r""" - Returns the value in the current assignment of the variable of given - index. - """ - return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_Value(self, index) - - def OldValue(self, index: "int64_t") -> "std::vector< int > const &": - return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_OldValue(self, index) - - def SetValue(self, index: "int64_t", value: "std::vector< int > const &") -> "void": - return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_SetValue(self, index, value) - - def OnStart(self) -> "void": - r""" - Called by Start() after synchronizing the operator with the current - assignment. Should be overridden instead of Start() to avoid calling - VarLocalSearchOperator::Start explicitly. - """ - return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_OnStart(self) - -# Register SequenceVarLocalSearchOperatorTemplate in _pywrapcp: -_pywrapcp.SequenceVarLocalSearchOperatorTemplate_swigregister(SequenceVarLocalSearchOperatorTemplate) - -class SequenceVarLocalSearchOperator(SequenceVarLocalSearchOperatorTemplate): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - -# Register SequenceVarLocalSearchOperator in _pywrapcp: -_pywrapcp.SequenceVarLocalSearchOperator_swigregister(SequenceVarLocalSearchOperator) - -class BaseLns(IntVarLocalSearchOperator): - r""" - This is the base class for building an Lns operator. An Lns fragment is a - collection of variables which will be relaxed. Fragments are built with - NextFragment(), which returns false if there are no more fragments to build. - Optionally one can override InitFragments, which is called from - LocalSearchOperator::Start to initialize fragment data. - - Here's a sample relaxing one variable at a time: - - class OneVarLns : public BaseLns { - public: - OneVarLns(const std::vector<IntVar*>& vars) : BaseLns(vars), index_(0) {} - virtual ~OneVarLns() {} - virtual void InitFragments() { index_ = 0; } - virtual bool NextFragment() { - const int size = Size(); - if (index_ < size) { - AppendToFragment(index_); - ++index_; - return true; - } else { - return false; - } - } - - private: - int index_; - }; - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - - def __init__(self, vars: "std::vector< operations_research::IntVar * > const &"): - if self.__class__ == BaseLns: - _self = None - else: - _self = self - _pywrapcp.BaseLns_swiginit(self, _pywrapcp.new_BaseLns(_self, vars)) - __swig_destroy__ = _pywrapcp.delete_BaseLns - - def InitFragments(self) -> "void": - return _pywrapcp.BaseLns_InitFragments(self) - - def NextFragment(self) -> "bool": - return _pywrapcp.BaseLns_NextFragment(self) - - def AppendToFragment(self, index: "int") -> "void": - return _pywrapcp.BaseLns_AppendToFragment(self, index) - - def FragmentSize(self) -> "int": - return _pywrapcp.BaseLns_FragmentSize(self) - - def __getitem__(self, index: "int") -> "int64_t": - return _pywrapcp.BaseLns___getitem__(self, index) - - def __len__(self) -> "int": - return _pywrapcp.BaseLns___len__(self) - def __disown__(self): - self.this.disown() - _pywrapcp.disown_BaseLns(self) - return weakref.proxy(self) - -# Register BaseLns in _pywrapcp: -_pywrapcp.BaseLns_swigregister(BaseLns) - -class ChangeValue(IntVarLocalSearchOperator): - r""" - Defines operators which change the value of variables; - each neighbor corresponds to *one* modified variable. - Sub-classes have to define ModifyValue which determines what the new - variable value is going to be (given the current value and the variable). - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - - def __init__(self, vars: "std::vector< operations_research::IntVar * > const &"): - if self.__class__ == ChangeValue: - _self = None - else: - _self = self - _pywrapcp.ChangeValue_swiginit(self, _pywrapcp.new_ChangeValue(_self, vars)) - __swig_destroy__ = _pywrapcp.delete_ChangeValue - - def ModifyValue(self, index: "int64_t", value: "int64_t") -> "int64_t": - return _pywrapcp.ChangeValue_ModifyValue(self, index, value) - - def OneNeighbor(self) -> "bool": - r""" This method should not be overridden. Override ModifyValue() instead.""" - return _pywrapcp.ChangeValue_OneNeighbor(self) - def __disown__(self): - self.this.disown() - _pywrapcp.disown_ChangeValue(self) - return weakref.proxy(self) - -# Register ChangeValue in _pywrapcp: -_pywrapcp.ChangeValue_swigregister(ChangeValue) - -class PathOperator(IntVarLocalSearchOperator): - r""" - Base class of the local search operators dedicated to path modifications - (a path is a set of nodes linked together by arcs). - This family of neighborhoods supposes they are handling next variables - representing the arcs (var[i] represents the node immediately after i on - a path). - Several services are provided: - - arc manipulators (SetNext(), ReverseChain(), MoveChain()) - - path inspectors (Next(), Prev(), IsPathEnd()) - - path iterators: operators need a given number of nodes to define a - neighbor; this class provides the iteration on a given number of (base) - nodes which can be used to define a neighbor (through the BaseNode method) - Subclasses only need to override MakeNeighbor to create neighbors using - the services above (no direct manipulation of assignments). - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - - def Neighbor(self) -> "bool": - return _pywrapcp.PathOperator_Neighbor(self) - -# Register PathOperator in _pywrapcp: -_pywrapcp.PathOperator_swigregister(PathOperator) - -class LocalSearchFilter(BaseObject): - r""" - Classes to which this template function can be applied to as of 04/2014. - Usage: LocalSearchOperator* op = MakeLocalSearchOperator<Relocate>(...); - class TwoOpt; - class Relocate; - class Exchange; - class Cross; - class MakeActiveOperator; - class MakeInactiveOperator; - class MakeChainInactiveOperator; - class SwapActiveOperator; - class ExtendedSwapActiveOperator; - class MakeActiveAndRelocate; - class RelocateAndMakeActiveOperator; - class RelocateAndMakeInactiveOperator; - Local Search Filters are used for fast neighbor pruning. - Filtering a move is done in several phases: - - in the Relax phase, filters determine which parts of their internals - will be changed by the candidate, and modify intermediary State - - in the Accept phase, filters check that the candidate is feasible, - - if the Accept phase succeeds, the solver may decide to trigger a - Synchronize phase that makes filters change their internal representation - to the last candidate, - - otherwise (Accept fails or the solver does not want to synchronize), - a Revert phase makes filters erase any intermediary State generated by the - Relax and Accept phases. - A given filter has phases called with the following pattern: - (Relax.Accept.Synchronize | Relax.Accept.Revert | Relax.Revert)*. - Filters's Revert() is always called in the reverse order their Accept() was - called, to allow late filters to use state done/undone by early filters' - Accept()/Revert(). - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - - def Accept(self, delta: "Assignment", deltadelta: "Assignment", objective_min: "int64_t", objective_max: "int64_t") -> "bool": - r""" - Accepts a "delta" given the assignment with which the filter has been - synchronized; the delta holds the variables which have been modified and - their new value. - If the filter represents a part of the global objective, its contribution - must be between objective_min and objective_max. - Sample: supposing one wants to maintain a[0,1] + b[0,1] <= 1, - for the assignment (a,1), (b,0), the delta (b,1) will be rejected - but the delta (a,0) will be accepted. - TODO(user): Remove arguments when there are no more need for those. - """ - return _pywrapcp.LocalSearchFilter_Accept(self, delta, deltadelta, objective_min, objective_max) - - def IsIncremental(self) -> "bool": - return _pywrapcp.LocalSearchFilter_IsIncremental(self) - - def Synchronize(self, assignment: "Assignment", delta: "Assignment") -> "void": - r""" - Synchronizes the filter with the current solution, delta being the - difference with the solution passed to the previous call to Synchronize() - or IncrementalSynchronize(). 'delta' can be used to incrementally - synchronizing the filter with the new solution by only considering the - changes in delta. - """ - return _pywrapcp.LocalSearchFilter_Synchronize(self, assignment, delta) - __swig_destroy__ = _pywrapcp.delete_LocalSearchFilter - -# Register LocalSearchFilter in _pywrapcp: -_pywrapcp.LocalSearchFilter_swigregister(LocalSearchFilter) - -class LocalSearchFilterManager(BaseObject): - r""" - Filter manager: when a move is made, filters are executed to decide whether - the solution is feasible and compute parts of the new cost. This class - schedules filter execution and composes costs as a sum. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - - def DebugString(self) -> "std::string": - return _pywrapcp.LocalSearchFilterManager_DebugString(self) - - def __init__(self, *args): - _pywrapcp.LocalSearchFilterManager_swiginit(self, _pywrapcp.new_LocalSearchFilterManager(*args)) - - def Accept(self, monitor: "operations_research::LocalSearchMonitor *const", delta: "Assignment", deltadelta: "Assignment", objective_min: "int64_t", objective_max: "int64_t") -> "bool": - r""" - Returns true iff all filters return true, and the sum of their accepted - objectives is between objective_min and objective_max. - The monitor has its Begin/EndFiltering events triggered. - """ - return _pywrapcp.LocalSearchFilterManager_Accept(self, monitor, delta, deltadelta, objective_min, objective_max) - - def Synchronize(self, assignment: "Assignment", delta: "Assignment") -> "void": - r""" Synchronizes all filters to assignment.""" - return _pywrapcp.LocalSearchFilterManager_Synchronize(self, assignment, delta) - __swig_destroy__ = _pywrapcp.delete_LocalSearchFilterManager - -# Register LocalSearchFilterManager in _pywrapcp: -_pywrapcp.LocalSearchFilterManager_swigregister(LocalSearchFilterManager) - -class IntVarLocalSearchFilter(LocalSearchFilter): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - - def __init__(self, vars: "std::vector< operations_research::IntVar * > const &"): - if self.__class__ == IntVarLocalSearchFilter: - _self = None - else: - _self = self - _pywrapcp.IntVarLocalSearchFilter_swiginit(self, _pywrapcp.new_IntVarLocalSearchFilter(_self, vars)) - __swig_destroy__ = _pywrapcp.delete_IntVarLocalSearchFilter - - def Synchronize(self, assignment: "Assignment", delta: "Assignment") -> "void": - r""" - This method should not be overridden. Override OnSynchronize() instead - which is called before exiting this method. - """ - return _pywrapcp.IntVarLocalSearchFilter_Synchronize(self, assignment, delta) - - def Size(self) -> "int": - return _pywrapcp.IntVarLocalSearchFilter_Size(self) - - def Value(self, index: "int") -> "int64_t": - return _pywrapcp.IntVarLocalSearchFilter_Value(self, index) - - def IndexFromVar(self, var: "IntVar") -> "int64_t": - return _pywrapcp.IntVarLocalSearchFilter_IndexFromVar(self, var) - def __disown__(self): - self.this.disown() - _pywrapcp.disown_IntVarLocalSearchFilter(self) - return weakref.proxy(self) - -# Register IntVarLocalSearchFilter in _pywrapcp: -_pywrapcp.IntVarLocalSearchFilter_swigregister(IntVarLocalSearchFilter) - -class BooleanVar(IntVar): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - - def Min(self) -> "int64_t": - return _pywrapcp.BooleanVar_Min(self) - - def SetMin(self, m: "int64_t") -> "void": - return _pywrapcp.BooleanVar_SetMin(self, m) - - def Max(self) -> "int64_t": - return _pywrapcp.BooleanVar_Max(self) - - def SetMax(self, m: "int64_t") -> "void": - return _pywrapcp.BooleanVar_SetMax(self, m) - - def SetRange(self, mi: "int64_t", ma: "int64_t") -> "void": - return _pywrapcp.BooleanVar_SetRange(self, mi, ma) - - def Bound(self) -> "bool": - return _pywrapcp.BooleanVar_Bound(self) - - def Value(self) -> "int64_t": - return _pywrapcp.BooleanVar_Value(self) - - def RemoveValue(self, v: "int64_t") -> "void": - return _pywrapcp.BooleanVar_RemoveValue(self, v) - - def RemoveInterval(self, l: "int64_t", u: "int64_t") -> "void": - return _pywrapcp.BooleanVar_RemoveInterval(self, l, u) - - def WhenBound(self, d: "Demon") -> "void": - return _pywrapcp.BooleanVar_WhenBound(self, d) - - def WhenRange(self, d: "Demon") -> "void": - return _pywrapcp.BooleanVar_WhenRange(self, d) - - def WhenDomain(self, d: "Demon") -> "void": - return _pywrapcp.BooleanVar_WhenDomain(self, d) - - def Size(self) -> "uint64_t": - return _pywrapcp.BooleanVar_Size(self) - - def Contains(self, v: "int64_t") -> "bool": - return _pywrapcp.BooleanVar_Contains(self, v) - - def HoleIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *": - return _pywrapcp.BooleanVar_HoleIteratorAux(self, reversible) - - def DomainIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *": - return _pywrapcp.BooleanVar_DomainIteratorAux(self, reversible) - - def DebugString(self) -> "std::string": - return _pywrapcp.BooleanVar_DebugString(self) - -# Register BooleanVar in _pywrapcp: -_pywrapcp.BooleanVar_swigregister(BooleanVar) - - -class PyDecision(Decision): - - def __init__(self): - Decision.__init__(self) - - def ApplyWrapper(self, solver): - try: - self.Apply(solver) - except Exception as e: - if 'CP Solver fail' in str(e): - solver.ShouldFail() - else: - raise - - def RefuteWrapper(self, solver): - try: - self.Refute(solver) - except Exception as e: - if 'CP Solver fail' in str(e): - solver.ShouldFail() - else: - raise - - def DebugString(self): - return "PyDecision" - - -class PyDecisionBuilder(DecisionBuilder): - - def __init__(self): - DecisionBuilder.__init__(self) - - def NextWrapper(self, solver): - try: - return self.Next(solver) - except Exception as e: - if 'CP Solver fail' in str(e): - return solver.FailDecision() - else: - raise - - def DebugString(self): - return "PyDecisionBuilder" - - -class PyDemon(Demon): - - def RunWrapper(self, solver): - try: - self.Run(solver) - except Exception as e: - if 'CP Solver fail' in str(e): - solver.ShouldFail() - else: - raise - - def DebugString(self): - return "PyDemon" - - -class PyConstraintDemon(PyDemon): - - def __init__(self, ct, method, delayed, *args): - PyDemon.__init__(self) - self.__constraint = ct - self.__method = method - self.__delayed = delayed - self.__args = args - - def Run(self, solver): - self.__method(self.__constraint, *self.__args) - - def Priority(self): - return Solver.DELAYED_PRIORITY if self.__delayed else Solver.NORMAL_PRIORITY - - def DebugString(self): - return 'PyConstraintDemon' - - -class PyConstraint(Constraint): - - def __init__(self, solver): - Constraint.__init__(self, solver) - self.__demons = [] - - def Demon(self, method, *args): - demon = PyConstraintDemon(self, method, False, *args) - self.__demons.append(demon) - return demon - - def DelayedDemon(self, method, *args): - demon = PyConstraintDemon(self, method, True, *args) - self.__demons.append(demon) - return demon - - def InitialPropagateDemon(self): - return self.solver().ConstraintInitialPropagateCallback(self) - - def DelayedInitialPropagateDemon(self): - return self.solver().DelayedConstraintInitialPropagateCallback(self) - - def InitialPropagateWrapper(self): - try: - self.InitialPropagate() - except Exception as e: - if 'CP Solver fail' in str(e): - self.solver().ShouldFail() - else: - raise - - def DebugString(self): - return "PyConstraint" - - - -class RoutingIndexManager(object): - r""" - Manager for any NodeIndex <-> variable index conversion. The routing solver - uses variable indices internally and through its API. These variable indices - are tricky to manage directly because one Node can correspond to a multitude - of variables, depending on the number of times they appear in the model, and - if they're used as start and/or end points. This class aims to simplify - variable index usage, allowing users to use NodeIndex instead. - - Usage: - - .. code-block:: c++ - - auto starts_ends = ...; /// These are NodeIndex. - RoutingIndexManager manager(10, 4, starts_ends); // 10 nodes, 4 vehicles. - RoutingModel model(manager); - - Then, use 'manager.NodeToIndex(node)' whenever model requires a variable - index. - - Note: the mapping between node indices and variables indices is subject to - change so no assumption should be made on it. The only guarantee is that - indices range between 0 and n-1, where n = number of vehicles * 2 (for start - and end nodes) + number of non-start or end nodes. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - - def __init__(self, *args): - _pywrapcp.RoutingIndexManager_swiginit(self, _pywrapcp.new_RoutingIndexManager(*args)) - __swig_destroy__ = _pywrapcp.delete_RoutingIndexManager - - def GetNumberOfNodes(self) -> "int": - return _pywrapcp.RoutingIndexManager_GetNumberOfNodes(self) - - def GetNumberOfVehicles(self) -> "int": - return _pywrapcp.RoutingIndexManager_GetNumberOfVehicles(self) - - def GetNumberOfIndices(self) -> "int": - return _pywrapcp.RoutingIndexManager_GetNumberOfIndices(self) - - def GetStartIndex(self, vehicle: "int") -> "int64_t": - return _pywrapcp.RoutingIndexManager_GetStartIndex(self, vehicle) - - def GetEndIndex(self, vehicle: "int") -> "int64_t": - return _pywrapcp.RoutingIndexManager_GetEndIndex(self, vehicle) - - def NodeToIndex(self, node: "operations_research::RoutingIndexManager::NodeIndex") -> "int64_t": - return _pywrapcp.RoutingIndexManager_NodeToIndex(self, node) - - def IndexToNode(self, index: "int64_t") -> "operations_research::RoutingIndexManager::NodeIndex": - return _pywrapcp.RoutingIndexManager_IndexToNode(self, index) - -# Register RoutingIndexManager in _pywrapcp: -_pywrapcp.RoutingIndexManager_swigregister(RoutingIndexManager) - - -def DefaultRoutingModelParameters() -> "operations_research::RoutingModelParameters": - return _pywrapcp.DefaultRoutingModelParameters() - -def DefaultRoutingSearchParameters() -> "operations_research::RoutingSearchParameters": - return _pywrapcp.DefaultRoutingSearchParameters() - -def FindErrorInRoutingSearchParameters(search_parameters: "operations_research::RoutingSearchParameters const &") -> "std::string": - r""" - Returns an empty std::string if the routing search parameters are valid, and - a non-empty, human readable error description if they're not. - """ - return _pywrapcp.FindErrorInRoutingSearchParameters(search_parameters) -BOOL_UNSPECIFIED = _pywrapcp.BOOL_UNSPECIFIED -BOOL_FALSE = _pywrapcp.BOOL_FALSE -BOOL_TRUE = _pywrapcp.BOOL_TRUE -class RoutingModel(object): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - ROUTING_NOT_SOLVED = _pywrapcp.RoutingModel_ROUTING_NOT_SOLVED - r""" Problem not solved yet (before calling RoutingModel::Solve()).""" - ROUTING_SUCCESS = _pywrapcp.RoutingModel_ROUTING_SUCCESS - r""" Problem solved successfully after calling RoutingModel::Solve().""" - ROUTING_FAIL = _pywrapcp.RoutingModel_ROUTING_FAIL - r""" No solution found to the problem after calling RoutingModel::Solve().""" - ROUTING_FAIL_TIMEOUT = _pywrapcp.RoutingModel_ROUTING_FAIL_TIMEOUT - r""" Time limit reached before finding a solution with RoutingModel::Solve().""" - ROUTING_INVALID = _pywrapcp.RoutingModel_ROUTING_INVALID - r""" Model, model parameters or flags are not valid.""" - PICKUP_AND_DELIVERY_NO_ORDER = _pywrapcp.RoutingModel_PICKUP_AND_DELIVERY_NO_ORDER - r""" Any precedence is accepted.""" - PICKUP_AND_DELIVERY_LIFO = _pywrapcp.RoutingModel_PICKUP_AND_DELIVERY_LIFO - r""" Deliveries must be performed in reverse order of pickups.""" - PICKUP_AND_DELIVERY_FIFO = _pywrapcp.RoutingModel_PICKUP_AND_DELIVERY_FIFO - r""" Deliveries must be performed in the same order as pickups.""" - - def __init__(self, *args): - _pywrapcp.RoutingModel_swiginit(self, _pywrapcp.new_RoutingModel(*args)) - __swig_destroy__ = _pywrapcp.delete_RoutingModel - - def RegisterUnaryTransitVector(self, values: "std::vector< int64_t >") -> "int": - r""" Registers 'callback' and returns its index.""" - return _pywrapcp.RoutingModel_RegisterUnaryTransitVector(self, values) - - def RegisterUnaryTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback1") -> "int": - return _pywrapcp.RoutingModel_RegisterUnaryTransitCallback(self, callback) - - def RegisterPositiveUnaryTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback1") -> "int": - return _pywrapcp.RoutingModel_RegisterPositiveUnaryTransitCallback(self, callback) - - def RegisterTransitMatrix(self, values: "std::vector< std::vector< int64_t > >") -> "int": - return _pywrapcp.RoutingModel_RegisterTransitMatrix(self, values) - - def RegisterTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback2") -> "int": - return _pywrapcp.RoutingModel_RegisterTransitCallback(self, callback) - - def RegisterPositiveTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback2") -> "int": - return _pywrapcp.RoutingModel_RegisterPositiveTransitCallback(self, callback) - - def TransitCallback(self, callback_index: "int") -> "operations_research::RoutingModel::TransitCallback2 const &": - return _pywrapcp.RoutingModel_TransitCallback(self, callback_index) - - def UnaryTransitCallbackOrNull(self, callback_index: "int") -> "operations_research::RoutingModel::TransitCallback1 const &": - return _pywrapcp.RoutingModel_UnaryTransitCallbackOrNull(self, callback_index) - - def AddDimension(self, evaluator_index: "int", slack_max: "int64_t", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool": - r""" - Model creation - Methods to add dimensions to routes; dimensions represent quantities - accumulated at nodes along the routes. They represent quantities such as - weights or volumes carried along the route, or distance or times. - Quantities at a node are represented by "cumul" variables and the increase - or decrease of quantities between nodes are represented by "transit" - variables. These variables are linked as follows: - if j == next(i), cumul(j) = cumul(i) + transit(i) + slack(i) - where slack is a positive slack variable (can represent waiting times for - a time dimension). - Setting the value of fix_start_cumul_to_zero to true will force the - "cumul" variable of the start node of all vehicles to be equal to 0. - Creates a dimension where the transit variable is constrained to be - equal to evaluator(i, next(i)); 'slack_max' is the upper bound of the - slack variable and 'capacity' is the upper bound of the cumul variables. - 'name' is the name used to reference the dimension; this name is used to - get cumul and transit variables from the routing model. - Returns false if a dimension with the same name has already been created - (and doesn't create the new dimension). - Takes ownership of the callback 'evaluator'. - """ - return _pywrapcp.RoutingModel_AddDimension(self, evaluator_index, slack_max, capacity, fix_start_cumul_to_zero, name) - - def AddDimensionWithVehicleTransits(self, evaluator_indices: "std::vector< int > const &", slack_max: "int64_t", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool": - return _pywrapcp.RoutingModel_AddDimensionWithVehicleTransits(self, evaluator_indices, slack_max, capacity, fix_start_cumul_to_zero, name) - - def AddDimensionWithVehicleCapacity(self, evaluator_index: "int", slack_max: "int64_t", vehicle_capacities: "std::vector< int64_t >", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool": - return _pywrapcp.RoutingModel_AddDimensionWithVehicleCapacity(self, evaluator_index, slack_max, vehicle_capacities, fix_start_cumul_to_zero, name) - - def AddDimensionWithVehicleTransitAndCapacity(self, evaluator_indices: "std::vector< int > const &", slack_max: "int64_t", vehicle_capacities: "std::vector< int64_t >", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool": - return _pywrapcp.RoutingModel_AddDimensionWithVehicleTransitAndCapacity(self, evaluator_indices, slack_max, vehicle_capacities, fix_start_cumul_to_zero, name) - - def AddConstantDimensionWithSlack(self, value: "int64_t", capacity: "int64_t", slack_max: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >": - r""" - Creates a dimension where the transit variable is constrained to be - equal to 'value'; 'capacity' is the upper bound of the cumul variables. - 'name' is the name used to reference the dimension; this name is used to - get cumul and transit variables from the routing model. - Returns a pair consisting of an index to the registered unary transit - callback and a bool denoting whether the dimension has been created. - It is false if a dimension with the same name has already been created - (and doesn't create the new dimension but still register a new callback). - """ - return _pywrapcp.RoutingModel_AddConstantDimensionWithSlack(self, value, capacity, slack_max, fix_start_cumul_to_zero, name) - - def AddConstantDimension(self, value: "int64_t", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >": - return _pywrapcp.RoutingModel_AddConstantDimension(self, value, capacity, fix_start_cumul_to_zero, name) - - def AddVectorDimension(self, values: "std::vector< int64_t >", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >": - r""" - Creates a dimension where the transit variable is constrained to be - equal to 'values[i]' for node i; 'capacity' is the upper bound of - the cumul variables. 'name' is the name used to reference the dimension; - this name is used to get cumul and transit variables from the routing - model. - Returns a pair consisting of an index to the registered unary transit - callback and a bool denoting whether the dimension has been created. - It is false if a dimension with the same name has already been created - (and doesn't create the new dimension but still register a new callback). - """ - return _pywrapcp.RoutingModel_AddVectorDimension(self, values, capacity, fix_start_cumul_to_zero, name) - - def AddMatrixDimension(self, values: "std::vector< std::vector< int64_t > >", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >": - r""" - Creates a dimension where the transit variable is constrained to be - equal to 'values[i][next(i)]' for node i; 'capacity' is the upper bound of - the cumul variables. 'name' is the name used to reference the dimension; - this name is used to get cumul and transit variables from the routing - model. - Returns a pair consisting of an index to the registered transit callback - and a bool denoting whether the dimension has been created. - It is false if a dimension with the same name has already been created - (and doesn't create the new dimension but still register a new callback). - """ - return _pywrapcp.RoutingModel_AddMatrixDimension(self, values, capacity, fix_start_cumul_to_zero, name) - - def MakePathSpansAndTotalSlacks(self, dimension: "RoutingDimension", spans: "std::vector< operations_research::IntVar * >", total_slacks: "std::vector< operations_research::IntVar * >") -> "operations_research::Constraint *": - r""" - For every vehicle of the routing model: - - if total_slacks[vehicle] is not nullptr, constrains it to be the sum of - slacks on that vehicle, that is, - dimension->CumulVar(end) - dimension->CumulVar(start) - - sum_{node in path of vehicle} dimension->FixedTransitVar(node). - - if spans[vehicle] is not nullptr, constrains it to be - dimension->CumulVar(end) - dimension->CumulVar(start) - This does stronger propagation than a decomposition, and takes breaks into - account. - """ - return _pywrapcp.RoutingModel_MakePathSpansAndTotalSlacks(self, dimension, spans, total_slacks) - - def GetAllDimensionNames(self) -> "std::vector< std::string >": - r""" Outputs the names of all dimensions added to the routing engine.""" - return _pywrapcp.RoutingModel_GetAllDimensionNames(self) - - def GetDimensions(self) -> "std::vector< operations_research::RoutingDimension * > const &": - r""" Returns all dimensions of the model.""" - return _pywrapcp.RoutingModel_GetDimensions(self) - - def GetDimensionsWithSoftOrSpanCosts(self) -> "std::vector< operations_research::RoutingDimension * >": - r""" Returns dimensions with soft or vehicle span costs.""" - return _pywrapcp.RoutingModel_GetDimensionsWithSoftOrSpanCosts(self) - - def GetGlobalDimensionCumulOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::GlobalDimensionCumulOptimizer > > const &": - r""" - Returns [global|local]_dimension_optimizers_, which are empty if the model - has not been closed. - """ - return _pywrapcp.RoutingModel_GetGlobalDimensionCumulOptimizers(self) - - def GetLocalDimensionCumulOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::LocalDimensionCumulOptimizer > > const &": - return _pywrapcp.RoutingModel_GetLocalDimensionCumulOptimizers(self) - - def GetLocalDimensionCumulMPOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::LocalDimensionCumulOptimizer > > const &": - return _pywrapcp.RoutingModel_GetLocalDimensionCumulMPOptimizers(self) - - def GetMutableGlobalCumulOptimizer(self, dimension: "RoutingDimension") -> "operations_research::GlobalDimensionCumulOptimizer *": - r""" - Returns the global/local dimension cumul optimizer for a given dimension, - or nullptr if there is none. - """ - return _pywrapcp.RoutingModel_GetMutableGlobalCumulOptimizer(self, dimension) - - def GetMutableLocalCumulOptimizer(self, dimension: "RoutingDimension") -> "operations_research::LocalDimensionCumulOptimizer *": - return _pywrapcp.RoutingModel_GetMutableLocalCumulOptimizer(self, dimension) - - def GetMutableLocalCumulMPOptimizer(self, dimension: "RoutingDimension") -> "operations_research::LocalDimensionCumulOptimizer *": - return _pywrapcp.RoutingModel_GetMutableLocalCumulMPOptimizer(self, dimension) - - def HasDimension(self, dimension_name: "std::string const &") -> "bool": - r""" Returns true if a dimension exists for a given dimension name.""" - return _pywrapcp.RoutingModel_HasDimension(self, dimension_name) - - def GetDimensionOrDie(self, dimension_name: "std::string const &") -> "operations_research::RoutingDimension const &": - r""" Returns a dimension from its name. Dies if the dimension does not exist.""" - return _pywrapcp.RoutingModel_GetDimensionOrDie(self, dimension_name) - - def GetMutableDimension(self, dimension_name: "std::string const &") -> "operations_research::RoutingDimension *": - r""" - Returns a dimension from its name. Returns nullptr if the dimension does - not exist. - """ - return _pywrapcp.RoutingModel_GetMutableDimension(self, dimension_name) - - def SetPrimaryConstrainedDimension(self, dimension_name: "std::string const &") -> "void": - r""" - Set the given dimension as "primary constrained". As of August 2013, this - is only used by ArcIsMoreConstrainedThanArc(). - "dimension" must be the name of an existing dimension, or be empty, in - which case there will not be a primary dimension after this call. - """ - return _pywrapcp.RoutingModel_SetPrimaryConstrainedDimension(self, dimension_name) - - def GetPrimaryConstrainedDimension(self) -> "std::string const &": - r""" Get the primary constrained dimension, or an empty string if it is unset.""" - return _pywrapcp.RoutingModel_GetPrimaryConstrainedDimension(self) - - def AddDisjunction(self, *args) -> "operations_research::RoutingModel::DisjunctionIndex": - r""" - Adds a disjunction constraint on the indices: exactly 'max_cardinality' of - the indices are active. Start and end indices of any vehicle cannot be - part of a disjunction. - - If a penalty is given, at most 'max_cardinality' of the indices can be - active, and if less are active, 'penalty' is payed per inactive index. - This is equivalent to adding the constraint: - p + Sum(i)active[i] == max_cardinality - where p is an integer variable, and the following cost to the cost - function: - p * penalty. - 'penalty' must be positive to make the disjunction optional; a negative - penalty will force 'max_cardinality' indices of the disjunction to be - performed, and therefore p == 0. - Note: passing a vector with a single index will model an optional index - with a penalty cost if it is not visited. - """ - return _pywrapcp.RoutingModel_AddDisjunction(self, *args) - - def GetDisjunctionIndices(self, index: "int64_t") -> "std::vector< operations_research::RoutingModel::DisjunctionIndex > const &": - r""" Returns the indices of the disjunctions to which an index belongs.""" - return _pywrapcp.RoutingModel_GetDisjunctionIndices(self, index) - - def GetDisjunctionPenalty(self, index: "operations_research::RoutingModel::DisjunctionIndex") -> "int64_t": - r""" Returns the penalty of the node disjunction of index 'index'.""" - return _pywrapcp.RoutingModel_GetDisjunctionPenalty(self, index) - - def GetDisjunctionMaxCardinality(self, index: "operations_research::RoutingModel::DisjunctionIndex") -> "int64_t": - r""" - Returns the maximum number of possible active nodes of the node - disjunction of index 'index'. - """ - return _pywrapcp.RoutingModel_GetDisjunctionMaxCardinality(self, index) - - def GetNumberOfDisjunctions(self) -> "int": - r""" Returns the number of node disjunctions in the model.""" - return _pywrapcp.RoutingModel_GetNumberOfDisjunctions(self) - - def GetPerfectBinaryDisjunctions(self) -> "std::vector< std::pair< int64_t,int64_t > >": - r""" - Returns the list of all perfect binary disjunctions, as pairs of variable - indices: a disjunction is "perfect" when its variables do not appear in - any other disjunction. Each pair is sorted (lowest variable index first), - and the output vector is also sorted (lowest pairs first). - """ - return _pywrapcp.RoutingModel_GetPerfectBinaryDisjunctions(self) - - def IgnoreDisjunctionsAlreadyForcedToZero(self) -> "void": - r""" - SPECIAL: Makes the solver ignore all the disjunctions whose active - variables are all trivially zero (i.e. Max() == 0), by setting their - max_cardinality to 0. - This can be useful when using the BaseBinaryDisjunctionNeighborhood - operators, in the context of arc-based routing. - """ - return _pywrapcp.RoutingModel_IgnoreDisjunctionsAlreadyForcedToZero(self) - - def AddSoftSameVehicleConstraint(self, indices: "std::vector< int64_t > const &", cost: "int64_t") -> "void": - r""" - Adds a soft constraint to force a set of variable indices to be on the - same vehicle. If all nodes are not on the same vehicle, each extra vehicle - used adds 'cost' to the cost function. - """ - return _pywrapcp.RoutingModel_AddSoftSameVehicleConstraint(self, indices, cost) - - def SetAllowedVehiclesForIndex(self, vehicles: "std::vector< int > const &", index: "int64_t") -> "void": - r""" - Sets the vehicles which can visit a given node. If the node is in a - disjunction, this will not prevent it from being unperformed. - Specifying an empty vector of vehicles has no effect (all vehicles - will be allowed to visit the node). - """ - return _pywrapcp.RoutingModel_SetAllowedVehiclesForIndex(self, vehicles, index) - - def IsVehicleAllowedForIndex(self, vehicle: "int", index: "int64_t") -> "bool": - r""" Returns true if a vehicle is allowed to visit a given node.""" - return _pywrapcp.RoutingModel_IsVehicleAllowedForIndex(self, vehicle, index) - - def AddPickupAndDelivery(self, pickup: "int64_t", delivery: "int64_t") -> "void": - r""" - Notifies that index1 and index2 form a pair of nodes which should belong - to the same route. This methods helps the search find better solutions, - especially in the local search phase. - It should be called each time you have an equality constraint linking - the vehicle variables of two node (including for instance pickup and - delivery problems): - Solver* const solver = routing.solver(); - int64_t index1 = manager.NodeToIndex(node1); - int64_t index2 = manager.NodeToIndex(node2); - solver->AddConstraint(solver->MakeEquality( - routing.VehicleVar(index1), - routing.VehicleVar(index2))); - routing.AddPickupAndDelivery(index1, index2); - """ - return _pywrapcp.RoutingModel_AddPickupAndDelivery(self, pickup, delivery) - - def AddPickupAndDeliverySets(self, pickup_disjunction: "operations_research::RoutingModel::DisjunctionIndex", delivery_disjunction: "operations_research::RoutingModel::DisjunctionIndex") -> "void": - r""" - Same as AddPickupAndDelivery but notifying that the performed node from - the disjunction of index 'pickup_disjunction' is on the same route as the - performed node from the disjunction of index 'delivery_disjunction'. - """ - return _pywrapcp.RoutingModel_AddPickupAndDeliverySets(self, pickup_disjunction, delivery_disjunction) - - def GetPickupIndexPairs(self, node_index: "int64_t") -> "std::vector< std::pair< int,int > > const &": - r""" - Returns pairs for which the node is a pickup; the first element of each - pair is the index in the pickup and delivery pairs list in which the - pickup appears, the second element is its index in the pickups list. - """ - return _pywrapcp.RoutingModel_GetPickupIndexPairs(self, node_index) - - def GetDeliveryIndexPairs(self, node_index: "int64_t") -> "std::vector< std::pair< int,int > > const &": - r""" Same as above for deliveries.""" - return _pywrapcp.RoutingModel_GetDeliveryIndexPairs(self, node_index) - - def SetPickupAndDeliveryPolicyOfAllVehicles(self, policy: "operations_research::RoutingModel::PickupAndDeliveryPolicy") -> "void": - r""" - Sets the Pickup and delivery policy of all vehicles. It is equivalent to - calling SetPickupAndDeliveryPolicyOfVehicle on all vehicles. - """ - return _pywrapcp.RoutingModel_SetPickupAndDeliveryPolicyOfAllVehicles(self, policy) - - def SetPickupAndDeliveryPolicyOfVehicle(self, policy: "operations_research::RoutingModel::PickupAndDeliveryPolicy", vehicle: "int") -> "void": - return _pywrapcp.RoutingModel_SetPickupAndDeliveryPolicyOfVehicle(self, policy, vehicle) - - def GetPickupAndDeliveryPolicyOfVehicle(self, vehicle: "int") -> "operations_research::RoutingModel::PickupAndDeliveryPolicy": - return _pywrapcp.RoutingModel_GetPickupAndDeliveryPolicyOfVehicle(self, vehicle) - - def GetNumOfSingletonNodes(self) -> "int": - r""" - Returns the number of non-start/end nodes which do not appear in a - pickup/delivery pair. - """ - return _pywrapcp.RoutingModel_GetNumOfSingletonNodes(self) - TYPE_ADDED_TO_VEHICLE = _pywrapcp.RoutingModel_TYPE_ADDED_TO_VEHICLE - r""" When visited, the number of types 'T' on the vehicle increases by one.""" - ADDED_TYPE_REMOVED_FROM_VEHICLE = _pywrapcp.RoutingModel_ADDED_TYPE_REMOVED_FROM_VEHICLE - r""" - When visited, one instance of type 'T' previously added to the route - (TYPE_ADDED_TO_VEHICLE), if any, is removed from the vehicle. - If the type was not previously added to the route or all added instances - have already been removed, this visit has no effect on the types. - """ - TYPE_ON_VEHICLE_UP_TO_VISIT = _pywrapcp.RoutingModel_TYPE_ON_VEHICLE_UP_TO_VISIT - r""" - With the following policy, the visit enforces that type 'T' is - considered on the route from its start until this node is visited. - """ - TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED = _pywrapcp.RoutingModel_TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED - r""" - The visit doesn't have an impact on the number of types 'T' on the - route, as it's (virtually) added and removed directly. - This policy can be used for visits which are part of an incompatibility - or requirement set without affecting the type count on the route. - """ - - def SetVisitType(self, index: "int64_t", type: "int", type_policy: "operations_research::RoutingModel::VisitTypePolicy") -> "void": - return _pywrapcp.RoutingModel_SetVisitType(self, index, type, type_policy) - - def GetVisitType(self, index: "int64_t") -> "int": - return _pywrapcp.RoutingModel_GetVisitType(self, index) - - def GetSingleNodesOfType(self, type: "int") -> "std::vector< int > const &": - return _pywrapcp.RoutingModel_GetSingleNodesOfType(self, type) - - def GetPairIndicesOfType(self, type: "int") -> "std::vector< int > const &": - return _pywrapcp.RoutingModel_GetPairIndicesOfType(self, type) - - def GetVisitTypePolicy(self, index: "int64_t") -> "operations_research::RoutingModel::VisitTypePolicy": - return _pywrapcp.RoutingModel_GetVisitTypePolicy(self, index) - - def CloseVisitTypes(self) -> "void": - r""" - This function should be called once all node visit types have been set and - prior to adding any incompatibilities/requirements. - "close" types. - """ - return _pywrapcp.RoutingModel_CloseVisitTypes(self) - - def GetNumberOfVisitTypes(self) -> "int": - return _pywrapcp.RoutingModel_GetNumberOfVisitTypes(self) - - def AddHardTypeIncompatibility(self, type1: "int", type2: "int") -> "void": - r""" - Incompatibilities: - Two nodes with "hard" incompatible types cannot share the same route at - all, while with a "temporal" incompatibility they can't be on the same - route at the same time. - """ - return _pywrapcp.RoutingModel_AddHardTypeIncompatibility(self, type1, type2) - - def AddTemporalTypeIncompatibility(self, type1: "int", type2: "int") -> "void": - return _pywrapcp.RoutingModel_AddTemporalTypeIncompatibility(self, type1, type2) - - def GetHardTypeIncompatibilitiesOfType(self, type: "int") -> "absl::flat_hash_set< int > const &": - r""" Returns visit types incompatible with a given type.""" - return _pywrapcp.RoutingModel_GetHardTypeIncompatibilitiesOfType(self, type) - - def GetTemporalTypeIncompatibilitiesOfType(self, type: "int") -> "absl::flat_hash_set< int > const &": - return _pywrapcp.RoutingModel_GetTemporalTypeIncompatibilitiesOfType(self, type) - - def HasHardTypeIncompatibilities(self) -> "bool": - r""" - Returns true iff any hard (resp. temporal) type incompatibilities have - been added to the model. - """ - return _pywrapcp.RoutingModel_HasHardTypeIncompatibilities(self) - - def HasTemporalTypeIncompatibilities(self) -> "bool": - return _pywrapcp.RoutingModel_HasTemporalTypeIncompatibilities(self) - - def AddSameVehicleRequiredTypeAlternatives(self, dependent_type: "int", required_type_alternatives: "absl::flat_hash_set< int >") -> "void": - r""" - Requirements: - NOTE: As of 2019-04, cycles in the requirement graph are not supported, - and lead to the dependent nodes being skipped if possible (otherwise - the model is considered infeasible). - The following functions specify that "dependent_type" requires at least - one of the types in "required_type_alternatives". - - For same-vehicle requirements, a node of dependent type type_D requires at - least one node of type type_R among the required alternatives on the same - route. - """ - return _pywrapcp.RoutingModel_AddSameVehicleRequiredTypeAlternatives(self, dependent_type, required_type_alternatives) - - def AddRequiredTypeAlternativesWhenAddingType(self, dependent_type: "int", required_type_alternatives: "absl::flat_hash_set< int >") -> "void": - r""" - If type_D depends on type_R when adding type_D, any node_D of type_D and - VisitTypePolicy TYPE_ADDED_TO_VEHICLE or - TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED requires at least one type_R on its - vehicle at the time node_D is visited. - """ - return _pywrapcp.RoutingModel_AddRequiredTypeAlternativesWhenAddingType(self, dependent_type, required_type_alternatives) - - def AddRequiredTypeAlternativesWhenRemovingType(self, dependent_type: "int", required_type_alternatives: "absl::flat_hash_set< int >") -> "void": - r""" - The following requirements apply when visiting dependent nodes that remove - their type from the route, i.e. type_R must be on the vehicle when type_D - of VisitTypePolicy ADDED_TYPE_REMOVED_FROM_VEHICLE, - TYPE_ON_VEHICLE_UP_TO_VISIT or TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED is - visited. - """ - return _pywrapcp.RoutingModel_AddRequiredTypeAlternativesWhenRemovingType(self, dependent_type, required_type_alternatives) - - def GetSameVehicleRequiredTypeAlternativesOfType(self, type: "int") -> "std::vector< absl::flat_hash_set< int > > const &": - r""" - Returns the set of same-vehicle requirement alternatives for the given - type. - """ - return _pywrapcp.RoutingModel_GetSameVehicleRequiredTypeAlternativesOfType(self, type) - - def GetRequiredTypeAlternativesWhenAddingType(self, type: "int") -> "std::vector< absl::flat_hash_set< int > > const &": - r""" Returns the set of requirement alternatives when adding the given type.""" - return _pywrapcp.RoutingModel_GetRequiredTypeAlternativesWhenAddingType(self, type) - - def GetRequiredTypeAlternativesWhenRemovingType(self, type: "int") -> "std::vector< absl::flat_hash_set< int > > const &": - r""" Returns the set of requirement alternatives when removing the given type.""" - return _pywrapcp.RoutingModel_GetRequiredTypeAlternativesWhenRemovingType(self, type) - - def HasSameVehicleTypeRequirements(self) -> "bool": - r""" - Returns true iff any same-route (resp. temporal) type requirements have - been added to the model. - """ - return _pywrapcp.RoutingModel_HasSameVehicleTypeRequirements(self) - - def HasTemporalTypeRequirements(self) -> "bool": - return _pywrapcp.RoutingModel_HasTemporalTypeRequirements(self) - - def HasTypeRegulations(self) -> "bool": - r""" - Returns true iff the model has any incompatibilities or requirements set - on node types. - """ - return _pywrapcp.RoutingModel_HasTypeRegulations(self) - - def UnperformedPenalty(self, var_index: "int64_t") -> "int64_t": - r""" - Get the "unperformed" penalty of a node. This is only well defined if the - node is only part of a single Disjunction involving only itself, and that - disjunction has a penalty. In all other cases, including forced active - nodes, this returns 0. - """ - return _pywrapcp.RoutingModel_UnperformedPenalty(self, var_index) - - def UnperformedPenaltyOrValue(self, default_value: "int64_t", var_index: "int64_t") -> "int64_t": - r""" - Same as above except that it returns default_value instead of 0 when - penalty is not well defined (default value is passed as first argument to - simplify the usage of the method in a callback). - """ - return _pywrapcp.RoutingModel_UnperformedPenaltyOrValue(self, default_value, var_index) - - def GetDepot(self) -> "int64_t": - r""" - Returns the variable index of the first starting or ending node of all - routes. If all routes start and end at the same node (single depot), this - is the node returned. - """ - return _pywrapcp.RoutingModel_GetDepot(self) - - def SetMaximumNumberOfActiveVehicles(self, max_active_vehicles: "int") -> "void": - r""" - Constrains the maximum number of active vehicles, aka the number of - vehicles which do not have an empty route. For instance, this can be used - to limit the number of routes in the case where there are fewer drivers - than vehicles and that the fleet of vehicle is heterogeneous. - """ - return _pywrapcp.RoutingModel_SetMaximumNumberOfActiveVehicles(self, max_active_vehicles) - - def GetMaximumNumberOfActiveVehicles(self) -> "int": - r""" Returns the maximum number of active vehicles.""" - return _pywrapcp.RoutingModel_GetMaximumNumberOfActiveVehicles(self) - - def SetArcCostEvaluatorOfAllVehicles(self, evaluator_index: "int") -> "void": - r""" - Sets the cost function of the model such that the cost of a segment of a - route between node 'from' and 'to' is evaluator(from, to), whatever the - route or vehicle performing the route. - """ - return _pywrapcp.RoutingModel_SetArcCostEvaluatorOfAllVehicles(self, evaluator_index) - - def SetArcCostEvaluatorOfVehicle(self, evaluator_index: "int", vehicle: "int") -> "void": - r""" Sets the cost function for a given vehicle route.""" - return _pywrapcp.RoutingModel_SetArcCostEvaluatorOfVehicle(self, evaluator_index, vehicle) - - def SetFixedCostOfAllVehicles(self, cost: "int64_t") -> "void": - r""" - Sets the fixed cost of all vehicle routes. It is equivalent to calling - SetFixedCostOfVehicle on all vehicle routes. - """ - return _pywrapcp.RoutingModel_SetFixedCostOfAllVehicles(self, cost) - - def SetFixedCostOfVehicle(self, cost: "int64_t", vehicle: "int") -> "void": - r""" Sets the fixed cost of one vehicle route.""" - return _pywrapcp.RoutingModel_SetFixedCostOfVehicle(self, cost, vehicle) - - def GetFixedCostOfVehicle(self, vehicle: "int") -> "int64_t": - r""" - Returns the route fixed cost taken into account if the route of the - vehicle is not empty, aka there's at least one node on the route other - than the first and last nodes. - """ - return _pywrapcp.RoutingModel_GetFixedCostOfVehicle(self, vehicle) - - def SetAmortizedCostFactorsOfAllVehicles(self, linear_cost_factor: "int64_t", quadratic_cost_factor: "int64_t") -> "void": - r""" - The following methods set the linear and quadratic cost factors of - vehicles (must be positive values). The default value of these parameters - is zero for all vehicles. - - When set, the cost_ of the model will contain terms aiming at reducing the - number of vehicles used in the model, by adding the following to the - objective for every vehicle v: - INDICATOR(v used in the model) * - [linear_cost_factor_of_vehicle_[v] - - quadratic_cost_factor_of_vehicle_[v]*(square of length of route v)] - i.e. for every used vehicle, we add the linear factor as fixed cost, and - subtract the square of the route length multiplied by the quadratic - factor. This second term aims at making the routes as dense as possible. - - Sets the linear and quadratic cost factor of all vehicles. - """ - return _pywrapcp.RoutingModel_SetAmortizedCostFactorsOfAllVehicles(self, linear_cost_factor, quadratic_cost_factor) - - def SetAmortizedCostFactorsOfVehicle(self, linear_cost_factor: "int64_t", quadratic_cost_factor: "int64_t", vehicle: "int") -> "void": - r""" Sets the linear and quadratic cost factor of the given vehicle.""" - return _pywrapcp.RoutingModel_SetAmortizedCostFactorsOfVehicle(self, linear_cost_factor, quadratic_cost_factor, vehicle) - - def GetAmortizedLinearCostFactorOfVehicles(self) -> "std::vector< int64_t > const &": - return _pywrapcp.RoutingModel_GetAmortizedLinearCostFactorOfVehicles(self) - - def GetAmortizedQuadraticCostFactorOfVehicles(self) -> "std::vector< int64_t > const &": - return _pywrapcp.RoutingModel_GetAmortizedQuadraticCostFactorOfVehicles(self) - - def ConsiderEmptyRouteCostsForVehicle(self, consider_costs: "bool", vehicle: "int") -> "void": - return _pywrapcp.RoutingModel_ConsiderEmptyRouteCostsForVehicle(self, consider_costs, vehicle) - - def AreEmptyRouteCostsConsideredForVehicle(self, vehicle: "int") -> "bool": - return _pywrapcp.RoutingModel_AreEmptyRouteCostsConsideredForVehicle(self, vehicle) - - def SetFirstSolutionEvaluator(self, evaluator: "operations_research::Solver::IndexEvaluator2") -> "void": - r""" - Gets/sets the evaluator used during the search. Only relevant when - RoutingSearchParameters.first_solution_strategy = EVALUATOR_STRATEGY. - Takes ownership of evaluator. - """ - return _pywrapcp.RoutingModel_SetFirstSolutionEvaluator(self, evaluator) - - def AddLocalSearchOperator(self, ls_operator: "LocalSearchOperator") -> "void": - r""" - Adds a local search operator to the set of operators used to solve the - vehicle routing problem. - """ - return _pywrapcp.RoutingModel_AddLocalSearchOperator(self, ls_operator) - - def AddSearchMonitor(self, monitor: "SearchMonitor") -> "void": - r""" Adds a search monitor to the search used to solve the routing model.""" - return _pywrapcp.RoutingModel_AddSearchMonitor(self, monitor) - - def AddAtSolutionCallback(self, callback: "std::function< void () >") -> "void": - r""" - Adds a callback called each time a solution is found during the search. - This is a shortcut to creating a monitor to call the callback on - AtSolution() and adding it with AddSearchMonitor. - """ - return _pywrapcp.RoutingModel_AddAtSolutionCallback(self, callback) - - def AddVariableMinimizedByFinalizer(self, var: "IntVar") -> "void": - r""" - Adds a variable to minimize in the solution finalizer. The solution - finalizer is called each time a solution is found during the search and - allows to instantiate secondary variables (such as dimension cumul - variables). - """ - return _pywrapcp.RoutingModel_AddVariableMinimizedByFinalizer(self, var) - - def AddVariableMaximizedByFinalizer(self, var: "IntVar") -> "void": - r""" - Adds a variable to maximize in the solution finalizer (see above for - information on the solution finalizer). - """ - return _pywrapcp.RoutingModel_AddVariableMaximizedByFinalizer(self, var) - - def AddWeightedVariableMinimizedByFinalizer(self, var: "IntVar", cost: "int64_t") -> "void": - r""" - Adds a variable to minimize in the solution finalizer, with a weighted - priority: the higher the more priority it has. - """ - return _pywrapcp.RoutingModel_AddWeightedVariableMinimizedByFinalizer(self, var, cost) - - def AddVariableTargetToFinalizer(self, var: "IntVar", target: "int64_t") -> "void": - r""" - Add a variable to set the closest possible to the target value in the - solution finalizer. - """ - return _pywrapcp.RoutingModel_AddVariableTargetToFinalizer(self, var, target) - - def CloseModel(self) -> "void": - r""" - Closes the current routing model; after this method is called, no - modification to the model can be done, but RoutesToAssignment becomes - available. Note that CloseModel() is automatically called by Solve() and - other methods that produce solution. - This is equivalent to calling - CloseModelWithParameters(DefaultRoutingSearchParameters()). - """ - return _pywrapcp.RoutingModel_CloseModel(self) - - def CloseModelWithParameters(self, search_parameters: "operations_research::RoutingSearchParameters const &") -> "void": - r""" - Same as above taking search parameters (as of 10/2015 some the parameters - have to be set when closing the model). - """ - return _pywrapcp.RoutingModel_CloseModelWithParameters(self, search_parameters) - - def Solve(self, assignment: "Assignment"=None) -> "operations_research::Assignment const *": - r""" - Solves the current routing model; closes the current model. - This is equivalent to calling - SolveWithParameters(DefaultRoutingSearchParameters()) - or - SolveFromAssignmentWithParameters(assignment, - DefaultRoutingSearchParameters()). - """ - return _pywrapcp.RoutingModel_Solve(self, assignment) - - def SolveWithParameters(self, search_parameters: "operations_research::RoutingSearchParameters const &", solutions: "std::vector< operations_research::Assignment const * > *"=None) -> "operations_research::Assignment const *": - r""" - Solves the current routing model with the given parameters. If 'solutions' - is specified, it will contain the k best solutions found during the search - (from worst to best, including the one returned by this method), where k - corresponds to the 'number_of_solutions_to_collect' in - 'search_parameters'. Note that the Assignment returned by the method and - the ones in solutions are owned by the underlying solver and should not be - deleted. - """ - return _pywrapcp.RoutingModel_SolveWithParameters(self, search_parameters, solutions) - - def SolveFromAssignmentWithParameters(self, assignment: "Assignment", search_parameters: "operations_research::RoutingSearchParameters const &", solutions: "std::vector< operations_research::Assignment const * > *"=None) -> "operations_research::Assignment const *": - r""" - Same as above, except that if assignment is not null, it will be used as - the initial solution. - """ - return _pywrapcp.RoutingModel_SolveFromAssignmentWithParameters(self, assignment, search_parameters, solutions) - - def SolveFromAssignmentsWithParameters(self, assignments: "std::vector< operations_research::Assignment const * > const &", search_parameters: "operations_research::RoutingSearchParameters const &", solutions: "std::vector< operations_research::Assignment const * > *"=None) -> "operations_research::Assignment const *": - r""" - Same as above but will try all assignments in order as first solutions - until one succeeds. - """ - return _pywrapcp.RoutingModel_SolveFromAssignmentsWithParameters(self, assignments, search_parameters, solutions) - - def SetAssignmentFromOtherModelAssignment(self, target_assignment: "Assignment", source_model: "RoutingModel", source_assignment: "Assignment") -> "void": - r""" - Given a "source_model" and its "source_assignment", resets - "target_assignment" with the IntVar variables (nexts_, and vehicle_vars_ - if costs aren't homogeneous across vehicles) of "this" model, with the - values set according to those in "other_assignment". - The objective_element of target_assignment is set to this->cost_. - """ - return _pywrapcp.RoutingModel_SetAssignmentFromOtherModelAssignment(self, target_assignment, source_model, source_assignment) - - def ComputeLowerBound(self) -> "int64_t": - r""" - Computes a lower bound to the routing problem solving a linear assignment - problem. The routing model must be closed before calling this method. - Note that problems with node disjunction constraints (including optional - nodes) and non-homogenous costs are not supported (the method returns 0 in - these cases). - """ - return _pywrapcp.RoutingModel_ComputeLowerBound(self) - - def status(self) -> "operations_research::RoutingModel::Status": - r""" Returns the current status of the routing model.""" - return _pywrapcp.RoutingModel_status(self) - - def ApplyLocks(self, locks: "std::vector< int64_t > const &") -> "operations_research::IntVar *": - r""" - Applies a lock chain to the next search. 'locks' represents an ordered - vector of nodes representing a partial route which will be fixed during - the next search; it will constrain next variables such that: - next[locks[i]] == locks[i+1]. - - Returns the next variable at the end of the locked chain; this variable is - not locked. An assignment containing the locks can be obtained by calling - PreAssignment(). - """ - return _pywrapcp.RoutingModel_ApplyLocks(self, locks) - - def ApplyLocksToAllVehicles(self, locks: "std::vector< std::vector< int64_t > > const &", close_routes: "bool") -> "bool": - r""" - Applies lock chains to all vehicles to the next search, such that locks[p] - is the lock chain for route p. Returns false if the locks do not contain - valid routes; expects that the routes do not contain the depots, - i.e. there are empty vectors in place of empty routes. - If close_routes is set to true, adds the end nodes to the route of each - vehicle and deactivates other nodes. - An assignment containing the locks can be obtained by calling - PreAssignment(). - """ - return _pywrapcp.RoutingModel_ApplyLocksToAllVehicles(self, locks, close_routes) - - def PreAssignment(self) -> "operations_research::Assignment const *const": - r""" - Returns an assignment used to fix some of the variables of the problem. - In practice, this assignment locks partial routes of the problem. This - can be used in the context of locking the parts of the routes which have - already been driven in online routing problems. - """ - return _pywrapcp.RoutingModel_PreAssignment(self) - - def MutablePreAssignment(self) -> "operations_research::Assignment *": - return _pywrapcp.RoutingModel_MutablePreAssignment(self) - - def WriteAssignment(self, file_name: "std::string const &") -> "bool": - r""" - Writes the current solution to a file containing an AssignmentProto. - Returns false if the file cannot be opened or if there is no current - solution. - """ - return _pywrapcp.RoutingModel_WriteAssignment(self, file_name) - - def ReadAssignment(self, file_name: "std::string const &") -> "operations_research::Assignment *": - r""" - Reads an assignment from a file and returns the current solution. - Returns nullptr if the file cannot be opened or if the assignment is not - valid. - """ - return _pywrapcp.RoutingModel_ReadAssignment(self, file_name) - - def RestoreAssignment(self, solution: "Assignment") -> "operations_research::Assignment *": - r""" - Restores an assignment as a solution in the routing model and returns the - new solution. Returns nullptr if the assignment is not valid. - """ - return _pywrapcp.RoutingModel_RestoreAssignment(self, solution) - - def ReadAssignmentFromRoutes(self, routes: "std::vector< std::vector< int64_t > > const &", ignore_inactive_indices: "bool") -> "operations_research::Assignment *": - r""" - Restores the routes as the current solution. Returns nullptr if the - solution cannot be restored (routes do not contain a valid solution). Note - that calling this method will run the solver to assign values to the - dimension variables; this may take considerable amount of time, especially - when using dimensions with slack. - """ - return _pywrapcp.RoutingModel_ReadAssignmentFromRoutes(self, routes, ignore_inactive_indices) - - def RoutesToAssignment(self, routes: "std::vector< std::vector< int64_t > > const &", ignore_inactive_indices: "bool", close_routes: "bool", assignment: "Assignment") -> "bool": - r""" - Fills an assignment from a specification of the routes of the - vehicles. The routes are specified as lists of variable indices that - appear on the routes of the vehicles. The indices of the outer vector in - 'routes' correspond to vehicles IDs, the inner vector contains the - variable indices on the routes for the given vehicle. The inner vectors - must not contain the start and end indices, as these are determined by the - routing model. Sets the value of NextVars in the assignment, adding the - variables to the assignment if necessary. The method does not touch other - variables in the assignment. The method can only be called after the model - is closed. With ignore_inactive_indices set to false, this method will - fail (return nullptr) in case some of the route contain indices that are - deactivated in the model; when set to true, these indices will be - skipped. Returns true if routes were successfully - loaded. However, such assignment still might not be a valid - solution to the routing problem due to more complex constraints; - it is advisible to call solver()->CheckSolution() afterwards. - """ - return _pywrapcp.RoutingModel_RoutesToAssignment(self, routes, ignore_inactive_indices, close_routes, assignment) - - def AssignmentToRoutes(self, assignment: "Assignment", routes: "std::vector< std::vector< int64_t > > *const") -> "void": - r""" - Converts the solution in the given assignment to routes for all vehicles. - Expects that assignment contains a valid solution (i.e. routes for all - vehicles end with an end index for that vehicle). - """ - return _pywrapcp.RoutingModel_AssignmentToRoutes(self, assignment, routes) - - def CompactAssignment(self, assignment: "Assignment") -> "operations_research::Assignment *": - r""" - Converts the solution in the given assignment to routes for all vehicles. - If the returned vector is route_indices, route_indices[i][j] is the index - for jth location visited on route i. Note that contrary to - AssignmentToRoutes, the vectors do include start and end locations. - Returns a compacted version of the given assignment, in which all vehicles - with id lower or equal to some N have non-empty routes, and all vehicles - with id greater than N have empty routes. Does not take ownership of the - returned object. - If found, the cost of the compact assignment is the same as in the - original assignment and it preserves the values of 'active' variables. - Returns nullptr if a compact assignment was not found. - This method only works in homogenous mode, and it only swaps equivalent - vehicles (vehicles with the same start and end nodes). When creating the - compact assignment, the empty plan is replaced by the route assigned to - the compatible vehicle with the highest id. Note that with more complex - constraints on vehicle variables, this method might fail even if a compact - solution exists. - This method changes the vehicle and dimension variables as necessary. - While compacting the solution, only basic checks on vehicle variables are - performed; if one of these checks fails no attempts to repair it are made - (instead, the method returns nullptr). - """ - return _pywrapcp.RoutingModel_CompactAssignment(self, assignment) - - def CompactAndCheckAssignment(self, assignment: "Assignment") -> "operations_research::Assignment *": - r""" - Same as CompactAssignment() but also checks the validity of the final - compact solution; if it is not valid, no attempts to repair it are made - (instead, the method returns nullptr). - """ - return _pywrapcp.RoutingModel_CompactAndCheckAssignment(self, assignment) - - def AddToAssignment(self, var: "IntVar") -> "void": - r""" Adds an extra variable to the vehicle routing assignment.""" - return _pywrapcp.RoutingModel_AddToAssignment(self, var) - - def AddIntervalToAssignment(self, interval: "IntervalVar") -> "void": - return _pywrapcp.RoutingModel_AddIntervalToAssignment(self, interval) - - def PackCumulsOfOptimizerDimensionsFromAssignment(self, original_assignment: "Assignment", duration_limit: "absl::Duration") -> "operations_research::Assignment const *": - r""" - For every dimension in the model with an optimizer in - local/global_dimension_optimizers_, this method tries to pack the cumul - values of the dimension, such that: - - The cumul costs (span costs, soft lower and upper bound costs, etc) are - minimized. - - The cumuls of the ends of the routes are minimized for this given - minimal cumul cost. - - Given these minimal end cumuls, the route start cumuls are maximized. - Returns the assignment resulting from allocating these packed cumuls with - the solver, and nullptr if these cumuls could not be set by the solver. - """ - return _pywrapcp.RoutingModel_PackCumulsOfOptimizerDimensionsFromAssignment(self, original_assignment, duration_limit) - - def AddLocalSearchFilter(self, filter: "LocalSearchFilter") -> "void": - r""" - Adds a custom local search filter to the list of filters used to speed up - local search by pruning unfeasible variable assignments. - Calling this method after the routing model has been closed (CloseModel() - or Solve() has been called) has no effect. - The routing model does not take ownership of the filter. - """ - return _pywrapcp.RoutingModel_AddLocalSearchFilter(self, filter) - - def Start(self, vehicle: "int") -> "int64_t": - r""" - Model inspection. - Returns the variable index of the starting node of a vehicle route. - """ - return _pywrapcp.RoutingModel_Start(self, vehicle) - - def End(self, vehicle: "int") -> "int64_t": - r""" Returns the variable index of the ending node of a vehicle route.""" - return _pywrapcp.RoutingModel_End(self, vehicle) - - def IsStart(self, index: "int64_t") -> "bool": - r""" Returns true if 'index' represents the first node of a route.""" - return _pywrapcp.RoutingModel_IsStart(self, index) - - def IsEnd(self, index: "int64_t") -> "bool": - r""" Returns true if 'index' represents the last node of a route.""" - return _pywrapcp.RoutingModel_IsEnd(self, index) - - def VehicleIndex(self, index: "int64_t") -> "int": - r""" - Returns the vehicle of the given start/end index, and -1 if the given - index is not a vehicle start/end. - """ - return _pywrapcp.RoutingModel_VehicleIndex(self, index) - - def Next(self, assignment: "Assignment", index: "int64_t") -> "int64_t": - r""" - Assignment inspection - Returns the variable index of the node directly after the node - corresponding to 'index' in 'assignment'. - """ - return _pywrapcp.RoutingModel_Next(self, assignment, index) - - def IsVehicleUsed(self, assignment: "Assignment", vehicle: "int") -> "bool": - r""" Returns true if the route of 'vehicle' is non empty in 'assignment'.""" - return _pywrapcp.RoutingModel_IsVehicleUsed(self, assignment, vehicle) - - def NextVar(self, index: "int64_t") -> "operations_research::IntVar *": - r""" - Returns the next variable of the node corresponding to index. Note that - NextVar(index) == index is equivalent to ActiveVar(index) == 0. - """ - return _pywrapcp.RoutingModel_NextVar(self, index) - - def ActiveVar(self, index: "int64_t") -> "operations_research::IntVar *": - r""" Returns the active variable of the node corresponding to index.""" - return _pywrapcp.RoutingModel_ActiveVar(self, index) - - def ActiveVehicleVar(self, vehicle: "int") -> "operations_research::IntVar *": - r""" - Returns the active variable of the vehicle. It will be equal to 1 iff the - route of the vehicle is not empty, 0 otherwise. - """ - return _pywrapcp.RoutingModel_ActiveVehicleVar(self, vehicle) - - def VehicleCostsConsideredVar(self, vehicle: "int") -> "operations_research::IntVar *": - r""" - Returns the variable specifying whether or not costs are considered for - vehicle. - """ - return _pywrapcp.RoutingModel_VehicleCostsConsideredVar(self, vehicle) - - def VehicleVar(self, index: "int64_t") -> "operations_research::IntVar *": - r""" - Returns the vehicle variable of the node corresponding to index. Note that - VehicleVar(index) == -1 is equivalent to ActiveVar(index) == 0. - """ - return _pywrapcp.RoutingModel_VehicleVar(self, index) - - def CostVar(self) -> "operations_research::IntVar *": - r""" Returns the global cost variable which is being minimized.""" - return _pywrapcp.RoutingModel_CostVar(self) - - def GetArcCostForVehicle(self, from_index: "int64_t", to_index: "int64_t", vehicle: "int64_t") -> "int64_t": - r""" - Returns the cost of the transit arc between two nodes for a given vehicle. - Input are variable indices of node. This returns 0 if vehicle < 0. - """ - return _pywrapcp.RoutingModel_GetArcCostForVehicle(self, from_index, to_index, vehicle) - - def CostsAreHomogeneousAcrossVehicles(self) -> "bool": - r""" Whether costs are homogeneous across all vehicles.""" - return _pywrapcp.RoutingModel_CostsAreHomogeneousAcrossVehicles(self) - - def GetHomogeneousCost(self, from_index: "int64_t", to_index: "int64_t") -> "int64_t": - r""" - Returns the cost of the segment between two nodes supposing all vehicle - costs are the same (returns the cost for the first vehicle otherwise). - """ - return _pywrapcp.RoutingModel_GetHomogeneousCost(self, from_index, to_index) - - def GetArcCostForFirstSolution(self, from_index: "int64_t", to_index: "int64_t") -> "int64_t": - r""" - Returns the cost of the arc in the context of the first solution strategy. - This is typically a simplification of the actual cost; see the .cc. - """ - return _pywrapcp.RoutingModel_GetArcCostForFirstSolution(self, from_index, to_index) - - def GetArcCostForClass(self, from_index: "int64_t", to_index: "int64_t", cost_class_index: "int64_t") -> "int64_t": - r""" - Returns the cost of the segment between two nodes for a given cost - class. Input are variable indices of nodes and the cost class. - Unlike GetArcCostForVehicle(), if cost_class is kNoCost, then the - returned cost won't necessarily be zero: only some of the components - of the cost that depend on the cost class will be omited. See the code - for details. - """ - return _pywrapcp.RoutingModel_GetArcCostForClass(self, from_index, to_index, cost_class_index) - - def GetCostClassIndexOfVehicle(self, vehicle: "int64_t") -> "operations_research::RoutingModel::CostClassIndex": - r""" Get the cost class index of the given vehicle.""" - return _pywrapcp.RoutingModel_GetCostClassIndexOfVehicle(self, vehicle) - - def HasVehicleWithCostClassIndex(self, cost_class_index: "operations_research::RoutingModel::CostClassIndex") -> "bool": - r""" - Returns true iff the model contains a vehicle with the given - cost_class_index. - """ - return _pywrapcp.RoutingModel_HasVehicleWithCostClassIndex(self, cost_class_index) - - def GetCostClassesCount(self) -> "int": - r""" Returns the number of different cost classes in the model.""" - return _pywrapcp.RoutingModel_GetCostClassesCount(self) - - def GetNonZeroCostClassesCount(self) -> "int": - r""" Ditto, minus the 'always zero', built-in cost class.""" - return _pywrapcp.RoutingModel_GetNonZeroCostClassesCount(self) - - def GetVehicleClassIndexOfVehicle(self, vehicle: "int64_t") -> "operations_research::RoutingModel::VehicleClassIndex": - return _pywrapcp.RoutingModel_GetVehicleClassIndexOfVehicle(self, vehicle) - - def GetVehicleClassesCount(self) -> "int": - r""" Returns the number of different vehicle classes in the model.""" - return _pywrapcp.RoutingModel_GetVehicleClassesCount(self) - - def GetSameVehicleIndicesOfIndex(self, node: "int") -> "std::vector< int > const &": - r""" Returns variable indices of nodes constrained to be on the same route.""" - return _pywrapcp.RoutingModel_GetSameVehicleIndicesOfIndex(self, node) - - def GetVehicleTypeContainer(self) -> "operations_research::RoutingModel::VehicleTypeContainer const &": - return _pywrapcp.RoutingModel_GetVehicleTypeContainer(self) - - def ArcIsMoreConstrainedThanArc(self, _from: "int64_t", to1: "int64_t", to2: "int64_t") -> "bool": - r""" - Returns whether the arc from->to1 is more constrained than from->to2, - taking into account, in order: - - whether the destination node isn't an end node - - whether the destination node is mandatory - - whether the destination node is bound to the same vehicle as the source - - the "primary constrained" dimension (see SetPrimaryConstrainedDimension) - It then breaks ties using, in order: - - the arc cost (taking unperformed penalties into account) - - the size of the vehicle vars of "to1" and "to2" (lowest size wins) - - the value: the lowest value of the indices to1 and to2 wins. - See the .cc for details. - The more constrained arc is typically preferable when building a - first solution. This method is intended to be used as a callback for the - BestValueByComparisonSelector value selector. - Args: - from: the variable index of the source node - to1: the variable index of the first candidate destination node. - to2: the variable index of the second candidate destination node. - """ - return _pywrapcp.RoutingModel_ArcIsMoreConstrainedThanArc(self, _from, to1, to2) - - def DebugOutputAssignment(self, solution_assignment: "Assignment", dimension_to_print: "std::string const &") -> "std::string": - r""" - Print some debugging information about an assignment, including the - feasible intervals of the CumulVar for dimension "dimension_to_print" - at each step of the routes. - If "dimension_to_print" is omitted, all dimensions will be printed. - """ - return _pywrapcp.RoutingModel_DebugOutputAssignment(self, solution_assignment, dimension_to_print) - - def solver(self) -> "operations_research::Solver *": - r""" - Returns a vector cumul_bounds, for which cumul_bounds[i][j] is a pair - containing the minimum and maximum of the CumulVar of the jth node on - route i. - - cumul_bounds[i][j].first is the minimum. - - cumul_bounds[i][j].second is the maximum. - Returns the underlying constraint solver. Can be used to add extra - constraints and/or modify search algoithms. - """ - return _pywrapcp.RoutingModel_solver(self) - - def CheckLimit(self) -> "bool": - r""" Returns true if the search limit has been crossed.""" - return _pywrapcp.RoutingModel_CheckLimit(self) - - def RemainingTime(self) -> "absl::Duration": - r""" Returns the time left in the search limit.""" - return _pywrapcp.RoutingModel_RemainingTime(self) - - def nodes(self) -> "int": - r""" - Sizes and indices - Returns the number of nodes in the model. - """ - return _pywrapcp.RoutingModel_nodes(self) - - def vehicles(self) -> "int": - r""" Returns the number of vehicle routes in the model.""" - return _pywrapcp.RoutingModel_vehicles(self) - - def Size(self) -> "int64_t": - r""" Returns the number of next variables in the model.""" - return _pywrapcp.RoutingModel_Size(self) - - def GetNumberOfDecisionsInFirstSolution(self, search_parameters: "operations_research::RoutingSearchParameters const &") -> "int64_t": - r""" - Returns statistics on first solution search, number of decisions sent to - filters, number of decisions rejected by filters. - """ - return _pywrapcp.RoutingModel_GetNumberOfDecisionsInFirstSolution(self, search_parameters) - - def GetNumberOfRejectsInFirstSolution(self, search_parameters: "operations_research::RoutingSearchParameters const &") -> "int64_t": - return _pywrapcp.RoutingModel_GetNumberOfRejectsInFirstSolution(self, search_parameters) - - def GetAutomaticFirstSolutionStrategy(self) -> "operations_research::FirstSolutionStrategy::Value": - r""" Returns the automatic first solution strategy selected.""" - return _pywrapcp.RoutingModel_GetAutomaticFirstSolutionStrategy(self) - - def IsMatchingModel(self) -> "bool": - r""" Returns true if a vehicle/node matching problem is detected.""" - return _pywrapcp.RoutingModel_IsMatchingModel(self) - - def MakeGuidedSlackFinalizer(self, dimension: "RoutingDimension", initializer: "std::function< int64_t (int64_t) >") -> "operations_research::DecisionBuilder *": - r""" - The next few members are in the public section only for testing purposes. - - MakeGuidedSlackFinalizer creates a DecisionBuilder for the slacks of a - dimension using a callback to choose which values to start with. - The finalizer works only when all next variables in the model have - been fixed. It has the following two characteristics: - 1. It follows the routes defined by the nexts variables when choosing a - variable to make a decision on. - 2. When it comes to choose a value for the slack of node i, the decision - builder first calls the callback with argument i, and supposingly the - returned value is x it creates decisions slack[i] = x, slack[i] = x + - 1, slack[i] = x - 1, slack[i] = x + 2, etc. - """ - return _pywrapcp.RoutingModel_MakeGuidedSlackFinalizer(self, dimension, initializer) - - def MakeSelfDependentDimensionFinalizer(self, dimension: "RoutingDimension") -> "operations_research::DecisionBuilder *": - r""" - MakeSelfDependentDimensionFinalizer is a finalizer for the slacks of a - self-dependent dimension. It makes an extensive use of the caches of the - state dependent transits. - In detail, MakeSelfDependentDimensionFinalizer returns a composition of a - local search decision builder with a greedy descent operator for the cumul - of the start of each route and a guided slack finalizer. Provided there - are no time windows and the maximum slacks are large enough, once the - cumul of the start of route is fixed, the guided finalizer can find - optimal values of the slacks for the rest of the route in time - proportional to the length of the route. Therefore the composed finalizer - generally works in time O(log(t)*n*m), where t is the latest possible - departute time, n is the number of nodes in the network and m is the - number of vehicles. - """ - return _pywrapcp.RoutingModel_MakeSelfDependentDimensionFinalizer(self, dimension) - -# Register RoutingModel in _pywrapcp: -_pywrapcp.RoutingModel_swigregister(RoutingModel) -cvar = _pywrapcp.cvar -RoutingModel.kNoPenalty = _pywrapcp.cvar.RoutingModel_kNoPenalty -RoutingModel.kNoDisjunction = _pywrapcp.cvar.RoutingModel_kNoDisjunction -RoutingModel.kNoDimension = _pywrapcp.cvar.RoutingModel_kNoDimension - -class RoutingModelVisitor(BaseObject): - r""" Routing model visitor.""" - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - - def __init__(self): - _pywrapcp.RoutingModelVisitor_swiginit(self, _pywrapcp.new_RoutingModelVisitor()) - __swig_destroy__ = _pywrapcp.delete_RoutingModelVisitor - -# Register RoutingModelVisitor in _pywrapcp: -_pywrapcp.RoutingModelVisitor_swigregister(RoutingModelVisitor) -RoutingModelVisitor.kLightElement = _pywrapcp.cvar.RoutingModelVisitor_kLightElement -RoutingModelVisitor.kLightElement2 = _pywrapcp.cvar.RoutingModelVisitor_kLightElement2 -RoutingModelVisitor.kRemoveValues = _pywrapcp.cvar.RoutingModelVisitor_kRemoveValues - -class GlobalVehicleBreaksConstraint(Constraint): - r""" - GlobalVehicleBreaksConstraint ensures breaks constraints are enforced on - all vehicles in the dimension passed to its constructor. - It is intended to be used for dimensions representing time. - A break constraint ensures break intervals fit on the route of a vehicle. - For a given vehicle, it forces break intervals to be disjoint from visit - intervals, where visit intervals start at CumulVar(node) and last for - node_visit_transit[node]. Moreover, it ensures that there is enough time - between two consecutive nodes of a route to do transit and vehicle breaks, - i.e. if Next(nodeA) = nodeB, CumulVar(nodeA) = tA and CumulVar(nodeB) = tB, - then SlackVar(nodeA) >= sum_{breaks [tA, tB)} duration(break). - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - - def __init__(self, dimension: "RoutingDimension"): - _pywrapcp.GlobalVehicleBreaksConstraint_swiginit(self, _pywrapcp.new_GlobalVehicleBreaksConstraint(dimension)) - - def DebugString(self) -> "std::string": - return _pywrapcp.GlobalVehicleBreaksConstraint_DebugString(self) - - def Post(self) -> "void": - return _pywrapcp.GlobalVehicleBreaksConstraint_Post(self) - - def InitialPropagateWrapper(self) -> "void": - return _pywrapcp.GlobalVehicleBreaksConstraint_InitialPropagateWrapper(self) - __swig_destroy__ = _pywrapcp.delete_GlobalVehicleBreaksConstraint - -# Register GlobalVehicleBreaksConstraint in _pywrapcp: -_pywrapcp.GlobalVehicleBreaksConstraint_swigregister(GlobalVehicleBreaksConstraint) - -class TypeRegulationsChecker(object): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - __swig_destroy__ = _pywrapcp.delete_TypeRegulationsChecker - - def CheckVehicle(self, vehicle: "int", next_accessor: "std::function< int64_t (int64_t) > const &") -> "bool": - return _pywrapcp.TypeRegulationsChecker_CheckVehicle(self, vehicle, next_accessor) - -# Register TypeRegulationsChecker in _pywrapcp: -_pywrapcp.TypeRegulationsChecker_swigregister(TypeRegulationsChecker) - -class TypeIncompatibilityChecker(TypeRegulationsChecker): - r""" Checker for type incompatibilities.""" - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - - def __init__(self, model: "RoutingModel", check_hard_incompatibilities: "bool"): - _pywrapcp.TypeIncompatibilityChecker_swiginit(self, _pywrapcp.new_TypeIncompatibilityChecker(model, check_hard_incompatibilities)) - __swig_destroy__ = _pywrapcp.delete_TypeIncompatibilityChecker - -# Register TypeIncompatibilityChecker in _pywrapcp: -_pywrapcp.TypeIncompatibilityChecker_swigregister(TypeIncompatibilityChecker) - -class TypeRequirementChecker(TypeRegulationsChecker): - r""" Checker for type requirements.""" - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - - def __init__(self, model: "RoutingModel"): - _pywrapcp.TypeRequirementChecker_swiginit(self, _pywrapcp.new_TypeRequirementChecker(model)) - __swig_destroy__ = _pywrapcp.delete_TypeRequirementChecker - -# Register TypeRequirementChecker in _pywrapcp: -_pywrapcp.TypeRequirementChecker_swigregister(TypeRequirementChecker) - -class TypeRegulationsConstraint(Constraint): - r""" - The following constraint ensures that incompatibilities and requirements - between types are respected. - - It verifies both "hard" and "temporal" incompatibilities. - Two nodes with hard incompatible types cannot be served by the same vehicle - at all, while with a temporal incompatibility they can't be on the same - route at the same time. - The VisitTypePolicy of a node determines how visiting it impacts the type - count on the route. - - For example, for - - three temporally incompatible types T1 T2 and T3 - - 2 pairs of nodes a1/r1 and a2/r2 of type T1 and T2 respectively, with - - a1 and a2 of VisitTypePolicy TYPE_ADDED_TO_VEHICLE - - r1 and r2 of policy ADDED_TYPE_REMOVED_FROM_VEHICLE - - 3 nodes A, UV and AR of type T3, respectively with type policies - TYPE_ADDED_TO_VEHICLE, TYPE_ON_VEHICLE_UP_TO_VISIT and - TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED - the configurations - UV --> a1 --> r1 --> a2 --> r2, a1 --> r1 --> a2 --> r2 --> A and - a1 --> r1 --> AR --> a2 --> r2 are acceptable, whereas the configurations - a1 --> a2 --> r1 --> ..., or A --> a1 --> r1 --> ..., or - a1 --> r1 --> UV --> ... are not feasible. - - It also verifies same-vehicle and temporal type requirements. - A node of type T_d with a same-vehicle requirement for type T_r needs to be - served by the same vehicle as a node of type T_r. - Temporal requirements, on the other hand, can take effect either when the - dependent type is being added to the route or when it's removed from it, - which is determined by the dependent node's VisitTypePolicy. - In the above example: - - If T3 is required on the same vehicle as T1, A, AR or UV must be on the - same vehicle as a1. - - If T2 is required when adding T1, a2 must be visited *before* a1, and if - r2 is also visited on the route, it must be *after* a1, i.e. T2 must be on - the vehicle when a1 is visited: - ... --> a2 --> ... --> a1 --> ... --> r2 --> ... - - If T3 is required when removing T1, T3 needs to be on the vehicle when - r1 is visited: - ... --> A --> ... --> r1 --> ... OR ... --> r1 --> ... --> UV --> ... - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - - def __init__(self, model: "RoutingModel"): - _pywrapcp.TypeRegulationsConstraint_swiginit(self, _pywrapcp.new_TypeRegulationsConstraint(model)) - - def Post(self) -> "void": - return _pywrapcp.TypeRegulationsConstraint_Post(self) - - def InitialPropagateWrapper(self) -> "void": - return _pywrapcp.TypeRegulationsConstraint_InitialPropagateWrapper(self) - __swig_destroy__ = _pywrapcp.delete_TypeRegulationsConstraint - -# Register TypeRegulationsConstraint in _pywrapcp: -_pywrapcp.TypeRegulationsConstraint_swigregister(TypeRegulationsConstraint) - -class RoutingDimension(object): - r""" - Dimensions represent quantities accumulated at nodes along the routes. They - represent quantities such as weights or volumes carried along the route, or - distance or times. - - Quantities at a node are represented by "cumul" variables and the increase - or decrease of quantities between nodes are represented by "transit" - variables. These variables are linked as follows: - - if j == next(i), - cumuls(j) = cumuls(i) + transits(i) + slacks(i) + - state_dependent_transits(i) - - where slack is a positive slack variable (can represent waiting times for - a time dimension), and state_dependent_transits is a non-purely functional - version of transits_. Favour transits over state_dependent_transits when - possible, because purely functional callbacks allow more optimisations and - make the model faster and easier to solve. - for a given vehicle, it is passed as an external vector, it would be better - to have this information here. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined") - __repr__ = _swig_repr - __swig_destroy__ = _pywrapcp.delete_RoutingDimension - - def model(self) -> "operations_research::RoutingModel *": - r""" Returns the model on which the dimension was created.""" - return _pywrapcp.RoutingDimension_model(self) - - def GetTransitValue(self, from_index: "int64_t", to_index: "int64_t", vehicle: "int64_t") -> "int64_t": - r""" - Returns the transition value for a given pair of nodes (as var index); - this value is the one taken by the corresponding transit variable when - the 'next' variable for 'from_index' is bound to 'to_index'. - """ - return _pywrapcp.RoutingDimension_GetTransitValue(self, from_index, to_index, vehicle) - - def GetTransitValueFromClass(self, from_index: "int64_t", to_index: "int64_t", vehicle_class: "int64_t") -> "int64_t": - r""" - Same as above but taking a vehicle class of the dimension instead of a - vehicle (the class of a vehicle can be obtained with vehicle_to_class()). - """ - return _pywrapcp.RoutingDimension_GetTransitValueFromClass(self, from_index, to_index, vehicle_class) - - def CumulVar(self, index: "int64_t") -> "operations_research::IntVar *": - r""" - Get the cumul, transit and slack variables for the given node (given as - int64_t var index). - """ - return _pywrapcp.RoutingDimension_CumulVar(self, index) - - def TransitVar(self, index: "int64_t") -> "operations_research::IntVar *": - return _pywrapcp.RoutingDimension_TransitVar(self, index) - - def FixedTransitVar(self, index: "int64_t") -> "operations_research::IntVar *": - return _pywrapcp.RoutingDimension_FixedTransitVar(self, index) - - def SlackVar(self, index: "int64_t") -> "operations_research::IntVar *": - return _pywrapcp.RoutingDimension_SlackVar(self, index) - - def SetSpanUpperBoundForVehicle(self, upper_bound: "int64_t", vehicle: "int") -> "void": - r""" - Sets an upper bound on the dimension span on a given vehicle. This is the - preferred way to limit the "length" of the route of a vehicle according to - a dimension. - """ - return _pywrapcp.RoutingDimension_SetSpanUpperBoundForVehicle(self, upper_bound, vehicle) - - def SetSpanCostCoefficientForVehicle(self, coefficient: "int64_t", vehicle: "int") -> "void": - r""" - Sets a cost proportional to the dimension span on a given vehicle, - or on all vehicles at once. "coefficient" must be nonnegative. - This is handy to model costs proportional to idle time when the dimension - represents time. - The cost for a vehicle is - span_cost = coefficient * (dimension end value - dimension start value). - """ - return _pywrapcp.RoutingDimension_SetSpanCostCoefficientForVehicle(self, coefficient, vehicle) - - def SetSpanCostCoefficientForAllVehicles(self, coefficient: "int64_t") -> "void": - return _pywrapcp.RoutingDimension_SetSpanCostCoefficientForAllVehicles(self, coefficient) - - def SetGlobalSpanCostCoefficient(self, coefficient: "int64_t") -> "void": - r""" - Sets a cost proportional to the *global* dimension span, that is the - difference between the largest value of route end cumul variables and - the smallest value of route start cumul variables. - In other words: - global_span_cost = - coefficient * (Max(dimension end value) - Min(dimension start value)). - """ - return _pywrapcp.RoutingDimension_SetGlobalSpanCostCoefficient(self, coefficient) - - def SetCumulVarSoftUpperBound(self, index: "int64_t", upper_bound: "int64_t", coefficient: "int64_t") -> "void": - r""" - Sets a soft upper bound to the cumul variable of a given variable index. - If the value of the cumul variable is greater than the bound, a cost - proportional to the difference between this value and the bound is added - to the cost function of the model: - cumulVar <= upper_bound -> cost = 0 - cumulVar > upper_bound -> cost = coefficient * (cumulVar - upper_bound) - This is also handy to model tardiness costs when the dimension represents - time. - """ - return _pywrapcp.RoutingDimension_SetCumulVarSoftUpperBound(self, index, upper_bound, coefficient) - - def HasCumulVarSoftUpperBound(self, index: "int64_t") -> "bool": - r""" - Returns true if a soft upper bound has been set for a given variable - index. - """ - return _pywrapcp.RoutingDimension_HasCumulVarSoftUpperBound(self, index) - - def GetCumulVarSoftUpperBound(self, index: "int64_t") -> "int64_t": - r""" - Returns the soft upper bound of a cumul variable for a given variable - index. The "hard" upper bound of the variable is returned if no soft upper - bound has been set. - """ - return _pywrapcp.RoutingDimension_GetCumulVarSoftUpperBound(self, index) - - def GetCumulVarSoftUpperBoundCoefficient(self, index: "int64_t") -> "int64_t": - r""" - Returns the cost coefficient of the soft upper bound of a cumul variable - for a given variable index. If no soft upper bound has been set, 0 is - returned. - """ - return _pywrapcp.RoutingDimension_GetCumulVarSoftUpperBoundCoefficient(self, index) - - def SetCumulVarSoftLowerBound(self, index: "int64_t", lower_bound: "int64_t", coefficient: "int64_t") -> "void": - r""" - Sets a soft lower bound to the cumul variable of a given variable index. - If the value of the cumul variable is less than the bound, a cost - proportional to the difference between this value and the bound is added - to the cost function of the model: - cumulVar > lower_bound -> cost = 0 - cumulVar <= lower_bound -> cost = coefficient * (lower_bound - - cumulVar). - This is also handy to model earliness costs when the dimension represents - time. - """ - return _pywrapcp.RoutingDimension_SetCumulVarSoftLowerBound(self, index, lower_bound, coefficient) - - def HasCumulVarSoftLowerBound(self, index: "int64_t") -> "bool": - r""" - Returns true if a soft lower bound has been set for a given variable - index. - """ - return _pywrapcp.RoutingDimension_HasCumulVarSoftLowerBound(self, index) - - def GetCumulVarSoftLowerBound(self, index: "int64_t") -> "int64_t": - r""" - Returns the soft lower bound of a cumul variable for a given variable - index. The "hard" lower bound of the variable is returned if no soft lower - bound has been set. - """ - return _pywrapcp.RoutingDimension_GetCumulVarSoftLowerBound(self, index) - - def GetCumulVarSoftLowerBoundCoefficient(self, index: "int64_t") -> "int64_t": - r""" - Returns the cost coefficient of the soft lower bound of a cumul variable - for a given variable index. If no soft lower bound has been set, 0 is - returned. - """ - return _pywrapcp.RoutingDimension_GetCumulVarSoftLowerBoundCoefficient(self, index) - - def SetBreakIntervalsOfVehicle(self, breaks: "std::vector< operations_research::IntervalVar * >", vehicle: "int", node_visit_transits: "std::vector< int64_t >") -> "void": - r""" - Sets the breaks for a given vehicle. Breaks are represented by - IntervalVars. They may interrupt transits between nodes and increase - the value of corresponding slack variables. - A break may take place before the start of a vehicle, after the end of - a vehicle, or during a travel i -> j. - - In that case, the interval [break.Start(), break.End()) must be a subset - of [CumulVar(i) + pre_travel(i, j), CumulVar(j) - post_travel(i, j)). In - other words, a break may not overlap any node n's visit, given by - [CumulVar(n) - post_travel(_, n), CumulVar(n) + pre_travel(n, _)). - This formula considers post_travel(_, start) and pre_travel(end, _) to be - 0; pre_travel will never be called on any (_, start) and post_travel will - never we called on any (end, _). If pre_travel_evaluator or - post_travel_evaluator is -1, it will be taken as a function that always - returns 0. - Deprecated, sets pre_travel(i, j) = node_visit_transit[i]. - """ - return _pywrapcp.RoutingDimension_SetBreakIntervalsOfVehicle(self, breaks, vehicle, node_visit_transits) - - def SetBreakDistanceDurationOfVehicle(self, distance: "int64_t", duration: "int64_t", vehicle: "int") -> "void": - r""" - With breaks supposed to be consecutive, this forces the distance between - breaks of size at least minimum_break_duration to be at most distance. - This supposes that the time until route start and after route end are - infinite breaks. - """ - return _pywrapcp.RoutingDimension_SetBreakDistanceDurationOfVehicle(self, distance, duration, vehicle) - - def InitializeBreaks(self) -> "void": - r""" - Sets up vehicle_break_intervals_, vehicle_break_distance_duration_, - pre_travel_evaluators and post_travel_evaluators. - """ - return _pywrapcp.RoutingDimension_InitializeBreaks(self) - - def HasBreakConstraints(self) -> "bool": - r""" Returns true if any break interval or break distance was defined.""" - return _pywrapcp.RoutingDimension_HasBreakConstraints(self) - - def GetPreTravelEvaluatorOfVehicle(self, vehicle: "int") -> "int": - return _pywrapcp.RoutingDimension_GetPreTravelEvaluatorOfVehicle(self, vehicle) - - def GetPostTravelEvaluatorOfVehicle(self, vehicle: "int") -> "int": - return _pywrapcp.RoutingDimension_GetPostTravelEvaluatorOfVehicle(self, vehicle) - - def base_dimension(self) -> "operations_research::RoutingDimension const *": - r""" Returns the parent in the dependency tree if any or nullptr otherwise.""" - return _pywrapcp.RoutingDimension_base_dimension(self) - - def ShortestTransitionSlack(self, node: "int64_t") -> "int64_t": - r""" - It makes sense to use the function only for self-dependent dimension. - For such dimensions the value of the slack of a node determines the - transition cost of the next transit. Provided that - 1. cumul[node] is fixed, - 2. next[node] and next[next[node]] (if exists) are fixed, - the value of slack[node] for which cumul[next[node]] + transit[next[node]] - is minimized can be found in O(1) using this function. - """ - return _pywrapcp.RoutingDimension_ShortestTransitionSlack(self, node) - - def name(self) -> "std::string const &": - r""" Returns the name of the dimension.""" - return _pywrapcp.RoutingDimension_name(self) - - def SetPickupToDeliveryLimitFunctionForPair(self, limit_function: "operations_research::RoutingDimension::PickupToDeliveryLimitFunction", pair_index: "int") -> "void": - return _pywrapcp.RoutingDimension_SetPickupToDeliveryLimitFunctionForPair(self, limit_function, pair_index) - - def HasPickupToDeliveryLimits(self) -> "bool": - return _pywrapcp.RoutingDimension_HasPickupToDeliveryLimits(self) - - def AddNodePrecedence(self, first_node: "int64_t", second_node: "int64_t", offset: "int64_t") -> "void": - return _pywrapcp.RoutingDimension_AddNodePrecedence(self, first_node, second_node, offset) - - def GetSpanUpperBoundForVehicle(self, vehicle: "int") -> "int64_t": - return _pywrapcp.RoutingDimension_GetSpanUpperBoundForVehicle(self, vehicle) - - def GetSpanCostCoefficientForVehicle(self, vehicle: "int") -> "int64_t": - return _pywrapcp.RoutingDimension_GetSpanCostCoefficientForVehicle(self, vehicle) - - def global_span_cost_coefficient(self) -> "int64_t": - return _pywrapcp.RoutingDimension_global_span_cost_coefficient(self) - - def GetGlobalOptimizerOffset(self) -> "int64_t": - return _pywrapcp.RoutingDimension_GetGlobalOptimizerOffset(self) - - def GetLocalOptimizerOffsetForVehicle(self, vehicle: "int") -> "int64_t": - return _pywrapcp.RoutingDimension_GetLocalOptimizerOffsetForVehicle(self, vehicle) - -# Register RoutingDimension in _pywrapcp: -_pywrapcp.RoutingDimension_swigregister(RoutingDimension) - - -def MakeSetValuesFromTargets(solver: "Solver", variables: "std::vector< operations_research::IntVar * >", targets: "std::vector< int64_t >") -> "operations_research::DecisionBuilder *": - r""" - A decision builder which tries to assign values to variables as close as - possible to target values first. - """ - return _pywrapcp.MakeSetValuesFromTargets(solver, variables, targets) - -def SolveModelWithSat(model: "RoutingModel", search_parameters: "operations_research::RoutingSearchParameters const &", initial_solution: "Assignment", solution: "Assignment") -> "bool": - r""" - Attempts to solve the model using the cp-sat solver. As of 5/2019, will - solve the TSP corresponding to the model if it has a single vehicle. - Therefore the resulting solution might not actually be feasible. Will return - false if a solution could not be found. - """ - return _pywrapcp.SolveModelWithSat(model, search_parameters, initial_solution, solution)
-
-
-
-
-
-
-
-

Functions

-
-
-def DefaultRoutingModelParameters() ‑> operations_research::RoutingModelParameters -
-
-
-
- -Expand source code - -
def DefaultRoutingModelParameters() -> "operations_research::RoutingModelParameters":
-    return _pywrapcp.DefaultRoutingModelParameters()
-
-
-
-def DefaultRoutingSearchParameters() ‑> operations_research::RoutingSearchParameters -
-
-
-
- -Expand source code - -
def DefaultRoutingSearchParameters() -> "operations_research::RoutingSearchParameters":
-    return _pywrapcp.DefaultRoutingSearchParameters()
-
-
-
-def FindErrorInRoutingSearchParameters(search_parameters: operations_research::RoutingSearchParameters const &) ‑> std::string -
-
-

Returns an empty std::string if the routing search parameters are valid, and -a non-empty, human readable error description if they're not.

-
- -Expand source code - -
def FindErrorInRoutingSearchParameters(search_parameters: "operations_research::RoutingSearchParameters const &") -> "std::string":
-    r"""
-    Returns an empty std::string if the routing search parameters are valid, and
-    a non-empty, human readable error description if they're not.
-    """
-    return _pywrapcp.FindErrorInRoutingSearchParameters(search_parameters)
-
-
-
-def MakeSetValuesFromTargets(solver: Solver, variables: std::vector< operations_research::IntVar * >, targets: std::vector< int64_t >) ‑> operations_research::DecisionBuilder * -
-
-

A decision builder which tries to assign values to variables as close as -possible to target values first.

-
- -Expand source code - -
def MakeSetValuesFromTargets(solver: "Solver", variables: "std::vector< operations_research::IntVar * >", targets: "std::vector< int64_t >") -> "operations_research::DecisionBuilder *":
-    r"""
-    A decision builder which tries to assign values to variables as close as
-    possible to target values first.
-    """
-    return _pywrapcp.MakeSetValuesFromTargets(solver, variables, targets)
-
-
-
-def SolveModelWithSat(model: RoutingModel, search_parameters: operations_research::RoutingSearchParameters const &, initial_solution: Assignment, solution: Assignment) ‑> bool -
-
-

Attempts to solve the model using the cp-sat solver. As of 5/2019, will -solve the TSP corresponding to the model if it has a single vehicle. -Therefore the resulting solution might not actually be feasible. Will return -false if a solution could not be found.

-
- -Expand source code - -
def SolveModelWithSat(model: "RoutingModel", search_parameters: "operations_research::RoutingSearchParameters const &", initial_solution: "Assignment", solution: "Assignment") -> "bool":
-    r"""
-    Attempts to solve the model using the cp-sat solver. As of 5/2019, will
-    solve the TSP corresponding to the model if it has a single vehicle.
-    Therefore the resulting solution might not actually be feasible. Will return
-    false if a solution could not be found.
-    """
-    return _pywrapcp.SolveModelWithSat(model, search_parameters, initial_solution, solution)
-
-
-
-def Solver_DefaultSolverParameters() ‑> operations_research::ConstraintSolverParameters -
-
-

Create a ConstraintSolverParameters proto with all the default values.

-
- -Expand source code - -
def Solver_DefaultSolverParameters() -> "operations_research::ConstraintSolverParameters":
-    r""" Create a ConstraintSolverParameters proto with all the default values."""
-    return _pywrapcp.Solver_DefaultSolverParameters()
-
-
-
-def Solver_MemoryUsage() ‑> int64_t -
-
-

Current memory usage in bytes

-
- -Expand source code - -
def Solver_MemoryUsage() -> "int64_t":
-    r""" Current memory usage in bytes"""
-    return _pywrapcp.Solver_MemoryUsage()
-
-
-
-
-
-

Classes

-
-
-class Assignment -(*args, **kwargs) -
-
-

An Assignment is a variable -> domains mapping, used -to report solutions to the user.

-
- -Expand source code - -
class Assignment(PropagationBaseObject):
-    r"""
-    An Assignment is a variable -> domains mapping, used
-    to report solutions to the user.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined")
-    __repr__ = _swig_repr
-
-    def Clear(self) -> "void":
-        return _pywrapcp.Assignment_Clear(self)
-
-    def Empty(self) -> "bool":
-        return _pywrapcp.Assignment_Empty(self)
-
-    def Size(self) -> "int":
-        return _pywrapcp.Assignment_Size(self)
-
-    def NumIntVars(self) -> "int":
-        return _pywrapcp.Assignment_NumIntVars(self)
-
-    def NumIntervalVars(self) -> "int":
-        return _pywrapcp.Assignment_NumIntervalVars(self)
-
-    def NumSequenceVars(self) -> "int":
-        return _pywrapcp.Assignment_NumSequenceVars(self)
-
-    def Store(self) -> "void":
-        return _pywrapcp.Assignment_Store(self)
-
-    def Restore(self) -> "void":
-        return _pywrapcp.Assignment_Restore(self)
-
-    def Load(self, *args) -> "void":
-        return _pywrapcp.Assignment_Load(self, *args)
-
-    def Save(self, *args) -> "void":
-        return _pywrapcp.Assignment_Save(self, *args)
-
-    def AddObjective(self, v: "IntVar") -> "void":
-        return _pywrapcp.Assignment_AddObjective(self, v)
-
-    def Objective(self) -> "operations_research::IntVar *":
-        return _pywrapcp.Assignment_Objective(self)
-
-    def HasObjective(self) -> "bool":
-        return _pywrapcp.Assignment_HasObjective(self)
-
-    def ObjectiveMin(self) -> "int64_t":
-        return _pywrapcp.Assignment_ObjectiveMin(self)
-
-    def ObjectiveMax(self) -> "int64_t":
-        return _pywrapcp.Assignment_ObjectiveMax(self)
-
-    def ObjectiveValue(self) -> "int64_t":
-        return _pywrapcp.Assignment_ObjectiveValue(self)
-
-    def ObjectiveBound(self) -> "bool":
-        return _pywrapcp.Assignment_ObjectiveBound(self)
-
-    def SetObjectiveMin(self, m: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetObjectiveMin(self, m)
-
-    def SetObjectiveMax(self, m: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetObjectiveMax(self, m)
-
-    def SetObjectiveValue(self, value: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetObjectiveValue(self, value)
-
-    def SetObjectiveRange(self, l: "int64_t", u: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetObjectiveRange(self, l, u)
-
-    def Min(self, var: "IntVar") -> "int64_t":
-        return _pywrapcp.Assignment_Min(self, var)
-
-    def Max(self, var: "IntVar") -> "int64_t":
-        return _pywrapcp.Assignment_Max(self, var)
-
-    def Value(self, var: "IntVar") -> "int64_t":
-        return _pywrapcp.Assignment_Value(self, var)
-
-    def Bound(self, var: "IntVar") -> "bool":
-        return _pywrapcp.Assignment_Bound(self, var)
-
-    def SetMin(self, var: "IntVar", m: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetMin(self, var, m)
-
-    def SetMax(self, var: "IntVar", m: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetMax(self, var, m)
-
-    def SetRange(self, var: "IntVar", l: "int64_t", u: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetRange(self, var, l, u)
-
-    def SetValue(self, var: "IntVar", value: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetValue(self, var, value)
-
-    def StartMin(self, var: "IntervalVar") -> "int64_t":
-        return _pywrapcp.Assignment_StartMin(self, var)
-
-    def StartMax(self, var: "IntervalVar") -> "int64_t":
-        return _pywrapcp.Assignment_StartMax(self, var)
-
-    def StartValue(self, var: "IntervalVar") -> "int64_t":
-        return _pywrapcp.Assignment_StartValue(self, var)
-
-    def DurationMin(self, var: "IntervalVar") -> "int64_t":
-        return _pywrapcp.Assignment_DurationMin(self, var)
-
-    def DurationMax(self, var: "IntervalVar") -> "int64_t":
-        return _pywrapcp.Assignment_DurationMax(self, var)
-
-    def DurationValue(self, var: "IntervalVar") -> "int64_t":
-        return _pywrapcp.Assignment_DurationValue(self, var)
-
-    def EndMin(self, var: "IntervalVar") -> "int64_t":
-        return _pywrapcp.Assignment_EndMin(self, var)
-
-    def EndMax(self, var: "IntervalVar") -> "int64_t":
-        return _pywrapcp.Assignment_EndMax(self, var)
-
-    def EndValue(self, var: "IntervalVar") -> "int64_t":
-        return _pywrapcp.Assignment_EndValue(self, var)
-
-    def PerformedMin(self, var: "IntervalVar") -> "int64_t":
-        return _pywrapcp.Assignment_PerformedMin(self, var)
-
-    def PerformedMax(self, var: "IntervalVar") -> "int64_t":
-        return _pywrapcp.Assignment_PerformedMax(self, var)
-
-    def PerformedValue(self, var: "IntervalVar") -> "int64_t":
-        return _pywrapcp.Assignment_PerformedValue(self, var)
-
-    def SetStartMin(self, var: "IntervalVar", m: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetStartMin(self, var, m)
-
-    def SetStartMax(self, var: "IntervalVar", m: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetStartMax(self, var, m)
-
-    def SetStartRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetStartRange(self, var, mi, ma)
-
-    def SetStartValue(self, var: "IntervalVar", value: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetStartValue(self, var, value)
-
-    def SetDurationMin(self, var: "IntervalVar", m: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetDurationMin(self, var, m)
-
-    def SetDurationMax(self, var: "IntervalVar", m: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetDurationMax(self, var, m)
-
-    def SetDurationRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetDurationRange(self, var, mi, ma)
-
-    def SetDurationValue(self, var: "IntervalVar", value: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetDurationValue(self, var, value)
-
-    def SetEndMin(self, var: "IntervalVar", m: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetEndMin(self, var, m)
-
-    def SetEndMax(self, var: "IntervalVar", m: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetEndMax(self, var, m)
-
-    def SetEndRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetEndRange(self, var, mi, ma)
-
-    def SetEndValue(self, var: "IntervalVar", value: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetEndValue(self, var, value)
-
-    def SetPerformedMin(self, var: "IntervalVar", m: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetPerformedMin(self, var, m)
-
-    def SetPerformedMax(self, var: "IntervalVar", m: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetPerformedMax(self, var, m)
-
-    def SetPerformedRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetPerformedRange(self, var, mi, ma)
-
-    def SetPerformedValue(self, var: "IntervalVar", value: "int64_t") -> "void":
-        return _pywrapcp.Assignment_SetPerformedValue(self, var, value)
-
-    def Add(self, *args) -> "void":
-        return _pywrapcp.Assignment_Add(self, *args)
-
-    def ForwardSequence(self, var: "SequenceVar") -> "std::vector< int > const &":
-        return _pywrapcp.Assignment_ForwardSequence(self, var)
-
-    def BackwardSequence(self, var: "SequenceVar") -> "std::vector< int > const &":
-        return _pywrapcp.Assignment_BackwardSequence(self, var)
-
-    def Unperformed(self, var: "SequenceVar") -> "std::vector< int > const &":
-        return _pywrapcp.Assignment_Unperformed(self, var)
-
-    def SetSequence(self, var: "SequenceVar", forward_sequence: "std::vector< int > const &", backward_sequence: "std::vector< int > const &", unperformed: "std::vector< int > const &") -> "void":
-        return _pywrapcp.Assignment_SetSequence(self, var, forward_sequence, backward_sequence, unperformed)
-
-    def SetForwardSequence(self, var: "SequenceVar", forward_sequence: "std::vector< int > const &") -> "void":
-        return _pywrapcp.Assignment_SetForwardSequence(self, var, forward_sequence)
-
-    def SetBackwardSequence(self, var: "SequenceVar", backward_sequence: "std::vector< int > const &") -> "void":
-        return _pywrapcp.Assignment_SetBackwardSequence(self, var, backward_sequence)
-
-    def SetUnperformed(self, var: "SequenceVar", unperformed: "std::vector< int > const &") -> "void":
-        return _pywrapcp.Assignment_SetUnperformed(self, var, unperformed)
-
-    def Activate(self, *args) -> "void":
-        return _pywrapcp.Assignment_Activate(self, *args)
-
-    def Deactivate(self, *args) -> "void":
-        return _pywrapcp.Assignment_Deactivate(self, *args)
-
-    def Activated(self, *args) -> "bool":
-        return _pywrapcp.Assignment_Activated(self, *args)
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.Assignment_DebugString(self)
-
-    def IntVarContainer(self) -> "operations_research::Assignment::IntContainer const &":
-        return _pywrapcp.Assignment_IntVarContainer(self)
-
-    def MutableIntVarContainer(self) -> "operations_research::Assignment::IntContainer *":
-        return _pywrapcp.Assignment_MutableIntVarContainer(self)
-
-    def IntervalVarContainer(self) -> "operations_research::Assignment::IntervalContainer const &":
-        return _pywrapcp.Assignment_IntervalVarContainer(self)
-
-    def MutableIntervalVarContainer(self) -> "operations_research::Assignment::IntervalContainer *":
-        return _pywrapcp.Assignment_MutableIntervalVarContainer(self)
-
-    def SequenceVarContainer(self) -> "operations_research::Assignment::SequenceContainer const &":
-        return _pywrapcp.Assignment_SequenceVarContainer(self)
-
-    def MutableSequenceVarContainer(self) -> "operations_research::Assignment::SequenceContainer *":
-        return _pywrapcp.Assignment_MutableSequenceVarContainer(self)
-
-    def __eq__(self, assignment: "Assignment") -> "bool":
-        return _pywrapcp.Assignment___eq__(self, assignment)
-
-    def __ne__(self, assignment: "Assignment") -> "bool":
-        return _pywrapcp.Assignment___ne__(self, assignment)
-
-

Ancestors

- -

Methods

-
-
-def Activate(self, *args) ‑> void -
-
-
-
- -Expand source code - -
def Activate(self, *args) -> "void":
-    return _pywrapcp.Assignment_Activate(self, *args)
-
-
-
-def Activated(self, *args) ‑> bool -
-
-
-
- -Expand source code - -
def Activated(self, *args) -> "bool":
-    return _pywrapcp.Assignment_Activated(self, *args)
-
-
-
-def Add(self, *args) ‑> void -
-
-
-
- -Expand source code - -
def Add(self, *args) -> "void":
-    return _pywrapcp.Assignment_Add(self, *args)
-
-
-
-def AddObjective(self, v: IntVar) ‑> void -
-
-
-
- -Expand source code - -
def AddObjective(self, v: "IntVar") -> "void":
-    return _pywrapcp.Assignment_AddObjective(self, v)
-
-
-
-def BackwardSequence(self, var: SequenceVar) ‑> std::vector< int > const & -
-
-
-
- -Expand source code - -
def BackwardSequence(self, var: "SequenceVar") -> "std::vector< int > const &":
-    return _pywrapcp.Assignment_BackwardSequence(self, var)
-
-
-
-def Bound(self, var: IntVar) ‑> bool -
-
-
-
- -Expand source code - -
def Bound(self, var: "IntVar") -> "bool":
-    return _pywrapcp.Assignment_Bound(self, var)
-
-
-
-def Clear(self) ‑> void -
-
-
-
- -Expand source code - -
def Clear(self) -> "void":
-    return _pywrapcp.Assignment_Clear(self)
-
-
-
-def Deactivate(self, *args) ‑> void -
-
-
-
- -Expand source code - -
def Deactivate(self, *args) -> "void":
-    return _pywrapcp.Assignment_Deactivate(self, *args)
-
-
-
-def DebugString(self) ‑> std::string -
-
-
-
- -Expand source code - -
def DebugString(self) -> "std::string":
-    return _pywrapcp.Assignment_DebugString(self)
-
-
-
-def DurationMax(self, var: IntervalVar) ‑> int64_t -
-
-
-
- -Expand source code - -
def DurationMax(self, var: "IntervalVar") -> "int64_t":
-    return _pywrapcp.Assignment_DurationMax(self, var)
-
-
-
-def DurationMin(self, var: IntervalVar) ‑> int64_t -
-
-
-
- -Expand source code - -
def DurationMin(self, var: "IntervalVar") -> "int64_t":
-    return _pywrapcp.Assignment_DurationMin(self, var)
-
-
-
-def DurationValue(self, var: IntervalVar) ‑> int64_t -
-
-
-
- -Expand source code - -
def DurationValue(self, var: "IntervalVar") -> "int64_t":
-    return _pywrapcp.Assignment_DurationValue(self, var)
-
-
-
-def Empty(self) ‑> bool -
-
-
-
- -Expand source code - -
def Empty(self) -> "bool":
-    return _pywrapcp.Assignment_Empty(self)
-
-
-
-def EndMax(self, var: IntervalVar) ‑> int64_t -
-
-
-
- -Expand source code - -
def EndMax(self, var: "IntervalVar") -> "int64_t":
-    return _pywrapcp.Assignment_EndMax(self, var)
-
-
-
-def EndMin(self, var: IntervalVar) ‑> int64_t -
-
-
-
- -Expand source code - -
def EndMin(self, var: "IntervalVar") -> "int64_t":
-    return _pywrapcp.Assignment_EndMin(self, var)
-
-
-
-def EndValue(self, var: IntervalVar) ‑> int64_t -
-
-
-
- -Expand source code - -
def EndValue(self, var: "IntervalVar") -> "int64_t":
-    return _pywrapcp.Assignment_EndValue(self, var)
-
-
-
-def ForwardSequence(self, var: SequenceVar) ‑> std::vector< int > const & -
-
-
-
- -Expand source code - -
def ForwardSequence(self, var: "SequenceVar") -> "std::vector< int > const &":
-    return _pywrapcp.Assignment_ForwardSequence(self, var)
-
-
-
-def HasObjective(self) ‑> bool -
-
-
-
- -Expand source code - -
def HasObjective(self) -> "bool":
-    return _pywrapcp.Assignment_HasObjective(self)
-
-
-
-def IntVarContainer(self) ‑> operations_research::Assignment::IntContainer const & -
-
-
-
- -Expand source code - -
def IntVarContainer(self) -> "operations_research::Assignment::IntContainer const &":
-    return _pywrapcp.Assignment_IntVarContainer(self)
-
-
-
-def IntervalVarContainer(self) ‑> operations_research::Assignment::IntervalContainer const & -
-
-
-
- -Expand source code - -
def IntervalVarContainer(self) -> "operations_research::Assignment::IntervalContainer const &":
-    return _pywrapcp.Assignment_IntervalVarContainer(self)
-
-
-
-def Load(self, *args) ‑> void -
-
-
-
- -Expand source code - -
def Load(self, *args) -> "void":
-    return _pywrapcp.Assignment_Load(self, *args)
-
-
-
-def Max(self, var: IntVar) ‑> int64_t -
-
-
-
- -Expand source code - -
def Max(self, var: "IntVar") -> "int64_t":
-    return _pywrapcp.Assignment_Max(self, var)
-
-
-
-def Min(self, var: IntVar) ‑> int64_t -
-
-
-
- -Expand source code - -
def Min(self, var: "IntVar") -> "int64_t":
-    return _pywrapcp.Assignment_Min(self, var)
-
-
-
-def MutableIntVarContainer(self) ‑> operations_research::Assignment::IntContainer * -
-
-
-
- -Expand source code - -
def MutableIntVarContainer(self) -> "operations_research::Assignment::IntContainer *":
-    return _pywrapcp.Assignment_MutableIntVarContainer(self)
-
-
-
-def MutableIntervalVarContainer(self) ‑> operations_research::Assignment::IntervalContainer * -
-
-
-
- -Expand source code - -
def MutableIntervalVarContainer(self) -> "operations_research::Assignment::IntervalContainer *":
-    return _pywrapcp.Assignment_MutableIntervalVarContainer(self)
-
-
-
-def MutableSequenceVarContainer(self) ‑> operations_research::Assignment::SequenceContainer * -
-
-
-
- -Expand source code - -
def MutableSequenceVarContainer(self) -> "operations_research::Assignment::SequenceContainer *":
-    return _pywrapcp.Assignment_MutableSequenceVarContainer(self)
-
-
-
-def NumIntVars(self) ‑> int -
-
-
-
- -Expand source code - -
def NumIntVars(self) -> "int":
-    return _pywrapcp.Assignment_NumIntVars(self)
-
-
-
-def NumIntervalVars(self) ‑> int -
-
-
-
- -Expand source code - -
def NumIntervalVars(self) -> "int":
-    return _pywrapcp.Assignment_NumIntervalVars(self)
-
-
-
-def NumSequenceVars(self) ‑> int -
-
-
-
- -Expand source code - -
def NumSequenceVars(self) -> "int":
-    return _pywrapcp.Assignment_NumSequenceVars(self)
-
-
-
-def Objective(self) ‑> operations_research::IntVar * -
-
-
-
- -Expand source code - -
def Objective(self) -> "operations_research::IntVar *":
-    return _pywrapcp.Assignment_Objective(self)
-
-
-
-def ObjectiveBound(self) ‑> bool -
-
-
-
- -Expand source code - -
def ObjectiveBound(self) -> "bool":
-    return _pywrapcp.Assignment_ObjectiveBound(self)
-
-
-
-def ObjectiveMax(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def ObjectiveMax(self) -> "int64_t":
-    return _pywrapcp.Assignment_ObjectiveMax(self)
-
-
-
-def ObjectiveMin(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def ObjectiveMin(self) -> "int64_t":
-    return _pywrapcp.Assignment_ObjectiveMin(self)
-
-
-
-def ObjectiveValue(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def ObjectiveValue(self) -> "int64_t":
-    return _pywrapcp.Assignment_ObjectiveValue(self)
-
-
-
-def PerformedMax(self, var: IntervalVar) ‑> int64_t -
-
-
-
- -Expand source code - -
def PerformedMax(self, var: "IntervalVar") -> "int64_t":
-    return _pywrapcp.Assignment_PerformedMax(self, var)
-
-
-
-def PerformedMin(self, var: IntervalVar) ‑> int64_t -
-
-
-
- -Expand source code - -
def PerformedMin(self, var: "IntervalVar") -> "int64_t":
-    return _pywrapcp.Assignment_PerformedMin(self, var)
-
-
-
-def PerformedValue(self, var: IntervalVar) ‑> int64_t -
-
-
-
- -Expand source code - -
def PerformedValue(self, var: "IntervalVar") -> "int64_t":
-    return _pywrapcp.Assignment_PerformedValue(self, var)
-
-
-
-def Restore(self) ‑> void -
-
-
-
- -Expand source code - -
def Restore(self) -> "void":
-    return _pywrapcp.Assignment_Restore(self)
-
-
-
-def Save(self, *args) ‑> void -
-
-
-
- -Expand source code - -
def Save(self, *args) -> "void":
-    return _pywrapcp.Assignment_Save(self, *args)
-
-
-
-def SequenceVarContainer(self) ‑> operations_research::Assignment::SequenceContainer const & -
-
-
-
- -Expand source code - -
def SequenceVarContainer(self) -> "operations_research::Assignment::SequenceContainer const &":
-    return _pywrapcp.Assignment_SequenceVarContainer(self)
-
-
-
-def SetBackwardSequence(self, var: SequenceVar, backward_sequence: std::vector< int > const &) ‑> void -
-
-
-
- -Expand source code - -
def SetBackwardSequence(self, var: "SequenceVar", backward_sequence: "std::vector< int > const &") -> "void":
-    return _pywrapcp.Assignment_SetBackwardSequence(self, var, backward_sequence)
-
-
-
-def SetDurationMax(self, var: IntervalVar, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetDurationMax(self, var: "IntervalVar", m: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetDurationMax(self, var, m)
-
-
-
-def SetDurationMin(self, var: IntervalVar, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetDurationMin(self, var: "IntervalVar", m: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetDurationMin(self, var, m)
-
-
-
-def SetDurationRange(self, var: IntervalVar, mi: int64_t, ma: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetDurationRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetDurationRange(self, var, mi, ma)
-
-
-
-def SetDurationValue(self, var: IntervalVar, value: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetDurationValue(self, var: "IntervalVar", value: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetDurationValue(self, var, value)
-
-
-
-def SetEndMax(self, var: IntervalVar, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetEndMax(self, var: "IntervalVar", m: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetEndMax(self, var, m)
-
-
-
-def SetEndMin(self, var: IntervalVar, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetEndMin(self, var: "IntervalVar", m: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetEndMin(self, var, m)
-
-
-
-def SetEndRange(self, var: IntervalVar, mi: int64_t, ma: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetEndRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetEndRange(self, var, mi, ma)
-
-
-
-def SetEndValue(self, var: IntervalVar, value: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetEndValue(self, var: "IntervalVar", value: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetEndValue(self, var, value)
-
-
-
-def SetForwardSequence(self, var: SequenceVar, forward_sequence: std::vector< int > const &) ‑> void -
-
-
-
- -Expand source code - -
def SetForwardSequence(self, var: "SequenceVar", forward_sequence: "std::vector< int > const &") -> "void":
-    return _pywrapcp.Assignment_SetForwardSequence(self, var, forward_sequence)
-
-
-
-def SetMax(self, var: IntVar, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetMax(self, var: "IntVar", m: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetMax(self, var, m)
-
-
-
-def SetMin(self, var: IntVar, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetMin(self, var: "IntVar", m: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetMin(self, var, m)
-
-
-
-def SetObjectiveMax(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetObjectiveMax(self, m: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetObjectiveMax(self, m)
-
-
-
-def SetObjectiveMin(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetObjectiveMin(self, m: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetObjectiveMin(self, m)
-
-
-
-def SetObjectiveRange(self, l: int64_t, u: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetObjectiveRange(self, l: "int64_t", u: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetObjectiveRange(self, l, u)
-
-
-
-def SetObjectiveValue(self, value: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetObjectiveValue(self, value: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetObjectiveValue(self, value)
-
-
-
-def SetPerformedMax(self, var: IntervalVar, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetPerformedMax(self, var: "IntervalVar", m: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetPerformedMax(self, var, m)
-
-
-
-def SetPerformedMin(self, var: IntervalVar, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetPerformedMin(self, var: "IntervalVar", m: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetPerformedMin(self, var, m)
-
-
-
-def SetPerformedRange(self, var: IntervalVar, mi: int64_t, ma: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetPerformedRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetPerformedRange(self, var, mi, ma)
-
-
-
-def SetPerformedValue(self, var: IntervalVar, value: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetPerformedValue(self, var: "IntervalVar", value: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetPerformedValue(self, var, value)
-
-
-
-def SetRange(self, var: IntVar, l: int64_t, u: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetRange(self, var: "IntVar", l: "int64_t", u: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetRange(self, var, l, u)
-
-
-
-def SetSequence(self, var: SequenceVar, forward_sequence: std::vector< int > const &, backward_sequence: std::vector< int > const &, unperformed: std::vector< int > const &) ‑> void -
-
-
-
- -Expand source code - -
def SetSequence(self, var: "SequenceVar", forward_sequence: "std::vector< int > const &", backward_sequence: "std::vector< int > const &", unperformed: "std::vector< int > const &") -> "void":
-    return _pywrapcp.Assignment_SetSequence(self, var, forward_sequence, backward_sequence, unperformed)
-
-
-
-def SetStartMax(self, var: IntervalVar, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetStartMax(self, var: "IntervalVar", m: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetStartMax(self, var, m)
-
-
-
-def SetStartMin(self, var: IntervalVar, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetStartMin(self, var: "IntervalVar", m: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetStartMin(self, var, m)
-
-
-
-def SetStartRange(self, var: IntervalVar, mi: int64_t, ma: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetStartRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetStartRange(self, var, mi, ma)
-
-
-
-def SetStartValue(self, var: IntervalVar, value: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetStartValue(self, var: "IntervalVar", value: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetStartValue(self, var, value)
-
-
-
-def SetUnperformed(self, var: SequenceVar, unperformed: std::vector< int > const &) ‑> void -
-
-
-
- -Expand source code - -
def SetUnperformed(self, var: "SequenceVar", unperformed: "std::vector< int > const &") -> "void":
-    return _pywrapcp.Assignment_SetUnperformed(self, var, unperformed)
-
-
-
-def SetValue(self, var: IntVar, value: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetValue(self, var: "IntVar", value: "int64_t") -> "void":
-    return _pywrapcp.Assignment_SetValue(self, var, value)
-
-
-
-def Size(self) ‑> int -
-
-
-
- -Expand source code - -
def Size(self) -> "int":
-    return _pywrapcp.Assignment_Size(self)
-
-
-
-def StartMax(self, var: IntervalVar) ‑> int64_t -
-
-
-
- -Expand source code - -
def StartMax(self, var: "IntervalVar") -> "int64_t":
-    return _pywrapcp.Assignment_StartMax(self, var)
-
-
-
-def StartMin(self, var: IntervalVar) ‑> int64_t -
-
-
-
- -Expand source code - -
def StartMin(self, var: "IntervalVar") -> "int64_t":
-    return _pywrapcp.Assignment_StartMin(self, var)
-
-
-
-def StartValue(self, var: IntervalVar) ‑> int64_t -
-
-
-
- -Expand source code - -
def StartValue(self, var: "IntervalVar") -> "int64_t":
-    return _pywrapcp.Assignment_StartValue(self, var)
-
-
-
-def Store(self) ‑> void -
-
-
-
- -Expand source code - -
def Store(self) -> "void":
-    return _pywrapcp.Assignment_Store(self)
-
-
-
-def Unperformed(self, var: SequenceVar) ‑> std::vector< int > const & -
-
-
-
- -Expand source code - -
def Unperformed(self, var: "SequenceVar") -> "std::vector< int > const &":
-    return _pywrapcp.Assignment_Unperformed(self, var)
-
-
-
-def Value(self, var: IntVar) ‑> int64_t -
-
-
-
- -Expand source code - -
def Value(self, var: "IntVar") -> "int64_t":
-    return _pywrapcp.Assignment_Value(self, var)
-
-
-
-

Inherited members

- -
-
-class AssignmentElement -(*args, **kwargs) -
-
-
-
- -Expand source code - -
class AssignmentElement(object):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined")
-    __repr__ = _swig_repr
-
-    def Activate(self) -> "void":
-        return _pywrapcp.AssignmentElement_Activate(self)
-
-    def Deactivate(self) -> "void":
-        return _pywrapcp.AssignmentElement_Deactivate(self)
-
-    def Activated(self) -> "bool":
-        return _pywrapcp.AssignmentElement_Activated(self)
-    __swig_destroy__ = _pywrapcp.delete_AssignmentElement
-
-

Subclasses

- -

Instance variables

-
-
var thisown
-
-

The membership flag

-
- -Expand source code - -
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-
-
-

Methods

-
-
-def Activate(self) ‑> void -
-
-
-
- -Expand source code - -
def Activate(self) -> "void":
-    return _pywrapcp.AssignmentElement_Activate(self)
-
-
-
-def Activated(self) ‑> bool -
-
-
-
- -Expand source code - -
def Activated(self) -> "bool":
-    return _pywrapcp.AssignmentElement_Activated(self)
-
-
-
-def Deactivate(self) ‑> void -
-
-
-
- -Expand source code - -
def Deactivate(self) -> "void":
-    return _pywrapcp.AssignmentElement_Deactivate(self)
-
-
-
-
-
-class BaseLns -(vars: std::vector< operations_research::IntVar * > const &) -
-
-

This is the base class for building an Lns operator. An Lns fragment is a -collection of variables which will be relaxed. Fragments are built with -NextFragment(), which returns false if there are no more fragments to build. -Optionally one can override InitFragments, which is called from -LocalSearchOperator::Start to initialize fragment data.

-

Here's a sample relaxing one variable at a time:

-

class OneVarLns : public BaseLns { -public: -OneVarLns(const std::vector& vars) : BaseLns(vars), index_(0) {} -virtual ~OneVarLns() {} -virtual void InitFragments() { index_ = 0; } -virtual bool NextFragment() { -const int size = Size(); -if (index_ < size) { -AppendToFragment(index_); -++index_; -return true; -} else { -return false; -} -}

-

private: -int index_; -};

-
- -Expand source code - -
class BaseLns(IntVarLocalSearchOperator):
-    r"""
-    This is the base class for building an Lns operator. An Lns fragment is a
-    collection of variables which will be relaxed. Fragments are built with
-    NextFragment(), which returns false if there are no more fragments to build.
-    Optionally one can override InitFragments, which is called from
-    LocalSearchOperator::Start to initialize fragment data.
-
-    Here's a sample relaxing one variable at a time:
-
-    class OneVarLns : public BaseLns {
-     public:
-      OneVarLns(const std::vector<IntVar*>& vars) : BaseLns(vars), index_(0) {}
-      virtual ~OneVarLns() {}
-      virtual void InitFragments() { index_ = 0; }
-      virtual bool NextFragment() {
-        const int size = Size();
-        if (index_ < size) {
-          AppendToFragment(index_);
-          ++index_;
-          return true;
-        } else {
-          return false;
-        }
-      }
-
-     private:
-      int index_;
-    };
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self, vars: "std::vector< operations_research::IntVar * > const &"):
-        if self.__class__ == BaseLns:
-            _self = None
-        else:
-            _self = self
-        _pywrapcp.BaseLns_swiginit(self, _pywrapcp.new_BaseLns(_self, vars))
-    __swig_destroy__ = _pywrapcp.delete_BaseLns
-
-    def InitFragments(self) -> "void":
-        return _pywrapcp.BaseLns_InitFragments(self)
-
-    def NextFragment(self) -> "bool":
-        return _pywrapcp.BaseLns_NextFragment(self)
-
-    def AppendToFragment(self, index: "int") -> "void":
-        return _pywrapcp.BaseLns_AppendToFragment(self, index)
-
-    def FragmentSize(self) -> "int":
-        return _pywrapcp.BaseLns_FragmentSize(self)
-
-    def __getitem__(self, index: "int") -> "int64_t":
-        return _pywrapcp.BaseLns___getitem__(self, index)
-
-    def __len__(self) -> "int":
-        return _pywrapcp.BaseLns___len__(self)
-    def __disown__(self):
-        self.this.disown()
-        _pywrapcp.disown_BaseLns(self)
-        return weakref.proxy(self)
-
-

Ancestors

- -

Methods

-
-
-def AppendToFragment(self, index: int) ‑> void -
-
-
-
- -Expand source code - -
def AppendToFragment(self, index: "int") -> "void":
-    return _pywrapcp.BaseLns_AppendToFragment(self, index)
-
-
-
-def FragmentSize(self) ‑> int -
-
-
-
- -Expand source code - -
def FragmentSize(self) -> "int":
-    return _pywrapcp.BaseLns_FragmentSize(self)
-
-
-
-def InitFragments(self) ‑> void -
-
-
-
- -Expand source code - -
def InitFragments(self) -> "void":
-    return _pywrapcp.BaseLns_InitFragments(self)
-
-
-
-def NextFragment(self) ‑> bool -
-
-
-
- -Expand source code - -
def NextFragment(self) -> "bool":
-    return _pywrapcp.BaseLns_NextFragment(self)
-
-
-
-

Inherited members

- -
-
-class BaseObject -
-
-

A BaseObject is the root of all reversibly allocated objects. -A DebugString method and the associated << operator are implemented -as a convenience.

-
- -Expand source code - -
class BaseObject(object):
-    r"""
-    A BaseObject is the root of all reversibly allocated objects.
-    A DebugString method and the associated << operator are implemented
-    as a convenience.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self):
-        if self.__class__ == BaseObject:
-            _self = None
-        else:
-            _self = self
-        _pywrapcp.BaseObject_swiginit(self, _pywrapcp.new_BaseObject(_self, ))
-    __swig_destroy__ = _pywrapcp.delete_BaseObject
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.BaseObject_DebugString(self)
-
-    def __str__(self) -> "std::string":
-        return _pywrapcp.BaseObject___str__(self)
-
-    def __repr__(self) -> "std::string":
-        return _pywrapcp.BaseObject___repr__(self)
-    def __disown__(self):
-        self.this.disown()
-        _pywrapcp.disown_BaseObject(self)
-        return weakref.proxy(self)
-
-

Subclasses

- -

Instance variables

-
-
var thisown
-
-

The membership flag

-
- -Expand source code - -
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-
-
-

Methods

-
-
-def DebugString(self) ‑> std::string -
-
-
-
- -Expand source code - -
def DebugString(self) -> "std::string":
-    return _pywrapcp.BaseObject_DebugString(self)
-
-
-
-
-
-class BooleanVar -(*args, **kwargs) -
-
-

The class IntVar is a subset of IntExpr. In addition to the -IntExpr protocol, it offers persistence, removing values from the domains, -and a finer model for events.

-
- -Expand source code - -
class BooleanVar(IntVar):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
-    __repr__ = _swig_repr
-
-    def Min(self) -> "int64_t":
-        return _pywrapcp.BooleanVar_Min(self)
-
-    def SetMin(self, m: "int64_t") -> "void":
-        return _pywrapcp.BooleanVar_SetMin(self, m)
-
-    def Max(self) -> "int64_t":
-        return _pywrapcp.BooleanVar_Max(self)
-
-    def SetMax(self, m: "int64_t") -> "void":
-        return _pywrapcp.BooleanVar_SetMax(self, m)
-
-    def SetRange(self, mi: "int64_t", ma: "int64_t") -> "void":
-        return _pywrapcp.BooleanVar_SetRange(self, mi, ma)
-
-    def Bound(self) -> "bool":
-        return _pywrapcp.BooleanVar_Bound(self)
-
-    def Value(self) -> "int64_t":
-        return _pywrapcp.BooleanVar_Value(self)
-
-    def RemoveValue(self, v: "int64_t") -> "void":
-        return _pywrapcp.BooleanVar_RemoveValue(self, v)
-
-    def RemoveInterval(self, l: "int64_t", u: "int64_t") -> "void":
-        return _pywrapcp.BooleanVar_RemoveInterval(self, l, u)
-
-    def WhenBound(self, d: "Demon") -> "void":
-        return _pywrapcp.BooleanVar_WhenBound(self, d)
-
-    def WhenRange(self, d: "Demon") -> "void":
-        return _pywrapcp.BooleanVar_WhenRange(self, d)
-
-    def WhenDomain(self, d: "Demon") -> "void":
-        return _pywrapcp.BooleanVar_WhenDomain(self, d)
-
-    def Size(self) -> "uint64_t":
-        return _pywrapcp.BooleanVar_Size(self)
-
-    def Contains(self, v: "int64_t") -> "bool":
-        return _pywrapcp.BooleanVar_Contains(self, v)
-
-    def HoleIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *":
-        return _pywrapcp.BooleanVar_HoleIteratorAux(self, reversible)
-
-    def DomainIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *":
-        return _pywrapcp.BooleanVar_DomainIteratorAux(self, reversible)
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.BooleanVar_DebugString(self)
-
-

Ancestors

- -

Methods

-
-
-def DebugString(self) ‑> std::string -
-
-
-
- -Expand source code - -
def DebugString(self) -> "std::string":
-    return _pywrapcp.BooleanVar_DebugString(self)
-
-
-
-def Max(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def Max(self) -> "int64_t":
-    return _pywrapcp.BooleanVar_Max(self)
-
-
-
-def Min(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def Min(self) -> "int64_t":
-    return _pywrapcp.BooleanVar_Min(self)
-
-
-
-def SetMax(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetMax(self, m: "int64_t") -> "void":
-    return _pywrapcp.BooleanVar_SetMax(self, m)
-
-
-
-def SetMin(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetMin(self, m: "int64_t") -> "void":
-    return _pywrapcp.BooleanVar_SetMin(self, m)
-
-
-
-

Inherited members

- -
-
-class ChangeValue -(vars: std::vector< operations_research::IntVar * > const &) -
-
-

Defines operators which change the value of variables; -each neighbor corresponds to one modified variable. -Sub-classes have to define ModifyValue which determines what the new -variable value is going to be (given the current value and the variable).

-
- -Expand source code - -
class ChangeValue(IntVarLocalSearchOperator):
-    r"""
-    Defines operators which change the value of variables;
-    each neighbor corresponds to *one* modified variable.
-    Sub-classes have to define ModifyValue which determines what the new
-    variable value is going to be (given the current value and the variable).
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self, vars: "std::vector< operations_research::IntVar * > const &"):
-        if self.__class__ == ChangeValue:
-            _self = None
-        else:
-            _self = self
-        _pywrapcp.ChangeValue_swiginit(self, _pywrapcp.new_ChangeValue(_self, vars))
-    __swig_destroy__ = _pywrapcp.delete_ChangeValue
-
-    def ModifyValue(self, index: "int64_t", value: "int64_t") -> "int64_t":
-        return _pywrapcp.ChangeValue_ModifyValue(self, index, value)
-
-    def OneNeighbor(self) -> "bool":
-        r""" This method should not be overridden. Override ModifyValue() instead."""
-        return _pywrapcp.ChangeValue_OneNeighbor(self)
-    def __disown__(self):
-        self.this.disown()
-        _pywrapcp.disown_ChangeValue(self)
-        return weakref.proxy(self)
-
-

Ancestors

- -

Methods

-
-
-def ModifyValue(self, index: int64_t, value: int64_t) ‑> int64_t -
-
-
-
- -Expand source code - -
def ModifyValue(self, index: "int64_t", value: "int64_t") -> "int64_t":
-    return _pywrapcp.ChangeValue_ModifyValue(self, index, value)
-
-
-
-def OneNeighbor(self) ‑> bool -
-
-

This method should not be overridden. Override ModifyValue() instead.

-
- -Expand source code - -
def OneNeighbor(self) -> "bool":
-    r""" This method should not be overridden. Override ModifyValue() instead."""
-    return _pywrapcp.ChangeValue_OneNeighbor(self)
-
-
-
-

Inherited members

- -
-
-class Constraint -(solver: Solver) -
-
-

A constraint is the main modeling object. It provides two methods: -- Post() is responsible for creating the demons and attaching them to -immediate demons(). -- InitialPropagate() is called once just after Post and performs -the initial propagation. The subsequent propagations will be performed -by the demons Posted during the post() method.

-
- -Expand source code - -
class Constraint(PropagationBaseObject):
-    r"""
-    A constraint is the main modeling object. It provides two methods:
-      - Post() is responsible for creating the demons and attaching them to
-        immediate demons().
-      - InitialPropagate() is called once just after Post and performs
-        the initial propagation. The subsequent propagations will be performed
-        by the demons Posted during the post() method.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, solver: "Solver"):
-        if self.__class__ == Constraint:
-            _self = None
-        else:
-            _self = self
-        _pywrapcp.Constraint_swiginit(self, _pywrapcp.new_Constraint(_self, solver))
-    __swig_destroy__ = _pywrapcp.delete_Constraint
-
-    def Post(self) -> "void":
-        r"""
-        This method is called when the constraint is processed by the
-        solver. Its main usage is to attach demons to variables.
-        """
-        return _pywrapcp.Constraint_Post(self)
-
-    def InitialPropagateWrapper(self) -> "void":
-        r"""
-        This method performs the initial propagation of the
-        constraint. It is called just after the post.
-        """
-        return _pywrapcp.Constraint_InitialPropagateWrapper(self)
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.Constraint_DebugString(self)
-
-    def Var(self) -> "operations_research::IntVar *":
-        r"""
-        Creates a Boolean variable representing the status of the constraint
-        (false = constraint is violated, true = constraint is satisfied). It
-        returns nullptr if the constraint does not support this API.
-        """
-        return _pywrapcp.Constraint_Var(self)
-
-    def __repr__(self) -> "std::string":
-        return _pywrapcp.Constraint___repr__(self)
-
-    def __str__(self) -> "std::string":
-        return _pywrapcp.Constraint___str__(self)
-
-    def __add__(self, *args) -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint___add__(self, *args)
-
-    def __radd__(self, v: "int64_t") -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint___radd__(self, v)
-
-    def __sub__(self, *args) -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint___sub__(self, *args)
-
-    def __rsub__(self, v: "int64_t") -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint___rsub__(self, v)
-
-    def __mul__(self, *args) -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint___mul__(self, *args)
-
-    def __rmul__(self, v: "int64_t") -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint___rmul__(self, v)
-
-    def __floordiv__(self, v: "int64_t") -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint___floordiv__(self, v)
-
-    def __neg__(self) -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint___neg__(self)
-
-    def __abs__(self) -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint___abs__(self)
-
-    def Square(self) -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint_Square(self)
-
-    def __eq__(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Constraint___eq__(self, *args)
-
-    def __ne__(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Constraint___ne__(self, *args)
-
-    def __ge__(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Constraint___ge__(self, *args)
-
-    def __gt__(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Constraint___gt__(self, *args)
-
-    def __le__(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Constraint___le__(self, *args)
-
-    def __lt__(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Constraint___lt__(self, *args)
-
-    def MapTo(self, vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-        return _pywrapcp.Constraint_MapTo(self, vars)
-
-    def IndexOf(self, *args) -> "operations_research::IntExpr *":
-        return _pywrapcp.Constraint_IndexOf(self, *args)
-    def __disown__(self):
-        self.this.disown()
-        _pywrapcp.disown_Constraint(self)
-        return weakref.proxy(self)
-
-

Ancestors

- -

Subclasses

- -

Methods

-
-
-def DebugString(self) ‑> std::string -
-
-
-
- -Expand source code - -
def DebugString(self) -> "std::string":
-    return _pywrapcp.Constraint_DebugString(self)
-
-
-
-def IndexOf(self, *args) ‑> operations_research::IntExpr * -
-
-
-
- -Expand source code - -
def IndexOf(self, *args) -> "operations_research::IntExpr *":
-    return _pywrapcp.Constraint_IndexOf(self, *args)
-
-
-
-def InitialPropagateWrapper(self) ‑> void -
-
-

This method performs the initial propagation of the -constraint. It is called just after the post.

-
- -Expand source code - -
def InitialPropagateWrapper(self) -> "void":
-    r"""
-    This method performs the initial propagation of the
-    constraint. It is called just after the post.
-    """
-    return _pywrapcp.Constraint_InitialPropagateWrapper(self)
-
-
-
-def MapTo(self, vars: std::vector< operations_research::IntVar * > const &) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def MapTo(self, vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-    return _pywrapcp.Constraint_MapTo(self, vars)
-
-
-
-def Post(self) ‑> void -
-
-

This method is called when the constraint is processed by the -solver. Its main usage is to attach demons to variables.

-
- -Expand source code - -
def Post(self) -> "void":
-    r"""
-    This method is called when the constraint is processed by the
-    solver. Its main usage is to attach demons to variables.
-    """
-    return _pywrapcp.Constraint_Post(self)
-
-
-
-def Square(self) ‑> operations_research::IntExpr * -
-
-
-
- -Expand source code - -
def Square(self) -> "operations_research::IntExpr *":
-    return _pywrapcp.Constraint_Square(self)
-
-
-
-def Var(self) ‑> operations_research::IntVar * -
-
-

Creates a Boolean variable representing the status of the constraint -(false = constraint is violated, true = constraint is satisfied). It -returns nullptr if the constraint does not support this API.

-
- -Expand source code - -
def Var(self) -> "operations_research::IntVar *":
-    r"""
-    Creates a Boolean variable representing the status of the constraint
-    (false = constraint is violated, true = constraint is satisfied). It
-    returns nullptr if the constraint does not support this API.
-    """
-    return _pywrapcp.Constraint_Var(self)
-
-
-
-

Inherited members

- -
-
-class Decision -
-
-

A Decision represents a choice point in the search tree. The two main -methods are Apply() to go left, or Refute() to go right.

-
- -Expand source code - -
class Decision(BaseObject):
-    r"""
-    A Decision represents a choice point in the search tree. The two main
-    methods are Apply() to go left, or Refute() to go right.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self):
-        if self.__class__ == Decision:
-            _self = None
-        else:
-            _self = self
-        _pywrapcp.Decision_swiginit(self, _pywrapcp.new_Decision(_self, ))
-    __swig_destroy__ = _pywrapcp.delete_Decision
-
-    def ApplyWrapper(self, s: "Solver") -> "void":
-        r""" Apply will be called first when the decision is executed."""
-        return _pywrapcp.Decision_ApplyWrapper(self, s)
-
-    def RefuteWrapper(self, s: "Solver") -> "void":
-        r""" Refute will be called after a backtrack."""
-        return _pywrapcp.Decision_RefuteWrapper(self, s)
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.Decision_DebugString(self)
-
-    def __repr__(self) -> "std::string":
-        return _pywrapcp.Decision___repr__(self)
-
-    def __str__(self) -> "std::string":
-        return _pywrapcp.Decision___str__(self)
-    def __disown__(self):
-        self.this.disown()
-        _pywrapcp.disown_Decision(self)
-        return weakref.proxy(self)
-
-

Ancestors

- -

Subclasses

- -

Methods

-
-
-def ApplyWrapper(self, s: Solver) ‑> void -
-
-

Apply will be called first when the decision is executed.

-
- -Expand source code - -
def ApplyWrapper(self, s: "Solver") -> "void":
-    r""" Apply will be called first when the decision is executed."""
-    return _pywrapcp.Decision_ApplyWrapper(self, s)
-
-
-
-def DebugString(self) ‑> std::string -
-
-
-
- -Expand source code - -
def DebugString(self) -> "std::string":
-    return _pywrapcp.Decision_DebugString(self)
-
-
-
-def RefuteWrapper(self, s: Solver) ‑> void -
-
-

Refute will be called after a backtrack.

-
- -Expand source code - -
def RefuteWrapper(self, s: "Solver") -> "void":
-    r""" Refute will be called after a backtrack."""
-    return _pywrapcp.Decision_RefuteWrapper(self, s)
-
-
-
-

Inherited members

- -
-
-class DecisionBuilder -
-
-

A DecisionBuilder is responsible for creating the search tree. The -important method is Next(), which returns the next decision to execute.

-
- -Expand source code - -
class DecisionBuilder(BaseObject):
-    r"""
-    A DecisionBuilder is responsible for creating the search tree. The
-    important method is Next(), which returns the next decision to execute.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self):
-        if self.__class__ == DecisionBuilder:
-            _self = None
-        else:
-            _self = self
-        _pywrapcp.DecisionBuilder_swiginit(self, _pywrapcp.new_DecisionBuilder(_self, ))
-    __swig_destroy__ = _pywrapcp.delete_DecisionBuilder
-
-    def NextWrapper(self, s: "Solver") -> "operations_research::Decision *":
-        r"""
-        This is the main method of the decision builder class. It must
-        return a decision (an instance of the class Decision). If it
-        returns nullptr, this means that the decision builder has finished
-        its work.
-        """
-        return _pywrapcp.DecisionBuilder_NextWrapper(self, s)
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.DecisionBuilder_DebugString(self)
-
-    def __repr__(self) -> "std::string":
-        return _pywrapcp.DecisionBuilder___repr__(self)
-
-    def __str__(self) -> "std::string":
-        return _pywrapcp.DecisionBuilder___str__(self)
-    def __disown__(self):
-        self.this.disown()
-        _pywrapcp.disown_DecisionBuilder(self)
-        return weakref.proxy(self)
-
-

Ancestors

- -

Subclasses

- -

Methods

-
-
-def DebugString(self) ‑> std::string -
-
-
-
- -Expand source code - -
def DebugString(self) -> "std::string":
-    return _pywrapcp.DecisionBuilder_DebugString(self)
-
-
-
-def NextWrapper(self, s: Solver) ‑> operations_research::Decision * -
-
-

This is the main method of the decision builder class. It must -return a decision (an instance of the class Decision). If it -returns nullptr, this means that the decision builder has finished -its work.

-
- -Expand source code - -
def NextWrapper(self, s: "Solver") -> "operations_research::Decision *":
-    r"""
-    This is the main method of the decision builder class. It must
-    return a decision (an instance of the class Decision). If it
-    returns nullptr, this means that the decision builder has finished
-    its work.
-    """
-    return _pywrapcp.DecisionBuilder_NextWrapper(self, s)
-
-
-
-

Inherited members

- -
-
-class DefaultPhaseParameters -
-
-

This struct holds all parameters for the default search. -DefaultPhaseParameters is only used by Solver::MakeDefaultPhase methods. -Note this is for advanced users only.

-
- -Expand source code - -
class DefaultPhaseParameters(object):
-    r"""
-    This struct holds all parameters for the default search.
-    DefaultPhaseParameters is only used by Solver::MakeDefaultPhase methods.
-    Note this is for advanced users only.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-    CHOOSE_MAX_SUM_IMPACT = _pywrapcp.DefaultPhaseParameters_CHOOSE_MAX_SUM_IMPACT
-    CHOOSE_MAX_AVERAGE_IMPACT = _pywrapcp.DefaultPhaseParameters_CHOOSE_MAX_AVERAGE_IMPACT
-    CHOOSE_MAX_VALUE_IMPACT = _pywrapcp.DefaultPhaseParameters_CHOOSE_MAX_VALUE_IMPACT
-    SELECT_MIN_IMPACT = _pywrapcp.DefaultPhaseParameters_SELECT_MIN_IMPACT
-    SELECT_MAX_IMPACT = _pywrapcp.DefaultPhaseParameters_SELECT_MAX_IMPACT
-    NONE = _pywrapcp.DefaultPhaseParameters_NONE
-    NORMAL = _pywrapcp.DefaultPhaseParameters_NORMAL
-    VERBOSE = _pywrapcp.DefaultPhaseParameters_VERBOSE
-    var_selection_schema = property(_pywrapcp.DefaultPhaseParameters_var_selection_schema_get, _pywrapcp.DefaultPhaseParameters_var_selection_schema_set, doc=r"""
-    This parameter describes how the next variable to instantiate
-    will be chosen.
-    """)
-    value_selection_schema = property(_pywrapcp.DefaultPhaseParameters_value_selection_schema_get, _pywrapcp.DefaultPhaseParameters_value_selection_schema_set, doc=r""" This parameter describes which value to select for a given var.""")
-    initialization_splits = property(_pywrapcp.DefaultPhaseParameters_initialization_splits_get, _pywrapcp.DefaultPhaseParameters_initialization_splits_set, doc=r"""
-    Maximum number of intervals that the initialization of impacts will scan
-    per variable.
-    """)
-    run_all_heuristics = property(_pywrapcp.DefaultPhaseParameters_run_all_heuristics_get, _pywrapcp.DefaultPhaseParameters_run_all_heuristics_set, doc=r"""
-    The default phase will run heuristics periodically. This parameter
-    indicates if we should run all heuristics, or a randomly selected
-    one.
-    """)
-    heuristic_period = property(_pywrapcp.DefaultPhaseParameters_heuristic_period_get, _pywrapcp.DefaultPhaseParameters_heuristic_period_set, doc=r"""
-    The distance in nodes between each run of the heuristics. A
-    negative or null value will mean that we will not run heuristics
-    at all.
-    """)
-    heuristic_num_failures_limit = property(_pywrapcp.DefaultPhaseParameters_heuristic_num_failures_limit_get, _pywrapcp.DefaultPhaseParameters_heuristic_num_failures_limit_set, doc=r""" The failure limit for each heuristic that we run.""")
-    persistent_impact = property(_pywrapcp.DefaultPhaseParameters_persistent_impact_get, _pywrapcp.DefaultPhaseParameters_persistent_impact_set, doc=r"""
-    Whether to keep the impact from the first search for other searches,
-    or to recompute the impact for each new search.
-    """)
-    random_seed = property(_pywrapcp.DefaultPhaseParameters_random_seed_get, _pywrapcp.DefaultPhaseParameters_random_seed_set, doc=r""" Seed used to initialize the random part in some heuristics.""")
-    display_level = property(_pywrapcp.DefaultPhaseParameters_display_level_get, _pywrapcp.DefaultPhaseParameters_display_level_set, doc=r"""
-    This represents the amount of information displayed by the default search.
-    NONE means no display, VERBOSE means extra information.
-    """)
-    decision_builder = property(_pywrapcp.DefaultPhaseParameters_decision_builder_get, _pywrapcp.DefaultPhaseParameters_decision_builder_set, doc=r""" When defined, this overrides the default impact based decision builder.""")
-
-    def __init__(self):
-        _pywrapcp.DefaultPhaseParameters_swiginit(self, _pywrapcp.new_DefaultPhaseParameters())
-    __swig_destroy__ = _pywrapcp.delete_DefaultPhaseParameters
-
-

Class variables

-
-
var CHOOSE_MAX_AVERAGE_IMPACT
-
-
-
-
var CHOOSE_MAX_SUM_IMPACT
-
-
-
-
var CHOOSE_MAX_VALUE_IMPACT
-
-
-
-
var NONE
-
-
-
-
var NORMAL
-
-
-
-
var SELECT_MAX_IMPACT
-
-
-
-
var SELECT_MIN_IMPACT
-
-
-
-
var VERBOSE
-
-
-
-
-

Instance variables

-
-
var decision_builder
-
-

When defined, this overrides the default impact based decision builder.

-
-
var display_level
-
-

This represents the amount of information displayed by the default search. -NONE means no display, VERBOSE means extra information.

-
-
var heuristic_num_failures_limit
-
-

The failure limit for each heuristic that we run.

-
-
var heuristic_period
-
-

The distance in nodes between each run of the heuristics. A -negative or null value will mean that we will not run heuristics -at all.

-
-
var initialization_splits
-
-

Maximum number of intervals that the initialization of impacts will scan -per variable.

-
-
var persistent_impact
-
-

Whether to keep the impact from the first search for other searches, -or to recompute the impact for each new search.

-
-
var random_seed
-
-

Seed used to initialize the random part in some heuristics.

-
-
var run_all_heuristics
-
-

The default phase will run heuristics periodically. This parameter -indicates if we should run all heuristics, or a randomly selected -one.

-
-
var thisown
-
-

The membership flag

-
- -Expand source code - -
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-
-
var value_selection_schema
-
-

This parameter describes which value to select for a given var.

-
-
var var_selection_schema
-
-

This parameter describes how the next variable to instantiate -will be chosen.

-
-
-
-
-class Demon -
-
-

A Demon is the base element of a propagation queue. It is the main -object responsible for implementing the actual propagation -of the constraint and pruning the inconsistent values in the domains -of the variables. The main concept is that demons are listeners that are -attached to the variables and listen to their modifications. -There are two methods: -- Run() is the actual method called when the demon is processed. -- priority() returns its priority. Standard priorities are slow, normal -or fast. "immediate" is reserved for variables and is treated separately.

-

This indicates the priority of a demon. Immediate demons are treated -separately and corresponds to variables.

-
- -Expand source code - -
class Demon(BaseObject):
-    r"""
-    A Demon is the base element of a propagation queue. It is the main
-      object responsible for implementing the actual propagation
-      of the constraint and pruning the inconsistent values in the domains
-      of the variables. The main concept is that demons are listeners that are
-      attached to the variables and listen to their modifications.
-    There are two methods:
-     - Run() is the actual method called when the demon is processed.
-     - priority() returns its priority. Standard priorities are slow, normal
-       or fast. "immediate" is reserved for variables and is treated separately.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self):
-        r"""
-        This indicates the priority of a demon. Immediate demons are treated
-        separately and corresponds to variables.
-        """
-        if self.__class__ == Demon:
-            _self = None
-        else:
-            _self = self
-        _pywrapcp.Demon_swiginit(self, _pywrapcp.new_Demon(_self, ))
-    __swig_destroy__ = _pywrapcp.delete_Demon
-
-    def RunWrapper(self, s: "Solver") -> "void":
-        r""" This is the main callback of the demon."""
-        return _pywrapcp.Demon_RunWrapper(self, s)
-
-    def Priority(self) -> "operations_research::Solver::DemonPriority":
-        r"""
-        This method returns the priority of the demon. Usually a demon is
-        fast, slow or normal. Immediate demons are reserved for internal
-        use to maintain variables.
-        """
-        return _pywrapcp.Demon_Priority(self)
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.Demon_DebugString(self)
-
-    def Inhibit(self, s: "Solver") -> "void":
-        r"""
-        This method inhibits the demon in the search tree below the
-        current position.
-        """
-        return _pywrapcp.Demon_Inhibit(self, s)
-
-    def Desinhibit(self, s: "Solver") -> "void":
-        r""" This method un-inhibits the demon that was previously inhibited."""
-        return _pywrapcp.Demon_Desinhibit(self, s)
-    def __disown__(self):
-        self.this.disown()
-        _pywrapcp.disown_Demon(self)
-        return weakref.proxy(self)
-
-

Ancestors

- -

Subclasses

- -

Methods

-
-
-def DebugString(self) ‑> std::string -
-
-
-
- -Expand source code - -
def DebugString(self) -> "std::string":
-    return _pywrapcp.Demon_DebugString(self)
-
-
-
-def Desinhibit(self, s: Solver) ‑> void -
-
-

This method un-inhibits the demon that was previously inhibited.

-
- -Expand source code - -
def Desinhibit(self, s: "Solver") -> "void":
-    r""" This method un-inhibits the demon that was previously inhibited."""
-    return _pywrapcp.Demon_Desinhibit(self, s)
-
-
-
-def Inhibit(self, s: Solver) ‑> void -
-
-

This method inhibits the demon in the search tree below the -current position.

-
- -Expand source code - -
def Inhibit(self, s: "Solver") -> "void":
-    r"""
-    This method inhibits the demon in the search tree below the
-    current position.
-    """
-    return _pywrapcp.Demon_Inhibit(self, s)
-
-
-
-def Priority(self) ‑> operations_research::Solver::DemonPriority -
-
-

This method returns the priority of the demon. Usually a demon is -fast, slow or normal. Immediate demons are reserved for internal -use to maintain variables.

-
- -Expand source code - -
def Priority(self) -> "operations_research::Solver::DemonPriority":
-    r"""
-    This method returns the priority of the demon. Usually a demon is
-    fast, slow or normal. Immediate demons are reserved for internal
-    use to maintain variables.
-    """
-    return _pywrapcp.Demon_Priority(self)
-
-
-
-def RunWrapper(self, s: Solver) ‑> void -
-
-

This is the main callback of the demon.

-
- -Expand source code - -
def RunWrapper(self, s: "Solver") -> "void":
-    r""" This is the main callback of the demon."""
-    return _pywrapcp.Demon_RunWrapper(self, s)
-
-
-
-

Inherited members

- -
-
-class DisjunctiveConstraint -(*args, **kwargs) -
-
-

A constraint is the main modeling object. It provides two methods: -- Post() is responsible for creating the demons and attaching them to -immediate demons(). -- InitialPropagate() is called once just after Post and performs -the initial propagation. The subsequent propagations will be performed -by the demons Posted during the post() method.

-
- -Expand source code - -
class DisjunctiveConstraint(Constraint):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
-    __repr__ = _swig_repr
-
-    def SequenceVar(self) -> "operations_research::SequenceVar *":
-        r""" Creates a sequence variable from the constraint."""
-        return _pywrapcp.DisjunctiveConstraint_SequenceVar(self)
-
-    def SetTransitionTime(self, transition_time: "operations_research::Solver::IndexEvaluator2") -> "void":
-        r"""
-        Add a transition time between intervals.  It forces the distance between
-        the end of interval a and start of interval b that follows it to be at
-        least transition_time(a, b). This function must always return
-        a positive or null value.
-        """
-        return _pywrapcp.DisjunctiveConstraint_SetTransitionTime(self, transition_time)
-
-    def TransitionTime(self, before_index: "int", after_index: "int") -> "int64_t":
-        return _pywrapcp.DisjunctiveConstraint_TransitionTime(self, before_index, after_index)
-
-

Ancestors

- -

Methods

-
-
-def SequenceVar(self) ‑> operations_research::SequenceVar * -
-
-

Creates a sequence variable from the constraint.

-
- -Expand source code - -
def SequenceVar(self) -> "operations_research::SequenceVar *":
-    r""" Creates a sequence variable from the constraint."""
-    return _pywrapcp.DisjunctiveConstraint_SequenceVar(self)
-
-
-
-def SetTransitionTime(self, transition_time: operations_research::Solver::IndexEvaluator2) ‑> void -
-
-

Add a transition time between intervals. -It forces the distance between -the end of interval a and start of interval b that follows it to be at -least transition_time(a, b). This function must always return -a positive or null value.

-
- -Expand source code - -
def SetTransitionTime(self, transition_time: "operations_research::Solver::IndexEvaluator2") -> "void":
-    r"""
-    Add a transition time between intervals.  It forces the distance between
-    the end of interval a and start of interval b that follows it to be at
-    least transition_time(a, b). This function must always return
-    a positive or null value.
-    """
-    return _pywrapcp.DisjunctiveConstraint_SetTransitionTime(self, transition_time)
-
-
-
-def TransitionTime(self, before_index: int, after_index: int) ‑> int64_t -
-
-
-
- -Expand source code - -
def TransitionTime(self, before_index: "int", after_index: "int") -> "int64_t":
-    return _pywrapcp.DisjunctiveConstraint_TransitionTime(self, before_index, after_index)
-
-
-
-

Inherited members

- -
-
-class GlobalVehicleBreaksConstraint -(dimension: RoutingDimension) -
-
-

GlobalVehicleBreaksConstraint ensures breaks constraints are enforced on -all vehicles in the dimension passed to its constructor. -It is intended to be used for dimensions representing time. -A break constraint ensures break intervals fit on the route of a vehicle. -For a given vehicle, it forces break intervals to be disjoint from visit -intervals, where visit intervals start at CumulVar(node) and last for -node_visit_transit[node]. Moreover, it ensures that there is enough time -between two consecutive nodes of a route to do transit and vehicle breaks, -i.e. if Next(nodeA) = nodeB, CumulVar(nodeA) = tA and CumulVar(nodeB) = tB, -then SlackVar(nodeA) >= sum_{breaks [tA, tB)} duration(break).

-
- -Expand source code - -
class GlobalVehicleBreaksConstraint(Constraint):
-    r"""
-    GlobalVehicleBreaksConstraint ensures breaks constraints are enforced on
-    all vehicles in the dimension passed to its constructor.
-    It is intended to be used for dimensions representing time.
-    A break constraint ensures break intervals fit on the route of a vehicle.
-    For a given vehicle, it forces break intervals to be disjoint from visit
-    intervals, where visit intervals start at CumulVar(node) and last for
-    node_visit_transit[node]. Moreover, it ensures that there is enough time
-    between two consecutive nodes of a route to do transit and vehicle breaks,
-    i.e. if Next(nodeA) = nodeB, CumulVar(nodeA) = tA and CumulVar(nodeB) = tB,
-    then SlackVar(nodeA) >= sum_{breaks [tA, tB)} duration(break).
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self, dimension: "RoutingDimension"):
-        _pywrapcp.GlobalVehicleBreaksConstraint_swiginit(self, _pywrapcp.new_GlobalVehicleBreaksConstraint(dimension))
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.GlobalVehicleBreaksConstraint_DebugString(self)
-
-    def Post(self) -> "void":
-        return _pywrapcp.GlobalVehicleBreaksConstraint_Post(self)
-
-    def InitialPropagateWrapper(self) -> "void":
-        return _pywrapcp.GlobalVehicleBreaksConstraint_InitialPropagateWrapper(self)
-    __swig_destroy__ = _pywrapcp.delete_GlobalVehicleBreaksConstraint
-
-

Ancestors

- -

Methods

-
-
-def DebugString(self) ‑> std::string -
-
-
-
- -Expand source code - -
def DebugString(self) -> "std::string":
-    return _pywrapcp.GlobalVehicleBreaksConstraint_DebugString(self)
-
-
-
-

Inherited members

- -
-
-class IntExpr -(*args, **kwargs) -
-
-

The class IntExpr is the base of all integer expressions in -constraint programming. -It contains the basic protocol for an expression: -- setting and modifying its bound -- querying if it is bound -- listening to events modifying its bounds -- casting it into a variable (instance of IntVar)

-
- -Expand source code - -
class IntExpr(PropagationBaseObject):
-    r"""
-    The class IntExpr is the base of all integer expressions in
-    constraint programming.
-    It contains the basic protocol for an expression:
-      - setting and modifying its bound
-      - querying if it is bound
-      - listening to events modifying its bounds
-      - casting it into a variable (instance of IntVar)
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
-
-    def Min(self) -> "int64_t":
-        return _pywrapcp.IntExpr_Min(self)
-
-    def SetMin(self, m: "int64_t") -> "void":
-        return _pywrapcp.IntExpr_SetMin(self, m)
-
-    def Max(self) -> "int64_t":
-        return _pywrapcp.IntExpr_Max(self)
-
-    def SetMax(self, m: "int64_t") -> "void":
-        return _pywrapcp.IntExpr_SetMax(self, m)
-
-    def SetRange(self, l: "int64_t", u: "int64_t") -> "void":
-        r""" This method sets both the min and the max of the expression."""
-        return _pywrapcp.IntExpr_SetRange(self, l, u)
-
-    def SetValue(self, v: "int64_t") -> "void":
-        r""" This method sets the value of the expression."""
-        return _pywrapcp.IntExpr_SetValue(self, v)
-
-    def Bound(self) -> "bool":
-        r""" Returns true if the min and the max of the expression are equal."""
-        return _pywrapcp.IntExpr_Bound(self)
-
-    def IsVar(self) -> "bool":
-        r""" Returns true if the expression is indeed a variable."""
-        return _pywrapcp.IntExpr_IsVar(self)
-
-    def Var(self) -> "operations_research::IntVar *":
-        r""" Creates a variable from the expression."""
-        return _pywrapcp.IntExpr_Var(self)
-
-    def VarWithName(self, name: "std::string const &") -> "operations_research::IntVar *":
-        r"""
-        Creates a variable from the expression and set the name of the
-        resulting var. If the expression is already a variable, then it
-        will set the name of the expression, possibly overwriting it.
-        This is just a shortcut to Var() followed by set_name().
-        """
-        return _pywrapcp.IntExpr_VarWithName(self, name)
-
-    def WhenRange(self, *args) -> "void":
-        r"""
-        *Overload 1:*
-        Attach a demon that will watch the min or the max of the expression.
-
-        |
-
-        *Overload 2:*
-        Attach a demon that will watch the min or the max of the expression.
-        """
-        return _pywrapcp.IntExpr_WhenRange(self, *args)
-
-    def __repr__(self) -> "std::string":
-        return _pywrapcp.IntExpr___repr__(self)
-
-    def __str__(self) -> "std::string":
-        return _pywrapcp.IntExpr___str__(self)
-
-    def __add__(self, *args) -> "operations_research::IntExpr *":
-        return _pywrapcp.IntExpr___add__(self, *args)
-
-    def __radd__(self, v: "int64_t") -> "operations_research::IntExpr *":
-        return _pywrapcp.IntExpr___radd__(self, v)
-
-    def __sub__(self, *args) -> "operations_research::IntExpr *":
-        return _pywrapcp.IntExpr___sub__(self, *args)
-
-    def __rsub__(self, v: "int64_t") -> "operations_research::IntExpr *":
-        return _pywrapcp.IntExpr___rsub__(self, v)
-
-    def __mul__(self, *args) -> "operations_research::IntExpr *":
-        return _pywrapcp.IntExpr___mul__(self, *args)
-
-    def __rmul__(self, v: "int64_t") -> "operations_research::IntExpr *":
-        return _pywrapcp.IntExpr___rmul__(self, v)
-
-    def __floordiv__(self, *args) -> "operations_research::IntExpr *":
-        return _pywrapcp.IntExpr___floordiv__(self, *args)
-
-    def __mod__(self, *args) -> "operations_research::IntExpr *":
-        return _pywrapcp.IntExpr___mod__(self, *args)
-
-    def __neg__(self) -> "operations_research::IntExpr *":
-        return _pywrapcp.IntExpr___neg__(self)
-
-    def __abs__(self) -> "operations_research::IntExpr *":
-        return _pywrapcp.IntExpr___abs__(self)
-
-    def Square(self) -> "operations_research::IntExpr *":
-        return _pywrapcp.IntExpr_Square(self)
-
-    def __eq__(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.IntExpr___eq__(self, *args)
-
-    def __ne__(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.IntExpr___ne__(self, *args)
-
-    def __ge__(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.IntExpr___ge__(self, *args)
-
-    def __gt__(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.IntExpr___gt__(self, *args)
-
-    def __le__(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.IntExpr___le__(self, *args)
-
-    def __lt__(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.IntExpr___lt__(self, *args)
-
-    def MapTo(self, vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-        return _pywrapcp.IntExpr_MapTo(self, vars)
-
-    def IndexOf(self, *args) -> "operations_research::IntExpr *":
-        return _pywrapcp.IntExpr_IndexOf(self, *args)
-
-    def IsMember(self, values: "std::vector< int64_t > const &") -> "operations_research::IntVar *":
-        return _pywrapcp.IntExpr_IsMember(self, values)
-
-    def Member(self, values: "std::vector< int64_t > const &") -> "operations_research::Constraint *":
-        return _pywrapcp.IntExpr_Member(self, values)
-
-    def NotMember(self, starts: "std::vector< int64_t > const &", ends: "std::vector< int64_t > const &") -> "operations_research::Constraint *":
-        return _pywrapcp.IntExpr_NotMember(self, starts, ends)
-
-

Ancestors

- -

Subclasses

- -

Methods

-
-
-def Bound(self) ‑> bool -
-
-

Returns true if the min and the max of the expression are equal.

-
- -Expand source code - -
def Bound(self) -> "bool":
-    r""" Returns true if the min and the max of the expression are equal."""
-    return _pywrapcp.IntExpr_Bound(self)
-
-
-
-def IndexOf(self, *args) ‑> operations_research::IntExpr * -
-
-
-
- -Expand source code - -
def IndexOf(self, *args) -> "operations_research::IntExpr *":
-    return _pywrapcp.IntExpr_IndexOf(self, *args)
-
-
-
-def IsMember(self, values: std::vector< int64_t > const &) ‑> operations_research::IntVar * -
-
-
-
- -Expand source code - -
def IsMember(self, values: "std::vector< int64_t > const &") -> "operations_research::IntVar *":
-    return _pywrapcp.IntExpr_IsMember(self, values)
-
-
-
-def IsVar(self) ‑> bool -
-
-

Returns true if the expression is indeed a variable.

-
- -Expand source code - -
def IsVar(self) -> "bool":
-    r""" Returns true if the expression is indeed a variable."""
-    return _pywrapcp.IntExpr_IsVar(self)
-
-
-
-def MapTo(self, vars: std::vector< operations_research::IntVar * > const &) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def MapTo(self, vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-    return _pywrapcp.IntExpr_MapTo(self, vars)
-
-
-
-def Max(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def Max(self) -> "int64_t":
-    return _pywrapcp.IntExpr_Max(self)
-
-
-
-def Member(self, values: std::vector< int64_t > const &) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def Member(self, values: "std::vector< int64_t > const &") -> "operations_research::Constraint *":
-    return _pywrapcp.IntExpr_Member(self, values)
-
-
-
-def Min(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def Min(self) -> "int64_t":
-    return _pywrapcp.IntExpr_Min(self)
-
-
-
-def NotMember(self, starts: std::vector< int64_t > const &, ends: std::vector< int64_t > const &) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def NotMember(self, starts: "std::vector< int64_t > const &", ends: "std::vector< int64_t > const &") -> "operations_research::Constraint *":
-    return _pywrapcp.IntExpr_NotMember(self, starts, ends)
-
-
-
-def SetMax(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetMax(self, m: "int64_t") -> "void":
-    return _pywrapcp.IntExpr_SetMax(self, m)
-
-
-
-def SetMin(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetMin(self, m: "int64_t") -> "void":
-    return _pywrapcp.IntExpr_SetMin(self, m)
-
-
-
-def SetRange(self, l: int64_t, u: int64_t) ‑> void -
-
-

This method sets both the min and the max of the expression.

-
- -Expand source code - -
def SetRange(self, l: "int64_t", u: "int64_t") -> "void":
-    r""" This method sets both the min and the max of the expression."""
-    return _pywrapcp.IntExpr_SetRange(self, l, u)
-
-
-
-def SetValue(self, v: int64_t) ‑> void -
-
-

This method sets the value of the expression.

-
- -Expand source code - -
def SetValue(self, v: "int64_t") -> "void":
-    r""" This method sets the value of the expression."""
-    return _pywrapcp.IntExpr_SetValue(self, v)
-
-
-
-def Square(self) ‑> operations_research::IntExpr * -
-
-
-
- -Expand source code - -
def Square(self) -> "operations_research::IntExpr *":
-    return _pywrapcp.IntExpr_Square(self)
-
-
-
-def Var(self) ‑> operations_research::IntVar * -
-
-

Creates a variable from the expression.

-
- -Expand source code - -
def Var(self) -> "operations_research::IntVar *":
-    r""" Creates a variable from the expression."""
-    return _pywrapcp.IntExpr_Var(self)
-
-
-
-def VarWithName(self, name: std::string const &) ‑> operations_research::IntVar * -
-
-

Creates a variable from the expression and set the name of the -resulting var. If the expression is already a variable, then it -will set the name of the expression, possibly overwriting it. -This is just a shortcut to Var() followed by set_name().

-
- -Expand source code - -
def VarWithName(self, name: "std::string const &") -> "operations_research::IntVar *":
-    r"""
-    Creates a variable from the expression and set the name of the
-    resulting var. If the expression is already a variable, then it
-    will set the name of the expression, possibly overwriting it.
-    This is just a shortcut to Var() followed by set_name().
-    """
-    return _pywrapcp.IntExpr_VarWithName(self, name)
-
-
-
-def WhenRange(self, *args) ‑> void -
-
-

Overload 1: -Attach a demon that will watch the min or the max of the expression.

-

|

-

Overload 2: -Attach a demon that will watch the min or the max of the expression.

-
- -Expand source code - -
def WhenRange(self, *args) -> "void":
-    r"""
-    *Overload 1:*
-    Attach a demon that will watch the min or the max of the expression.
-
-    |
-
-    *Overload 2:*
-    Attach a demon that will watch the min or the max of the expression.
-    """
-    return _pywrapcp.IntExpr_WhenRange(self, *args)
-
-
-
-

Inherited members

- -
-
-class IntVar -(*args, **kwargs) -
-
-

The class IntVar is a subset of IntExpr. In addition to the -IntExpr protocol, it offers persistence, removing values from the domains, -and a finer model for events.

-
- -Expand source code - -
class IntVar(IntExpr):
-    r"""
-    The class IntVar is a subset of IntExpr. In addition to the
-    IntExpr protocol, it offers persistence, removing values from the domains,
-    and a finer model for events.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
-
-    def IsVar(self) -> "bool":
-        return _pywrapcp.IntVar_IsVar(self)
-
-    def Var(self) -> "operations_research::IntVar *":
-        return _pywrapcp.IntVar_Var(self)
-
-    def Value(self) -> "int64_t":
-        r"""
-        This method returns the value of the variable. This method checks
-        before that the variable is bound.
-        """
-        return _pywrapcp.IntVar_Value(self)
-
-    def RemoveValue(self, v: "int64_t") -> "void":
-        r""" This method removes the value 'v' from the domain of the variable."""
-        return _pywrapcp.IntVar_RemoveValue(self, v)
-
-    def RemoveInterval(self, l: "int64_t", u: "int64_t") -> "void":
-        r"""
-        This method removes the interval 'l' .. 'u' from the domain of
-        the variable. It assumes that 'l' <= 'u'.
-        """
-        return _pywrapcp.IntVar_RemoveInterval(self, l, u)
-
-    def RemoveValues(self, values: "std::vector< int64_t > const &") -> "void":
-        r""" This method remove the values from the domain of the variable."""
-        return _pywrapcp.IntVar_RemoveValues(self, values)
-
-    def SetValues(self, values: "std::vector< int64_t > const &") -> "void":
-        r""" This method intersects the current domain with the values in the array."""
-        return _pywrapcp.IntVar_SetValues(self, values)
-
-    def WhenBound(self, *args) -> "void":
-        r"""
-        *Overload 1:*
-        This method attaches a demon that will be awakened when the
-        variable is bound.
-
-        |
-
-        *Overload 2:*
-        This method attaches a closure that will be awakened when the
-        variable is bound.
-        """
-        return _pywrapcp.IntVar_WhenBound(self, *args)
-
-    def WhenDomain(self, *args) -> "void":
-        r"""
-        *Overload 1:*
-        This method attaches a demon that will watch any domain
-        modification of the domain of the variable.
-
-        |
-
-        *Overload 2:*
-        This method attaches a closure that will watch any domain
-        modification of the domain of the variable.
-        """
-        return _pywrapcp.IntVar_WhenDomain(self, *args)
-
-    def Size(self) -> "uint64_t":
-        r""" This method returns the number of values in the domain of the variable."""
-        return _pywrapcp.IntVar_Size(self)
-
-    def Contains(self, v: "int64_t") -> "bool":
-        r"""
-        This method returns whether the value 'v' is in the domain of the
-        variable.
-        """
-        return _pywrapcp.IntVar_Contains(self, v)
-
-    def HoleIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *":
-        r"""
-        Creates a hole iterator. When 'reversible' is false, the returned
-        object is created on the normal C++ heap and the solver does NOT
-        take ownership of the object.
-        """
-        return _pywrapcp.IntVar_HoleIteratorAux(self, reversible)
-
-    def DomainIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *":
-        r"""
-        Creates a domain iterator. When 'reversible' is false, the
-        returned object is created on the normal C++ heap and the solver
-        does NOT take ownership of the object.
-        """
-        return _pywrapcp.IntVar_DomainIteratorAux(self, reversible)
-
-    def OldMin(self) -> "int64_t":
-        r""" Returns the previous min."""
-        return _pywrapcp.IntVar_OldMin(self)
-
-    def OldMax(self) -> "int64_t":
-        r""" Returns the previous max."""
-        return _pywrapcp.IntVar_OldMax(self)
-
-    def __repr__(self) -> "std::string":
-        return _pywrapcp.IntVar___repr__(self)
-
-    def __str__(self) -> "std::string":
-        return _pywrapcp.IntVar___str__(self)
-
-    def DomainIterator(self):
-      return iter(self.DomainIteratorAux(False))
-
-    def HoleIterator(self):
-      return iter(self.HoleIteratorAux(False))
-
-

Ancestors

- -

Subclasses

- -

Methods

-
-
-def Contains(self, v: int64_t) ‑> bool -
-
-

This method returns whether the value 'v' is in the domain of the -variable.

-
- -Expand source code - -
def Contains(self, v: "int64_t") -> "bool":
-    r"""
-    This method returns whether the value 'v' is in the domain of the
-    variable.
-    """
-    return _pywrapcp.IntVar_Contains(self, v)
-
-
-
-def DomainIterator(self) -
-
-
-
- -Expand source code - -
def DomainIterator(self):
-  return iter(self.DomainIteratorAux(False))
-
-
-
-def DomainIteratorAux(self, reversible: bool) ‑> operations_research::IntVarIterator * -
-
-

Creates a domain iterator. When 'reversible' is false, the -returned object is created on the normal C++ heap and the solver -does NOT take ownership of the object.

-
- -Expand source code - -
def DomainIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *":
-    r"""
-    Creates a domain iterator. When 'reversible' is false, the
-    returned object is created on the normal C++ heap and the solver
-    does NOT take ownership of the object.
-    """
-    return _pywrapcp.IntVar_DomainIteratorAux(self, reversible)
-
-
-
-def HoleIterator(self) -
-
-
-
- -Expand source code - -
def HoleIterator(self):
-  return iter(self.HoleIteratorAux(False))
-
-
-
-def HoleIteratorAux(self, reversible: bool) ‑> operations_research::IntVarIterator * -
-
-

Creates a hole iterator. When 'reversible' is false, the returned -object is created on the normal C++ heap and the solver does NOT -take ownership of the object.

-
- -Expand source code - -
def HoleIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *":
-    r"""
-    Creates a hole iterator. When 'reversible' is false, the returned
-    object is created on the normal C++ heap and the solver does NOT
-    take ownership of the object.
-    """
-    return _pywrapcp.IntVar_HoleIteratorAux(self, reversible)
-
-
-
-def OldMax(self) ‑> int64_t -
-
-

Returns the previous max.

-
- -Expand source code - -
def OldMax(self) -> "int64_t":
-    r""" Returns the previous max."""
-    return _pywrapcp.IntVar_OldMax(self)
-
-
-
-def OldMin(self) ‑> int64_t -
-
-

Returns the previous min.

-
- -Expand source code - -
def OldMin(self) -> "int64_t":
-    r""" Returns the previous min."""
-    return _pywrapcp.IntVar_OldMin(self)
-
-
-
-def RemoveInterval(self, l: int64_t, u: int64_t) ‑> void -
-
-

This method removes the interval 'l' .. 'u' from the domain of -the variable. It assumes that 'l' <= 'u'.

-
- -Expand source code - -
def RemoveInterval(self, l: "int64_t", u: "int64_t") -> "void":
-    r"""
-    This method removes the interval 'l' .. 'u' from the domain of
-    the variable. It assumes that 'l' <= 'u'.
-    """
-    return _pywrapcp.IntVar_RemoveInterval(self, l, u)
-
-
-
-def RemoveValue(self, v: int64_t) ‑> void -
-
-

This method removes the value 'v' from the domain of the variable.

-
- -Expand source code - -
def RemoveValue(self, v: "int64_t") -> "void":
-    r""" This method removes the value 'v' from the domain of the variable."""
-    return _pywrapcp.IntVar_RemoveValue(self, v)
-
-
-
-def RemoveValues(self, values: std::vector< int64_t > const &) ‑> void -
-
-

This method remove the values from the domain of the variable.

-
- -Expand source code - -
def RemoveValues(self, values: "std::vector< int64_t > const &") -> "void":
-    r""" This method remove the values from the domain of the variable."""
-    return _pywrapcp.IntVar_RemoveValues(self, values)
-
-
-
-def SetValues(self, values: std::vector< int64_t > const &) ‑> void -
-
-

This method intersects the current domain with the values in the array.

-
- -Expand source code - -
def SetValues(self, values: "std::vector< int64_t > const &") -> "void":
-    r""" This method intersects the current domain with the values in the array."""
-    return _pywrapcp.IntVar_SetValues(self, values)
-
-
-
-def Size(self) ‑> uint64_t -
-
-

This method returns the number of values in the domain of the variable.

-
- -Expand source code - -
def Size(self) -> "uint64_t":
-    r""" This method returns the number of values in the domain of the variable."""
-    return _pywrapcp.IntVar_Size(self)
-
-
-
-def Value(self) ‑> int64_t -
-
-

This method returns the value of the variable. This method checks -before that the variable is bound.

-
- -Expand source code - -
def Value(self) -> "int64_t":
-    r"""
-    This method returns the value of the variable. This method checks
-    before that the variable is bound.
-    """
-    return _pywrapcp.IntVar_Value(self)
-
-
-
-def WhenBound(self, *args) ‑> void -
-
-

Overload 1: -This method attaches a demon that will be awakened when the -variable is bound.

-

|

-

Overload 2: -This method attaches a closure that will be awakened when the -variable is bound.

-
- -Expand source code - -
def WhenBound(self, *args) -> "void":
-    r"""
-    *Overload 1:*
-    This method attaches a demon that will be awakened when the
-    variable is bound.
-
-    |
-
-    *Overload 2:*
-    This method attaches a closure that will be awakened when the
-    variable is bound.
-    """
-    return _pywrapcp.IntVar_WhenBound(self, *args)
-
-
-
-def WhenDomain(self, *args) ‑> void -
-
-

Overload 1: -This method attaches a demon that will watch any domain -modification of the domain of the variable.

-

|

-

Overload 2: -This method attaches a closure that will watch any domain -modification of the domain of the variable.

-
- -Expand source code - -
def WhenDomain(self, *args) -> "void":
-    r"""
-    *Overload 1:*
-    This method attaches a demon that will watch any domain
-    modification of the domain of the variable.
-
-    |
-
-    *Overload 2:*
-    This method attaches a closure that will watch any domain
-    modification of the domain of the variable.
-    """
-    return _pywrapcp.IntVar_WhenDomain(self, *args)
-
-
-
-

Inherited members

- -
-
-class IntVarContainer -(*args, **kwargs) -
-
-
-
- -Expand source code - -
class IntVarContainer(object):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined")
-    __repr__ = _swig_repr
-
-    def Contains(self, var: "IntVar") -> "bool":
-        return _pywrapcp.IntVarContainer_Contains(self, var)
-
-    def Element(self, index: "int") -> "operations_research::IntVarElement *":
-        return _pywrapcp.IntVarContainer_Element(self, index)
-
-    def Size(self) -> "int":
-        return _pywrapcp.IntVarContainer_Size(self)
-
-    def Store(self) -> "void":
-        return _pywrapcp.IntVarContainer_Store(self)
-
-    def Restore(self) -> "void":
-        return _pywrapcp.IntVarContainer_Restore(self)
-
-    def __eq__(self, container: "IntVarContainer") -> "bool":
-        r"""
-        Returns true if this and 'container' both represent the same V* -> E map.
-        Runs in linear time; requires that the == operator on the type E is well
-        defined.
-        """
-        return _pywrapcp.IntVarContainer___eq__(self, container)
-
-    def __ne__(self, container: "IntVarContainer") -> "bool":
-        return _pywrapcp.IntVarContainer___ne__(self, container)
-    __swig_destroy__ = _pywrapcp.delete_IntVarContainer
-
-

Instance variables

-
-
var thisown
-
-

The membership flag

-
- -Expand source code - -
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-
-
-

Methods

-
-
-def Contains(self, var: IntVar) ‑> bool -
-
-
-
- -Expand source code - -
def Contains(self, var: "IntVar") -> "bool":
-    return _pywrapcp.IntVarContainer_Contains(self, var)
-
-
-
-def Element(self, index: int) ‑> operations_research::IntVarElement * -
-
-
-
- -Expand source code - -
def Element(self, index: "int") -> "operations_research::IntVarElement *":
-    return _pywrapcp.IntVarContainer_Element(self, index)
-
-
-
-def Restore(self) ‑> void -
-
-
-
- -Expand source code - -
def Restore(self) -> "void":
-    return _pywrapcp.IntVarContainer_Restore(self)
-
-
-
-def Size(self) ‑> int -
-
-
-
- -Expand source code - -
def Size(self) -> "int":
-    return _pywrapcp.IntVarContainer_Size(self)
-
-
-
-def Store(self) ‑> void -
-
-
-
- -Expand source code - -
def Store(self) -> "void":
-    return _pywrapcp.IntVarContainer_Store(self)
-
-
-
-
-
-class IntVarElement -(*args, **kwargs) -
-
-
-
- -Expand source code - -
class IntVarElement(AssignmentElement):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined")
-    __repr__ = _swig_repr
-
-    def Var(self) -> "operations_research::IntVar *":
-        return _pywrapcp.IntVarElement_Var(self)
-
-    def Min(self) -> "int64_t":
-        return _pywrapcp.IntVarElement_Min(self)
-
-    def SetMin(self, m: "int64_t") -> "void":
-        return _pywrapcp.IntVarElement_SetMin(self, m)
-
-    def Max(self) -> "int64_t":
-        return _pywrapcp.IntVarElement_Max(self)
-
-    def SetMax(self, m: "int64_t") -> "void":
-        return _pywrapcp.IntVarElement_SetMax(self, m)
-
-    def Value(self) -> "int64_t":
-        return _pywrapcp.IntVarElement_Value(self)
-
-    def Bound(self) -> "bool":
-        return _pywrapcp.IntVarElement_Bound(self)
-
-    def SetRange(self, l: "int64_t", u: "int64_t") -> "void":
-        return _pywrapcp.IntVarElement_SetRange(self, l, u)
-
-    def SetValue(self, v: "int64_t") -> "void":
-        return _pywrapcp.IntVarElement_SetValue(self, v)
-
-    def __eq__(self, element: "IntVarElement") -> "bool":
-        return _pywrapcp.IntVarElement___eq__(self, element)
-
-    def __ne__(self, element: "IntVarElement") -> "bool":
-        return _pywrapcp.IntVarElement___ne__(self, element)
-    __swig_destroy__ = _pywrapcp.delete_IntVarElement
-
-

Ancestors

- -

Methods

-
-
-def Bound(self) ‑> bool -
-
-
-
- -Expand source code - -
def Bound(self) -> "bool":
-    return _pywrapcp.IntVarElement_Bound(self)
-
-
-
-def Max(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def Max(self) -> "int64_t":
-    return _pywrapcp.IntVarElement_Max(self)
-
-
-
-def Min(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def Min(self) -> "int64_t":
-    return _pywrapcp.IntVarElement_Min(self)
-
-
-
-def SetMax(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetMax(self, m: "int64_t") -> "void":
-    return _pywrapcp.IntVarElement_SetMax(self, m)
-
-
-
-def SetMin(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetMin(self, m: "int64_t") -> "void":
-    return _pywrapcp.IntVarElement_SetMin(self, m)
-
-
-
-def SetRange(self, l: int64_t, u: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetRange(self, l: "int64_t", u: "int64_t") -> "void":
-    return _pywrapcp.IntVarElement_SetRange(self, l, u)
-
-
-
-def SetValue(self, v: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetValue(self, v: "int64_t") -> "void":
-    return _pywrapcp.IntVarElement_SetValue(self, v)
-
-
-
-def Value(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def Value(self) -> "int64_t":
-    return _pywrapcp.IntVarElement_Value(self)
-
-
-
-def Var(self) ‑> operations_research::IntVar * -
-
-
-
- -Expand source code - -
def Var(self) -> "operations_research::IntVar *":
-    return _pywrapcp.IntVarElement_Var(self)
-
-
-
-

Inherited members

- -
-
-class IntVarIterator -(*args, **kwargs) -
-
-

The class Iterator has two direct subclasses. HoleIterators -iterates over all holes, that is value removed between the -current min and max of the variable since the last time the -variable was processed in the queue. DomainIterators iterates -over all elements of the variable domain. Both iterators are not -robust to domain changes. Hole iterators can also report values outside -the current min and max of the variable. -HoleIterators should only be called from a demon attached to the -variable that has created this iterator. -IntVar* current_var; -std::unique_ptr it(current_var->MakeHoleIterator(false)); -for (const int64_t hole : InitAndGetValues(it)) { -use the hole -}

-
- -Expand source code - -
class IntVarIterator(BaseObject):
-    r"""
-     The class Iterator has two direct subclasses. HoleIterators
-     iterates over all holes, that is value removed between the
-     current min and max of the variable since the last time the
-     variable was processed in the queue. DomainIterators iterates
-     over all elements of the variable domain. Both iterators are not
-     robust to domain changes. Hole iterators can also report values outside
-     the current min and max of the variable.
-     HoleIterators should only be called from a demon attached to the
-     variable that has created this iterator.
-     IntVar* current_var;
-     std::unique_ptr<IntVarIterator> it(current_var->MakeHoleIterator(false));
-     for (const int64_t hole : InitAndGetValues(it)) {
-    use the hole
-     }
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
-    __repr__ = _swig_repr
-
-    def Init(self) -> "void":
-        r""" This method must be called before each loop."""
-        return _pywrapcp.IntVarIterator_Init(self)
-
-    def Ok(self) -> "bool":
-        r""" This method indicates if we can call Value() or not."""
-        return _pywrapcp.IntVarIterator_Ok(self)
-
-    def Value(self) -> "int64_t":
-        r""" This method returns the current value of the iterator."""
-        return _pywrapcp.IntVarIterator_Value(self)
-
-    def Next(self) -> "void":
-        r""" This method moves the iterator to the next value."""
-        return _pywrapcp.IntVarIterator_Next(self)
-
-    def DebugString(self) -> "std::string":
-        r""" Pretty Print."""
-        return _pywrapcp.IntVarIterator_DebugString(self)
-
-    def __iter__(self):
-      self.Init()
-      return self
-
-    def next(self):
-      if self.Ok():
-        result = self.Value()
-        self.Next()
-        return result
-      else:
-        raise StopIteration()
-
-    def __next__(self):
-      return self.next()
-
-

Ancestors

- -

Methods

-
-
-def DebugString(self) ‑> std::string -
-
-

Pretty Print.

-
- -Expand source code - -
def DebugString(self) -> "std::string":
-    r""" Pretty Print."""
-    return _pywrapcp.IntVarIterator_DebugString(self)
-
-
-
-def Init(self) ‑> void -
-
-

This method must be called before each loop.

-
- -Expand source code - -
def Init(self) -> "void":
-    r""" This method must be called before each loop."""
-    return _pywrapcp.IntVarIterator_Init(self)
-
-
-
-def Next(self) ‑> void -
-
-

This method moves the iterator to the next value.

-
- -Expand source code - -
def Next(self) -> "void":
-    r""" This method moves the iterator to the next value."""
-    return _pywrapcp.IntVarIterator_Next(self)
-
-
-
-def Ok(self) ‑> bool -
-
-

This method indicates if we can call Value() or not.

-
- -Expand source code - -
def Ok(self) -> "bool":
-    r""" This method indicates if we can call Value() or not."""
-    return _pywrapcp.IntVarIterator_Ok(self)
-
-
-
-def Value(self) ‑> int64_t -
-
-

This method returns the current value of the iterator.

-
- -Expand source code - -
def Value(self) -> "int64_t":
-    r""" This method returns the current value of the iterator."""
-    return _pywrapcp.IntVarIterator_Value(self)
-
-
-
-def next(self) -
-
-
-
- -Expand source code - -
def next(self):
-  if self.Ok():
-    result = self.Value()
-    self.Next()
-    return result
-  else:
-    raise StopIteration()
-
-
-
-

Inherited members

- -
-
-class IntVarLocalSearchFilter -(vars: std::vector< operations_research::IntVar * > const &) -
-
-

Classes to which this template function can be applied to as of 04/2014. -Usage: LocalSearchOperator op = MakeLocalSearchOperator(…); -class TwoOpt; -class Relocate; -class Exchange; -class Cross; -class MakeActiveOperator; -class MakeInactiveOperator; -class MakeChainInactiveOperator; -class SwapActiveOperator; -class ExtendedSwapActiveOperator; -class MakeActiveAndRelocate; -class RelocateAndMakeActiveOperator; -class RelocateAndMakeInactiveOperator; -Local Search Filters are used for fast neighbor pruning. -Filtering a move is done in several phases: -- in the Relax phase, filters determine which parts of their internals -will be changed by the candidate, and modify intermediary State -- in the Accept phase, filters check that the candidate is feasible, -- if the Accept phase succeeds, the solver may decide to trigger a -Synchronize phase that makes filters change their internal representation -to the last candidate, -- otherwise (Accept fails or the solver does not want to synchronize), -a Revert phase makes filters erase any intermediary State generated by the -Relax and Accept phases. -A given filter has phases called with the following pattern: -(Relax.Accept.Synchronize | Relax.Accept.Revert | Relax.Revert). -Filters's Revert() is always called in the reverse order their Accept() was -called, to allow late filters to use state done/undone by early filters' -Accept()/Revert().

-
- -Expand source code - -
class IntVarLocalSearchFilter(LocalSearchFilter):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self, vars: "std::vector< operations_research::IntVar * > const &"):
-        if self.__class__ == IntVarLocalSearchFilter:
-            _self = None
-        else:
-            _self = self
-        _pywrapcp.IntVarLocalSearchFilter_swiginit(self, _pywrapcp.new_IntVarLocalSearchFilter(_self, vars))
-    __swig_destroy__ = _pywrapcp.delete_IntVarLocalSearchFilter
-
-    def Synchronize(self, assignment: "Assignment", delta: "Assignment") -> "void":
-        r"""
-        This method should not be overridden. Override OnSynchronize() instead
-        which is called before exiting this method.
-        """
-        return _pywrapcp.IntVarLocalSearchFilter_Synchronize(self, assignment, delta)
-
-    def Size(self) -> "int":
-        return _pywrapcp.IntVarLocalSearchFilter_Size(self)
-
-    def Value(self, index: "int") -> "int64_t":
-        return _pywrapcp.IntVarLocalSearchFilter_Value(self, index)
-
-    def IndexFromVar(self, var: "IntVar") -> "int64_t":
-        return _pywrapcp.IntVarLocalSearchFilter_IndexFromVar(self, var)
-    def __disown__(self):
-        self.this.disown()
-        _pywrapcp.disown_IntVarLocalSearchFilter(self)
-        return weakref.proxy(self)
-
-

Ancestors

- -

Methods

-
-
-def IndexFromVar(self, var: IntVar) ‑> int64_t -
-
-
-
- -Expand source code - -
def IndexFromVar(self, var: "IntVar") -> "int64_t":
-    return _pywrapcp.IntVarLocalSearchFilter_IndexFromVar(self, var)
-
-
-
-def Size(self) ‑> int -
-
-
-
- -Expand source code - -
def Size(self) -> "int":
-    return _pywrapcp.IntVarLocalSearchFilter_Size(self)
-
-
-
-def Synchronize(self, assignment: Assignment, delta: Assignment) ‑> void -
-
-

This method should not be overridden. Override OnSynchronize() instead -which is called before exiting this method.

-
- -Expand source code - -
def Synchronize(self, assignment: "Assignment", delta: "Assignment") -> "void":
-    r"""
-    This method should not be overridden. Override OnSynchronize() instead
-    which is called before exiting this method.
-    """
-    return _pywrapcp.IntVarLocalSearchFilter_Synchronize(self, assignment, delta)
-
-
-
-def Value(self, index: int) ‑> int64_t -
-
-
-
- -Expand source code - -
def Value(self, index: "int") -> "int64_t":
-    return _pywrapcp.IntVarLocalSearchFilter_Value(self, index)
-
-
-
-

Inherited members

- -
-
-class IntVarLocalSearchOperator -(*args) -
-
-

Base operator class for operators manipulating variables.

-
- -Expand source code - -
class IntVarLocalSearchOperator(IntVarLocalSearchOperatorTemplate):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self, *args):
-        if self.__class__ == IntVarLocalSearchOperator:
-            _self = None
-        else:
-            _self = self
-        _pywrapcp.IntVarLocalSearchOperator_swiginit(self, _pywrapcp.new_IntVarLocalSearchOperator(_self, *args))
-    __swig_destroy__ = _pywrapcp.delete_IntVarLocalSearchOperator
-
-    def NextNeighbor(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
-        r"""
-        Redefines MakeNextNeighbor to export a simpler interface. The calls to
-        ApplyChanges() and RevertChanges() are factored in this method, hiding
-        both delta and deltadelta from subclasses which only need to override
-        MakeOneNeighbor().
-        Therefore this method should not be overridden. Override MakeOneNeighbor()
-        instead.
-        """
-        return _pywrapcp.IntVarLocalSearchOperator_NextNeighbor(self, delta, deltadelta)
-
-    def OneNeighbor(self) -> "bool":
-        r"""
-        Creates a new neighbor. It returns false when the neighborhood is
-        completely explored.
-        MakeNextNeighbor() in a subclass of IntVarLocalSearchOperator.
-        """
-        return _pywrapcp.IntVarLocalSearchOperator_OneNeighbor(self)
-    def __disown__(self):
-        self.this.disown()
-        _pywrapcp.disown_IntVarLocalSearchOperator(self)
-        return weakref.proxy(self)
-
-

Ancestors

- -

Subclasses

- -

Methods

-
-
-def NextNeighbor(self, delta: Assignment, deltadelta: Assignment) ‑> bool -
-
-

Redefines MakeNextNeighbor to export a simpler interface. The calls to -ApplyChanges() and RevertChanges() are factored in this method, hiding -both delta and deltadelta from subclasses which only need to override -MakeOneNeighbor(). -Therefore this method should not be overridden. Override MakeOneNeighbor() -instead.

-
- -Expand source code - -
def NextNeighbor(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
-    r"""
-    Redefines MakeNextNeighbor to export a simpler interface. The calls to
-    ApplyChanges() and RevertChanges() are factored in this method, hiding
-    both delta and deltadelta from subclasses which only need to override
-    MakeOneNeighbor().
-    Therefore this method should not be overridden. Override MakeOneNeighbor()
-    instead.
-    """
-    return _pywrapcp.IntVarLocalSearchOperator_NextNeighbor(self, delta, deltadelta)
-
-
-
-def OneNeighbor(self) ‑> bool -
-
-

Creates a new neighbor. It returns false when the neighborhood is -completely explored. -MakeNextNeighbor() in a subclass of IntVarLocalSearchOperator.

-
- -Expand source code - -
def OneNeighbor(self) -> "bool":
-    r"""
-    Creates a new neighbor. It returns false when the neighborhood is
-    completely explored.
-    MakeNextNeighbor() in a subclass of IntVarLocalSearchOperator.
-    """
-    return _pywrapcp.IntVarLocalSearchOperator_OneNeighbor(self)
-
-
-
-

Inherited members

- -
-
-class IntVarLocalSearchOperatorTemplate -(*args, **kwargs) -
-
-

Base operator class for operators manipulating variables.

-
- -Expand source code - -
class IntVarLocalSearchOperatorTemplate(LocalSearchOperator):
-    r""" Base operator class for operators manipulating variables."""
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
-    __repr__ = _swig_repr
-
-    def Start(self, assignment: "Assignment") -> "void":
-        r"""
-        This method should not be overridden. Override OnStart() instead which is
-        called before exiting this method.
-        """
-        return _pywrapcp.IntVarLocalSearchOperatorTemplate_Start(self, assignment)
-
-    def IsIncremental(self) -> "bool":
-        return _pywrapcp.IntVarLocalSearchOperatorTemplate_IsIncremental(self)
-
-    def Size(self) -> "int":
-        return _pywrapcp.IntVarLocalSearchOperatorTemplate_Size(self)
-
-    def Value(self, index: "int64_t") -> "long const &":
-        r"""
-        Returns the value in the current assignment of the variable of given
-        index.
-        """
-        return _pywrapcp.IntVarLocalSearchOperatorTemplate_Value(self, index)
-
-    def OldValue(self, index: "int64_t") -> "long const &":
-        return _pywrapcp.IntVarLocalSearchOperatorTemplate_OldValue(self, index)
-
-    def SetValue(self, index: "int64_t", value: "long const &") -> "void":
-        return _pywrapcp.IntVarLocalSearchOperatorTemplate_SetValue(self, index, value)
-
-    def OnStart(self) -> "void":
-        r"""
-        Called by Start() after synchronizing the operator with the current
-        assignment. Should be overridden instead of Start() to avoid calling
-        VarLocalSearchOperator::Start explicitly.
-        """
-        return _pywrapcp.IntVarLocalSearchOperatorTemplate_OnStart(self)
-
-

Ancestors

- -

Subclasses

- -

Methods

-
-
-def IsIncremental(self) ‑> bool -
-
-
-
- -Expand source code - -
def IsIncremental(self) -> "bool":
-    return _pywrapcp.IntVarLocalSearchOperatorTemplate_IsIncremental(self)
-
-
-
-def OldValue(self, index: int64_t) ‑> long const & -
-
-
-
- -Expand source code - -
def OldValue(self, index: "int64_t") -> "long const &":
-    return _pywrapcp.IntVarLocalSearchOperatorTemplate_OldValue(self, index)
-
-
-
-def OnStart(self) ‑> void -
-
-

Called by Start() after synchronizing the operator with the current -assignment. Should be overridden instead of Start() to avoid calling -VarLocalSearchOperator::Start explicitly.

-
- -Expand source code - -
def OnStart(self) -> "void":
-    r"""
-    Called by Start() after synchronizing the operator with the current
-    assignment. Should be overridden instead of Start() to avoid calling
-    VarLocalSearchOperator::Start explicitly.
-    """
-    return _pywrapcp.IntVarLocalSearchOperatorTemplate_OnStart(self)
-
-
-
-def SetValue(self, index: int64_t, value: long const &) ‑> void -
-
-
-
- -Expand source code - -
def SetValue(self, index: "int64_t", value: "long const &") -> "void":
-    return _pywrapcp.IntVarLocalSearchOperatorTemplate_SetValue(self, index, value)
-
-
-
-def Size(self) ‑> int -
-
-
-
- -Expand source code - -
def Size(self) -> "int":
-    return _pywrapcp.IntVarLocalSearchOperatorTemplate_Size(self)
-
-
-
-def Start(self, assignment: Assignment) ‑> void -
-
-

This method should not be overridden. Override OnStart() instead which is -called before exiting this method.

-
- -Expand source code - -
def Start(self, assignment: "Assignment") -> "void":
-    r"""
-    This method should not be overridden. Override OnStart() instead which is
-    called before exiting this method.
-    """
-    return _pywrapcp.IntVarLocalSearchOperatorTemplate_Start(self, assignment)
-
-
-
-def Value(self, index: int64_t) ‑> long const & -
-
-

Returns the value in the current assignment of the variable of given -index.

-
- -Expand source code - -
def Value(self, index: "int64_t") -> "long const &":
-    r"""
-    Returns the value in the current assignment of the variable of given
-    index.
-    """
-    return _pywrapcp.IntVarLocalSearchOperatorTemplate_Value(self, index)
-
-
-
-

Inherited members

- -
-
-class IntervalVar -(*args, **kwargs) -
-
-

Interval variables are often used in scheduling. The main characteristics -of an IntervalVar are the start position, duration, and end -date. All these characteristics can be queried and set, and demons can -be posted on their modifications.

-

An important aspect is optionality: an IntervalVar can be performed or not. -If unperformed, then it simply does not exist, and its characteristics -cannot be accessed any more. An interval var is automatically marked -as unperformed when it is not consistent anymore (start greater -than end, duration < 0…)

-
- -Expand source code - -
class IntervalVar(PropagationBaseObject):
-    r"""
-    Interval variables are often used in scheduling. The main characteristics
-    of an IntervalVar are the start position, duration, and end
-    date. All these characteristics can be queried and set, and demons can
-    be posted on their modifications.
-
-    An important aspect is optionality: an IntervalVar can be performed or not.
-    If unperformed, then it simply does not exist, and its characteristics
-    cannot be accessed any more. An interval var is automatically marked
-    as unperformed when it is not consistent anymore (start greater
-    than end, duration < 0...)
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
-
-    def StartMin(self) -> "int64_t":
-        r"""
-        These methods query, set, and watch the start position of the
-        interval var.
-        """
-        return _pywrapcp.IntervalVar_StartMin(self)
-
-    def StartMax(self) -> "int64_t":
-        return _pywrapcp.IntervalVar_StartMax(self)
-
-    def SetStartMin(self, m: "int64_t") -> "void":
-        return _pywrapcp.IntervalVar_SetStartMin(self, m)
-
-    def SetStartMax(self, m: "int64_t") -> "void":
-        return _pywrapcp.IntervalVar_SetStartMax(self, m)
-
-    def SetStartRange(self, mi: "int64_t", ma: "int64_t") -> "void":
-        return _pywrapcp.IntervalVar_SetStartRange(self, mi, ma)
-
-    def OldStartMin(self) -> "int64_t":
-        return _pywrapcp.IntervalVar_OldStartMin(self)
-
-    def OldStartMax(self) -> "int64_t":
-        return _pywrapcp.IntervalVar_OldStartMax(self)
-
-    def WhenStartRange(self, *args) -> "void":
-        return _pywrapcp.IntervalVar_WhenStartRange(self, *args)
-
-    def WhenStartBound(self, *args) -> "void":
-        return _pywrapcp.IntervalVar_WhenStartBound(self, *args)
-
-    def DurationMin(self) -> "int64_t":
-        r""" These methods query, set, and watch the duration of the interval var."""
-        return _pywrapcp.IntervalVar_DurationMin(self)
-
-    def DurationMax(self) -> "int64_t":
-        return _pywrapcp.IntervalVar_DurationMax(self)
-
-    def SetDurationMin(self, m: "int64_t") -> "void":
-        return _pywrapcp.IntervalVar_SetDurationMin(self, m)
-
-    def SetDurationMax(self, m: "int64_t") -> "void":
-        return _pywrapcp.IntervalVar_SetDurationMax(self, m)
-
-    def SetDurationRange(self, mi: "int64_t", ma: "int64_t") -> "void":
-        return _pywrapcp.IntervalVar_SetDurationRange(self, mi, ma)
-
-    def OldDurationMin(self) -> "int64_t":
-        return _pywrapcp.IntervalVar_OldDurationMin(self)
-
-    def OldDurationMax(self) -> "int64_t":
-        return _pywrapcp.IntervalVar_OldDurationMax(self)
-
-    def WhenDurationRange(self, *args) -> "void":
-        return _pywrapcp.IntervalVar_WhenDurationRange(self, *args)
-
-    def WhenDurationBound(self, *args) -> "void":
-        return _pywrapcp.IntervalVar_WhenDurationBound(self, *args)
-
-    def EndMin(self) -> "int64_t":
-        r""" These methods query, set, and watch the end position of the interval var."""
-        return _pywrapcp.IntervalVar_EndMin(self)
-
-    def EndMax(self) -> "int64_t":
-        return _pywrapcp.IntervalVar_EndMax(self)
-
-    def SetEndMin(self, m: "int64_t") -> "void":
-        return _pywrapcp.IntervalVar_SetEndMin(self, m)
-
-    def SetEndMax(self, m: "int64_t") -> "void":
-        return _pywrapcp.IntervalVar_SetEndMax(self, m)
-
-    def SetEndRange(self, mi: "int64_t", ma: "int64_t") -> "void":
-        return _pywrapcp.IntervalVar_SetEndRange(self, mi, ma)
-
-    def OldEndMin(self) -> "int64_t":
-        return _pywrapcp.IntervalVar_OldEndMin(self)
-
-    def OldEndMax(self) -> "int64_t":
-        return _pywrapcp.IntervalVar_OldEndMax(self)
-
-    def WhenEndRange(self, *args) -> "void":
-        return _pywrapcp.IntervalVar_WhenEndRange(self, *args)
-
-    def WhenEndBound(self, *args) -> "void":
-        return _pywrapcp.IntervalVar_WhenEndBound(self, *args)
-
-    def MustBePerformed(self) -> "bool":
-        r"""
-        These methods query, set, and watch the performed status of the
-        interval var.
-        """
-        return _pywrapcp.IntervalVar_MustBePerformed(self)
-
-    def MayBePerformed(self) -> "bool":
-        return _pywrapcp.IntervalVar_MayBePerformed(self)
-
-    def CannotBePerformed(self) -> "bool":
-        return _pywrapcp.IntervalVar_CannotBePerformed(self)
-
-    def IsPerformedBound(self) -> "bool":
-        return _pywrapcp.IntervalVar_IsPerformedBound(self)
-
-    def SetPerformed(self, val: "bool") -> "void":
-        return _pywrapcp.IntervalVar_SetPerformed(self, val)
-
-    def WasPerformedBound(self) -> "bool":
-        return _pywrapcp.IntervalVar_WasPerformedBound(self)
-
-    def WhenPerformedBound(self, *args) -> "void":
-        return _pywrapcp.IntervalVar_WhenPerformedBound(self, *args)
-
-    def WhenAnything(self, *args) -> "void":
-        r"""
-        *Overload 1:*
-        Attaches a demon awakened when anything about this interval changes.
-
-        |
-
-        *Overload 2:*
-        Attaches a closure awakened when anything about this interval changes.
-        """
-        return _pywrapcp.IntervalVar_WhenAnything(self, *args)
-
-    def StartExpr(self) -> "operations_research::IntExpr *":
-        r"""
-        These methods create expressions encapsulating the start, end
-        and duration of the interval var. Please note that these must not
-        be used if the interval var is unperformed.
-        """
-        return _pywrapcp.IntervalVar_StartExpr(self)
-
-    def DurationExpr(self) -> "operations_research::IntExpr *":
-        return _pywrapcp.IntervalVar_DurationExpr(self)
-
-    def EndExpr(self) -> "operations_research::IntExpr *":
-        return _pywrapcp.IntervalVar_EndExpr(self)
-
-    def PerformedExpr(self) -> "operations_research::IntExpr *":
-        return _pywrapcp.IntervalVar_PerformedExpr(self)
-
-    def SafeStartExpr(self, unperformed_value: "int64_t") -> "operations_research::IntExpr *":
-        r"""
-        These methods create expressions encapsulating the start, end
-        and duration of the interval var. If the interval var is
-        unperformed, they will return the unperformed_value.
-        """
-        return _pywrapcp.IntervalVar_SafeStartExpr(self, unperformed_value)
-
-    def SafeDurationExpr(self, unperformed_value: "int64_t") -> "operations_research::IntExpr *":
-        return _pywrapcp.IntervalVar_SafeDurationExpr(self, unperformed_value)
-
-    def SafeEndExpr(self, unperformed_value: "int64_t") -> "operations_research::IntExpr *":
-        return _pywrapcp.IntervalVar_SafeEndExpr(self, unperformed_value)
-
-    def EndsAfterEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_EndsAfterEnd(self, other)
-
-    def EndsAfterEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_EndsAfterEndWithDelay(self, other, delay)
-
-    def EndsAfterStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_EndsAfterStart(self, other)
-
-    def EndsAfterStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_EndsAfterStartWithDelay(self, other, delay)
-
-    def EndsAtEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_EndsAtEnd(self, other)
-
-    def EndsAtEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_EndsAtEndWithDelay(self, other, delay)
-
-    def EndsAtStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_EndsAtStart(self, other)
-
-    def EndsAtStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_EndsAtStartWithDelay(self, other, delay)
-
-    def StartsAfterEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_StartsAfterEnd(self, other)
-
-    def StartsAfterEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_StartsAfterEndWithDelay(self, other, delay)
-
-    def StartsAfterStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_StartsAfterStart(self, other)
-
-    def StartsAfterStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_StartsAfterStartWithDelay(self, other, delay)
-
-    def StartsAtEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_StartsAtEnd(self, other)
-
-    def StartsAtEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_StartsAtEndWithDelay(self, other, delay)
-
-    def StartsAtStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_StartsAtStart(self, other)
-
-    def StartsAtStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_StartsAtStartWithDelay(self, other, delay)
-
-    def StaysInSync(self, other: "IntervalVar") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_StaysInSync(self, other)
-
-    def StaysInSyncWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_StaysInSyncWithDelay(self, other, delay)
-
-    def EndsAfter(self, date: "int64_t") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_EndsAfter(self, date)
-
-    def EndsAt(self, date: "int64_t") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_EndsAt(self, date)
-
-    def EndsBefore(self, date: "int64_t") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_EndsBefore(self, date)
-
-    def StartsAfter(self, date: "int64_t") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_StartsAfter(self, date)
-
-    def StartsAt(self, date: "int64_t") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_StartsAt(self, date)
-
-    def StartsBefore(self, date: "int64_t") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_StartsBefore(self, date)
-
-    def CrossesDate(self, date: "int64_t") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_CrossesDate(self, date)
-
-    def AvoidsDate(self, date: "int64_t") -> "operations_research::Constraint *":
-        return _pywrapcp.IntervalVar_AvoidsDate(self, date)
-
-    def __repr__(self) -> "std::string":
-        return _pywrapcp.IntervalVar___repr__(self)
-
-    def __str__(self) -> "std::string":
-        return _pywrapcp.IntervalVar___str__(self)
-
-

Ancestors

- -

Methods

-
-
-def AvoidsDate(self, date: int64_t) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def AvoidsDate(self, date: "int64_t") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_AvoidsDate(self, date)
-
-
-
-def CannotBePerformed(self) ‑> bool -
-
-
-
- -Expand source code - -
def CannotBePerformed(self) -> "bool":
-    return _pywrapcp.IntervalVar_CannotBePerformed(self)
-
-
-
-def CrossesDate(self, date: int64_t) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def CrossesDate(self, date: "int64_t") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_CrossesDate(self, date)
-
-
-
-def DurationExpr(self) ‑> operations_research::IntExpr * -
-
-
-
- -Expand source code - -
def DurationExpr(self) -> "operations_research::IntExpr *":
-    return _pywrapcp.IntervalVar_DurationExpr(self)
-
-
-
-def DurationMax(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def DurationMax(self) -> "int64_t":
-    return _pywrapcp.IntervalVar_DurationMax(self)
-
-
-
-def DurationMin(self) ‑> int64_t -
-
-

These methods query, set, and watch the duration of the interval var.

-
- -Expand source code - -
def DurationMin(self) -> "int64_t":
-    r""" These methods query, set, and watch the duration of the interval var."""
-    return _pywrapcp.IntervalVar_DurationMin(self)
-
-
-
-def EndExpr(self) ‑> operations_research::IntExpr * -
-
-
-
- -Expand source code - -
def EndExpr(self) -> "operations_research::IntExpr *":
-    return _pywrapcp.IntervalVar_EndExpr(self)
-
-
-
-def EndMax(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def EndMax(self) -> "int64_t":
-    return _pywrapcp.IntervalVar_EndMax(self)
-
-
-
-def EndMin(self) ‑> int64_t -
-
-

These methods query, set, and watch the end position of the interval var.

-
- -Expand source code - -
def EndMin(self) -> "int64_t":
-    r""" These methods query, set, and watch the end position of the interval var."""
-    return _pywrapcp.IntervalVar_EndMin(self)
-
-
-
-def EndsAfter(self, date: int64_t) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def EndsAfter(self, date: "int64_t") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_EndsAfter(self, date)
-
-
-
-def EndsAfterEnd(self, other: IntervalVar) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def EndsAfterEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_EndsAfterEnd(self, other)
-
-
-
-def EndsAfterEndWithDelay(self, other: IntervalVar, delay: int64_t) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def EndsAfterEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_EndsAfterEndWithDelay(self, other, delay)
-
-
-
-def EndsAfterStart(self, other: IntervalVar) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def EndsAfterStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_EndsAfterStart(self, other)
-
-
-
-def EndsAfterStartWithDelay(self, other: IntervalVar, delay: int64_t) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def EndsAfterStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_EndsAfterStartWithDelay(self, other, delay)
-
-
-
-def EndsAt(self, date: int64_t) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def EndsAt(self, date: "int64_t") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_EndsAt(self, date)
-
-
-
-def EndsAtEnd(self, other: IntervalVar) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def EndsAtEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_EndsAtEnd(self, other)
-
-
-
-def EndsAtEndWithDelay(self, other: IntervalVar, delay: int64_t) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def EndsAtEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_EndsAtEndWithDelay(self, other, delay)
-
-
-
-def EndsAtStart(self, other: IntervalVar) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def EndsAtStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_EndsAtStart(self, other)
-
-
-
-def EndsAtStartWithDelay(self, other: IntervalVar, delay: int64_t) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def EndsAtStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_EndsAtStartWithDelay(self, other, delay)
-
-
-
-def EndsBefore(self, date: int64_t) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def EndsBefore(self, date: "int64_t") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_EndsBefore(self, date)
-
-
-
-def IsPerformedBound(self) ‑> bool -
-
-
-
- -Expand source code - -
def IsPerformedBound(self) -> "bool":
-    return _pywrapcp.IntervalVar_IsPerformedBound(self)
-
-
-
-def MayBePerformed(self) ‑> bool -
-
-
-
- -Expand source code - -
def MayBePerformed(self) -> "bool":
-    return _pywrapcp.IntervalVar_MayBePerformed(self)
-
-
-
-def MustBePerformed(self) ‑> bool -
-
-

These methods query, set, and watch the performed status of the -interval var.

-
- -Expand source code - -
def MustBePerformed(self) -> "bool":
-    r"""
-    These methods query, set, and watch the performed status of the
-    interval var.
-    """
-    return _pywrapcp.IntervalVar_MustBePerformed(self)
-
-
-
-def OldDurationMax(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def OldDurationMax(self) -> "int64_t":
-    return _pywrapcp.IntervalVar_OldDurationMax(self)
-
-
-
-def OldDurationMin(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def OldDurationMin(self) -> "int64_t":
-    return _pywrapcp.IntervalVar_OldDurationMin(self)
-
-
-
-def OldEndMax(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def OldEndMax(self) -> "int64_t":
-    return _pywrapcp.IntervalVar_OldEndMax(self)
-
-
-
-def OldEndMin(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def OldEndMin(self) -> "int64_t":
-    return _pywrapcp.IntervalVar_OldEndMin(self)
-
-
-
-def OldStartMax(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def OldStartMax(self) -> "int64_t":
-    return _pywrapcp.IntervalVar_OldStartMax(self)
-
-
-
-def OldStartMin(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def OldStartMin(self) -> "int64_t":
-    return _pywrapcp.IntervalVar_OldStartMin(self)
-
-
-
-def PerformedExpr(self) ‑> operations_research::IntExpr * -
-
-
-
- -Expand source code - -
def PerformedExpr(self) -> "operations_research::IntExpr *":
-    return _pywrapcp.IntervalVar_PerformedExpr(self)
-
-
-
-def SafeDurationExpr(self, unperformed_value: int64_t) ‑> operations_research::IntExpr * -
-
-
-
- -Expand source code - -
def SafeDurationExpr(self, unperformed_value: "int64_t") -> "operations_research::IntExpr *":
-    return _pywrapcp.IntervalVar_SafeDurationExpr(self, unperformed_value)
-
-
-
-def SafeEndExpr(self, unperformed_value: int64_t) ‑> operations_research::IntExpr * -
-
-
-
- -Expand source code - -
def SafeEndExpr(self, unperformed_value: "int64_t") -> "operations_research::IntExpr *":
-    return _pywrapcp.IntervalVar_SafeEndExpr(self, unperformed_value)
-
-
-
-def SafeStartExpr(self, unperformed_value: int64_t) ‑> operations_research::IntExpr * -
-
-

These methods create expressions encapsulating the start, end -and duration of the interval var. If the interval var is -unperformed, they will return the unperformed_value.

-
- -Expand source code - -
def SafeStartExpr(self, unperformed_value: "int64_t") -> "operations_research::IntExpr *":
-    r"""
-    These methods create expressions encapsulating the start, end
-    and duration of the interval var. If the interval var is
-    unperformed, they will return the unperformed_value.
-    """
-    return _pywrapcp.IntervalVar_SafeStartExpr(self, unperformed_value)
-
-
-
-def SetDurationMax(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetDurationMax(self, m: "int64_t") -> "void":
-    return _pywrapcp.IntervalVar_SetDurationMax(self, m)
-
-
-
-def SetDurationMin(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetDurationMin(self, m: "int64_t") -> "void":
-    return _pywrapcp.IntervalVar_SetDurationMin(self, m)
-
-
-
-def SetDurationRange(self, mi: int64_t, ma: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetDurationRange(self, mi: "int64_t", ma: "int64_t") -> "void":
-    return _pywrapcp.IntervalVar_SetDurationRange(self, mi, ma)
-
-
-
-def SetEndMax(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetEndMax(self, m: "int64_t") -> "void":
-    return _pywrapcp.IntervalVar_SetEndMax(self, m)
-
-
-
-def SetEndMin(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetEndMin(self, m: "int64_t") -> "void":
-    return _pywrapcp.IntervalVar_SetEndMin(self, m)
-
-
-
-def SetEndRange(self, mi: int64_t, ma: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetEndRange(self, mi: "int64_t", ma: "int64_t") -> "void":
-    return _pywrapcp.IntervalVar_SetEndRange(self, mi, ma)
-
-
-
-def SetPerformed(self, val: bool) ‑> void -
-
-
-
- -Expand source code - -
def SetPerformed(self, val: "bool") -> "void":
-    return _pywrapcp.IntervalVar_SetPerformed(self, val)
-
-
-
-def SetStartMax(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetStartMax(self, m: "int64_t") -> "void":
-    return _pywrapcp.IntervalVar_SetStartMax(self, m)
-
-
-
-def SetStartMin(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetStartMin(self, m: "int64_t") -> "void":
-    return _pywrapcp.IntervalVar_SetStartMin(self, m)
-
-
-
-def SetStartRange(self, mi: int64_t, ma: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetStartRange(self, mi: "int64_t", ma: "int64_t") -> "void":
-    return _pywrapcp.IntervalVar_SetStartRange(self, mi, ma)
-
-
-
-def StartExpr(self) ‑> operations_research::IntExpr * -
-
-

These methods create expressions encapsulating the start, end -and duration of the interval var. Please note that these must not -be used if the interval var is unperformed.

-
- -Expand source code - -
def StartExpr(self) -> "operations_research::IntExpr *":
-    r"""
-    These methods create expressions encapsulating the start, end
-    and duration of the interval var. Please note that these must not
-    be used if the interval var is unperformed.
-    """
-    return _pywrapcp.IntervalVar_StartExpr(self)
-
-
-
-def StartMax(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def StartMax(self) -> "int64_t":
-    return _pywrapcp.IntervalVar_StartMax(self)
-
-
-
-def StartMin(self) ‑> int64_t -
-
-

These methods query, set, and watch the start position of the -interval var.

-
- -Expand source code - -
def StartMin(self) -> "int64_t":
-    r"""
-    These methods query, set, and watch the start position of the
-    interval var.
-    """
-    return _pywrapcp.IntervalVar_StartMin(self)
-
-
-
-def StartsAfter(self, date: int64_t) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def StartsAfter(self, date: "int64_t") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_StartsAfter(self, date)
-
-
-
-def StartsAfterEnd(self, other: IntervalVar) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def StartsAfterEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_StartsAfterEnd(self, other)
-
-
-
-def StartsAfterEndWithDelay(self, other: IntervalVar, delay: int64_t) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def StartsAfterEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_StartsAfterEndWithDelay(self, other, delay)
-
-
-
-def StartsAfterStart(self, other: IntervalVar) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def StartsAfterStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_StartsAfterStart(self, other)
-
-
-
-def StartsAfterStartWithDelay(self, other: IntervalVar, delay: int64_t) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def StartsAfterStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_StartsAfterStartWithDelay(self, other, delay)
-
-
-
-def StartsAt(self, date: int64_t) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def StartsAt(self, date: "int64_t") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_StartsAt(self, date)
-
-
-
-def StartsAtEnd(self, other: IntervalVar) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def StartsAtEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_StartsAtEnd(self, other)
-
-
-
-def StartsAtEndWithDelay(self, other: IntervalVar, delay: int64_t) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def StartsAtEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_StartsAtEndWithDelay(self, other, delay)
-
-
-
-def StartsAtStart(self, other: IntervalVar) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def StartsAtStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_StartsAtStart(self, other)
-
-
-
-def StartsAtStartWithDelay(self, other: IntervalVar, delay: int64_t) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def StartsAtStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_StartsAtStartWithDelay(self, other, delay)
-
-
-
-def StartsBefore(self, date: int64_t) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def StartsBefore(self, date: "int64_t") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_StartsBefore(self, date)
-
-
-
-def StaysInSync(self, other: IntervalVar) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def StaysInSync(self, other: "IntervalVar") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_StaysInSync(self, other)
-
-
-
-def StaysInSyncWithDelay(self, other: IntervalVar, delay: int64_t) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def StaysInSyncWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
-    return _pywrapcp.IntervalVar_StaysInSyncWithDelay(self, other, delay)
-
-
-
-def WasPerformedBound(self) ‑> bool -
-
-
-
- -Expand source code - -
def WasPerformedBound(self) -> "bool":
-    return _pywrapcp.IntervalVar_WasPerformedBound(self)
-
-
-
-def WhenAnything(self, *args) ‑> void -
-
-

Overload 1: -Attaches a demon awakened when anything about this interval changes.

-

|

-

Overload 2: -Attaches a closure awakened when anything about this interval changes.

-
- -Expand source code - -
def WhenAnything(self, *args) -> "void":
-    r"""
-    *Overload 1:*
-    Attaches a demon awakened when anything about this interval changes.
-
-    |
-
-    *Overload 2:*
-    Attaches a closure awakened when anything about this interval changes.
-    """
-    return _pywrapcp.IntervalVar_WhenAnything(self, *args)
-
-
-
-def WhenDurationBound(self, *args) ‑> void -
-
-
-
- -Expand source code - -
def WhenDurationBound(self, *args) -> "void":
-    return _pywrapcp.IntervalVar_WhenDurationBound(self, *args)
-
-
-
-def WhenDurationRange(self, *args) ‑> void -
-
-
-
- -Expand source code - -
def WhenDurationRange(self, *args) -> "void":
-    return _pywrapcp.IntervalVar_WhenDurationRange(self, *args)
-
-
-
-def WhenEndBound(self, *args) ‑> void -
-
-
-
- -Expand source code - -
def WhenEndBound(self, *args) -> "void":
-    return _pywrapcp.IntervalVar_WhenEndBound(self, *args)
-
-
-
-def WhenEndRange(self, *args) ‑> void -
-
-
-
- -Expand source code - -
def WhenEndRange(self, *args) -> "void":
-    return _pywrapcp.IntervalVar_WhenEndRange(self, *args)
-
-
-
-def WhenPerformedBound(self, *args) ‑> void -
-
-
-
- -Expand source code - -
def WhenPerformedBound(self, *args) -> "void":
-    return _pywrapcp.IntervalVar_WhenPerformedBound(self, *args)
-
-
-
-def WhenStartBound(self, *args) ‑> void -
-
-
-
- -Expand source code - -
def WhenStartBound(self, *args) -> "void":
-    return _pywrapcp.IntervalVar_WhenStartBound(self, *args)
-
-
-
-def WhenStartRange(self, *args) ‑> void -
-
-
-
- -Expand source code - -
def WhenStartRange(self, *args) -> "void":
-    return _pywrapcp.IntervalVar_WhenStartRange(self, *args)
-
-
-
-

Inherited members

- -
-
-class IntervalVarContainer -(*args, **kwargs) -
-
-
-
- -Expand source code - -
class IntervalVarContainer(object):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined")
-    __repr__ = _swig_repr
-
-    def Contains(self, var: "IntervalVar") -> "bool":
-        return _pywrapcp.IntervalVarContainer_Contains(self, var)
-
-    def Element(self, index: "int") -> "operations_research::IntervalVarElement *":
-        return _pywrapcp.IntervalVarContainer_Element(self, index)
-
-    def Size(self) -> "int":
-        return _pywrapcp.IntervalVarContainer_Size(self)
-
-    def Store(self) -> "void":
-        return _pywrapcp.IntervalVarContainer_Store(self)
-
-    def Restore(self) -> "void":
-        return _pywrapcp.IntervalVarContainer_Restore(self)
-
-    def __eq__(self, container: "IntervalVarContainer") -> "bool":
-        r"""
-        Returns true if this and 'container' both represent the same V* -> E map.
-        Runs in linear time; requires that the == operator on the type E is well
-        defined.
-        """
-        return _pywrapcp.IntervalVarContainer___eq__(self, container)
-
-    def __ne__(self, container: "IntervalVarContainer") -> "bool":
-        return _pywrapcp.IntervalVarContainer___ne__(self, container)
-    __swig_destroy__ = _pywrapcp.delete_IntervalVarContainer
-
-

Instance variables

-
-
var thisown
-
-

The membership flag

-
- -Expand source code - -
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-
-
-

Methods

-
-
-def Contains(self, var: IntervalVar) ‑> bool -
-
-
-
- -Expand source code - -
def Contains(self, var: "IntervalVar") -> "bool":
-    return _pywrapcp.IntervalVarContainer_Contains(self, var)
-
-
-
-def Element(self, index: int) ‑> operations_research::IntervalVarElement * -
-
-
-
- -Expand source code - -
def Element(self, index: "int") -> "operations_research::IntervalVarElement *":
-    return _pywrapcp.IntervalVarContainer_Element(self, index)
-
-
-
-def Restore(self) ‑> void -
-
-
-
- -Expand source code - -
def Restore(self) -> "void":
-    return _pywrapcp.IntervalVarContainer_Restore(self)
-
-
-
-def Size(self) ‑> int -
-
-
-
- -Expand source code - -
def Size(self) -> "int":
-    return _pywrapcp.IntervalVarContainer_Size(self)
-
-
-
-def Store(self) ‑> void -
-
-
-
- -Expand source code - -
def Store(self) -> "void":
-    return _pywrapcp.IntervalVarContainer_Store(self)
-
-
-
-
-
-class IntervalVarElement -(*args, **kwargs) -
-
-
-
- -Expand source code - -
class IntervalVarElement(AssignmentElement):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined")
-    __repr__ = _swig_repr
-
-    def Var(self) -> "operations_research::IntervalVar *":
-        return _pywrapcp.IntervalVarElement_Var(self)
-
-    def StartMin(self) -> "int64_t":
-        return _pywrapcp.IntervalVarElement_StartMin(self)
-
-    def StartMax(self) -> "int64_t":
-        return _pywrapcp.IntervalVarElement_StartMax(self)
-
-    def StartValue(self) -> "int64_t":
-        return _pywrapcp.IntervalVarElement_StartValue(self)
-
-    def DurationMin(self) -> "int64_t":
-        return _pywrapcp.IntervalVarElement_DurationMin(self)
-
-    def DurationMax(self) -> "int64_t":
-        return _pywrapcp.IntervalVarElement_DurationMax(self)
-
-    def DurationValue(self) -> "int64_t":
-        return _pywrapcp.IntervalVarElement_DurationValue(self)
-
-    def EndMin(self) -> "int64_t":
-        return _pywrapcp.IntervalVarElement_EndMin(self)
-
-    def EndMax(self) -> "int64_t":
-        return _pywrapcp.IntervalVarElement_EndMax(self)
-
-    def EndValue(self) -> "int64_t":
-        return _pywrapcp.IntervalVarElement_EndValue(self)
-
-    def PerformedMin(self) -> "int64_t":
-        return _pywrapcp.IntervalVarElement_PerformedMin(self)
-
-    def PerformedMax(self) -> "int64_t":
-        return _pywrapcp.IntervalVarElement_PerformedMax(self)
-
-    def PerformedValue(self) -> "int64_t":
-        return _pywrapcp.IntervalVarElement_PerformedValue(self)
-
-    def SetStartMin(self, m: "int64_t") -> "void":
-        return _pywrapcp.IntervalVarElement_SetStartMin(self, m)
-
-    def SetStartMax(self, m: "int64_t") -> "void":
-        return _pywrapcp.IntervalVarElement_SetStartMax(self, m)
-
-    def SetStartRange(self, mi: "int64_t", ma: "int64_t") -> "void":
-        return _pywrapcp.IntervalVarElement_SetStartRange(self, mi, ma)
-
-    def SetStartValue(self, v: "int64_t") -> "void":
-        return _pywrapcp.IntervalVarElement_SetStartValue(self, v)
-
-    def SetDurationMin(self, m: "int64_t") -> "void":
-        return _pywrapcp.IntervalVarElement_SetDurationMin(self, m)
-
-    def SetDurationMax(self, m: "int64_t") -> "void":
-        return _pywrapcp.IntervalVarElement_SetDurationMax(self, m)
-
-    def SetDurationRange(self, mi: "int64_t", ma: "int64_t") -> "void":
-        return _pywrapcp.IntervalVarElement_SetDurationRange(self, mi, ma)
-
-    def SetDurationValue(self, v: "int64_t") -> "void":
-        return _pywrapcp.IntervalVarElement_SetDurationValue(self, v)
-
-    def SetEndMin(self, m: "int64_t") -> "void":
-        return _pywrapcp.IntervalVarElement_SetEndMin(self, m)
-
-    def SetEndMax(self, m: "int64_t") -> "void":
-        return _pywrapcp.IntervalVarElement_SetEndMax(self, m)
-
-    def SetEndRange(self, mi: "int64_t", ma: "int64_t") -> "void":
-        return _pywrapcp.IntervalVarElement_SetEndRange(self, mi, ma)
-
-    def SetEndValue(self, v: "int64_t") -> "void":
-        return _pywrapcp.IntervalVarElement_SetEndValue(self, v)
-
-    def SetPerformedMin(self, m: "int64_t") -> "void":
-        return _pywrapcp.IntervalVarElement_SetPerformedMin(self, m)
-
-    def SetPerformedMax(self, m: "int64_t") -> "void":
-        return _pywrapcp.IntervalVarElement_SetPerformedMax(self, m)
-
-    def SetPerformedRange(self, mi: "int64_t", ma: "int64_t") -> "void":
-        return _pywrapcp.IntervalVarElement_SetPerformedRange(self, mi, ma)
-
-    def SetPerformedValue(self, v: "int64_t") -> "void":
-        return _pywrapcp.IntervalVarElement_SetPerformedValue(self, v)
-
-    def __eq__(self, element: "IntervalVarElement") -> "bool":
-        return _pywrapcp.IntervalVarElement___eq__(self, element)
-
-    def __ne__(self, element: "IntervalVarElement") -> "bool":
-        return _pywrapcp.IntervalVarElement___ne__(self, element)
-    __swig_destroy__ = _pywrapcp.delete_IntervalVarElement
-
-

Ancestors

- -

Methods

-
-
-def DurationMax(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def DurationMax(self) -> "int64_t":
-    return _pywrapcp.IntervalVarElement_DurationMax(self)
-
-
-
-def DurationMin(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def DurationMin(self) -> "int64_t":
-    return _pywrapcp.IntervalVarElement_DurationMin(self)
-
-
-
-def DurationValue(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def DurationValue(self) -> "int64_t":
-    return _pywrapcp.IntervalVarElement_DurationValue(self)
-
-
-
-def EndMax(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def EndMax(self) -> "int64_t":
-    return _pywrapcp.IntervalVarElement_EndMax(self)
-
-
-
-def EndMin(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def EndMin(self) -> "int64_t":
-    return _pywrapcp.IntervalVarElement_EndMin(self)
-
-
-
-def EndValue(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def EndValue(self) -> "int64_t":
-    return _pywrapcp.IntervalVarElement_EndValue(self)
-
-
-
-def PerformedMax(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def PerformedMax(self) -> "int64_t":
-    return _pywrapcp.IntervalVarElement_PerformedMax(self)
-
-
-
-def PerformedMin(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def PerformedMin(self) -> "int64_t":
-    return _pywrapcp.IntervalVarElement_PerformedMin(self)
-
-
-
-def PerformedValue(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def PerformedValue(self) -> "int64_t":
-    return _pywrapcp.IntervalVarElement_PerformedValue(self)
-
-
-
-def SetDurationMax(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetDurationMax(self, m: "int64_t") -> "void":
-    return _pywrapcp.IntervalVarElement_SetDurationMax(self, m)
-
-
-
-def SetDurationMin(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetDurationMin(self, m: "int64_t") -> "void":
-    return _pywrapcp.IntervalVarElement_SetDurationMin(self, m)
-
-
-
-def SetDurationRange(self, mi: int64_t, ma: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetDurationRange(self, mi: "int64_t", ma: "int64_t") -> "void":
-    return _pywrapcp.IntervalVarElement_SetDurationRange(self, mi, ma)
-
-
-
-def SetDurationValue(self, v: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetDurationValue(self, v: "int64_t") -> "void":
-    return _pywrapcp.IntervalVarElement_SetDurationValue(self, v)
-
-
-
-def SetEndMax(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetEndMax(self, m: "int64_t") -> "void":
-    return _pywrapcp.IntervalVarElement_SetEndMax(self, m)
-
-
-
-def SetEndMin(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetEndMin(self, m: "int64_t") -> "void":
-    return _pywrapcp.IntervalVarElement_SetEndMin(self, m)
-
-
-
-def SetEndRange(self, mi: int64_t, ma: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetEndRange(self, mi: "int64_t", ma: "int64_t") -> "void":
-    return _pywrapcp.IntervalVarElement_SetEndRange(self, mi, ma)
-
-
-
-def SetEndValue(self, v: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetEndValue(self, v: "int64_t") -> "void":
-    return _pywrapcp.IntervalVarElement_SetEndValue(self, v)
-
-
-
-def SetPerformedMax(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetPerformedMax(self, m: "int64_t") -> "void":
-    return _pywrapcp.IntervalVarElement_SetPerformedMax(self, m)
-
-
-
-def SetPerformedMin(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetPerformedMin(self, m: "int64_t") -> "void":
-    return _pywrapcp.IntervalVarElement_SetPerformedMin(self, m)
-
-
-
-def SetPerformedRange(self, mi: int64_t, ma: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetPerformedRange(self, mi: "int64_t", ma: "int64_t") -> "void":
-    return _pywrapcp.IntervalVarElement_SetPerformedRange(self, mi, ma)
-
-
-
-def SetPerformedValue(self, v: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetPerformedValue(self, v: "int64_t") -> "void":
-    return _pywrapcp.IntervalVarElement_SetPerformedValue(self, v)
-
-
-
-def SetStartMax(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetStartMax(self, m: "int64_t") -> "void":
-    return _pywrapcp.IntervalVarElement_SetStartMax(self, m)
-
-
-
-def SetStartMin(self, m: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetStartMin(self, m: "int64_t") -> "void":
-    return _pywrapcp.IntervalVarElement_SetStartMin(self, m)
-
-
-
-def SetStartRange(self, mi: int64_t, ma: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetStartRange(self, mi: "int64_t", ma: "int64_t") -> "void":
-    return _pywrapcp.IntervalVarElement_SetStartRange(self, mi, ma)
-
-
-
-def SetStartValue(self, v: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetStartValue(self, v: "int64_t") -> "void":
-    return _pywrapcp.IntervalVarElement_SetStartValue(self, v)
-
-
-
-def StartMax(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def StartMax(self) -> "int64_t":
-    return _pywrapcp.IntervalVarElement_StartMax(self)
-
-
-
-def StartMin(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def StartMin(self) -> "int64_t":
-    return _pywrapcp.IntervalVarElement_StartMin(self)
-
-
-
-def StartValue(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def StartValue(self) -> "int64_t":
-    return _pywrapcp.IntervalVarElement_StartValue(self)
-
-
-
-def Var(self) ‑> operations_research::IntervalVar * -
-
-
-
- -Expand source code - -
def Var(self) -> "operations_research::IntervalVar *":
-    return _pywrapcp.IntervalVarElement_Var(self)
-
-
-
-

Inherited members

- -
-
-class LocalSearchFilter -(*args, **kwargs) -
-
-

Classes to which this template function can be applied to as of 04/2014. -Usage: LocalSearchOperator op = MakeLocalSearchOperator(…); -class TwoOpt; -class Relocate; -class Exchange; -class Cross; -class MakeActiveOperator; -class MakeInactiveOperator; -class MakeChainInactiveOperator; -class SwapActiveOperator; -class ExtendedSwapActiveOperator; -class MakeActiveAndRelocate; -class RelocateAndMakeActiveOperator; -class RelocateAndMakeInactiveOperator; -Local Search Filters are used for fast neighbor pruning. -Filtering a move is done in several phases: -- in the Relax phase, filters determine which parts of their internals -will be changed by the candidate, and modify intermediary State -- in the Accept phase, filters check that the candidate is feasible, -- if the Accept phase succeeds, the solver may decide to trigger a -Synchronize phase that makes filters change their internal representation -to the last candidate, -- otherwise (Accept fails or the solver does not want to synchronize), -a Revert phase makes filters erase any intermediary State generated by the -Relax and Accept phases. -A given filter has phases called with the following pattern: -(Relax.Accept.Synchronize | Relax.Accept.Revert | Relax.Revert). -Filters's Revert() is always called in the reverse order their Accept() was -called, to allow late filters to use state done/undone by early filters' -Accept()/Revert().

-
- -Expand source code - -
class LocalSearchFilter(BaseObject):
-    r"""
-    Classes to which this template function can be applied to as of 04/2014.
-    Usage: LocalSearchOperator* op = MakeLocalSearchOperator<Relocate>(...);
-    class TwoOpt;
-    class Relocate;
-    class Exchange;
-    class Cross;
-    class MakeActiveOperator;
-    class MakeInactiveOperator;
-    class MakeChainInactiveOperator;
-    class SwapActiveOperator;
-    class ExtendedSwapActiveOperator;
-    class MakeActiveAndRelocate;
-    class RelocateAndMakeActiveOperator;
-    class RelocateAndMakeInactiveOperator;
-    Local Search Filters are used for fast neighbor pruning.
-    Filtering a move is done in several phases:
-    - in the Relax phase, filters determine which parts of their internals
-      will be changed by the candidate, and modify intermediary State
-    - in the Accept phase, filters check that the candidate is feasible,
-    - if the Accept phase succeeds, the solver may decide to trigger a
-      Synchronize phase that makes filters change their internal representation
-      to the last candidate,
-    - otherwise (Accept fails or the solver does not want to synchronize),
-      a Revert phase makes filters erase any intermediary State generated by the
-      Relax and Accept phases.
-    A given filter has phases called with the following pattern:
-    (Relax.Accept.Synchronize | Relax.Accept.Revert | Relax.Revert)*.
-    Filters's Revert() is always called in the reverse order their Accept() was
-    called, to allow late filters to use state done/undone by early filters'
-    Accept()/Revert().
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
-    __repr__ = _swig_repr
-
-    def Accept(self, delta: "Assignment", deltadelta: "Assignment", objective_min: "int64_t", objective_max: "int64_t") -> "bool":
-        r"""
-        Accepts a "delta" given the assignment with which the filter has been
-        synchronized; the delta holds the variables which have been modified and
-        their new value.
-        If the filter represents a part of the global objective, its contribution
-        must be between objective_min and objective_max.
-        Sample: supposing one wants to maintain a[0,1] + b[0,1] <= 1,
-        for the assignment (a,1), (b,0), the delta (b,1) will be rejected
-        but the delta (a,0) will be accepted.
-        TODO(user): Remove arguments when there are no more need for those.
-        """
-        return _pywrapcp.LocalSearchFilter_Accept(self, delta, deltadelta, objective_min, objective_max)
-
-    def IsIncremental(self) -> "bool":
-        return _pywrapcp.LocalSearchFilter_IsIncremental(self)
-
-    def Synchronize(self, assignment: "Assignment", delta: "Assignment") -> "void":
-        r"""
-        Synchronizes the filter with the current solution, delta being the
-        difference with the solution passed to the previous call to Synchronize()
-        or IncrementalSynchronize(). 'delta' can be used to incrementally
-        synchronizing the filter with the new solution by only considering the
-        changes in delta.
-        """
-        return _pywrapcp.LocalSearchFilter_Synchronize(self, assignment, delta)
-    __swig_destroy__ = _pywrapcp.delete_LocalSearchFilter
-
-

Ancestors

- -

Subclasses

- -

Methods

-
-
-def Accept(self, delta: Assignment, deltadelta: Assignment, objective_min: int64_t, objective_max: int64_t) ‑> bool -
-
-

Accepts a "delta" given the assignment with which the filter has been -synchronized; the delta holds the variables which have been modified and -their new value. -If the filter represents a part of the global objective, its contribution -must be between objective_min and objective_max. -Sample: supposing one wants to maintain a[0,1] + b[0,1] <= 1, -for the assignment (a,1), (b,0), the delta (b,1) will be rejected -but the delta (a,0) will be accepted. -TODO(user): Remove arguments when there are no more need for those.

-
- -Expand source code - -
def Accept(self, delta: "Assignment", deltadelta: "Assignment", objective_min: "int64_t", objective_max: "int64_t") -> "bool":
-    r"""
-    Accepts a "delta" given the assignment with which the filter has been
-    synchronized; the delta holds the variables which have been modified and
-    their new value.
-    If the filter represents a part of the global objective, its contribution
-    must be between objective_min and objective_max.
-    Sample: supposing one wants to maintain a[0,1] + b[0,1] <= 1,
-    for the assignment (a,1), (b,0), the delta (b,1) will be rejected
-    but the delta (a,0) will be accepted.
-    TODO(user): Remove arguments when there are no more need for those.
-    """
-    return _pywrapcp.LocalSearchFilter_Accept(self, delta, deltadelta, objective_min, objective_max)
-
-
-
-def IsIncremental(self) ‑> bool -
-
-
-
- -Expand source code - -
def IsIncremental(self) -> "bool":
-    return _pywrapcp.LocalSearchFilter_IsIncremental(self)
-
-
-
-def Synchronize(self, assignment: Assignment, delta: Assignment) ‑> void -
-
-

Synchronizes the filter with the current solution, delta being the -difference with the solution passed to the previous call to Synchronize() -or IncrementalSynchronize(). 'delta' can be used to incrementally -synchronizing the filter with the new solution by only considering the -changes in delta.

-
- -Expand source code - -
def Synchronize(self, assignment: "Assignment", delta: "Assignment") -> "void":
-    r"""
-    Synchronizes the filter with the current solution, delta being the
-    difference with the solution passed to the previous call to Synchronize()
-    or IncrementalSynchronize(). 'delta' can be used to incrementally
-    synchronizing the filter with the new solution by only considering the
-    changes in delta.
-    """
-    return _pywrapcp.LocalSearchFilter_Synchronize(self, assignment, delta)
-
-
-
-

Inherited members

- -
-
-class LocalSearchFilterManager -(*args) -
-
-

Filter manager: when a move is made, filters are executed to decide whether -the solution is feasible and compute parts of the new cost. This class -schedules filter execution and composes costs as a sum.

-
- -Expand source code - -
class LocalSearchFilterManager(BaseObject):
-    r"""
-    Filter manager: when a move is made, filters are executed to decide whether
-    the solution is feasible and compute parts of the new cost. This class
-    schedules filter execution and composes costs as a sum.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.LocalSearchFilterManager_DebugString(self)
-
-    def __init__(self, *args):
-        _pywrapcp.LocalSearchFilterManager_swiginit(self, _pywrapcp.new_LocalSearchFilterManager(*args))
-
-    def Accept(self, monitor: "operations_research::LocalSearchMonitor *const", delta: "Assignment", deltadelta: "Assignment", objective_min: "int64_t", objective_max: "int64_t") -> "bool":
-        r"""
-        Returns true iff all filters return true, and the sum of their accepted
-        objectives is between objective_min and objective_max.
-        The monitor has its Begin/EndFiltering events triggered.
-        """
-        return _pywrapcp.LocalSearchFilterManager_Accept(self, monitor, delta, deltadelta, objective_min, objective_max)
-
-    def Synchronize(self, assignment: "Assignment", delta: "Assignment") -> "void":
-        r""" Synchronizes all filters to assignment."""
-        return _pywrapcp.LocalSearchFilterManager_Synchronize(self, assignment, delta)
-    __swig_destroy__ = _pywrapcp.delete_LocalSearchFilterManager
-
-

Ancestors

- -

Methods

-
-
-def Accept(self, monitor: operations_research::LocalSearchMonitor *const, delta: Assignment, deltadelta: Assignment, objective_min: int64_t, objective_max: int64_t) ‑> bool -
-
-

Returns true iff all filters return true, and the sum of their accepted -objectives is between objective_min and objective_max. -The monitor has its Begin/EndFiltering events triggered.

-
- -Expand source code - -
def Accept(self, monitor: "operations_research::LocalSearchMonitor *const", delta: "Assignment", deltadelta: "Assignment", objective_min: "int64_t", objective_max: "int64_t") -> "bool":
-    r"""
-    Returns true iff all filters return true, and the sum of their accepted
-    objectives is between objective_min and objective_max.
-    The monitor has its Begin/EndFiltering events triggered.
-    """
-    return _pywrapcp.LocalSearchFilterManager_Accept(self, monitor, delta, deltadelta, objective_min, objective_max)
-
-
-
-def DebugString(self) ‑> std::string -
-
-
-
- -Expand source code - -
def DebugString(self) -> "std::string":
-    return _pywrapcp.LocalSearchFilterManager_DebugString(self)
-
-
-
-def Synchronize(self, assignment: Assignment, delta: Assignment) ‑> void -
-
-

Synchronizes all filters to assignment.

-
- -Expand source code - -
def Synchronize(self, assignment: "Assignment", delta: "Assignment") -> "void":
-    r""" Synchronizes all filters to assignment."""
-    return _pywrapcp.LocalSearchFilterManager_Synchronize(self, assignment, delta)
-
-
-
-

Inherited members

- -
-
-class LocalSearchOperator -(*args, **kwargs) -
-
-

This class represent a reversible FIFO structure. -The main difference w.r.t a standard FIFO structure is that a Solver is -given as parameter to the modifiers such that the solver can store the -backtrack information -Iterator's traversing order should not be changed, as some algorithm -depend on it to be consistent. -It's main use is to store a list of demons in the various classes of -variables. -The base class for all local search operators.

-

A local search operator is an object that defines the neighborhood of a -solution. In other words, a neighborhood is the set of solutions which can -be reached from a given solution using an operator.

-

The behavior of the LocalSearchOperator class is similar to iterators. -The operator is synchronized with an assignment (gives the -current values of the variables); this is done in the Start() method.

-

Then one can iterate over the neighbors using the MakeNextNeighbor method. -This method returns an assignment which represents the incremental changes -to the current solution. It also returns a second assignment representing -the changes to the last solution defined by the neighborhood operator; this -assignment is empty if the neighborhood operator cannot track this -information.

-
- -Expand source code - -
class LocalSearchOperator(BaseObject):
-    r"""
-    This class represent a reversible FIFO structure.
-    The main difference w.r.t a standard FIFO structure is that a Solver is
-    given as parameter to the modifiers such that the solver can store the
-    backtrack information
-    Iterator's traversing order should not be changed, as some algorithm
-    depend on it to be consistent.
-    It's main use is to store a list of demons in the various classes of
-    variables.
-    The base class for all local search operators.
-
-    A local search operator is an object that defines the neighborhood of a
-    solution. In other words, a neighborhood is the set of solutions which can
-    be reached from a given solution using an operator.
-
-    The behavior of the LocalSearchOperator class is similar to iterators.
-    The operator is synchronized with an assignment (gives the
-    current values of the variables); this is done in the Start() method.
-
-    Then one can iterate over the neighbors using the MakeNextNeighbor method.
-    This method returns an assignment which represents the incremental changes
-    to the current solution. It also returns a second assignment representing
-    the changes to the last solution defined by the neighborhood operator; this
-    assignment is empty if the neighborhood operator cannot track this
-    information.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
-    __repr__ = _swig_repr
-
-    def NextNeighbor(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
-        return _pywrapcp.LocalSearchOperator_NextNeighbor(self, delta, deltadelta)
-
-    def Start(self, assignment: "Assignment") -> "void":
-        return _pywrapcp.LocalSearchOperator_Start(self, assignment)
-    def __disown__(self):
-        self.this.disown()
-        _pywrapcp.disown_LocalSearchOperator(self)
-        return weakref.proxy(self)
-
-

Ancestors

- -

Subclasses

- -

Methods

-
-
-def NextNeighbor(self, delta: Assignment, deltadelta: Assignment) ‑> bool -
-
-
-
- -Expand source code - -
def NextNeighbor(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
-    return _pywrapcp.LocalSearchOperator_NextNeighbor(self, delta, deltadelta)
-
-
-
-def Start(self, assignment: Assignment) ‑> void -
-
-
-
- -Expand source code - -
def Start(self, assignment: "Assignment") -> "void":
-    return _pywrapcp.LocalSearchOperator_Start(self, assignment)
-
-
-
-

Inherited members

- -
-
-class NumericalRevInteger -(val: long const &) -
-
-

Subclass of Rev which adds numerical operations.

-
- -Expand source code - -
class NumericalRevInteger(RevInteger):
-    r""" Subclass of Rev<T> which adds numerical operations."""
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self, val: "long const &"):
-        _pywrapcp.NumericalRevInteger_swiginit(self, _pywrapcp.new_NumericalRevInteger(val))
-
-    def Add(self, s: "Solver", to_add: "long const &") -> "void":
-        return _pywrapcp.NumericalRevInteger_Add(self, s, to_add)
-
-    def Incr(self, s: "Solver") -> "void":
-        return _pywrapcp.NumericalRevInteger_Incr(self, s)
-
-    def Decr(self, s: "Solver") -> "void":
-        return _pywrapcp.NumericalRevInteger_Decr(self, s)
-    __swig_destroy__ = _pywrapcp.delete_NumericalRevInteger
-
-

Ancestors

- -

Methods

-
-
-def Add(self, s: Solver, to_add: long const &) ‑> void -
-
-
-
- -Expand source code - -
def Add(self, s: "Solver", to_add: "long const &") -> "void":
-    return _pywrapcp.NumericalRevInteger_Add(self, s, to_add)
-
-
-
-def Decr(self, s: Solver) ‑> void -
-
-
-
- -Expand source code - -
def Decr(self, s: "Solver") -> "void":
-    return _pywrapcp.NumericalRevInteger_Decr(self, s)
-
-
-
-def Incr(self, s: Solver) ‑> void -
-
-
-
- -Expand source code - -
def Incr(self, s: "Solver") -> "void":
-    return _pywrapcp.NumericalRevInteger_Incr(self, s)
-
-
-
-

Inherited members

- -
-
-class OptimizeVar -(*args, **kwargs) -
-
-

This class encapsulates an objective. It requires the direction -(minimize or maximize), the variable to optimize, and the -improvement step.

-
- -Expand source code - -
class OptimizeVar(SearchMonitor):
-    r"""
-    This class encapsulates an objective. It requires the direction
-    (minimize or maximize), the variable to optimize, and the
-    improvement step.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined")
-    __repr__ = _swig_repr
-
-    def Best(self) -> "int64_t":
-        r""" Returns the best value found during search."""
-        return _pywrapcp.OptimizeVar_Best(self)
-
-    def Var(self) -> "operations_research::IntVar *":
-        r""" Returns the variable that is optimized."""
-        return _pywrapcp.OptimizeVar_Var(self)
-
-    def AcceptDelta(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
-        r""" Internal methods."""
-        return _pywrapcp.OptimizeVar_AcceptDelta(self, delta, deltadelta)
-
-    def EnterSearch(self) -> "void":
-        return _pywrapcp.OptimizeVar_EnterSearch(self)
-
-    def BeginNextDecision(self, db: "DecisionBuilder") -> "void":
-        return _pywrapcp.OptimizeVar_BeginNextDecision(self, db)
-
-    def RefuteDecision(self, d: "Decision") -> "void":
-        return _pywrapcp.OptimizeVar_RefuteDecision(self, d)
-
-    def AtSolution(self) -> "bool":
-        return _pywrapcp.OptimizeVar_AtSolution(self)
-
-    def AcceptSolution(self) -> "bool":
-        return _pywrapcp.OptimizeVar_AcceptSolution(self)
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.OptimizeVar_DebugString(self)
-
-

Ancestors

- -

Methods

-
-
-def AcceptDelta(self, delta: Assignment, deltadelta: Assignment) ‑> bool -
-
-

Internal methods.

-
- -Expand source code - -
def AcceptDelta(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
-    r""" Internal methods."""
-    return _pywrapcp.OptimizeVar_AcceptDelta(self, delta, deltadelta)
-
-
-
-def Best(self) ‑> int64_t -
-
-

Returns the best value found during search.

-
- -Expand source code - -
def Best(self) -> "int64_t":
-    r""" Returns the best value found during search."""
-    return _pywrapcp.OptimizeVar_Best(self)
-
-
-
-def DebugString(self) ‑> std::string -
-
-
-
- -Expand source code - -
def DebugString(self) -> "std::string":
-    return _pywrapcp.OptimizeVar_DebugString(self)
-
-
-
-def Var(self) ‑> operations_research::IntVar * -
-
-

Returns the variable that is optimized.

-
- -Expand source code - -
def Var(self) -> "operations_research::IntVar *":
-    r""" Returns the variable that is optimized."""
-    return _pywrapcp.OptimizeVar_Var(self)
-
-
-
-

Inherited members

- -
-
-class Pack -(*args, **kwargs) -
-
-

A constraint is the main modeling object. It provides two methods: -- Post() is responsible for creating the demons and attaching them to -immediate demons(). -- InitialPropagate() is called once just after Post and performs -the initial propagation. The subsequent propagations will be performed -by the demons Posted during the post() method.

-
- -Expand source code - -
class Pack(Constraint):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined")
-    __repr__ = _swig_repr
-
-    def AddWeightedSumLessOrEqualConstantDimension(self, *args) -> "void":
-        r"""
-        *Overload 1:*
-        Dimensions are additional constraints than can restrict what is
-        possible with the pack constraint. It can be used to set capacity
-        limits, to count objects per bin, to compute unassigned
-        penalties...
-        This dimension imposes that for all bins b, the weighted sum
-        (weights[i]) of all objects i assigned to 'b' is less or equal
-        'bounds[b]'.
-
-        |
-
-        *Overload 2:*
-        This dimension imposes that for all bins b, the weighted sum
-        (weights->Run(i)) of all objects i assigned to 'b' is less or
-        equal to 'bounds[b]'. Ownership of the callback is transferred to
-        the pack constraint.
-
-        |
-
-        *Overload 3:*
-        This dimension imposes that for all bins b, the weighted sum
-        (weights->Run(i, b) of all objects i assigned to 'b' is less or
-        equal to 'bounds[b]'. Ownership of the callback is transferred to
-        the pack constraint.
-        """
-        return _pywrapcp.Pack_AddWeightedSumLessOrEqualConstantDimension(self, *args)
-
-    def AddWeightedSumEqualVarDimension(self, *args) -> "void":
-        r"""
-        *Overload 1:*
-        This dimension imposes that for all bins b, the weighted sum
-        (weights[i]) of all objects i assigned to 'b' is equal to loads[b].
-
-        |
-
-        *Overload 2:*
-        This dimension imposes that for all bins b, the weighted sum
-        (weights->Run(i, b)) of all objects i assigned to 'b' is equal to
-        loads[b].
-        """
-        return _pywrapcp.Pack_AddWeightedSumEqualVarDimension(self, *args)
-
-    def AddSumVariableWeightsLessOrEqualConstantDimension(self, usage: "std::vector< operations_research::IntVar * > const &", capacity: "std::vector< int64_t > const &") -> "void":
-        r"""
-        This dimension imposes:
-        forall b in bins,
-           sum (i in items: usage[i] * is_assigned(i, b)) <= capacity[b]
-        where is_assigned(i, b) is true if and only if item i is assigned
-        to the bin b.
-
-        This can be used to model shapes of items by linking variables of
-        the same item on parallel dimensions with an allowed assignment
-        constraint.
-        """
-        return _pywrapcp.Pack_AddSumVariableWeightsLessOrEqualConstantDimension(self, usage, capacity)
-
-    def AddWeightedSumOfAssignedDimension(self, weights: "std::vector< int64_t > const &", cost_var: "IntVar") -> "void":
-        r"""
-        This dimension enforces that cost_var == sum of weights[i] for
-        all objects 'i' assigned to a bin.
-        """
-        return _pywrapcp.Pack_AddWeightedSumOfAssignedDimension(self, weights, cost_var)
-
-    def AddCountUsedBinDimension(self, count_var: "IntVar") -> "void":
-        r"""
-        This dimension links 'count_var' to the actual number of bins used in the
-        pack.
-        """
-        return _pywrapcp.Pack_AddCountUsedBinDimension(self, count_var)
-
-    def AddCountAssignedItemsDimension(self, count_var: "IntVar") -> "void":
-        r"""
-        This dimension links 'count_var' to the actual number of items
-        assigned to a bin in the pack.
-        """
-        return _pywrapcp.Pack_AddCountAssignedItemsDimension(self, count_var)
-
-    def Post(self) -> "void":
-        return _pywrapcp.Pack_Post(self)
-
-    def InitialPropagateWrapper(self) -> "void":
-        return _pywrapcp.Pack_InitialPropagateWrapper(self)
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.Pack_DebugString(self)
-
-

Ancestors

- -

Methods

-
-
-def AddCountAssignedItemsDimension(self, count_var: IntVar) ‑> void -
-
-

This dimension links 'count_var' to the actual number of items -assigned to a bin in the pack.

-
- -Expand source code - -
def AddCountAssignedItemsDimension(self, count_var: "IntVar") -> "void":
-    r"""
-    This dimension links 'count_var' to the actual number of items
-    assigned to a bin in the pack.
-    """
-    return _pywrapcp.Pack_AddCountAssignedItemsDimension(self, count_var)
-
-
-
-def AddCountUsedBinDimension(self, count_var: IntVar) ‑> void -
-
-

This dimension links 'count_var' to the actual number of bins used in the -pack.

-
- -Expand source code - -
def AddCountUsedBinDimension(self, count_var: "IntVar") -> "void":
-    r"""
-    This dimension links 'count_var' to the actual number of bins used in the
-    pack.
-    """
-    return _pywrapcp.Pack_AddCountUsedBinDimension(self, count_var)
-
-
-
-def AddSumVariableWeightsLessOrEqualConstantDimension(self, usage: std::vector< operations_research::IntVar * > const &, capacity: std::vector< int64_t > const &) ‑> void -
-
-

This dimension imposes: -forall b in bins, -sum (i in items: usage[i] * is_assigned(i, b)) <= capacity[b] -where is_assigned(i, b) is true if and only if item i is assigned -to the bin b.

-

This can be used to model shapes of items by linking variables of -the same item on parallel dimensions with an allowed assignment -constraint.

-
- -Expand source code - -
def AddSumVariableWeightsLessOrEqualConstantDimension(self, usage: "std::vector< operations_research::IntVar * > const &", capacity: "std::vector< int64_t > const &") -> "void":
-    r"""
-    This dimension imposes:
-    forall b in bins,
-       sum (i in items: usage[i] * is_assigned(i, b)) <= capacity[b]
-    where is_assigned(i, b) is true if and only if item i is assigned
-    to the bin b.
-
-    This can be used to model shapes of items by linking variables of
-    the same item on parallel dimensions with an allowed assignment
-    constraint.
-    """
-    return _pywrapcp.Pack_AddSumVariableWeightsLessOrEqualConstantDimension(self, usage, capacity)
-
-
-
-def AddWeightedSumEqualVarDimension(self, *args) ‑> void -
-
-

Overload 1: -This dimension imposes that for all bins b, the weighted sum -(weights[i]) of all objects i assigned to 'b' is equal to loads[b].

-

|

-

Overload 2: -This dimension imposes that for all bins b, the weighted sum -(weights->Run(i, b)) of all objects i assigned to 'b' is equal to -loads[b].

-
- -Expand source code - -
def AddWeightedSumEqualVarDimension(self, *args) -> "void":
-    r"""
-    *Overload 1:*
-    This dimension imposes that for all bins b, the weighted sum
-    (weights[i]) of all objects i assigned to 'b' is equal to loads[b].
-
-    |
-
-    *Overload 2:*
-    This dimension imposes that for all bins b, the weighted sum
-    (weights->Run(i, b)) of all objects i assigned to 'b' is equal to
-    loads[b].
-    """
-    return _pywrapcp.Pack_AddWeightedSumEqualVarDimension(self, *args)
-
-
-
-def AddWeightedSumLessOrEqualConstantDimension(self, *args) ‑> void -
-
-

Overload 1: -Dimensions are additional constraints than can restrict what is -possible with the pack constraint. It can be used to set capacity -limits, to count objects per bin, to compute unassigned -penalties… -This dimension imposes that for all bins b, the weighted sum -(weights[i]) of all objects i assigned to 'b' is less or equal -'bounds[b]'.

-

|

-

Overload 2: -This dimension imposes that for all bins b, the weighted sum -(weights->Run(i)) of all objects i assigned to 'b' is less or -equal to 'bounds[b]'. Ownership of the callback is transferred to -the pack constraint.

-

|

-

Overload 3: -This dimension imposes that for all bins b, the weighted sum -(weights->Run(i, b) of all objects i assigned to 'b' is less or -equal to 'bounds[b]'. Ownership of the callback is transferred to -the pack constraint.

-
- -Expand source code - -
def AddWeightedSumLessOrEqualConstantDimension(self, *args) -> "void":
-    r"""
-    *Overload 1:*
-    Dimensions are additional constraints than can restrict what is
-    possible with the pack constraint. It can be used to set capacity
-    limits, to count objects per bin, to compute unassigned
-    penalties...
-    This dimension imposes that for all bins b, the weighted sum
-    (weights[i]) of all objects i assigned to 'b' is less or equal
-    'bounds[b]'.
-
-    |
-
-    *Overload 2:*
-    This dimension imposes that for all bins b, the weighted sum
-    (weights->Run(i)) of all objects i assigned to 'b' is less or
-    equal to 'bounds[b]'. Ownership of the callback is transferred to
-    the pack constraint.
-
-    |
-
-    *Overload 3:*
-    This dimension imposes that for all bins b, the weighted sum
-    (weights->Run(i, b) of all objects i assigned to 'b' is less or
-    equal to 'bounds[b]'. Ownership of the callback is transferred to
-    the pack constraint.
-    """
-    return _pywrapcp.Pack_AddWeightedSumLessOrEqualConstantDimension(self, *args)
-
-
-
-def AddWeightedSumOfAssignedDimension(self, weights: std::vector< int64_t > const &, cost_var: IntVar) ‑> void -
-
-

This dimension enforces that cost_var == sum of weights[i] for -all objects 'i' assigned to a bin.

-
- -Expand source code - -
def AddWeightedSumOfAssignedDimension(self, weights: "std::vector< int64_t > const &", cost_var: "IntVar") -> "void":
-    r"""
-    This dimension enforces that cost_var == sum of weights[i] for
-    all objects 'i' assigned to a bin.
-    """
-    return _pywrapcp.Pack_AddWeightedSumOfAssignedDimension(self, weights, cost_var)
-
-
-
-def DebugString(self) ‑> std::string -
-
-
-
- -Expand source code - -
def DebugString(self) -> "std::string":
-    return _pywrapcp.Pack_DebugString(self)
-
-
-
-

Inherited members

- -
-
-class PathOperator -(*args, **kwargs) -
-
-

Base class of the local search operators dedicated to path modifications -(a path is a set of nodes linked together by arcs). -This family of neighborhoods supposes they are handling next variables -representing the arcs (var[i] represents the node immediately after i on -a path). -Several services are provided: -- arc manipulators (SetNext(), ReverseChain(), MoveChain()) -- path inspectors (Next(), Prev(), IsPathEnd()) -- path iterators: operators need a given number of nodes to define a -neighbor; this class provides the iteration on a given number of (base) -nodes which can be used to define a neighbor (through the BaseNode method) -Subclasses only need to override MakeNeighbor to create neighbors using -the services above (no direct manipulation of assignments).

-
- -Expand source code - -
class PathOperator(IntVarLocalSearchOperator):
-    r"""
-    Base class of the local search operators dedicated to path modifications
-    (a path is a set of nodes linked together by arcs).
-    This family of neighborhoods supposes they are handling next variables
-    representing the arcs (var[i] represents the node immediately after i on
-    a path).
-    Several services are provided:
-    - arc manipulators (SetNext(), ReverseChain(), MoveChain())
-    - path inspectors (Next(), Prev(), IsPathEnd())
-    - path iterators: operators need a given number of nodes to define a
-      neighbor; this class provides the iteration on a given number of (base)
-      nodes which can be used to define a neighbor (through the BaseNode method)
-    Subclasses only need to override MakeNeighbor to create neighbors using
-    the services above (no direct manipulation of assignments).
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
-    __repr__ = _swig_repr
-
-    def Neighbor(self) -> "bool":
-        return _pywrapcp.PathOperator_Neighbor(self)
-
-

Ancestors

- -

Methods

-
-
-def Neighbor(self) ‑> bool -
-
-
-
- -Expand source code - -
def Neighbor(self) -> "bool":
-    return _pywrapcp.PathOperator_Neighbor(self)
-
-
-
-

Inherited members

- -
-
-class PropagationBaseObject -(s: Solver) -
-
-

NOLINT -The PropagationBaseObject is a subclass of BaseObject that is also -friend to the Solver class. It allows accessing methods useful when -writing new constraints or new expressions.

-
- -Expand source code - -
class PropagationBaseObject(BaseObject):
-    r"""
-    NOLINT
-    The PropagationBaseObject is a subclass of BaseObject that is also
-    friend to the Solver class. It allows accessing methods useful when
-    writing new constraints or new expressions.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self, s: "Solver"):
-        if self.__class__ == PropagationBaseObject:
-            _self = None
-        else:
-            _self = self
-        _pywrapcp.PropagationBaseObject_swiginit(self, _pywrapcp.new_PropagationBaseObject(_self, s))
-    __swig_destroy__ = _pywrapcp.delete_PropagationBaseObject
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.PropagationBaseObject_DebugString(self)
-
-    def solver(self) -> "operations_research::Solver *":
-        return _pywrapcp.PropagationBaseObject_solver(self)
-
-    def Name(self) -> "std::string":
-        r""" Object naming."""
-        return _pywrapcp.PropagationBaseObject_Name(self)
-    def __disown__(self):
-        self.this.disown()
-        _pywrapcp.disown_PropagationBaseObject(self)
-        return weakref.proxy(self)
-
-

Ancestors

- -

Subclasses

- -

Methods

-
-
-def DebugString(self) ‑> std::string -
-
-
-
- -Expand source code - -
def DebugString(self) -> "std::string":
-    return _pywrapcp.PropagationBaseObject_DebugString(self)
-
-
-
-def Name(self) ‑> std::string -
-
-

Object naming.

-
- -Expand source code - -
def Name(self) -> "std::string":
-    r""" Object naming."""
-    return _pywrapcp.PropagationBaseObject_Name(self)
-
-
-
-def solver(self) ‑> operations_research::Solver * -
-
-
-
- -Expand source code - -
def solver(self) -> "operations_research::Solver *":
-    return _pywrapcp.PropagationBaseObject_solver(self)
-
-
-
-

Inherited members

- -
-
-class PyConstraint -(solver) -
-
-

A constraint is the main modeling object. It provides two methods: -- Post() is responsible for creating the demons and attaching them to -immediate demons(). -- InitialPropagate() is called once just after Post and performs -the initial propagation. The subsequent propagations will be performed -by the demons Posted during the post() method.

-
- -Expand source code - -
class PyConstraint(Constraint):
-
-  def __init__(self, solver):
-    Constraint.__init__(self, solver)
-    self.__demons = []
-
-  def Demon(self, method, *args):
-    demon = PyConstraintDemon(self, method, False, *args)
-    self.__demons.append(demon)
-    return demon
-
-  def DelayedDemon(self, method, *args):
-    demon = PyConstraintDemon(self, method, True, *args)
-    self.__demons.append(demon)
-    return demon
-
-  def InitialPropagateDemon(self):
-    return self.solver().ConstraintInitialPropagateCallback(self)
-
-  def DelayedInitialPropagateDemon(self):
-    return self.solver().DelayedConstraintInitialPropagateCallback(self)
-
-  def InitialPropagateWrapper(self):
-    try:
-      self.InitialPropagate()
-    except Exception as e:
-      if 'CP Solver fail' in str(e):
-        self.solver().ShouldFail()
-      else:
-        raise
-
-  def DebugString(self):
-    return "PyConstraint"
-
-

Ancestors

- -

Methods

-
-
-def DebugString(self) -
-
-
-
- -Expand source code - -
def DebugString(self):
-  return "PyConstraint"
-
-
-
-def DelayedDemon(self, method, *args) -
-
-
-
- -Expand source code - -
def DelayedDemon(self, method, *args):
-  demon = PyConstraintDemon(self, method, True, *args)
-  self.__demons.append(demon)
-  return demon
-
-
-
-def DelayedInitialPropagateDemon(self) -
-
-
-
- -Expand source code - -
def DelayedInitialPropagateDemon(self):
-  return self.solver().DelayedConstraintInitialPropagateCallback(self)
-
-
-
-def Demon(self, method, *args) -
-
-
-
- -Expand source code - -
def Demon(self, method, *args):
-  demon = PyConstraintDemon(self, method, False, *args)
-  self.__demons.append(demon)
-  return demon
-
-
-
-def InitialPropagateDemon(self) -
-
-
-
- -Expand source code - -
def InitialPropagateDemon(self):
-  return self.solver().ConstraintInitialPropagateCallback(self)
-
-
-
-

Inherited members

- -
-
-class PyConstraintDemon -(ct, method, delayed, *args) -
-
-

A Demon is the base element of a propagation queue. It is the main -object responsible for implementing the actual propagation -of the constraint and pruning the inconsistent values in the domains -of the variables. The main concept is that demons are listeners that are -attached to the variables and listen to their modifications. -There are two methods: -- Run() is the actual method called when the demon is processed. -- priority() returns its priority. Standard priorities are slow, normal -or fast. "immediate" is reserved for variables and is treated separately.

-

This indicates the priority of a demon. Immediate demons are treated -separately and corresponds to variables.

-
- -Expand source code - -
class PyConstraintDemon(PyDemon):
-
-  def __init__(self, ct, method, delayed, *args):
-    PyDemon.__init__(self)
-    self.__constraint = ct
-    self.__method = method
-    self.__delayed = delayed
-    self.__args = args
-
-  def Run(self, solver):
-    self.__method(self.__constraint, *self.__args)
-
-  def Priority(self):
-    return Solver.DELAYED_PRIORITY if self.__delayed else Solver.NORMAL_PRIORITY
-
-  def DebugString(self):
-    return 'PyConstraintDemon'
-
-

Ancestors

- -

Methods

-
-
-def DebugString(self) -
-
-
-
- -Expand source code - -
def DebugString(self):
-  return 'PyConstraintDemon'
-
-
-
-def Run(self, solver) -
-
-
-
- -Expand source code - -
def Run(self, solver):
-  self.__method(self.__constraint, *self.__args)
-
-
-
-

Inherited members

- -
-
-class PyDecision -
-
-

A Decision represents a choice point in the search tree. The two main -methods are Apply() to go left, or Refute() to go right.

-
- -Expand source code - -
class PyDecision(Decision):
-
-  def __init__(self):
-    Decision.__init__(self)
-
-  def ApplyWrapper(self, solver):
-    try:
-       self.Apply(solver)
-    except Exception as e:
-      if 'CP Solver fail' in str(e):
-        solver.ShouldFail()
-      else:
-        raise
-
-  def RefuteWrapper(self, solver):
-    try:
-       self.Refute(solver)
-    except Exception as e:
-      if 'CP Solver fail' in str(e):
-        solver.ShouldFail()
-      else:
-        raise
-
-  def DebugString(self):
-    return "PyDecision"
-
-

Ancestors

- -

Methods

-
-
-def DebugString(self) -
-
-
-
- -Expand source code - -
def DebugString(self):
-  return "PyDecision"
-
-
-
-

Inherited members

- -
-
-class PyDecisionBuilder -
-
-

A DecisionBuilder is responsible for creating the search tree. The -important method is Next(), which returns the next decision to execute.

-
- -Expand source code - -
class PyDecisionBuilder(DecisionBuilder):
-
-  def __init__(self):
-    DecisionBuilder.__init__(self)
-
-  def NextWrapper(self, solver):
-    try:
-      return self.Next(solver)
-    except Exception as e:
-      if 'CP Solver fail' in str(e):
-        return solver.FailDecision()
-      else:
-        raise
-
-  def DebugString(self):
-    return "PyDecisionBuilder"
-
-

Ancestors

- -

Methods

-
-
-def DebugString(self) -
-
-
-
- -Expand source code - -
def DebugString(self):
-  return "PyDecisionBuilder"
-
-
-
-

Inherited members

- -
-
-class PyDemon -
-
-

A Demon is the base element of a propagation queue. It is the main -object responsible for implementing the actual propagation -of the constraint and pruning the inconsistent values in the domains -of the variables. The main concept is that demons are listeners that are -attached to the variables and listen to their modifications. -There are two methods: -- Run() is the actual method called when the demon is processed. -- priority() returns its priority. Standard priorities are slow, normal -or fast. "immediate" is reserved for variables and is treated separately.

-

This indicates the priority of a demon. Immediate demons are treated -separately and corresponds to variables.

-
- -Expand source code - -
class PyDemon(Demon):
-
-  def RunWrapper(self, solver):
-    try:
-      self.Run(solver)
-    except Exception as e:
-      if 'CP Solver fail' in str(e):
-        solver.ShouldFail()
-      else:
-        raise
-
-  def DebugString(self):
-    return "PyDemon"
-
-

Ancestors

- -

Subclasses

- -

Methods

-
-
-def DebugString(self) -
-
-
-
- -Expand source code - -
def DebugString(self):
-  return "PyDemon"
-
-
-
-

Inherited members

- -
-
-class RevBool -(val: bool const &) -
-
-

This class adds reversibility to a POD type. -It contains the stamp optimization. i.e. the SaveValue call is done -only once per node of the search tree. -Please note that actual -stamps always starts at 1, thus an initial value of 0 will always -trigger the first SaveValue.

-
- -Expand source code - -
class RevBool(object):
-    r"""
-    This class adds reversibility to a POD type.
-    It contains the stamp optimization. i.e. the SaveValue call is done
-    only once per node of the search tree.  Please note that actual
-    stamps always starts at 1, thus an initial value of 0 will always
-    trigger the first SaveValue.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self, val: "bool const &"):
-        _pywrapcp.RevBool_swiginit(self, _pywrapcp.new_RevBool(val))
-
-    def Value(self) -> "bool const &":
-        return _pywrapcp.RevBool_Value(self)
-
-    def SetValue(self, s: "Solver", val: "bool const &") -> "void":
-        return _pywrapcp.RevBool_SetValue(self, s, val)
-    __swig_destroy__ = _pywrapcp.delete_RevBool
-
-

Instance variables

-
-
var thisown
-
-

The membership flag

-
- -Expand source code - -
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-
-
-

Methods

-
-
-def SetValue(self, s: Solver, val: bool const &) ‑> void -
-
-
-
- -Expand source code - -
def SetValue(self, s: "Solver", val: "bool const &") -> "void":
-    return _pywrapcp.RevBool_SetValue(self, s, val)
-
-
-
-def Value(self) ‑> bool const & -
-
-
-
- -Expand source code - -
def Value(self) -> "bool const &":
-    return _pywrapcp.RevBool_Value(self)
-
-
-
-
-
-class RevInteger -(val: long const &) -
-
-

This class adds reversibility to a POD type. -It contains the stamp optimization. i.e. the SaveValue call is done -only once per node of the search tree. -Please note that actual -stamps always starts at 1, thus an initial value of 0 will always -trigger the first SaveValue.

-
- -Expand source code - -
class RevInteger(object):
-    r"""
-    This class adds reversibility to a POD type.
-    It contains the stamp optimization. i.e. the SaveValue call is done
-    only once per node of the search tree.  Please note that actual
-    stamps always starts at 1, thus an initial value of 0 will always
-    trigger the first SaveValue.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self, val: "long const &"):
-        _pywrapcp.RevInteger_swiginit(self, _pywrapcp.new_RevInteger(val))
-
-    def Value(self) -> "long const &":
-        return _pywrapcp.RevInteger_Value(self)
-
-    def SetValue(self, s: "Solver", val: "long const &") -> "void":
-        return _pywrapcp.RevInteger_SetValue(self, s, val)
-    __swig_destroy__ = _pywrapcp.delete_RevInteger
-
-

Subclasses

- -

Instance variables

-
-
var thisown
-
-

The membership flag

-
- -Expand source code - -
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-
-
-

Methods

-
-
-def SetValue(self, s: Solver, val: long const &) ‑> void -
-
-
-
- -Expand source code - -
def SetValue(self, s: "Solver", val: "long const &") -> "void":
-    return _pywrapcp.RevInteger_SetValue(self, s, val)
-
-
-
-def Value(self) ‑> long const & -
-
-
-
- -Expand source code - -
def Value(self) -> "long const &":
-    return _pywrapcp.RevInteger_Value(self)
-
-
-
-
-
-class RoutingDimension -(*args, **kwargs) -
-
-

Dimensions represent quantities accumulated at nodes along the routes. They -represent quantities such as weights or volumes carried along the route, or -distance or times.

-

Quantities at a node are represented by "cumul" variables and the increase -or decrease of quantities between nodes are represented by "transit" -variables. These variables are linked as follows:

-

if j == next(i), -cumuls(j) = cumuls(i) + transits(i) + slacks(i) + -state_dependent_transits(i)

-

where slack is a positive slack variable (can represent waiting times for -a time dimension), and state_dependent_transits is a non-purely functional -version of transits_. Favour transits over state_dependent_transits when -possible, because purely functional callbacks allow more optimisations and -make the model faster and easier to solve. -for a given vehicle, it is passed as an external vector, it would be better -to have this information here.

-
- -Expand source code - -
class RoutingDimension(object):
-    r"""
-    Dimensions represent quantities accumulated at nodes along the routes. They
-    represent quantities such as weights or volumes carried along the route, or
-    distance or times.
-
-    Quantities at a node are represented by "cumul" variables and the increase
-    or decrease of quantities between nodes are represented by "transit"
-    variables. These variables are linked as follows:
-
-    if j == next(i),
-    cumuls(j) = cumuls(i) + transits(i) + slacks(i) +
-                state_dependent_transits(i)
-
-    where slack is a positive slack variable (can represent waiting times for
-    a time dimension), and state_dependent_transits is a non-purely functional
-    version of transits_. Favour transits over state_dependent_transits when
-    possible, because purely functional callbacks allow more optimisations and
-    make the model faster and easier to solve.
-    for a given vehicle, it is passed as an external vector, it would be better
-    to have this information here.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined")
-    __repr__ = _swig_repr
-    __swig_destroy__ = _pywrapcp.delete_RoutingDimension
-
-    def model(self) -> "operations_research::RoutingModel *":
-        r""" Returns the model on which the dimension was created."""
-        return _pywrapcp.RoutingDimension_model(self)
-
-    def GetTransitValue(self, from_index: "int64_t", to_index: "int64_t", vehicle: "int64_t") -> "int64_t":
-        r"""
-        Returns the transition value for a given pair of nodes (as var index);
-        this value is the one taken by the corresponding transit variable when
-        the 'next' variable for 'from_index' is bound to 'to_index'.
-        """
-        return _pywrapcp.RoutingDimension_GetTransitValue(self, from_index, to_index, vehicle)
-
-    def GetTransitValueFromClass(self, from_index: "int64_t", to_index: "int64_t", vehicle_class: "int64_t") -> "int64_t":
-        r"""
-        Same as above but taking a vehicle class of the dimension instead of a
-        vehicle (the class of a vehicle can be obtained with vehicle_to_class()).
-        """
-        return _pywrapcp.RoutingDimension_GetTransitValueFromClass(self, from_index, to_index, vehicle_class)
-
-    def CumulVar(self, index: "int64_t") -> "operations_research::IntVar *":
-        r"""
-        Get the cumul, transit and slack variables for the given node (given as
-        int64_t var index).
-        """
-        return _pywrapcp.RoutingDimension_CumulVar(self, index)
-
-    def TransitVar(self, index: "int64_t") -> "operations_research::IntVar *":
-        return _pywrapcp.RoutingDimension_TransitVar(self, index)
-
-    def FixedTransitVar(self, index: "int64_t") -> "operations_research::IntVar *":
-        return _pywrapcp.RoutingDimension_FixedTransitVar(self, index)
-
-    def SlackVar(self, index: "int64_t") -> "operations_research::IntVar *":
-        return _pywrapcp.RoutingDimension_SlackVar(self, index)
-
-    def SetSpanUpperBoundForVehicle(self, upper_bound: "int64_t", vehicle: "int") -> "void":
-        r"""
-        Sets an upper bound on the dimension span on a given vehicle. This is the
-        preferred way to limit the "length" of the route of a vehicle according to
-        a dimension.
-        """
-        return _pywrapcp.RoutingDimension_SetSpanUpperBoundForVehicle(self, upper_bound, vehicle)
-
-    def SetSpanCostCoefficientForVehicle(self, coefficient: "int64_t", vehicle: "int") -> "void":
-        r"""
-        Sets a cost proportional to the dimension span on a given vehicle,
-        or on all vehicles at once. "coefficient" must be nonnegative.
-        This is handy to model costs proportional to idle time when the dimension
-        represents time.
-        The cost for a vehicle is
-          span_cost = coefficient * (dimension end value - dimension start value).
-        """
-        return _pywrapcp.RoutingDimension_SetSpanCostCoefficientForVehicle(self, coefficient, vehicle)
-
-    def SetSpanCostCoefficientForAllVehicles(self, coefficient: "int64_t") -> "void":
-        return _pywrapcp.RoutingDimension_SetSpanCostCoefficientForAllVehicles(self, coefficient)
-
-    def SetGlobalSpanCostCoefficient(self, coefficient: "int64_t") -> "void":
-        r"""
-        Sets a cost proportional to the *global* dimension span, that is the
-        difference between the largest value of route end cumul variables and
-        the smallest value of route start cumul variables.
-        In other words:
-        global_span_cost =
-          coefficient * (Max(dimension end value) - Min(dimension start value)).
-        """
-        return _pywrapcp.RoutingDimension_SetGlobalSpanCostCoefficient(self, coefficient)
-
-    def SetCumulVarSoftUpperBound(self, index: "int64_t", upper_bound: "int64_t", coefficient: "int64_t") -> "void":
-        r"""
-        Sets a soft upper bound to the cumul variable of a given variable index.
-        If the value of the cumul variable is greater than the bound, a cost
-        proportional to the difference between this value and the bound is added
-        to the cost function of the model:
-          cumulVar <= upper_bound -> cost = 0
-           cumulVar > upper_bound -> cost = coefficient * (cumulVar - upper_bound)
-        This is also handy to model tardiness costs when the dimension represents
-        time.
-        """
-        return _pywrapcp.RoutingDimension_SetCumulVarSoftUpperBound(self, index, upper_bound, coefficient)
-
-    def HasCumulVarSoftUpperBound(self, index: "int64_t") -> "bool":
-        r"""
-        Returns true if a soft upper bound has been set for a given variable
-        index.
-        """
-        return _pywrapcp.RoutingDimension_HasCumulVarSoftUpperBound(self, index)
-
-    def GetCumulVarSoftUpperBound(self, index: "int64_t") -> "int64_t":
-        r"""
-        Returns the soft upper bound of a cumul variable for a given variable
-        index. The "hard" upper bound of the variable is returned if no soft upper
-        bound has been set.
-        """
-        return _pywrapcp.RoutingDimension_GetCumulVarSoftUpperBound(self, index)
-
-    def GetCumulVarSoftUpperBoundCoefficient(self, index: "int64_t") -> "int64_t":
-        r"""
-        Returns the cost coefficient of the soft upper bound of a cumul variable
-        for a given variable index. If no soft upper bound has been set, 0 is
-        returned.
-        """
-        return _pywrapcp.RoutingDimension_GetCumulVarSoftUpperBoundCoefficient(self, index)
-
-    def SetCumulVarSoftLowerBound(self, index: "int64_t", lower_bound: "int64_t", coefficient: "int64_t") -> "void":
-        r"""
-        Sets a soft lower bound to the cumul variable of a given variable index.
-        If the value of the cumul variable is less than the bound, a cost
-        proportional to the difference between this value and the bound is added
-        to the cost function of the model:
-          cumulVar > lower_bound -> cost = 0
-          cumulVar <= lower_bound -> cost = coefficient * (lower_bound -
-                      cumulVar).
-        This is also handy to model earliness costs when the dimension represents
-        time.
-        """
-        return _pywrapcp.RoutingDimension_SetCumulVarSoftLowerBound(self, index, lower_bound, coefficient)
-
-    def HasCumulVarSoftLowerBound(self, index: "int64_t") -> "bool":
-        r"""
-        Returns true if a soft lower bound has been set for a given variable
-        index.
-        """
-        return _pywrapcp.RoutingDimension_HasCumulVarSoftLowerBound(self, index)
-
-    def GetCumulVarSoftLowerBound(self, index: "int64_t") -> "int64_t":
-        r"""
-        Returns the soft lower bound of a cumul variable for a given variable
-        index. The "hard" lower bound of the variable is returned if no soft lower
-        bound has been set.
-        """
-        return _pywrapcp.RoutingDimension_GetCumulVarSoftLowerBound(self, index)
-
-    def GetCumulVarSoftLowerBoundCoefficient(self, index: "int64_t") -> "int64_t":
-        r"""
-        Returns the cost coefficient of the soft lower bound of a cumul variable
-        for a given variable index. If no soft lower bound has been set, 0 is
-        returned.
-        """
-        return _pywrapcp.RoutingDimension_GetCumulVarSoftLowerBoundCoefficient(self, index)
-
-    def SetBreakIntervalsOfVehicle(self, breaks: "std::vector< operations_research::IntervalVar * >", vehicle: "int", node_visit_transits: "std::vector< int64_t >") -> "void":
-        r"""
-        Sets the breaks for a given vehicle. Breaks are represented by
-        IntervalVars. They may interrupt transits between nodes and increase
-        the value of corresponding slack variables.
-        A break may take place before the start of a vehicle, after the end of
-        a vehicle, or during a travel i -> j.
-
-        In that case, the interval [break.Start(), break.End()) must be a subset
-        of [CumulVar(i) + pre_travel(i, j), CumulVar(j) - post_travel(i, j)). In
-        other words, a break may not overlap any node n's visit, given by
-        [CumulVar(n) - post_travel(_, n), CumulVar(n) + pre_travel(n, _)).
-        This formula considers post_travel(_, start) and pre_travel(end, _) to be
-        0; pre_travel will never be called on any (_, start) and post_travel will
-        never we called on any (end, _). If pre_travel_evaluator or
-        post_travel_evaluator is -1, it will be taken as a function that always
-        returns 0.
-        Deprecated, sets pre_travel(i, j) = node_visit_transit[i].
-        """
-        return _pywrapcp.RoutingDimension_SetBreakIntervalsOfVehicle(self, breaks, vehicle, node_visit_transits)
-
-    def SetBreakDistanceDurationOfVehicle(self, distance: "int64_t", duration: "int64_t", vehicle: "int") -> "void":
-        r"""
-        With breaks supposed to be consecutive, this forces the distance between
-        breaks of size at least minimum_break_duration to be at most distance.
-        This supposes that the time until route start and after route end are
-        infinite breaks.
-        """
-        return _pywrapcp.RoutingDimension_SetBreakDistanceDurationOfVehicle(self, distance, duration, vehicle)
-
-    def InitializeBreaks(self) -> "void":
-        r"""
-        Sets up vehicle_break_intervals_, vehicle_break_distance_duration_,
-        pre_travel_evaluators and post_travel_evaluators.
-        """
-        return _pywrapcp.RoutingDimension_InitializeBreaks(self)
-
-    def HasBreakConstraints(self) -> "bool":
-        r""" Returns true if any break interval or break distance was defined."""
-        return _pywrapcp.RoutingDimension_HasBreakConstraints(self)
-
-    def GetPreTravelEvaluatorOfVehicle(self, vehicle: "int") -> "int":
-        return _pywrapcp.RoutingDimension_GetPreTravelEvaluatorOfVehicle(self, vehicle)
-
-    def GetPostTravelEvaluatorOfVehicle(self, vehicle: "int") -> "int":
-        return _pywrapcp.RoutingDimension_GetPostTravelEvaluatorOfVehicle(self, vehicle)
-
-    def base_dimension(self) -> "operations_research::RoutingDimension const *":
-        r""" Returns the parent in the dependency tree if any or nullptr otherwise."""
-        return _pywrapcp.RoutingDimension_base_dimension(self)
-
-    def ShortestTransitionSlack(self, node: "int64_t") -> "int64_t":
-        r"""
-        It makes sense to use the function only for self-dependent dimension.
-        For such dimensions the value of the slack of a node determines the
-        transition cost of the next transit. Provided that
-          1. cumul[node] is fixed,
-          2. next[node] and next[next[node]] (if exists) are fixed,
-        the value of slack[node] for which cumul[next[node]] + transit[next[node]]
-        is minimized can be found in O(1) using this function.
-        """
-        return _pywrapcp.RoutingDimension_ShortestTransitionSlack(self, node)
-
-    def name(self) -> "std::string const &":
-        r""" Returns the name of the dimension."""
-        return _pywrapcp.RoutingDimension_name(self)
-
-    def SetPickupToDeliveryLimitFunctionForPair(self, limit_function: "operations_research::RoutingDimension::PickupToDeliveryLimitFunction", pair_index: "int") -> "void":
-        return _pywrapcp.RoutingDimension_SetPickupToDeliveryLimitFunctionForPair(self, limit_function, pair_index)
-
-    def HasPickupToDeliveryLimits(self) -> "bool":
-        return _pywrapcp.RoutingDimension_HasPickupToDeliveryLimits(self)
-
-    def AddNodePrecedence(self, first_node: "int64_t", second_node: "int64_t", offset: "int64_t") -> "void":
-        return _pywrapcp.RoutingDimension_AddNodePrecedence(self, first_node, second_node, offset)
-
-    def GetSpanUpperBoundForVehicle(self, vehicle: "int") -> "int64_t":
-        return _pywrapcp.RoutingDimension_GetSpanUpperBoundForVehicle(self, vehicle)
-
-    def GetSpanCostCoefficientForVehicle(self, vehicle: "int") -> "int64_t":
-        return _pywrapcp.RoutingDimension_GetSpanCostCoefficientForVehicle(self, vehicle)
-
-    def global_span_cost_coefficient(self) -> "int64_t":
-        return _pywrapcp.RoutingDimension_global_span_cost_coefficient(self)
-
-    def GetGlobalOptimizerOffset(self) -> "int64_t":
-        return _pywrapcp.RoutingDimension_GetGlobalOptimizerOffset(self)
-
-    def GetLocalOptimizerOffsetForVehicle(self, vehicle: "int") -> "int64_t":
-        return _pywrapcp.RoutingDimension_GetLocalOptimizerOffsetForVehicle(self, vehicle)
-
-

Instance variables

-
-
var thisown
-
-

The membership flag

-
- -Expand source code - -
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-
-
-

Methods

-
-
-def AddNodePrecedence(self, first_node: int64_t, second_node: int64_t, offset: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def AddNodePrecedence(self, first_node: "int64_t", second_node: "int64_t", offset: "int64_t") -> "void":
-    return _pywrapcp.RoutingDimension_AddNodePrecedence(self, first_node, second_node, offset)
-
-
-
-def CumulVar(self, index: int64_t) ‑> operations_research::IntVar * -
-
-

Get the cumul, transit and slack variables for the given node (given as -int64_t var index).

-
- -Expand source code - -
def CumulVar(self, index: "int64_t") -> "operations_research::IntVar *":
-    r"""
-    Get the cumul, transit and slack variables for the given node (given as
-    int64_t var index).
-    """
-    return _pywrapcp.RoutingDimension_CumulVar(self, index)
-
-
-
-def FixedTransitVar(self, index: int64_t) ‑> operations_research::IntVar * -
-
-
-
- -Expand source code - -
def FixedTransitVar(self, index: "int64_t") -> "operations_research::IntVar *":
-    return _pywrapcp.RoutingDimension_FixedTransitVar(self, index)
-
-
-
-def GetCumulVarSoftLowerBound(self, index: int64_t) ‑> int64_t -
-
-

Returns the soft lower bound of a cumul variable for a given variable -index. The "hard" lower bound of the variable is returned if no soft lower -bound has been set.

-
- -Expand source code - -
def GetCumulVarSoftLowerBound(self, index: "int64_t") -> "int64_t":
-    r"""
-    Returns the soft lower bound of a cumul variable for a given variable
-    index. The "hard" lower bound of the variable is returned if no soft lower
-    bound has been set.
-    """
-    return _pywrapcp.RoutingDimension_GetCumulVarSoftLowerBound(self, index)
-
-
-
-def GetCumulVarSoftLowerBoundCoefficient(self, index: int64_t) ‑> int64_t -
-
-

Returns the cost coefficient of the soft lower bound of a cumul variable -for a given variable index. If no soft lower bound has been set, 0 is -returned.

-
- -Expand source code - -
def GetCumulVarSoftLowerBoundCoefficient(self, index: "int64_t") -> "int64_t":
-    r"""
-    Returns the cost coefficient of the soft lower bound of a cumul variable
-    for a given variable index. If no soft lower bound has been set, 0 is
-    returned.
-    """
-    return _pywrapcp.RoutingDimension_GetCumulVarSoftLowerBoundCoefficient(self, index)
-
-
-
-def GetCumulVarSoftUpperBound(self, index: int64_t) ‑> int64_t -
-
-

Returns the soft upper bound of a cumul variable for a given variable -index. The "hard" upper bound of the variable is returned if no soft upper -bound has been set.

-
- -Expand source code - -
def GetCumulVarSoftUpperBound(self, index: "int64_t") -> "int64_t":
-    r"""
-    Returns the soft upper bound of a cumul variable for a given variable
-    index. The "hard" upper bound of the variable is returned if no soft upper
-    bound has been set.
-    """
-    return _pywrapcp.RoutingDimension_GetCumulVarSoftUpperBound(self, index)
-
-
-
-def GetCumulVarSoftUpperBoundCoefficient(self, index: int64_t) ‑> int64_t -
-
-

Returns the cost coefficient of the soft upper bound of a cumul variable -for a given variable index. If no soft upper bound has been set, 0 is -returned.

-
- -Expand source code - -
def GetCumulVarSoftUpperBoundCoefficient(self, index: "int64_t") -> "int64_t":
-    r"""
-    Returns the cost coefficient of the soft upper bound of a cumul variable
-    for a given variable index. If no soft upper bound has been set, 0 is
-    returned.
-    """
-    return _pywrapcp.RoutingDimension_GetCumulVarSoftUpperBoundCoefficient(self, index)
-
-
-
-def GetGlobalOptimizerOffset(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def GetGlobalOptimizerOffset(self) -> "int64_t":
-    return _pywrapcp.RoutingDimension_GetGlobalOptimizerOffset(self)
-
-
-
-def GetLocalOptimizerOffsetForVehicle(self, vehicle: int) ‑> int64_t -
-
-
-
- -Expand source code - -
def GetLocalOptimizerOffsetForVehicle(self, vehicle: "int") -> "int64_t":
-    return _pywrapcp.RoutingDimension_GetLocalOptimizerOffsetForVehicle(self, vehicle)
-
-
-
-def GetPostTravelEvaluatorOfVehicle(self, vehicle: int) ‑> int -
-
-
-
- -Expand source code - -
def GetPostTravelEvaluatorOfVehicle(self, vehicle: "int") -> "int":
-    return _pywrapcp.RoutingDimension_GetPostTravelEvaluatorOfVehicle(self, vehicle)
-
-
-
-def GetPreTravelEvaluatorOfVehicle(self, vehicle: int) ‑> int -
-
-
-
- -Expand source code - -
def GetPreTravelEvaluatorOfVehicle(self, vehicle: "int") -> "int":
-    return _pywrapcp.RoutingDimension_GetPreTravelEvaluatorOfVehicle(self, vehicle)
-
-
-
-def GetSpanCostCoefficientForVehicle(self, vehicle: int) ‑> int64_t -
-
-
-
- -Expand source code - -
def GetSpanCostCoefficientForVehicle(self, vehicle: "int") -> "int64_t":
-    return _pywrapcp.RoutingDimension_GetSpanCostCoefficientForVehicle(self, vehicle)
-
-
-
-def GetSpanUpperBoundForVehicle(self, vehicle: int) ‑> int64_t -
-
-
-
- -Expand source code - -
def GetSpanUpperBoundForVehicle(self, vehicle: "int") -> "int64_t":
-    return _pywrapcp.RoutingDimension_GetSpanUpperBoundForVehicle(self, vehicle)
-
-
-
-def GetTransitValue(self, from_index: int64_t, to_index: int64_t, vehicle: int64_t) ‑> int64_t -
-
-

Returns the transition value for a given pair of nodes (as var index); -this value is the one taken by the corresponding transit variable when -the 'next' variable for 'from_index' is bound to 'to_index'.

-
- -Expand source code - -
def GetTransitValue(self, from_index: "int64_t", to_index: "int64_t", vehicle: "int64_t") -> "int64_t":
-    r"""
-    Returns the transition value for a given pair of nodes (as var index);
-    this value is the one taken by the corresponding transit variable when
-    the 'next' variable for 'from_index' is bound to 'to_index'.
-    """
-    return _pywrapcp.RoutingDimension_GetTransitValue(self, from_index, to_index, vehicle)
-
-
-
-def GetTransitValueFromClass(self, from_index: int64_t, to_index: int64_t, vehicle_class: int64_t) ‑> int64_t -
-
-

Same as above but taking a vehicle class of the dimension instead of a -vehicle (the class of a vehicle can be obtained with vehicle_to_class()).

-
- -Expand source code - -
def GetTransitValueFromClass(self, from_index: "int64_t", to_index: "int64_t", vehicle_class: "int64_t") -> "int64_t":
-    r"""
-    Same as above but taking a vehicle class of the dimension instead of a
-    vehicle (the class of a vehicle can be obtained with vehicle_to_class()).
-    """
-    return _pywrapcp.RoutingDimension_GetTransitValueFromClass(self, from_index, to_index, vehicle_class)
-
-
-
-def HasBreakConstraints(self) ‑> bool -
-
-

Returns true if any break interval or break distance was defined.

-
- -Expand source code - -
def HasBreakConstraints(self) -> "bool":
-    r""" Returns true if any break interval or break distance was defined."""
-    return _pywrapcp.RoutingDimension_HasBreakConstraints(self)
-
-
-
-def HasCumulVarSoftLowerBound(self, index: int64_t) ‑> bool -
-
-

Returns true if a soft lower bound has been set for a given variable -index.

-
- -Expand source code - -
def HasCumulVarSoftLowerBound(self, index: "int64_t") -> "bool":
-    r"""
-    Returns true if a soft lower bound has been set for a given variable
-    index.
-    """
-    return _pywrapcp.RoutingDimension_HasCumulVarSoftLowerBound(self, index)
-
-
-
-def HasCumulVarSoftUpperBound(self, index: int64_t) ‑> bool -
-
-

Returns true if a soft upper bound has been set for a given variable -index.

-
- -Expand source code - -
def HasCumulVarSoftUpperBound(self, index: "int64_t") -> "bool":
-    r"""
-    Returns true if a soft upper bound has been set for a given variable
-    index.
-    """
-    return _pywrapcp.RoutingDimension_HasCumulVarSoftUpperBound(self, index)
-
-
-
-def HasPickupToDeliveryLimits(self) ‑> bool -
-
-
-
- -Expand source code - -
def HasPickupToDeliveryLimits(self) -> "bool":
-    return _pywrapcp.RoutingDimension_HasPickupToDeliveryLimits(self)
-
-
-
-def InitializeBreaks(self) ‑> void -
-
-

Sets up vehicle_break_intervals_, vehicle_break_distance_duration_, -pre_travel_evaluators and post_travel_evaluators.

-
- -Expand source code - -
def InitializeBreaks(self) -> "void":
-    r"""
-    Sets up vehicle_break_intervals_, vehicle_break_distance_duration_,
-    pre_travel_evaluators and post_travel_evaluators.
-    """
-    return _pywrapcp.RoutingDimension_InitializeBreaks(self)
-
-
-
-def SetBreakDistanceDurationOfVehicle(self, distance: int64_t, duration: int64_t, vehicle: int) ‑> void -
-
-

With breaks supposed to be consecutive, this forces the distance between -breaks of size at least minimum_break_duration to be at most distance. -This supposes that the time until route start and after route end are -infinite breaks.

-
- -Expand source code - -
def SetBreakDistanceDurationOfVehicle(self, distance: "int64_t", duration: "int64_t", vehicle: "int") -> "void":
-    r"""
-    With breaks supposed to be consecutive, this forces the distance between
-    breaks of size at least minimum_break_duration to be at most distance.
-    This supposes that the time until route start and after route end are
-    infinite breaks.
-    """
-    return _pywrapcp.RoutingDimension_SetBreakDistanceDurationOfVehicle(self, distance, duration, vehicle)
-
-
-
-def SetBreakIntervalsOfVehicle(self, breaks: std::vector< operations_research::IntervalVar * >, vehicle: int, node_visit_transits: std::vector< int64_t >) ‑> void -
-
-

Sets the breaks for a given vehicle. Breaks are represented by -IntervalVars. They may interrupt transits between nodes and increase -the value of corresponding slack variables. -A break may take place before the start of a vehicle, after the end of -a vehicle, or during a travel i -> j.

-

In that case, the interval [break.Start(), break.End()) must be a subset -of [CumulVar(i) + pre_travel(i, j), CumulVar(j) - post_travel(i, j)). In -other words, a break may not overlap any node n's visit, given by -[CumulVar(n) - post_travel(, n), CumulVar(n) + pre_travel(n, )). -This formula considers post_travel(, start) and pre_travel(end, ) to be -0; pre_travel will never be called on any (, start) and post_travel will -never we called on any (end, ). If pre_travel_evaluator or -post_travel_evaluator is -1, it will be taken as a function that always -returns 0. -Deprecated, sets pre_travel(i, j) = node_visit_transit[i].

-
- -Expand source code - -
def SetBreakIntervalsOfVehicle(self, breaks: "std::vector< operations_research::IntervalVar * >", vehicle: "int", node_visit_transits: "std::vector< int64_t >") -> "void":
-    r"""
-    Sets the breaks for a given vehicle. Breaks are represented by
-    IntervalVars. They may interrupt transits between nodes and increase
-    the value of corresponding slack variables.
-    A break may take place before the start of a vehicle, after the end of
-    a vehicle, or during a travel i -> j.
-
-    In that case, the interval [break.Start(), break.End()) must be a subset
-    of [CumulVar(i) + pre_travel(i, j), CumulVar(j) - post_travel(i, j)). In
-    other words, a break may not overlap any node n's visit, given by
-    [CumulVar(n) - post_travel(_, n), CumulVar(n) + pre_travel(n, _)).
-    This formula considers post_travel(_, start) and pre_travel(end, _) to be
-    0; pre_travel will never be called on any (_, start) and post_travel will
-    never we called on any (end, _). If pre_travel_evaluator or
-    post_travel_evaluator is -1, it will be taken as a function that always
-    returns 0.
-    Deprecated, sets pre_travel(i, j) = node_visit_transit[i].
-    """
-    return _pywrapcp.RoutingDimension_SetBreakIntervalsOfVehicle(self, breaks, vehicle, node_visit_transits)
-
-
-
-def SetCumulVarSoftLowerBound(self, index: int64_t, lower_bound: int64_t, coefficient: int64_t) ‑> void -
-
-

Sets a soft lower bound to the cumul variable of a given variable index. -If the value of the cumul variable is less than the bound, a cost -proportional to the difference between this value and the bound is added -to the cost function of the model: -cumulVar > lower_bound -> cost = 0 -cumulVar <= lower_bound -> cost = coefficient * (lower_bound - -cumulVar). -This is also handy to model earliness costs when the dimension represents -time.

-
- -Expand source code - -
def SetCumulVarSoftLowerBound(self, index: "int64_t", lower_bound: "int64_t", coefficient: "int64_t") -> "void":
-    r"""
-    Sets a soft lower bound to the cumul variable of a given variable index.
-    If the value of the cumul variable is less than the bound, a cost
-    proportional to the difference between this value and the bound is added
-    to the cost function of the model:
-      cumulVar > lower_bound -> cost = 0
-      cumulVar <= lower_bound -> cost = coefficient * (lower_bound -
-                  cumulVar).
-    This is also handy to model earliness costs when the dimension represents
-    time.
-    """
-    return _pywrapcp.RoutingDimension_SetCumulVarSoftLowerBound(self, index, lower_bound, coefficient)
-
-
-
-def SetCumulVarSoftUpperBound(self, index: int64_t, upper_bound: int64_t, coefficient: int64_t) ‑> void -
-
-

Sets a soft upper bound to the cumul variable of a given variable index. -If the value of the cumul variable is greater than the bound, a cost -proportional to the difference between this value and the bound is added -to the cost function of the model: -cumulVar <= upper_bound -> cost = 0 -cumulVar > upper_bound -> cost = coefficient * (cumulVar - upper_bound) -This is also handy to model tardiness costs when the dimension represents -time.

-
- -Expand source code - -
def SetCumulVarSoftUpperBound(self, index: "int64_t", upper_bound: "int64_t", coefficient: "int64_t") -> "void":
-    r"""
-    Sets a soft upper bound to the cumul variable of a given variable index.
-    If the value of the cumul variable is greater than the bound, a cost
-    proportional to the difference between this value and the bound is added
-    to the cost function of the model:
-      cumulVar <= upper_bound -> cost = 0
-       cumulVar > upper_bound -> cost = coefficient * (cumulVar - upper_bound)
-    This is also handy to model tardiness costs when the dimension represents
-    time.
-    """
-    return _pywrapcp.RoutingDimension_SetCumulVarSoftUpperBound(self, index, upper_bound, coefficient)
-
-
-
-def SetGlobalSpanCostCoefficient(self, coefficient: int64_t) ‑> void -
-
-

Sets a cost proportional to the global dimension span, that is the -difference between the largest value of route end cumul variables and -the smallest value of route start cumul variables. -In other words: -global_span_cost = -coefficient * (Max(dimension end value) - Min(dimension start value)).

-
- -Expand source code - -
def SetGlobalSpanCostCoefficient(self, coefficient: "int64_t") -> "void":
-    r"""
-    Sets a cost proportional to the *global* dimension span, that is the
-    difference between the largest value of route end cumul variables and
-    the smallest value of route start cumul variables.
-    In other words:
-    global_span_cost =
-      coefficient * (Max(dimension end value) - Min(dimension start value)).
-    """
-    return _pywrapcp.RoutingDimension_SetGlobalSpanCostCoefficient(self, coefficient)
-
-
-
-def SetPickupToDeliveryLimitFunctionForPair(self, limit_function: operations_research::RoutingDimension::PickupToDeliveryLimitFunction, pair_index: int) ‑> void -
-
-
-
- -Expand source code - -
def SetPickupToDeliveryLimitFunctionForPair(self, limit_function: "operations_research::RoutingDimension::PickupToDeliveryLimitFunction", pair_index: "int") -> "void":
-    return _pywrapcp.RoutingDimension_SetPickupToDeliveryLimitFunctionForPair(self, limit_function, pair_index)
-
-
-
-def SetSpanCostCoefficientForAllVehicles(self, coefficient: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetSpanCostCoefficientForAllVehicles(self, coefficient: "int64_t") -> "void":
-    return _pywrapcp.RoutingDimension_SetSpanCostCoefficientForAllVehicles(self, coefficient)
-
-
-
-def SetSpanCostCoefficientForVehicle(self, coefficient: int64_t, vehicle: int) ‑> void -
-
-

Sets a cost proportional to the dimension span on a given vehicle, -or on all vehicles at once. "coefficient" must be nonnegative. -This is handy to model costs proportional to idle time when the dimension -represents time. -The cost for a vehicle is -span_cost = coefficient * (dimension end value - dimension start value).

-
- -Expand source code - -
def SetSpanCostCoefficientForVehicle(self, coefficient: "int64_t", vehicle: "int") -> "void":
-    r"""
-    Sets a cost proportional to the dimension span on a given vehicle,
-    or on all vehicles at once. "coefficient" must be nonnegative.
-    This is handy to model costs proportional to idle time when the dimension
-    represents time.
-    The cost for a vehicle is
-      span_cost = coefficient * (dimension end value - dimension start value).
-    """
-    return _pywrapcp.RoutingDimension_SetSpanCostCoefficientForVehicle(self, coefficient, vehicle)
-
-
-
-def SetSpanUpperBoundForVehicle(self, upper_bound: int64_t, vehicle: int) ‑> void -
-
-

Sets an upper bound on the dimension span on a given vehicle. This is the -preferred way to limit the "length" of the route of a vehicle according to -a dimension.

-
- -Expand source code - -
def SetSpanUpperBoundForVehicle(self, upper_bound: "int64_t", vehicle: "int") -> "void":
-    r"""
-    Sets an upper bound on the dimension span on a given vehicle. This is the
-    preferred way to limit the "length" of the route of a vehicle according to
-    a dimension.
-    """
-    return _pywrapcp.RoutingDimension_SetSpanUpperBoundForVehicle(self, upper_bound, vehicle)
-
-
-
-def ShortestTransitionSlack(self, node: int64_t) ‑> int64_t -
-
-

It makes sense to use the function only for self-dependent dimension. -For such dimensions the value of the slack of a node determines the -transition cost of the next transit. Provided that -1. cumul[node] is fixed, -2. next[node] and next[next[node]] (if exists) are fixed, -the value of slack[node] for which cumul[next[node]] + transit[next[node]] -is minimized can be found in O(1) using this function.

-
- -Expand source code - -
def ShortestTransitionSlack(self, node: "int64_t") -> "int64_t":
-    r"""
-    It makes sense to use the function only for self-dependent dimension.
-    For such dimensions the value of the slack of a node determines the
-    transition cost of the next transit. Provided that
-      1. cumul[node] is fixed,
-      2. next[node] and next[next[node]] (if exists) are fixed,
-    the value of slack[node] for which cumul[next[node]] + transit[next[node]]
-    is minimized can be found in O(1) using this function.
-    """
-    return _pywrapcp.RoutingDimension_ShortestTransitionSlack(self, node)
-
-
-
-def SlackVar(self, index: int64_t) ‑> operations_research::IntVar * -
-
-
-
- -Expand source code - -
def SlackVar(self, index: "int64_t") -> "operations_research::IntVar *":
-    return _pywrapcp.RoutingDimension_SlackVar(self, index)
-
-
-
-def TransitVar(self, index: int64_t) ‑> operations_research::IntVar * -
-
-
-
- -Expand source code - -
def TransitVar(self, index: "int64_t") -> "operations_research::IntVar *":
-    return _pywrapcp.RoutingDimension_TransitVar(self, index)
-
-
-
-def base_dimension(self) ‑> operations_research::RoutingDimension const * -
-
-

Returns the parent in the dependency tree if any or nullptr otherwise.

-
- -Expand source code - -
def base_dimension(self) -> "operations_research::RoutingDimension const *":
-    r""" Returns the parent in the dependency tree if any or nullptr otherwise."""
-    return _pywrapcp.RoutingDimension_base_dimension(self)
-
-
-
-def global_span_cost_coefficient(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def global_span_cost_coefficient(self) -> "int64_t":
-    return _pywrapcp.RoutingDimension_global_span_cost_coefficient(self)
-
-
-
-def model(self) ‑> operations_research::RoutingModel * -
-
-

Returns the model on which the dimension was created.

-
- -Expand source code - -
def model(self) -> "operations_research::RoutingModel *":
-    r""" Returns the model on which the dimension was created."""
-    return _pywrapcp.RoutingDimension_model(self)
-
-
-
-def name(self) ‑> std::string const & -
-
-

Returns the name of the dimension.

-
- -Expand source code - -
def name(self) -> "std::string const &":
-    r""" Returns the name of the dimension."""
-    return _pywrapcp.RoutingDimension_name(self)
-
-
-
-
-
-class RoutingIndexManager -(*args) -
-
-

Manager for any NodeIndex <-> variable index conversion. The routing solver -uses variable indices internally and through its API. These variable indices -are tricky to manage directly because one Node can correspond to a multitude -of variables, depending on the number of times they appear in the model, and -if they're used as start and/or end points. This class aims to simplify -variable index usage, allowing users to use NodeIndex instead.

-

Usage

-

.. code-block:: c++

-
auto starts_ends = ...;  /// These are NodeIndex.
-RoutingIndexManager manager(10, 4, starts_ends);  // 10 nodes, 4 vehicles.
-RoutingModel model(manager);
-
-

Then, use 'manager.NodeToIndex(node)' whenever model requires a variable -index.

-

Note: the mapping between node indices and variables indices is subject to -change so no assumption should be made on it. The only guarantee is that -indices range between 0 and n-1, where n = number of vehicles * 2 (for start -and end nodes) + number of non-start or end nodes.

-
- -Expand source code - -
class RoutingIndexManager(object):
-    r"""
-    Manager for any NodeIndex <-> variable index conversion. The routing solver
-    uses variable indices internally and through its API. These variable indices
-    are tricky to manage directly because one Node can correspond to a multitude
-    of variables, depending on the number of times they appear in the model, and
-    if they're used as start and/or end points. This class aims to simplify
-    variable index usage, allowing users to use NodeIndex instead.
-
-    Usage:
-
-      .. code-block:: c++
-
-          auto starts_ends = ...;  /// These are NodeIndex.
-          RoutingIndexManager manager(10, 4, starts_ends);  // 10 nodes, 4 vehicles.
-          RoutingModel model(manager);
-
-    Then, use 'manager.NodeToIndex(node)' whenever model requires a variable
-    index.
-
-    Note: the mapping between node indices and variables indices is subject to
-    change so no assumption should be made on it. The only guarantee is that
-    indices range between 0 and n-1, where n = number of vehicles * 2 (for start
-    and end nodes) + number of non-start or end nodes.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self, *args):
-        _pywrapcp.RoutingIndexManager_swiginit(self, _pywrapcp.new_RoutingIndexManager(*args))
-    __swig_destroy__ = _pywrapcp.delete_RoutingIndexManager
-
-    def GetNumberOfNodes(self) -> "int":
-        return _pywrapcp.RoutingIndexManager_GetNumberOfNodes(self)
-
-    def GetNumberOfVehicles(self) -> "int":
-        return _pywrapcp.RoutingIndexManager_GetNumberOfVehicles(self)
-
-    def GetNumberOfIndices(self) -> "int":
-        return _pywrapcp.RoutingIndexManager_GetNumberOfIndices(self)
-
-    def GetStartIndex(self, vehicle: "int") -> "int64_t":
-        return _pywrapcp.RoutingIndexManager_GetStartIndex(self, vehicle)
-
-    def GetEndIndex(self, vehicle: "int") -> "int64_t":
-        return _pywrapcp.RoutingIndexManager_GetEndIndex(self, vehicle)
-
-    def NodeToIndex(self, node: "operations_research::RoutingIndexManager::NodeIndex") -> "int64_t":
-        return _pywrapcp.RoutingIndexManager_NodeToIndex(self, node)
-
-    def IndexToNode(self, index: "int64_t") -> "operations_research::RoutingIndexManager::NodeIndex":
-        return _pywrapcp.RoutingIndexManager_IndexToNode(self, index)
-
-

Instance variables

-
-
var thisown
-
-

The membership flag

-
- -Expand source code - -
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-
-
-

Methods

-
-
-def GetEndIndex(self, vehicle: int) ‑> int64_t -
-
-
-
- -Expand source code - -
def GetEndIndex(self, vehicle: "int") -> "int64_t":
-    return _pywrapcp.RoutingIndexManager_GetEndIndex(self, vehicle)
-
-
-
-def GetNumberOfIndices(self) ‑> int -
-
-
-
- -Expand source code - -
def GetNumberOfIndices(self) -> "int":
-    return _pywrapcp.RoutingIndexManager_GetNumberOfIndices(self)
-
-
-
-def GetNumberOfNodes(self) ‑> int -
-
-
-
- -Expand source code - -
def GetNumberOfNodes(self) -> "int":
-    return _pywrapcp.RoutingIndexManager_GetNumberOfNodes(self)
-
-
-
-def GetNumberOfVehicles(self) ‑> int -
-
-
-
- -Expand source code - -
def GetNumberOfVehicles(self) -> "int":
-    return _pywrapcp.RoutingIndexManager_GetNumberOfVehicles(self)
-
-
-
-def GetStartIndex(self, vehicle: int) ‑> int64_t -
-
-
-
- -Expand source code - -
def GetStartIndex(self, vehicle: "int") -> "int64_t":
-    return _pywrapcp.RoutingIndexManager_GetStartIndex(self, vehicle)
-
-
-
-def IndexToNode(self, index: int64_t) ‑> operations_research::RoutingIndexManager::NodeIndex -
-
-
-
- -Expand source code - -
def IndexToNode(self, index: "int64_t") -> "operations_research::RoutingIndexManager::NodeIndex":
-    return _pywrapcp.RoutingIndexManager_IndexToNode(self, index)
-
-
-
-def NodeToIndex(self, node: operations_research::RoutingIndexManager::NodeIndex) ‑> int64_t -
-
-
-
- -Expand source code - -
def NodeToIndex(self, node: "operations_research::RoutingIndexManager::NodeIndex") -> "int64_t":
-    return _pywrapcp.RoutingIndexManager_NodeToIndex(self, node)
-
-
-
-
-
-class RoutingModel -(*args) -
-
-
-
- -Expand source code - -
class RoutingModel(object):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-    ROUTING_NOT_SOLVED = _pywrapcp.RoutingModel_ROUTING_NOT_SOLVED
-    r""" Problem not solved yet (before calling RoutingModel::Solve())."""
-    ROUTING_SUCCESS = _pywrapcp.RoutingModel_ROUTING_SUCCESS
-    r""" Problem solved successfully after calling RoutingModel::Solve()."""
-    ROUTING_FAIL = _pywrapcp.RoutingModel_ROUTING_FAIL
-    r""" No solution found to the problem after calling RoutingModel::Solve()."""
-    ROUTING_FAIL_TIMEOUT = _pywrapcp.RoutingModel_ROUTING_FAIL_TIMEOUT
-    r""" Time limit reached before finding a solution with RoutingModel::Solve()."""
-    ROUTING_INVALID = _pywrapcp.RoutingModel_ROUTING_INVALID
-    r""" Model, model parameters or flags are not valid."""
-    PICKUP_AND_DELIVERY_NO_ORDER = _pywrapcp.RoutingModel_PICKUP_AND_DELIVERY_NO_ORDER
-    r""" Any precedence is accepted."""
-    PICKUP_AND_DELIVERY_LIFO = _pywrapcp.RoutingModel_PICKUP_AND_DELIVERY_LIFO
-    r""" Deliveries must be performed in reverse order of pickups."""
-    PICKUP_AND_DELIVERY_FIFO = _pywrapcp.RoutingModel_PICKUP_AND_DELIVERY_FIFO
-    r""" Deliveries must be performed in the same order as pickups."""
-
-    def __init__(self, *args):
-        _pywrapcp.RoutingModel_swiginit(self, _pywrapcp.new_RoutingModel(*args))
-    __swig_destroy__ = _pywrapcp.delete_RoutingModel
-
-    def RegisterUnaryTransitVector(self, values: "std::vector< int64_t >") -> "int":
-        r""" Registers 'callback' and returns its index."""
-        return _pywrapcp.RoutingModel_RegisterUnaryTransitVector(self, values)
-
-    def RegisterUnaryTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback1") -> "int":
-        return _pywrapcp.RoutingModel_RegisterUnaryTransitCallback(self, callback)
-
-    def RegisterPositiveUnaryTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback1") -> "int":
-        return _pywrapcp.RoutingModel_RegisterPositiveUnaryTransitCallback(self, callback)
-
-    def RegisterTransitMatrix(self, values: "std::vector< std::vector< int64_t > >") -> "int":
-        return _pywrapcp.RoutingModel_RegisterTransitMatrix(self, values)
-
-    def RegisterTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback2") -> "int":
-        return _pywrapcp.RoutingModel_RegisterTransitCallback(self, callback)
-
-    def RegisterPositiveTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback2") -> "int":
-        return _pywrapcp.RoutingModel_RegisterPositiveTransitCallback(self, callback)
-
-    def TransitCallback(self, callback_index: "int") -> "operations_research::RoutingModel::TransitCallback2 const &":
-        return _pywrapcp.RoutingModel_TransitCallback(self, callback_index)
-
-    def UnaryTransitCallbackOrNull(self, callback_index: "int") -> "operations_research::RoutingModel::TransitCallback1 const &":
-        return _pywrapcp.RoutingModel_UnaryTransitCallbackOrNull(self, callback_index)
-
-    def AddDimension(self, evaluator_index: "int", slack_max: "int64_t", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
-        r"""
-        Model creation
-        Methods to add dimensions to routes; dimensions represent quantities
-        accumulated at nodes along the routes. They represent quantities such as
-        weights or volumes carried along the route, or distance or times.
-        Quantities at a node are represented by "cumul" variables and the increase
-        or decrease of quantities between nodes are represented by "transit"
-        variables. These variables are linked as follows:
-        if j == next(i), cumul(j) = cumul(i) + transit(i) + slack(i)
-        where slack is a positive slack variable (can represent waiting times for
-        a time dimension).
-        Setting the value of fix_start_cumul_to_zero to true will force the
-        "cumul" variable of the start node of all vehicles to be equal to 0.
-        Creates a dimension where the transit variable is constrained to be
-        equal to evaluator(i, next(i)); 'slack_max' is the upper bound of the
-        slack variable and 'capacity' is the upper bound of the cumul variables.
-        'name' is the name used to reference the dimension; this name is used to
-        get cumul and transit variables from the routing model.
-        Returns false if a dimension with the same name has already been created
-        (and doesn't create the new dimension).
-        Takes ownership of the callback 'evaluator'.
-        """
-        return _pywrapcp.RoutingModel_AddDimension(self, evaluator_index, slack_max, capacity, fix_start_cumul_to_zero, name)
-
-    def AddDimensionWithVehicleTransits(self, evaluator_indices: "std::vector< int > const &", slack_max: "int64_t", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
-        return _pywrapcp.RoutingModel_AddDimensionWithVehicleTransits(self, evaluator_indices, slack_max, capacity, fix_start_cumul_to_zero, name)
-
-    def AddDimensionWithVehicleCapacity(self, evaluator_index: "int", slack_max: "int64_t", vehicle_capacities: "std::vector< int64_t >", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
-        return _pywrapcp.RoutingModel_AddDimensionWithVehicleCapacity(self, evaluator_index, slack_max, vehicle_capacities, fix_start_cumul_to_zero, name)
-
-    def AddDimensionWithVehicleTransitAndCapacity(self, evaluator_indices: "std::vector< int > const &", slack_max: "int64_t", vehicle_capacities: "std::vector< int64_t >", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
-        return _pywrapcp.RoutingModel_AddDimensionWithVehicleTransitAndCapacity(self, evaluator_indices, slack_max, vehicle_capacities, fix_start_cumul_to_zero, name)
-
-    def AddConstantDimensionWithSlack(self, value: "int64_t", capacity: "int64_t", slack_max: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
-        r"""
-        Creates a dimension where the transit variable is constrained to be
-        equal to 'value'; 'capacity' is the upper bound of the cumul variables.
-        'name' is the name used to reference the dimension; this name is used to
-        get cumul and transit variables from the routing model.
-        Returns a pair consisting of an index to the registered unary transit
-        callback and a bool denoting whether the dimension has been created.
-        It is false if a dimension with the same name has already been created
-        (and doesn't create the new dimension but still register a new callback).
-        """
-        return _pywrapcp.RoutingModel_AddConstantDimensionWithSlack(self, value, capacity, slack_max, fix_start_cumul_to_zero, name)
-
-    def AddConstantDimension(self, value: "int64_t", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
-        return _pywrapcp.RoutingModel_AddConstantDimension(self, value, capacity, fix_start_cumul_to_zero, name)
-
-    def AddVectorDimension(self, values: "std::vector< int64_t >", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
-        r"""
-        Creates a dimension where the transit variable is constrained to be
-        equal to 'values[i]' for node i; 'capacity' is the upper bound of
-        the cumul variables. 'name' is the name used to reference the dimension;
-        this name is used to get cumul and transit variables from the routing
-        model.
-        Returns a pair consisting of an index to the registered unary transit
-        callback and a bool denoting whether the dimension has been created.
-        It is false if a dimension with the same name has already been created
-        (and doesn't create the new dimension but still register a new callback).
-        """
-        return _pywrapcp.RoutingModel_AddVectorDimension(self, values, capacity, fix_start_cumul_to_zero, name)
-
-    def AddMatrixDimension(self, values: "std::vector< std::vector< int64_t > >", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
-        r"""
-        Creates a dimension where the transit variable is constrained to be
-        equal to 'values[i][next(i)]' for node i; 'capacity' is the upper bound of
-        the cumul variables. 'name' is the name used to reference the dimension;
-        this name is used to get cumul and transit variables from the routing
-        model.
-        Returns a pair consisting of an index to the registered transit callback
-        and a bool denoting whether the dimension has been created.
-        It is false if a dimension with the same name has already been created
-        (and doesn't create the new dimension but still register a new callback).
-        """
-        return _pywrapcp.RoutingModel_AddMatrixDimension(self, values, capacity, fix_start_cumul_to_zero, name)
-
-    def MakePathSpansAndTotalSlacks(self, dimension: "RoutingDimension", spans: "std::vector< operations_research::IntVar * >", total_slacks: "std::vector< operations_research::IntVar * >") -> "operations_research::Constraint *":
-        r"""
-        For every vehicle of the routing model:
-        - if total_slacks[vehicle] is not nullptr, constrains it to be the sum of
-          slacks on that vehicle, that is,
-          dimension->CumulVar(end) - dimension->CumulVar(start) -
-          sum_{node in path of vehicle} dimension->FixedTransitVar(node).
-        - if spans[vehicle] is not nullptr, constrains it to be
-          dimension->CumulVar(end) - dimension->CumulVar(start)
-        This does stronger propagation than a decomposition, and takes breaks into
-        account.
-        """
-        return _pywrapcp.RoutingModel_MakePathSpansAndTotalSlacks(self, dimension, spans, total_slacks)
-
-    def GetAllDimensionNames(self) -> "std::vector< std::string >":
-        r""" Outputs the names of all dimensions added to the routing engine."""
-        return _pywrapcp.RoutingModel_GetAllDimensionNames(self)
-
-    def GetDimensions(self) -> "std::vector< operations_research::RoutingDimension * > const &":
-        r""" Returns all dimensions of the model."""
-        return _pywrapcp.RoutingModel_GetDimensions(self)
-
-    def GetDimensionsWithSoftOrSpanCosts(self) -> "std::vector< operations_research::RoutingDimension * >":
-        r""" Returns dimensions with soft or vehicle span costs."""
-        return _pywrapcp.RoutingModel_GetDimensionsWithSoftOrSpanCosts(self)
-
-    def GetGlobalDimensionCumulOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::GlobalDimensionCumulOptimizer > > const &":
-        r"""
-        Returns [global|local]_dimension_optimizers_, which are empty if the model
-        has not been closed.
-        """
-        return _pywrapcp.RoutingModel_GetGlobalDimensionCumulOptimizers(self)
-
-    def GetLocalDimensionCumulOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::LocalDimensionCumulOptimizer > > const &":
-        return _pywrapcp.RoutingModel_GetLocalDimensionCumulOptimizers(self)
-
-    def GetLocalDimensionCumulMPOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::LocalDimensionCumulOptimizer > > const &":
-        return _pywrapcp.RoutingModel_GetLocalDimensionCumulMPOptimizers(self)
-
-    def GetMutableGlobalCumulOptimizer(self, dimension: "RoutingDimension") -> "operations_research::GlobalDimensionCumulOptimizer *":
-        r"""
-        Returns the global/local dimension cumul optimizer for a given dimension,
-        or nullptr if there is none.
-        """
-        return _pywrapcp.RoutingModel_GetMutableGlobalCumulOptimizer(self, dimension)
-
-    def GetMutableLocalCumulOptimizer(self, dimension: "RoutingDimension") -> "operations_research::LocalDimensionCumulOptimizer *":
-        return _pywrapcp.RoutingModel_GetMutableLocalCumulOptimizer(self, dimension)
-
-    def GetMutableLocalCumulMPOptimizer(self, dimension: "RoutingDimension") -> "operations_research::LocalDimensionCumulOptimizer *":
-        return _pywrapcp.RoutingModel_GetMutableLocalCumulMPOptimizer(self, dimension)
-
-    def HasDimension(self, dimension_name: "std::string const &") -> "bool":
-        r""" Returns true if a dimension exists for a given dimension name."""
-        return _pywrapcp.RoutingModel_HasDimension(self, dimension_name)
-
-    def GetDimensionOrDie(self, dimension_name: "std::string const &") -> "operations_research::RoutingDimension const &":
-        r""" Returns a dimension from its name. Dies if the dimension does not exist."""
-        return _pywrapcp.RoutingModel_GetDimensionOrDie(self, dimension_name)
-
-    def GetMutableDimension(self, dimension_name: "std::string const &") -> "operations_research::RoutingDimension *":
-        r"""
-        Returns a dimension from its name. Returns nullptr if the dimension does
-        not exist.
-        """
-        return _pywrapcp.RoutingModel_GetMutableDimension(self, dimension_name)
-
-    def SetPrimaryConstrainedDimension(self, dimension_name: "std::string const &") -> "void":
-        r"""
-        Set the given dimension as "primary constrained". As of August 2013, this
-        is only used by ArcIsMoreConstrainedThanArc().
-        "dimension" must be the name of an existing dimension, or be empty, in
-        which case there will not be a primary dimension after this call.
-        """
-        return _pywrapcp.RoutingModel_SetPrimaryConstrainedDimension(self, dimension_name)
-
-    def GetPrimaryConstrainedDimension(self) -> "std::string const &":
-        r""" Get the primary constrained dimension, or an empty string if it is unset."""
-        return _pywrapcp.RoutingModel_GetPrimaryConstrainedDimension(self)
-
-    def AddDisjunction(self, *args) -> "operations_research::RoutingModel::DisjunctionIndex":
-        r"""
-        Adds a disjunction constraint on the indices: exactly 'max_cardinality' of
-        the indices are active. Start and end indices of any vehicle cannot be
-        part of a disjunction.
-
-        If a penalty is given, at most 'max_cardinality' of the indices can be
-        active, and if less are active, 'penalty' is payed per inactive index.
-        This is equivalent to adding the constraint:
-            p + Sum(i)active[i] == max_cardinality
-        where p is an integer variable, and the following cost to the cost
-        function:
-            p * penalty.
-        'penalty' must be positive to make the disjunction optional; a negative
-        penalty will force 'max_cardinality' indices of the disjunction to be
-        performed, and therefore p == 0.
-        Note: passing a vector with a single index will model an optional index
-        with a penalty cost if it is not visited.
-        """
-        return _pywrapcp.RoutingModel_AddDisjunction(self, *args)
-
-    def GetDisjunctionIndices(self, index: "int64_t") -> "std::vector< operations_research::RoutingModel::DisjunctionIndex > const &":
-        r""" Returns the indices of the disjunctions to which an index belongs."""
-        return _pywrapcp.RoutingModel_GetDisjunctionIndices(self, index)
-
-    def GetDisjunctionPenalty(self, index: "operations_research::RoutingModel::DisjunctionIndex") -> "int64_t":
-        r""" Returns the penalty of the node disjunction of index 'index'."""
-        return _pywrapcp.RoutingModel_GetDisjunctionPenalty(self, index)
-
-    def GetDisjunctionMaxCardinality(self, index: "operations_research::RoutingModel::DisjunctionIndex") -> "int64_t":
-        r"""
-        Returns the maximum number of possible active nodes of the node
-        disjunction of index 'index'.
-        """
-        return _pywrapcp.RoutingModel_GetDisjunctionMaxCardinality(self, index)
-
-    def GetNumberOfDisjunctions(self) -> "int":
-        r""" Returns the number of node disjunctions in the model."""
-        return _pywrapcp.RoutingModel_GetNumberOfDisjunctions(self)
-
-    def GetPerfectBinaryDisjunctions(self) -> "std::vector< std::pair< int64_t,int64_t > >":
-        r"""
-        Returns the list of all perfect binary disjunctions, as pairs of variable
-        indices: a disjunction is "perfect" when its variables do not appear in
-        any other disjunction. Each pair is sorted (lowest variable index first),
-        and the output vector is also sorted (lowest pairs first).
-        """
-        return _pywrapcp.RoutingModel_GetPerfectBinaryDisjunctions(self)
-
-    def IgnoreDisjunctionsAlreadyForcedToZero(self) -> "void":
-        r"""
-        SPECIAL: Makes the solver ignore all the disjunctions whose active
-        variables are all trivially zero (i.e. Max() == 0), by setting their
-        max_cardinality to 0.
-        This can be useful when using the BaseBinaryDisjunctionNeighborhood
-        operators, in the context of arc-based routing.
-        """
-        return _pywrapcp.RoutingModel_IgnoreDisjunctionsAlreadyForcedToZero(self)
-
-    def AddSoftSameVehicleConstraint(self, indices: "std::vector< int64_t > const &", cost: "int64_t") -> "void":
-        r"""
-        Adds a soft constraint to force a set of variable indices to be on the
-        same vehicle. If all nodes are not on the same vehicle, each extra vehicle
-        used adds 'cost' to the cost function.
-        """
-        return _pywrapcp.RoutingModel_AddSoftSameVehicleConstraint(self, indices, cost)
-
-    def SetAllowedVehiclesForIndex(self, vehicles: "std::vector< int > const &", index: "int64_t") -> "void":
-        r"""
-        Sets the vehicles which can visit a given node. If the node is in a
-        disjunction, this will not prevent it from being unperformed.
-        Specifying an empty vector of vehicles has no effect (all vehicles
-        will be allowed to visit the node).
-        """
-        return _pywrapcp.RoutingModel_SetAllowedVehiclesForIndex(self, vehicles, index)
-
-    def IsVehicleAllowedForIndex(self, vehicle: "int", index: "int64_t") -> "bool":
-        r""" Returns true if a vehicle is allowed to visit a given node."""
-        return _pywrapcp.RoutingModel_IsVehicleAllowedForIndex(self, vehicle, index)
-
-    def AddPickupAndDelivery(self, pickup: "int64_t", delivery: "int64_t") -> "void":
-        r"""
-        Notifies that index1 and index2 form a pair of nodes which should belong
-        to the same route. This methods helps the search find better solutions,
-        especially in the local search phase.
-        It should be called each time you have an equality constraint linking
-        the vehicle variables of two node (including for instance pickup and
-        delivery problems):
-            Solver* const solver = routing.solver();
-            int64_t index1 = manager.NodeToIndex(node1);
-            int64_t index2 = manager.NodeToIndex(node2);
-            solver->AddConstraint(solver->MakeEquality(
-                routing.VehicleVar(index1),
-                routing.VehicleVar(index2)));
-            routing.AddPickupAndDelivery(index1, index2);
-        """
-        return _pywrapcp.RoutingModel_AddPickupAndDelivery(self, pickup, delivery)
-
-    def AddPickupAndDeliverySets(self, pickup_disjunction: "operations_research::RoutingModel::DisjunctionIndex", delivery_disjunction: "operations_research::RoutingModel::DisjunctionIndex") -> "void":
-        r"""
-        Same as AddPickupAndDelivery but notifying that the performed node from
-        the disjunction of index 'pickup_disjunction' is on the same route as the
-        performed node from the disjunction of index 'delivery_disjunction'.
-        """
-        return _pywrapcp.RoutingModel_AddPickupAndDeliverySets(self, pickup_disjunction, delivery_disjunction)
-
-    def GetPickupIndexPairs(self, node_index: "int64_t") -> "std::vector< std::pair< int,int > > const &":
-        r"""
-        Returns pairs for which the node is a pickup; the first element of each
-        pair is the index in the pickup and delivery pairs list in which the
-        pickup appears, the second element is its index in the pickups list.
-        """
-        return _pywrapcp.RoutingModel_GetPickupIndexPairs(self, node_index)
-
-    def GetDeliveryIndexPairs(self, node_index: "int64_t") -> "std::vector< std::pair< int,int > > const &":
-        r""" Same as above for deliveries."""
-        return _pywrapcp.RoutingModel_GetDeliveryIndexPairs(self, node_index)
-
-    def SetPickupAndDeliveryPolicyOfAllVehicles(self, policy: "operations_research::RoutingModel::PickupAndDeliveryPolicy") -> "void":
-        r"""
-        Sets the Pickup and delivery policy of all vehicles. It is equivalent to
-        calling SetPickupAndDeliveryPolicyOfVehicle on all vehicles.
-        """
-        return _pywrapcp.RoutingModel_SetPickupAndDeliveryPolicyOfAllVehicles(self, policy)
-
-    def SetPickupAndDeliveryPolicyOfVehicle(self, policy: "operations_research::RoutingModel::PickupAndDeliveryPolicy", vehicle: "int") -> "void":
-        return _pywrapcp.RoutingModel_SetPickupAndDeliveryPolicyOfVehicle(self, policy, vehicle)
-
-    def GetPickupAndDeliveryPolicyOfVehicle(self, vehicle: "int") -> "operations_research::RoutingModel::PickupAndDeliveryPolicy":
-        return _pywrapcp.RoutingModel_GetPickupAndDeliveryPolicyOfVehicle(self, vehicle)
-
-    def GetNumOfSingletonNodes(self) -> "int":
-        r"""
-        Returns the number of non-start/end nodes which do not appear in a
-        pickup/delivery pair.
-        """
-        return _pywrapcp.RoutingModel_GetNumOfSingletonNodes(self)
-    TYPE_ADDED_TO_VEHICLE = _pywrapcp.RoutingModel_TYPE_ADDED_TO_VEHICLE
-    r""" When visited, the number of types 'T' on the vehicle increases by one."""
-    ADDED_TYPE_REMOVED_FROM_VEHICLE = _pywrapcp.RoutingModel_ADDED_TYPE_REMOVED_FROM_VEHICLE
-    r"""
-    When visited, one instance of type 'T' previously added to the route
-    (TYPE_ADDED_TO_VEHICLE), if any, is removed from the vehicle.
-    If the type was not previously added to the route or all added instances
-    have already been removed, this visit has no effect on the types.
-    """
-    TYPE_ON_VEHICLE_UP_TO_VISIT = _pywrapcp.RoutingModel_TYPE_ON_VEHICLE_UP_TO_VISIT
-    r"""
-    With the following policy, the visit enforces that type 'T' is
-    considered on the route from its start until this node is visited.
-    """
-    TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED = _pywrapcp.RoutingModel_TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED
-    r"""
-    The visit doesn't have an impact on the number of types 'T' on the
-    route, as it's (virtually) added and removed directly.
-    This policy can be used for visits which are part of an incompatibility
-    or requirement set without affecting the type count on the route.
-    """
-
-    def SetVisitType(self, index: "int64_t", type: "int", type_policy: "operations_research::RoutingModel::VisitTypePolicy") -> "void":
-        return _pywrapcp.RoutingModel_SetVisitType(self, index, type, type_policy)
-
-    def GetVisitType(self, index: "int64_t") -> "int":
-        return _pywrapcp.RoutingModel_GetVisitType(self, index)
-
-    def GetSingleNodesOfType(self, type: "int") -> "std::vector< int > const &":
-        return _pywrapcp.RoutingModel_GetSingleNodesOfType(self, type)
-
-    def GetPairIndicesOfType(self, type: "int") -> "std::vector< int > const &":
-        return _pywrapcp.RoutingModel_GetPairIndicesOfType(self, type)
-
-    def GetVisitTypePolicy(self, index: "int64_t") -> "operations_research::RoutingModel::VisitTypePolicy":
-        return _pywrapcp.RoutingModel_GetVisitTypePolicy(self, index)
-
-    def CloseVisitTypes(self) -> "void":
-        r"""
-        This function should be called once all node visit types have been set and
-        prior to adding any incompatibilities/requirements.
-        "close" types.
-        """
-        return _pywrapcp.RoutingModel_CloseVisitTypes(self)
-
-    def GetNumberOfVisitTypes(self) -> "int":
-        return _pywrapcp.RoutingModel_GetNumberOfVisitTypes(self)
-
-    def AddHardTypeIncompatibility(self, type1: "int", type2: "int") -> "void":
-        r"""
-        Incompatibilities:
-        Two nodes with "hard" incompatible types cannot share the same route at
-        all, while with a "temporal" incompatibility they can't be on the same
-        route at the same time.
-        """
-        return _pywrapcp.RoutingModel_AddHardTypeIncompatibility(self, type1, type2)
-
-    def AddTemporalTypeIncompatibility(self, type1: "int", type2: "int") -> "void":
-        return _pywrapcp.RoutingModel_AddTemporalTypeIncompatibility(self, type1, type2)
-
-    def GetHardTypeIncompatibilitiesOfType(self, type: "int") -> "absl::flat_hash_set< int > const &":
-        r""" Returns visit types incompatible with a given type."""
-        return _pywrapcp.RoutingModel_GetHardTypeIncompatibilitiesOfType(self, type)
-
-    def GetTemporalTypeIncompatibilitiesOfType(self, type: "int") -> "absl::flat_hash_set< int > const &":
-        return _pywrapcp.RoutingModel_GetTemporalTypeIncompatibilitiesOfType(self, type)
-
-    def HasHardTypeIncompatibilities(self) -> "bool":
-        r"""
-        Returns true iff any hard (resp. temporal) type incompatibilities have
-        been added to the model.
-        """
-        return _pywrapcp.RoutingModel_HasHardTypeIncompatibilities(self)
-
-    def HasTemporalTypeIncompatibilities(self) -> "bool":
-        return _pywrapcp.RoutingModel_HasTemporalTypeIncompatibilities(self)
-
-    def AddSameVehicleRequiredTypeAlternatives(self, dependent_type: "int", required_type_alternatives: "absl::flat_hash_set< int >") -> "void":
-        r"""
-        Requirements:
-        NOTE: As of 2019-04, cycles in the requirement graph are not supported,
-        and lead to the dependent nodes being skipped if possible (otherwise
-        the model is considered infeasible).
-        The following functions specify that "dependent_type" requires at least
-        one of the types in "required_type_alternatives".
-
-        For same-vehicle requirements, a node of dependent type type_D requires at
-        least one node of type type_R among the required alternatives on the same
-        route.
-        """
-        return _pywrapcp.RoutingModel_AddSameVehicleRequiredTypeAlternatives(self, dependent_type, required_type_alternatives)
-
-    def AddRequiredTypeAlternativesWhenAddingType(self, dependent_type: "int", required_type_alternatives: "absl::flat_hash_set< int >") -> "void":
-        r"""
-        If type_D depends on type_R when adding type_D, any node_D of type_D and
-        VisitTypePolicy TYPE_ADDED_TO_VEHICLE or
-        TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED requires at least one type_R on its
-        vehicle at the time node_D is visited.
-        """
-        return _pywrapcp.RoutingModel_AddRequiredTypeAlternativesWhenAddingType(self, dependent_type, required_type_alternatives)
-
-    def AddRequiredTypeAlternativesWhenRemovingType(self, dependent_type: "int", required_type_alternatives: "absl::flat_hash_set< int >") -> "void":
-        r"""
-        The following requirements apply when visiting dependent nodes that remove
-        their type from the route, i.e. type_R must be on the vehicle when type_D
-        of VisitTypePolicy ADDED_TYPE_REMOVED_FROM_VEHICLE,
-        TYPE_ON_VEHICLE_UP_TO_VISIT or TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED is
-        visited.
-        """
-        return _pywrapcp.RoutingModel_AddRequiredTypeAlternativesWhenRemovingType(self, dependent_type, required_type_alternatives)
-
-    def GetSameVehicleRequiredTypeAlternativesOfType(self, type: "int") -> "std::vector< absl::flat_hash_set< int > > const &":
-        r"""
-        Returns the set of same-vehicle requirement alternatives for the given
-        type.
-        """
-        return _pywrapcp.RoutingModel_GetSameVehicleRequiredTypeAlternativesOfType(self, type)
-
-    def GetRequiredTypeAlternativesWhenAddingType(self, type: "int") -> "std::vector< absl::flat_hash_set< int > > const &":
-        r""" Returns the set of requirement alternatives when adding the given type."""
-        return _pywrapcp.RoutingModel_GetRequiredTypeAlternativesWhenAddingType(self, type)
-
-    def GetRequiredTypeAlternativesWhenRemovingType(self, type: "int") -> "std::vector< absl::flat_hash_set< int > > const &":
-        r""" Returns the set of requirement alternatives when removing the given type."""
-        return _pywrapcp.RoutingModel_GetRequiredTypeAlternativesWhenRemovingType(self, type)
-
-    def HasSameVehicleTypeRequirements(self) -> "bool":
-        r"""
-        Returns true iff any same-route (resp. temporal) type requirements have
-        been added to the model.
-        """
-        return _pywrapcp.RoutingModel_HasSameVehicleTypeRequirements(self)
-
-    def HasTemporalTypeRequirements(self) -> "bool":
-        return _pywrapcp.RoutingModel_HasTemporalTypeRequirements(self)
-
-    def HasTypeRegulations(self) -> "bool":
-        r"""
-        Returns true iff the model has any incompatibilities or requirements set
-        on node types.
-        """
-        return _pywrapcp.RoutingModel_HasTypeRegulations(self)
-
-    def UnperformedPenalty(self, var_index: "int64_t") -> "int64_t":
-        r"""
-        Get the "unperformed" penalty of a node. This is only well defined if the
-        node is only part of a single Disjunction involving only itself, and that
-        disjunction has a penalty. In all other cases, including forced active
-        nodes, this returns 0.
-        """
-        return _pywrapcp.RoutingModel_UnperformedPenalty(self, var_index)
-
-    def UnperformedPenaltyOrValue(self, default_value: "int64_t", var_index: "int64_t") -> "int64_t":
-        r"""
-        Same as above except that it returns default_value instead of 0 when
-        penalty is not well defined (default value is passed as first argument to
-        simplify the usage of the method in a callback).
-        """
-        return _pywrapcp.RoutingModel_UnperformedPenaltyOrValue(self, default_value, var_index)
-
-    def GetDepot(self) -> "int64_t":
-        r"""
-        Returns the variable index of the first starting or ending node of all
-        routes. If all routes start  and end at the same node (single depot), this
-        is the node returned.
-        """
-        return _pywrapcp.RoutingModel_GetDepot(self)
-
-    def SetMaximumNumberOfActiveVehicles(self, max_active_vehicles: "int") -> "void":
-        r"""
-        Constrains the maximum number of active vehicles, aka the number of
-        vehicles which do not have an empty route. For instance, this can be used
-        to limit the number of routes in the case where there are fewer drivers
-        than vehicles and that the fleet of vehicle is heterogeneous.
-        """
-        return _pywrapcp.RoutingModel_SetMaximumNumberOfActiveVehicles(self, max_active_vehicles)
-
-    def GetMaximumNumberOfActiveVehicles(self) -> "int":
-        r""" Returns the maximum number of active vehicles."""
-        return _pywrapcp.RoutingModel_GetMaximumNumberOfActiveVehicles(self)
-
-    def SetArcCostEvaluatorOfAllVehicles(self, evaluator_index: "int") -> "void":
-        r"""
-        Sets the cost function of the model such that the cost of a segment of a
-        route between node 'from' and 'to' is evaluator(from, to), whatever the
-        route or vehicle performing the route.
-        """
-        return _pywrapcp.RoutingModel_SetArcCostEvaluatorOfAllVehicles(self, evaluator_index)
-
-    def SetArcCostEvaluatorOfVehicle(self, evaluator_index: "int", vehicle: "int") -> "void":
-        r""" Sets the cost function for a given vehicle route."""
-        return _pywrapcp.RoutingModel_SetArcCostEvaluatorOfVehicle(self, evaluator_index, vehicle)
-
-    def SetFixedCostOfAllVehicles(self, cost: "int64_t") -> "void":
-        r"""
-        Sets the fixed cost of all vehicle routes. It is equivalent to calling
-        SetFixedCostOfVehicle on all vehicle routes.
-        """
-        return _pywrapcp.RoutingModel_SetFixedCostOfAllVehicles(self, cost)
-
-    def SetFixedCostOfVehicle(self, cost: "int64_t", vehicle: "int") -> "void":
-        r""" Sets the fixed cost of one vehicle route."""
-        return _pywrapcp.RoutingModel_SetFixedCostOfVehicle(self, cost, vehicle)
-
-    def GetFixedCostOfVehicle(self, vehicle: "int") -> "int64_t":
-        r"""
-        Returns the route fixed cost taken into account if the route of the
-        vehicle is not empty, aka there's at least one node on the route other
-        than the first and last nodes.
-        """
-        return _pywrapcp.RoutingModel_GetFixedCostOfVehicle(self, vehicle)
-
-    def SetAmortizedCostFactorsOfAllVehicles(self, linear_cost_factor: "int64_t", quadratic_cost_factor: "int64_t") -> "void":
-        r"""
-        The following methods set the linear and quadratic cost factors of
-        vehicles (must be positive values). The default value of these parameters
-        is zero for all vehicles.
-
-        When set, the cost_ of the model will contain terms aiming at reducing the
-        number of vehicles used in the model, by adding the following to the
-        objective for every vehicle v:
-        INDICATOR(v used in the model) *
-          [linear_cost_factor_of_vehicle_[v]
-           - quadratic_cost_factor_of_vehicle_[v]*(square of length of route v)]
-        i.e. for every used vehicle, we add the linear factor as fixed cost, and
-        subtract the square of the route length multiplied by the quadratic
-        factor. This second term aims at making the routes as dense as possible.
-
-        Sets the linear and quadratic cost factor of all vehicles.
-        """
-        return _pywrapcp.RoutingModel_SetAmortizedCostFactorsOfAllVehicles(self, linear_cost_factor, quadratic_cost_factor)
-
-    def SetAmortizedCostFactorsOfVehicle(self, linear_cost_factor: "int64_t", quadratic_cost_factor: "int64_t", vehicle: "int") -> "void":
-        r""" Sets the linear and quadratic cost factor of the given vehicle."""
-        return _pywrapcp.RoutingModel_SetAmortizedCostFactorsOfVehicle(self, linear_cost_factor, quadratic_cost_factor, vehicle)
-
-    def GetAmortizedLinearCostFactorOfVehicles(self) -> "std::vector< int64_t > const &":
-        return _pywrapcp.RoutingModel_GetAmortizedLinearCostFactorOfVehicles(self)
-
-    def GetAmortizedQuadraticCostFactorOfVehicles(self) -> "std::vector< int64_t > const &":
-        return _pywrapcp.RoutingModel_GetAmortizedQuadraticCostFactorOfVehicles(self)
-
-    def ConsiderEmptyRouteCostsForVehicle(self, consider_costs: "bool", vehicle: "int") -> "void":
-        return _pywrapcp.RoutingModel_ConsiderEmptyRouteCostsForVehicle(self, consider_costs, vehicle)
-
-    def AreEmptyRouteCostsConsideredForVehicle(self, vehicle: "int") -> "bool":
-        return _pywrapcp.RoutingModel_AreEmptyRouteCostsConsideredForVehicle(self, vehicle)
-
-    def SetFirstSolutionEvaluator(self, evaluator: "operations_research::Solver::IndexEvaluator2") -> "void":
-        r"""
-        Gets/sets the evaluator used during the search. Only relevant when
-        RoutingSearchParameters.first_solution_strategy = EVALUATOR_STRATEGY.
-        Takes ownership of evaluator.
-        """
-        return _pywrapcp.RoutingModel_SetFirstSolutionEvaluator(self, evaluator)
-
-    def AddLocalSearchOperator(self, ls_operator: "LocalSearchOperator") -> "void":
-        r"""
-        Adds a local search operator to the set of operators used to solve the
-        vehicle routing problem.
-        """
-        return _pywrapcp.RoutingModel_AddLocalSearchOperator(self, ls_operator)
-
-    def AddSearchMonitor(self, monitor: "SearchMonitor") -> "void":
-        r""" Adds a search monitor to the search used to solve the routing model."""
-        return _pywrapcp.RoutingModel_AddSearchMonitor(self, monitor)
-
-    def AddAtSolutionCallback(self, callback: "std::function< void () >") -> "void":
-        r"""
-        Adds a callback called each time a solution is found during the search.
-        This is a shortcut to creating a monitor to call the callback on
-        AtSolution() and adding it with AddSearchMonitor.
-        """
-        return _pywrapcp.RoutingModel_AddAtSolutionCallback(self, callback)
-
-    def AddVariableMinimizedByFinalizer(self, var: "IntVar") -> "void":
-        r"""
-        Adds a variable to minimize in the solution finalizer. The solution
-        finalizer is called each time a solution is found during the search and
-        allows to instantiate secondary variables (such as dimension cumul
-        variables).
-        """
-        return _pywrapcp.RoutingModel_AddVariableMinimizedByFinalizer(self, var)
-
-    def AddVariableMaximizedByFinalizer(self, var: "IntVar") -> "void":
-        r"""
-        Adds a variable to maximize in the solution finalizer (see above for
-        information on the solution finalizer).
-        """
-        return _pywrapcp.RoutingModel_AddVariableMaximizedByFinalizer(self, var)
-
-    def AddWeightedVariableMinimizedByFinalizer(self, var: "IntVar", cost: "int64_t") -> "void":
-        r"""
-        Adds a variable to minimize in the solution finalizer, with a weighted
-        priority: the higher the more priority it has.
-        """
-        return _pywrapcp.RoutingModel_AddWeightedVariableMinimizedByFinalizer(self, var, cost)
-
-    def AddVariableTargetToFinalizer(self, var: "IntVar", target: "int64_t") -> "void":
-        r"""
-        Add a variable to set the closest possible to the target value in the
-        solution finalizer.
-        """
-        return _pywrapcp.RoutingModel_AddVariableTargetToFinalizer(self, var, target)
-
-    def CloseModel(self) -> "void":
-        r"""
-        Closes the current routing model; after this method is called, no
-        modification to the model can be done, but RoutesToAssignment becomes
-        available. Note that CloseModel() is automatically called by Solve() and
-        other methods that produce solution.
-        This is equivalent to calling
-        CloseModelWithParameters(DefaultRoutingSearchParameters()).
-        """
-        return _pywrapcp.RoutingModel_CloseModel(self)
-
-    def CloseModelWithParameters(self, search_parameters: "operations_research::RoutingSearchParameters const &") -> "void":
-        r"""
-        Same as above taking search parameters (as of 10/2015 some the parameters
-        have to be set when closing the model).
-        """
-        return _pywrapcp.RoutingModel_CloseModelWithParameters(self, search_parameters)
-
-    def Solve(self, assignment: "Assignment"=None) -> "operations_research::Assignment const *":
-        r"""
-        Solves the current routing model; closes the current model.
-        This is equivalent to calling
-        SolveWithParameters(DefaultRoutingSearchParameters())
-        or
-        SolveFromAssignmentWithParameters(assignment,
-                                          DefaultRoutingSearchParameters()).
-        """
-        return _pywrapcp.RoutingModel_Solve(self, assignment)
-
-    def SolveWithParameters(self, search_parameters: "operations_research::RoutingSearchParameters const &", solutions: "std::vector< operations_research::Assignment const * > *"=None) -> "operations_research::Assignment const *":
-        r"""
-        Solves the current routing model with the given parameters. If 'solutions'
-        is specified, it will contain the k best solutions found during the search
-        (from worst to best, including the one returned by this method), where k
-        corresponds to the 'number_of_solutions_to_collect' in
-        'search_parameters'. Note that the Assignment returned by the method and
-        the ones in solutions are owned by the underlying solver and should not be
-        deleted.
-        """
-        return _pywrapcp.RoutingModel_SolveWithParameters(self, search_parameters, solutions)
-
-    def SolveFromAssignmentWithParameters(self, assignment: "Assignment", search_parameters: "operations_research::RoutingSearchParameters const &", solutions: "std::vector< operations_research::Assignment const * > *"=None) -> "operations_research::Assignment const *":
-        r"""
-        Same as above, except that if assignment is not null, it will be used as
-        the initial solution.
-        """
-        return _pywrapcp.RoutingModel_SolveFromAssignmentWithParameters(self, assignment, search_parameters, solutions)
-
-    def SolveFromAssignmentsWithParameters(self, assignments: "std::vector< operations_research::Assignment const * > const &", search_parameters: "operations_research::RoutingSearchParameters const &", solutions: "std::vector< operations_research::Assignment const * > *"=None) -> "operations_research::Assignment const *":
-        r"""
-        Same as above but will try all assignments in order as first solutions
-        until one succeeds.
-        """
-        return _pywrapcp.RoutingModel_SolveFromAssignmentsWithParameters(self, assignments, search_parameters, solutions)
-
-    def SetAssignmentFromOtherModelAssignment(self, target_assignment: "Assignment", source_model: "RoutingModel", source_assignment: "Assignment") -> "void":
-        r"""
-        Given a "source_model" and its "source_assignment", resets
-        "target_assignment" with the IntVar variables (nexts_, and vehicle_vars_
-        if costs aren't homogeneous across vehicles) of "this" model, with the
-        values set according to those in "other_assignment".
-        The objective_element of target_assignment is set to this->cost_.
-        """
-        return _pywrapcp.RoutingModel_SetAssignmentFromOtherModelAssignment(self, target_assignment, source_model, source_assignment)
-
-    def ComputeLowerBound(self) -> "int64_t":
-        r"""
-        Computes a lower bound to the routing problem solving a linear assignment
-        problem. The routing model must be closed before calling this method.
-        Note that problems with node disjunction constraints (including optional
-        nodes) and non-homogenous costs are not supported (the method returns 0 in
-        these cases).
-        """
-        return _pywrapcp.RoutingModel_ComputeLowerBound(self)
-
-    def status(self) -> "operations_research::RoutingModel::Status":
-        r""" Returns the current status of the routing model."""
-        return _pywrapcp.RoutingModel_status(self)
-
-    def ApplyLocks(self, locks: "std::vector< int64_t > const &") -> "operations_research::IntVar *":
-        r"""
-        Applies a lock chain to the next search. 'locks' represents an ordered
-        vector of nodes representing a partial route which will be fixed during
-        the next search; it will constrain next variables such that:
-        next[locks[i]] == locks[i+1].
-
-        Returns the next variable at the end of the locked chain; this variable is
-        not locked. An assignment containing the locks can be obtained by calling
-        PreAssignment().
-        """
-        return _pywrapcp.RoutingModel_ApplyLocks(self, locks)
-
-    def ApplyLocksToAllVehicles(self, locks: "std::vector< std::vector< int64_t > > const &", close_routes: "bool") -> "bool":
-        r"""
-        Applies lock chains to all vehicles to the next search, such that locks[p]
-        is the lock chain for route p. Returns false if the locks do not contain
-        valid routes; expects that the routes do not contain the depots,
-        i.e. there are empty vectors in place of empty routes.
-        If close_routes is set to true, adds the end nodes to the route of each
-        vehicle and deactivates other nodes.
-        An assignment containing the locks can be obtained by calling
-        PreAssignment().
-        """
-        return _pywrapcp.RoutingModel_ApplyLocksToAllVehicles(self, locks, close_routes)
-
-    def PreAssignment(self) -> "operations_research::Assignment const *const":
-        r"""
-        Returns an assignment used to fix some of the variables of the problem.
-        In practice, this assignment locks partial routes of the problem. This
-        can be used in the context of locking the parts of the routes which have
-        already been driven in online routing problems.
-        """
-        return _pywrapcp.RoutingModel_PreAssignment(self)
-
-    def MutablePreAssignment(self) -> "operations_research::Assignment *":
-        return _pywrapcp.RoutingModel_MutablePreAssignment(self)
-
-    def WriteAssignment(self, file_name: "std::string const &") -> "bool":
-        r"""
-        Writes the current solution to a file containing an AssignmentProto.
-        Returns false if the file cannot be opened or if there is no current
-        solution.
-        """
-        return _pywrapcp.RoutingModel_WriteAssignment(self, file_name)
-
-    def ReadAssignment(self, file_name: "std::string const &") -> "operations_research::Assignment *":
-        r"""
-        Reads an assignment from a file and returns the current solution.
-        Returns nullptr if the file cannot be opened or if the assignment is not
-        valid.
-        """
-        return _pywrapcp.RoutingModel_ReadAssignment(self, file_name)
-
-    def RestoreAssignment(self, solution: "Assignment") -> "operations_research::Assignment *":
-        r"""
-        Restores an assignment as a solution in the routing model and returns the
-        new solution. Returns nullptr if the assignment is not valid.
-        """
-        return _pywrapcp.RoutingModel_RestoreAssignment(self, solution)
-
-    def ReadAssignmentFromRoutes(self, routes: "std::vector< std::vector< int64_t > > const &", ignore_inactive_indices: "bool") -> "operations_research::Assignment *":
-        r"""
-        Restores the routes as the current solution. Returns nullptr if the
-        solution cannot be restored (routes do not contain a valid solution). Note
-        that calling this method will run the solver to assign values to the
-        dimension variables; this may take considerable amount of time, especially
-        when using dimensions with slack.
-        """
-        return _pywrapcp.RoutingModel_ReadAssignmentFromRoutes(self, routes, ignore_inactive_indices)
-
-    def RoutesToAssignment(self, routes: "std::vector< std::vector< int64_t > > const &", ignore_inactive_indices: "bool", close_routes: "bool", assignment: "Assignment") -> "bool":
-        r"""
-        Fills an assignment from a specification of the routes of the
-        vehicles. The routes are specified as lists of variable indices that
-        appear on the routes of the vehicles. The indices of the outer vector in
-        'routes' correspond to vehicles IDs, the inner vector contains the
-        variable indices on the routes for the given vehicle. The inner vectors
-        must not contain the start and end indices, as these are determined by the
-        routing model.  Sets the value of NextVars in the assignment, adding the
-        variables to the assignment if necessary. The method does not touch other
-        variables in the assignment. The method can only be called after the model
-        is closed.  With ignore_inactive_indices set to false, this method will
-        fail (return nullptr) in case some of the route contain indices that are
-        deactivated in the model; when set to true, these indices will be
-        skipped.  Returns true if routes were successfully
-        loaded. However, such assignment still might not be a valid
-        solution to the routing problem due to more complex constraints;
-        it is advisible to call solver()->CheckSolution() afterwards.
-        """
-        return _pywrapcp.RoutingModel_RoutesToAssignment(self, routes, ignore_inactive_indices, close_routes, assignment)
-
-    def AssignmentToRoutes(self, assignment: "Assignment", routes: "std::vector< std::vector< int64_t > > *const") -> "void":
-        r"""
-        Converts the solution in the given assignment to routes for all vehicles.
-        Expects that assignment contains a valid solution (i.e. routes for all
-        vehicles end with an end index for that vehicle).
-        """
-        return _pywrapcp.RoutingModel_AssignmentToRoutes(self, assignment, routes)
-
-    def CompactAssignment(self, assignment: "Assignment") -> "operations_research::Assignment *":
-        r"""
-        Converts the solution in the given assignment to routes for all vehicles.
-        If the returned vector is route_indices, route_indices[i][j] is the index
-        for jth location visited on route i. Note that contrary to
-        AssignmentToRoutes, the vectors do include start and end locations.
-        Returns a compacted version of the given assignment, in which all vehicles
-        with id lower or equal to some N have non-empty routes, and all vehicles
-        with id greater than N have empty routes. Does not take ownership of the
-        returned object.
-        If found, the cost of the compact assignment is the same as in the
-        original assignment and it preserves the values of 'active' variables.
-        Returns nullptr if a compact assignment was not found.
-        This method only works in homogenous mode, and it only swaps equivalent
-        vehicles (vehicles with the same start and end nodes). When creating the
-        compact assignment, the empty plan is replaced by the route assigned to
-        the compatible vehicle with the highest id. Note that with more complex
-        constraints on vehicle variables, this method might fail even if a compact
-        solution exists.
-        This method changes the vehicle and dimension variables as necessary.
-        While compacting the solution, only basic checks on vehicle variables are
-        performed; if one of these checks fails no attempts to repair it are made
-        (instead, the method returns nullptr).
-        """
-        return _pywrapcp.RoutingModel_CompactAssignment(self, assignment)
-
-    def CompactAndCheckAssignment(self, assignment: "Assignment") -> "operations_research::Assignment *":
-        r"""
-        Same as CompactAssignment() but also checks the validity of the final
-        compact solution; if it is not valid, no attempts to repair it are made
-        (instead, the method returns nullptr).
-        """
-        return _pywrapcp.RoutingModel_CompactAndCheckAssignment(self, assignment)
-
-    def AddToAssignment(self, var: "IntVar") -> "void":
-        r""" Adds an extra variable to the vehicle routing assignment."""
-        return _pywrapcp.RoutingModel_AddToAssignment(self, var)
-
-    def AddIntervalToAssignment(self, interval: "IntervalVar") -> "void":
-        return _pywrapcp.RoutingModel_AddIntervalToAssignment(self, interval)
-
-    def PackCumulsOfOptimizerDimensionsFromAssignment(self, original_assignment: "Assignment", duration_limit: "absl::Duration") -> "operations_research::Assignment const *":
-        r"""
-        For every dimension in the model with an optimizer in
-        local/global_dimension_optimizers_, this method tries to pack the cumul
-        values of the dimension, such that:
-        - The cumul costs (span costs, soft lower and upper bound costs, etc) are
-          minimized.
-        - The cumuls of the ends of the routes are minimized for this given
-          minimal cumul cost.
-        - Given these minimal end cumuls, the route start cumuls are maximized.
-        Returns the assignment resulting from allocating these packed cumuls with
-        the solver, and nullptr if these cumuls could not be set by the solver.
-        """
-        return _pywrapcp.RoutingModel_PackCumulsOfOptimizerDimensionsFromAssignment(self, original_assignment, duration_limit)
-
-    def AddLocalSearchFilter(self, filter: "LocalSearchFilter") -> "void":
-        r"""
-        Adds a custom local search filter to the list of filters used to speed up
-        local search by pruning unfeasible variable assignments.
-        Calling this method after the routing model has been closed (CloseModel()
-        or Solve() has been called) has no effect.
-        The routing model does not take ownership of the filter.
-        """
-        return _pywrapcp.RoutingModel_AddLocalSearchFilter(self, filter)
-
-    def Start(self, vehicle: "int") -> "int64_t":
-        r"""
-        Model inspection.
-        Returns the variable index of the starting node of a vehicle route.
-        """
-        return _pywrapcp.RoutingModel_Start(self, vehicle)
-
-    def End(self, vehicle: "int") -> "int64_t":
-        r""" Returns the variable index of the ending node of a vehicle route."""
-        return _pywrapcp.RoutingModel_End(self, vehicle)
-
-    def IsStart(self, index: "int64_t") -> "bool":
-        r""" Returns true if 'index' represents the first node of a route."""
-        return _pywrapcp.RoutingModel_IsStart(self, index)
-
-    def IsEnd(self, index: "int64_t") -> "bool":
-        r""" Returns true if 'index' represents the last node of a route."""
-        return _pywrapcp.RoutingModel_IsEnd(self, index)
-
-    def VehicleIndex(self, index: "int64_t") -> "int":
-        r"""
-        Returns the vehicle of the given start/end index, and -1 if the given
-        index is not a vehicle start/end.
-        """
-        return _pywrapcp.RoutingModel_VehicleIndex(self, index)
-
-    def Next(self, assignment: "Assignment", index: "int64_t") -> "int64_t":
-        r"""
-        Assignment inspection
-        Returns the variable index of the node directly after the node
-        corresponding to 'index' in 'assignment'.
-        """
-        return _pywrapcp.RoutingModel_Next(self, assignment, index)
-
-    def IsVehicleUsed(self, assignment: "Assignment", vehicle: "int") -> "bool":
-        r""" Returns true if the route of 'vehicle' is non empty in 'assignment'."""
-        return _pywrapcp.RoutingModel_IsVehicleUsed(self, assignment, vehicle)
-
-    def NextVar(self, index: "int64_t") -> "operations_research::IntVar *":
-        r"""
-        Returns the next variable of the node corresponding to index. Note that
-        NextVar(index) == index is equivalent to ActiveVar(index) == 0.
-        """
-        return _pywrapcp.RoutingModel_NextVar(self, index)
-
-    def ActiveVar(self, index: "int64_t") -> "operations_research::IntVar *":
-        r""" Returns the active variable of the node corresponding to index."""
-        return _pywrapcp.RoutingModel_ActiveVar(self, index)
-
-    def ActiveVehicleVar(self, vehicle: "int") -> "operations_research::IntVar *":
-        r"""
-        Returns the active variable of the vehicle. It will be equal to 1 iff the
-        route of the vehicle is not empty, 0 otherwise.
-        """
-        return _pywrapcp.RoutingModel_ActiveVehicleVar(self, vehicle)
-
-    def VehicleCostsConsideredVar(self, vehicle: "int") -> "operations_research::IntVar *":
-        r"""
-        Returns the variable specifying whether or not costs are considered for
-        vehicle.
-        """
-        return _pywrapcp.RoutingModel_VehicleCostsConsideredVar(self, vehicle)
-
-    def VehicleVar(self, index: "int64_t") -> "operations_research::IntVar *":
-        r"""
-        Returns the vehicle variable of the node corresponding to index. Note that
-        VehicleVar(index) == -1 is equivalent to ActiveVar(index) == 0.
-        """
-        return _pywrapcp.RoutingModel_VehicleVar(self, index)
-
-    def CostVar(self) -> "operations_research::IntVar *":
-        r""" Returns the global cost variable which is being minimized."""
-        return _pywrapcp.RoutingModel_CostVar(self)
-
-    def GetArcCostForVehicle(self, from_index: "int64_t", to_index: "int64_t", vehicle: "int64_t") -> "int64_t":
-        r"""
-        Returns the cost of the transit arc between two nodes for a given vehicle.
-        Input are variable indices of node. This returns 0 if vehicle < 0.
-        """
-        return _pywrapcp.RoutingModel_GetArcCostForVehicle(self, from_index, to_index, vehicle)
-
-    def CostsAreHomogeneousAcrossVehicles(self) -> "bool":
-        r""" Whether costs are homogeneous across all vehicles."""
-        return _pywrapcp.RoutingModel_CostsAreHomogeneousAcrossVehicles(self)
-
-    def GetHomogeneousCost(self, from_index: "int64_t", to_index: "int64_t") -> "int64_t":
-        r"""
-        Returns the cost of the segment between two nodes supposing all vehicle
-        costs are the same (returns the cost for the first vehicle otherwise).
-        """
-        return _pywrapcp.RoutingModel_GetHomogeneousCost(self, from_index, to_index)
-
-    def GetArcCostForFirstSolution(self, from_index: "int64_t", to_index: "int64_t") -> "int64_t":
-        r"""
-        Returns the cost of the arc in the context of the first solution strategy.
-        This is typically a simplification of the actual cost; see the .cc.
-        """
-        return _pywrapcp.RoutingModel_GetArcCostForFirstSolution(self, from_index, to_index)
-
-    def GetArcCostForClass(self, from_index: "int64_t", to_index: "int64_t", cost_class_index: "int64_t") -> "int64_t":
-        r"""
-        Returns the cost of the segment between two nodes for a given cost
-        class. Input are variable indices of nodes and the cost class.
-        Unlike GetArcCostForVehicle(), if cost_class is kNoCost, then the
-        returned cost won't necessarily be zero: only some of the components
-        of the cost that depend on the cost class will be omited. See the code
-        for details.
-        """
-        return _pywrapcp.RoutingModel_GetArcCostForClass(self, from_index, to_index, cost_class_index)
-
-    def GetCostClassIndexOfVehicle(self, vehicle: "int64_t") -> "operations_research::RoutingModel::CostClassIndex":
-        r""" Get the cost class index of the given vehicle."""
-        return _pywrapcp.RoutingModel_GetCostClassIndexOfVehicle(self, vehicle)
-
-    def HasVehicleWithCostClassIndex(self, cost_class_index: "operations_research::RoutingModel::CostClassIndex") -> "bool":
-        r"""
-        Returns true iff the model contains a vehicle with the given
-        cost_class_index.
-        """
-        return _pywrapcp.RoutingModel_HasVehicleWithCostClassIndex(self, cost_class_index)
-
-    def GetCostClassesCount(self) -> "int":
-        r""" Returns the number of different cost classes in the model."""
-        return _pywrapcp.RoutingModel_GetCostClassesCount(self)
-
-    def GetNonZeroCostClassesCount(self) -> "int":
-        r""" Ditto, minus the 'always zero', built-in cost class."""
-        return _pywrapcp.RoutingModel_GetNonZeroCostClassesCount(self)
-
-    def GetVehicleClassIndexOfVehicle(self, vehicle: "int64_t") -> "operations_research::RoutingModel::VehicleClassIndex":
-        return _pywrapcp.RoutingModel_GetVehicleClassIndexOfVehicle(self, vehicle)
-
-    def GetVehicleClassesCount(self) -> "int":
-        r""" Returns the number of different vehicle classes in the model."""
-        return _pywrapcp.RoutingModel_GetVehicleClassesCount(self)
-
-    def GetSameVehicleIndicesOfIndex(self, node: "int") -> "std::vector< int > const &":
-        r""" Returns variable indices of nodes constrained to be on the same route."""
-        return _pywrapcp.RoutingModel_GetSameVehicleIndicesOfIndex(self, node)
-
-    def GetVehicleTypeContainer(self) -> "operations_research::RoutingModel::VehicleTypeContainer const &":
-        return _pywrapcp.RoutingModel_GetVehicleTypeContainer(self)
-
-    def ArcIsMoreConstrainedThanArc(self, _from: "int64_t", to1: "int64_t", to2: "int64_t") -> "bool":
-        r"""
-        Returns whether the arc from->to1 is more constrained than from->to2,
-        taking into account, in order:
-        - whether the destination node isn't an end node
-        - whether the destination node is mandatory
-        - whether the destination node is bound to the same vehicle as the source
-        - the "primary constrained" dimension (see SetPrimaryConstrainedDimension)
-        It then breaks ties using, in order:
-        - the arc cost (taking unperformed penalties into account)
-        - the size of the vehicle vars of "to1" and "to2" (lowest size wins)
-        - the value: the lowest value of the indices to1 and to2 wins.
-        See the .cc for details.
-        The more constrained arc is typically preferable when building a
-        first solution. This method is intended to be used as a callback for the
-        BestValueByComparisonSelector value selector.
-        Args:
-          from: the variable index of the source node
-          to1: the variable index of the first candidate destination node.
-          to2: the variable index of the second candidate destination node.
-        """
-        return _pywrapcp.RoutingModel_ArcIsMoreConstrainedThanArc(self, _from, to1, to2)
-
-    def DebugOutputAssignment(self, solution_assignment: "Assignment", dimension_to_print: "std::string const &") -> "std::string":
-        r"""
-        Print some debugging information about an assignment, including the
-        feasible intervals of the CumulVar for dimension "dimension_to_print"
-        at each step of the routes.
-        If "dimension_to_print" is omitted, all dimensions will be printed.
-        """
-        return _pywrapcp.RoutingModel_DebugOutputAssignment(self, solution_assignment, dimension_to_print)
-
-    def solver(self) -> "operations_research::Solver *":
-        r"""
-        Returns a vector cumul_bounds, for which cumul_bounds[i][j] is a pair
-        containing the minimum and maximum of the CumulVar of the jth node on
-        route i.
-        - cumul_bounds[i][j].first is the minimum.
-        - cumul_bounds[i][j].second is the maximum.
-        Returns the underlying constraint solver. Can be used to add extra
-        constraints and/or modify search algoithms.
-        """
-        return _pywrapcp.RoutingModel_solver(self)
-
-    def CheckLimit(self) -> "bool":
-        r""" Returns true if the search limit has been crossed."""
-        return _pywrapcp.RoutingModel_CheckLimit(self)
-
-    def RemainingTime(self) -> "absl::Duration":
-        r""" Returns the time left in the search limit."""
-        return _pywrapcp.RoutingModel_RemainingTime(self)
-
-    def nodes(self) -> "int":
-        r"""
-        Sizes and indices
-        Returns the number of nodes in the model.
-        """
-        return _pywrapcp.RoutingModel_nodes(self)
-
-    def vehicles(self) -> "int":
-        r""" Returns the number of vehicle routes in the model."""
-        return _pywrapcp.RoutingModel_vehicles(self)
-
-    def Size(self) -> "int64_t":
-        r""" Returns the number of next variables in the model."""
-        return _pywrapcp.RoutingModel_Size(self)
-
-    def GetNumberOfDecisionsInFirstSolution(self, search_parameters: "operations_research::RoutingSearchParameters const &") -> "int64_t":
-        r"""
-        Returns statistics on first solution search, number of decisions sent to
-        filters, number of decisions rejected by filters.
-        """
-        return _pywrapcp.RoutingModel_GetNumberOfDecisionsInFirstSolution(self, search_parameters)
-
-    def GetNumberOfRejectsInFirstSolution(self, search_parameters: "operations_research::RoutingSearchParameters const &") -> "int64_t":
-        return _pywrapcp.RoutingModel_GetNumberOfRejectsInFirstSolution(self, search_parameters)
-
-    def GetAutomaticFirstSolutionStrategy(self) -> "operations_research::FirstSolutionStrategy::Value":
-        r""" Returns the automatic first solution strategy selected."""
-        return _pywrapcp.RoutingModel_GetAutomaticFirstSolutionStrategy(self)
-
-    def IsMatchingModel(self) -> "bool":
-        r""" Returns true if a vehicle/node matching problem is detected."""
-        return _pywrapcp.RoutingModel_IsMatchingModel(self)
-
-    def MakeGuidedSlackFinalizer(self, dimension: "RoutingDimension", initializer: "std::function< int64_t (int64_t) >") -> "operations_research::DecisionBuilder *":
-        r"""
-        The next few members are in the public section only for testing purposes.
-
-        MakeGuidedSlackFinalizer creates a DecisionBuilder for the slacks of a
-        dimension using a callback to choose which values to start with.
-        The finalizer works only when all next variables in the model have
-        been fixed. It has the following two characteristics:
-        1. It follows the routes defined by the nexts variables when choosing a
-           variable to make a decision on.
-        2. When it comes to choose a value for the slack of node i, the decision
-           builder first calls the callback with argument i, and supposingly the
-           returned value is x it creates decisions slack[i] = x, slack[i] = x +
-           1, slack[i] = x - 1, slack[i] = x + 2, etc.
-        """
-        return _pywrapcp.RoutingModel_MakeGuidedSlackFinalizer(self, dimension, initializer)
-
-    def MakeSelfDependentDimensionFinalizer(self, dimension: "RoutingDimension") -> "operations_research::DecisionBuilder *":
-        r"""
-        MakeSelfDependentDimensionFinalizer is a finalizer for the slacks of a
-        self-dependent dimension. It makes an extensive use of the caches of the
-        state dependent transits.
-        In detail, MakeSelfDependentDimensionFinalizer returns a composition of a
-        local search decision builder with a greedy descent operator for the cumul
-        of the start of each route and a guided slack finalizer. Provided there
-        are no time windows and the maximum slacks are large enough, once the
-        cumul of the start of route is fixed, the guided finalizer can find
-        optimal values of the slacks for the rest of the route in time
-        proportional to the length of the route. Therefore the composed finalizer
-        generally works in time O(log(t)*n*m), where t is the latest possible
-        departute time, n is the number of nodes in the network and m is the
-        number of vehicles.
-        """
-        return _pywrapcp.RoutingModel_MakeSelfDependentDimensionFinalizer(self, dimension)
-
-

Class variables

-
-
var ADDED_TYPE_REMOVED_FROM_VEHICLE
-
-

When visited, one instance of type 'T' previously added to the route -(TYPE_ADDED_TO_VEHICLE), if any, is removed from the vehicle. -If the type was not previously added to the route or all added instances -have already been removed, this visit has no effect on the types.

-
-
var PICKUP_AND_DELIVERY_FIFO
-
-

Deliveries must be performed in the same order as pickups.

-
-
var PICKUP_AND_DELIVERY_LIFO
-
-

Deliveries must be performed in reverse order of pickups.

-
-
var PICKUP_AND_DELIVERY_NO_ORDER
-
-

Any precedence is accepted.

-
-
var ROUTING_FAIL
-
-

No solution found to the problem after calling RoutingModel::Solve().

-
-
var ROUTING_FAIL_TIMEOUT
-
-

Time limit reached before finding a solution with RoutingModel::Solve().

-
-
var ROUTING_INVALID
-
-

Model, model parameters or flags are not valid.

-
-
var ROUTING_NOT_SOLVED
-
-

Problem not solved yet (before calling RoutingModel::Solve()).

-
-
var ROUTING_SUCCESS
-
-

Problem solved successfully after calling RoutingModel::Solve().

-
-
var TYPE_ADDED_TO_VEHICLE
-
-

When visited, the number of types 'T' on the vehicle increases by one.

-
-
var TYPE_ON_VEHICLE_UP_TO_VISIT
-
-

With the following policy, the visit enforces that type 'T' is -considered on the route from its start until this node is visited.

-
-
var TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED
-
-

The visit doesn't have an impact on the number of types 'T' on the -route, as it's (virtually) added and removed directly. -This policy can be used for visits which are part of an incompatibility -or requirement set without affecting the type count on the route.

-
-
var kNoDimension
-
-
-
-
var kNoDisjunction
-
-
-
-
var kNoPenalty
-
-
-
-
-

Instance variables

-
-
var thisown
-
-

The membership flag

-
- -Expand source code - -
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-
-
-

Methods

-
-
-def ActiveVar(self, index: int64_t) ‑> operations_research::IntVar * -
-
-

Returns the active variable of the node corresponding to index.

-
- -Expand source code - -
def ActiveVar(self, index: "int64_t") -> "operations_research::IntVar *":
-    r""" Returns the active variable of the node corresponding to index."""
-    return _pywrapcp.RoutingModel_ActiveVar(self, index)
-
-
-
-def ActiveVehicleVar(self, vehicle: int) ‑> operations_research::IntVar * -
-
-

Returns the active variable of the vehicle. It will be equal to 1 iff the -route of the vehicle is not empty, 0 otherwise.

-
- -Expand source code - -
def ActiveVehicleVar(self, vehicle: "int") -> "operations_research::IntVar *":
-    r"""
-    Returns the active variable of the vehicle. It will be equal to 1 iff the
-    route of the vehicle is not empty, 0 otherwise.
-    """
-    return _pywrapcp.RoutingModel_ActiveVehicleVar(self, vehicle)
-
-
-
-def AddAtSolutionCallback(self, callback: std::function< void () >) ‑> void -
-
-

Adds a callback called each time a solution is found during the search. -This is a shortcut to creating a monitor to call the callback on -AtSolution() and adding it with AddSearchMonitor.

-
- -Expand source code - -
def AddAtSolutionCallback(self, callback: "std::function< void () >") -> "void":
-    r"""
-    Adds a callback called each time a solution is found during the search.
-    This is a shortcut to creating a monitor to call the callback on
-    AtSolution() and adding it with AddSearchMonitor.
-    """
-    return _pywrapcp.RoutingModel_AddAtSolutionCallback(self, callback)
-
-
-
-def AddConstantDimension(self, value: int64_t, capacity: int64_t, fix_start_cumul_to_zero: bool, name: std::string const &) ‑> std::pair< int,bool > -
-
-
-
- -Expand source code - -
def AddConstantDimension(self, value: "int64_t", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
-    return _pywrapcp.RoutingModel_AddConstantDimension(self, value, capacity, fix_start_cumul_to_zero, name)
-
-
-
-def AddConstantDimensionWithSlack(self, value: int64_t, capacity: int64_t, slack_max: int64_t, fix_start_cumul_to_zero: bool, name: std::string const &) ‑> std::pair< int,bool > -
-
-

Creates a dimension where the transit variable is constrained to be -equal to 'value'; 'capacity' is the upper bound of the cumul variables. -'name' is the name used to reference the dimension; this name is used to -get cumul and transit variables from the routing model. -Returns a pair consisting of an index to the registered unary transit -callback and a bool denoting whether the dimension has been created. -It is false if a dimension with the same name has already been created -(and doesn't create the new dimension but still register a new callback).

-
- -Expand source code - -
def AddConstantDimensionWithSlack(self, value: "int64_t", capacity: "int64_t", slack_max: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
-    r"""
-    Creates a dimension where the transit variable is constrained to be
-    equal to 'value'; 'capacity' is the upper bound of the cumul variables.
-    'name' is the name used to reference the dimension; this name is used to
-    get cumul and transit variables from the routing model.
-    Returns a pair consisting of an index to the registered unary transit
-    callback and a bool denoting whether the dimension has been created.
-    It is false if a dimension with the same name has already been created
-    (and doesn't create the new dimension but still register a new callback).
-    """
-    return _pywrapcp.RoutingModel_AddConstantDimensionWithSlack(self, value, capacity, slack_max, fix_start_cumul_to_zero, name)
-
-
-
-def AddDimension(self, evaluator_index: int, slack_max: int64_t, capacity: int64_t, fix_start_cumul_to_zero: bool, name: std::string const &) ‑> bool -
-
-

Model creation -Methods to add dimensions to routes; dimensions represent quantities -accumulated at nodes along the routes. They represent quantities such as -weights or volumes carried along the route, or distance or times. -Quantities at a node are represented by "cumul" variables and the increase -or decrease of quantities between nodes are represented by "transit" -variables. These variables are linked as follows: -if j == next(i), cumul(j) = cumul(i) + transit(i) + slack(i) -where slack is a positive slack variable (can represent waiting times for -a time dimension). -Setting the value of fix_start_cumul_to_zero to true will force the -"cumul" variable of the start node of all vehicles to be equal to 0. -Creates a dimension where the transit variable is constrained to be -equal to evaluator(i, next(i)); 'slack_max' is the upper bound of the -slack variable and 'capacity' is the upper bound of the cumul variables. -'name' is the name used to reference the dimension; this name is used to -get cumul and transit variables from the routing model. -Returns false if a dimension with the same name has already been created -(and doesn't create the new dimension). -Takes ownership of the callback 'evaluator'.

-
- -Expand source code - -
def AddDimension(self, evaluator_index: "int", slack_max: "int64_t", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
-    r"""
-    Model creation
-    Methods to add dimensions to routes; dimensions represent quantities
-    accumulated at nodes along the routes. They represent quantities such as
-    weights or volumes carried along the route, or distance or times.
-    Quantities at a node are represented by "cumul" variables and the increase
-    or decrease of quantities between nodes are represented by "transit"
-    variables. These variables are linked as follows:
-    if j == next(i), cumul(j) = cumul(i) + transit(i) + slack(i)
-    where slack is a positive slack variable (can represent waiting times for
-    a time dimension).
-    Setting the value of fix_start_cumul_to_zero to true will force the
-    "cumul" variable of the start node of all vehicles to be equal to 0.
-    Creates a dimension where the transit variable is constrained to be
-    equal to evaluator(i, next(i)); 'slack_max' is the upper bound of the
-    slack variable and 'capacity' is the upper bound of the cumul variables.
-    'name' is the name used to reference the dimension; this name is used to
-    get cumul and transit variables from the routing model.
-    Returns false if a dimension with the same name has already been created
-    (and doesn't create the new dimension).
-    Takes ownership of the callback 'evaluator'.
-    """
-    return _pywrapcp.RoutingModel_AddDimension(self, evaluator_index, slack_max, capacity, fix_start_cumul_to_zero, name)
-
-
-
-def AddDimensionWithVehicleCapacity(self, evaluator_index: int, slack_max: int64_t, vehicle_capacities: std::vector< int64_t >, fix_start_cumul_to_zero: bool, name: std::string const &) ‑> bool -
-
-
-
- -Expand source code - -
def AddDimensionWithVehicleCapacity(self, evaluator_index: "int", slack_max: "int64_t", vehicle_capacities: "std::vector< int64_t >", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
-    return _pywrapcp.RoutingModel_AddDimensionWithVehicleCapacity(self, evaluator_index, slack_max, vehicle_capacities, fix_start_cumul_to_zero, name)
-
-
-
-def AddDimensionWithVehicleTransitAndCapacity(self, evaluator_indices: std::vector< int > const &, slack_max: int64_t, vehicle_capacities: std::vector< int64_t >, fix_start_cumul_to_zero: bool, name: std::string const &) ‑> bool -
-
-
-
- -Expand source code - -
def AddDimensionWithVehicleTransitAndCapacity(self, evaluator_indices: "std::vector< int > const &", slack_max: "int64_t", vehicle_capacities: "std::vector< int64_t >", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
-    return _pywrapcp.RoutingModel_AddDimensionWithVehicleTransitAndCapacity(self, evaluator_indices, slack_max, vehicle_capacities, fix_start_cumul_to_zero, name)
-
-
-
-def AddDimensionWithVehicleTransits(self, evaluator_indices: std::vector< int > const &, slack_max: int64_t, capacity: int64_t, fix_start_cumul_to_zero: bool, name: std::string const &) ‑> bool -
-
-
-
- -Expand source code - -
def AddDimensionWithVehicleTransits(self, evaluator_indices: "std::vector< int > const &", slack_max: "int64_t", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
-    return _pywrapcp.RoutingModel_AddDimensionWithVehicleTransits(self, evaluator_indices, slack_max, capacity, fix_start_cumul_to_zero, name)
-
-
-
-def AddDisjunction(self, *args) ‑> operations_research::RoutingModel::DisjunctionIndex -
-
-

Adds a disjunction constraint on the indices: exactly 'max_cardinality' of -the indices are active. Start and end indices of any vehicle cannot be -part of a disjunction.

-

If a penalty is given, at most 'max_cardinality' of the indices can be -active, and if less are active, 'penalty' is payed per inactive index. -This is equivalent to adding the constraint: -p + Sum(i)active[i] == max_cardinality -where p is an integer variable, and the following cost to the cost -function: -p * penalty. -'penalty' must be positive to make the disjunction optional; a negative -penalty will force 'max_cardinality' indices of the disjunction to be -performed, and therefore p == 0. -Note: passing a vector with a single index will model an optional index -with a penalty cost if it is not visited.

-
- -Expand source code - -
def AddDisjunction(self, *args) -> "operations_research::RoutingModel::DisjunctionIndex":
-    r"""
-    Adds a disjunction constraint on the indices: exactly 'max_cardinality' of
-    the indices are active. Start and end indices of any vehicle cannot be
-    part of a disjunction.
-
-    If a penalty is given, at most 'max_cardinality' of the indices can be
-    active, and if less are active, 'penalty' is payed per inactive index.
-    This is equivalent to adding the constraint:
-        p + Sum(i)active[i] == max_cardinality
-    where p is an integer variable, and the following cost to the cost
-    function:
-        p * penalty.
-    'penalty' must be positive to make the disjunction optional; a negative
-    penalty will force 'max_cardinality' indices of the disjunction to be
-    performed, and therefore p == 0.
-    Note: passing a vector with a single index will model an optional index
-    with a penalty cost if it is not visited.
-    """
-    return _pywrapcp.RoutingModel_AddDisjunction(self, *args)
-
-
-
-def AddHardTypeIncompatibility(self, type1: int, type2: int) ‑> void -
-
-

Incompatibilities: -Two nodes with "hard" incompatible types cannot share the same route at -all, while with a "temporal" incompatibility they can't be on the same -route at the same time.

-
- -Expand source code - -
def AddHardTypeIncompatibility(self, type1: "int", type2: "int") -> "void":
-    r"""
-    Incompatibilities:
-    Two nodes with "hard" incompatible types cannot share the same route at
-    all, while with a "temporal" incompatibility they can't be on the same
-    route at the same time.
-    """
-    return _pywrapcp.RoutingModel_AddHardTypeIncompatibility(self, type1, type2)
-
-
-
-def AddIntervalToAssignment(self, interval: IntervalVar) ‑> void -
-
-
-
- -Expand source code - -
def AddIntervalToAssignment(self, interval: "IntervalVar") -> "void":
-    return _pywrapcp.RoutingModel_AddIntervalToAssignment(self, interval)
-
-
-
-def AddLocalSearchFilter(self, filter: LocalSearchFilter) ‑> void -
-
-

Adds a custom local search filter to the list of filters used to speed up -local search by pruning unfeasible variable assignments. -Calling this method after the routing model has been closed (CloseModel() -or Solve() has been called) has no effect. -The routing model does not take ownership of the filter.

-
- -Expand source code - -
def AddLocalSearchFilter(self, filter: "LocalSearchFilter") -> "void":
-    r"""
-    Adds a custom local search filter to the list of filters used to speed up
-    local search by pruning unfeasible variable assignments.
-    Calling this method after the routing model has been closed (CloseModel()
-    or Solve() has been called) has no effect.
-    The routing model does not take ownership of the filter.
-    """
-    return _pywrapcp.RoutingModel_AddLocalSearchFilter(self, filter)
-
-
-
-def AddLocalSearchOperator(self, ls_operator: LocalSearchOperator) ‑> void -
-
-

Adds a local search operator to the set of operators used to solve the -vehicle routing problem.

-
- -Expand source code - -
def AddLocalSearchOperator(self, ls_operator: "LocalSearchOperator") -> "void":
-    r"""
-    Adds a local search operator to the set of operators used to solve the
-    vehicle routing problem.
-    """
-    return _pywrapcp.RoutingModel_AddLocalSearchOperator(self, ls_operator)
-
-
-
-def AddMatrixDimension(self, values: std::vector< std::vector< int64_t > >, capacity: int64_t, fix_start_cumul_to_zero: bool, name: std::string const &) ‑> std::pair< int,bool > -
-
-

Creates a dimension where the transit variable is constrained to be -equal to 'values[i][next(i)]' for node i; 'capacity' is the upper bound of -the cumul variables. 'name' is the name used to reference the dimension; -this name is used to get cumul and transit variables from the routing -model. -Returns a pair consisting of an index to the registered transit callback -and a bool denoting whether the dimension has been created. -It is false if a dimension with the same name has already been created -(and doesn't create the new dimension but still register a new callback).

-
- -Expand source code - -
def AddMatrixDimension(self, values: "std::vector< std::vector< int64_t > >", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
-    r"""
-    Creates a dimension where the transit variable is constrained to be
-    equal to 'values[i][next(i)]' for node i; 'capacity' is the upper bound of
-    the cumul variables. 'name' is the name used to reference the dimension;
-    this name is used to get cumul and transit variables from the routing
-    model.
-    Returns a pair consisting of an index to the registered transit callback
-    and a bool denoting whether the dimension has been created.
-    It is false if a dimension with the same name has already been created
-    (and doesn't create the new dimension but still register a new callback).
-    """
-    return _pywrapcp.RoutingModel_AddMatrixDimension(self, values, capacity, fix_start_cumul_to_zero, name)
-
-
-
-def AddPickupAndDelivery(self, pickup: int64_t, delivery: int64_t) ‑> void -
-
-

Notifies that index1 and index2 form a pair of nodes which should belong -to the same route. This methods helps the search find better solutions, -especially in the local search phase. -It should be called each time you have an equality constraint linking -the vehicle variables of two node (including for instance pickup and -delivery problems): -Solver* const solver = routing.solver(); -int64_t index1 = manager.NodeToIndex(node1); -int64_t index2 = manager.NodeToIndex(node2); -solver->AddConstraint(solver->MakeEquality( -routing.VehicleVar(index1), -routing.VehicleVar(index2))); -routing.AddPickupAndDelivery(index1, index2);

-
- -Expand source code - -
def AddPickupAndDelivery(self, pickup: "int64_t", delivery: "int64_t") -> "void":
-    r"""
-    Notifies that index1 and index2 form a pair of nodes which should belong
-    to the same route. This methods helps the search find better solutions,
-    especially in the local search phase.
-    It should be called each time you have an equality constraint linking
-    the vehicle variables of two node (including for instance pickup and
-    delivery problems):
-        Solver* const solver = routing.solver();
-        int64_t index1 = manager.NodeToIndex(node1);
-        int64_t index2 = manager.NodeToIndex(node2);
-        solver->AddConstraint(solver->MakeEquality(
-            routing.VehicleVar(index1),
-            routing.VehicleVar(index2)));
-        routing.AddPickupAndDelivery(index1, index2);
-    """
-    return _pywrapcp.RoutingModel_AddPickupAndDelivery(self, pickup, delivery)
-
-
-
-def AddPickupAndDeliverySets(self, pickup_disjunction: operations_research::RoutingModel::DisjunctionIndex, delivery_disjunction: operations_research::RoutingModel::DisjunctionIndex) ‑> void -
-
-

Same as AddPickupAndDelivery but notifying that the performed node from -the disjunction of index 'pickup_disjunction' is on the same route as the -performed node from the disjunction of index 'delivery_disjunction'.

-
- -Expand source code - -
def AddPickupAndDeliverySets(self, pickup_disjunction: "operations_research::RoutingModel::DisjunctionIndex", delivery_disjunction: "operations_research::RoutingModel::DisjunctionIndex") -> "void":
-    r"""
-    Same as AddPickupAndDelivery but notifying that the performed node from
-    the disjunction of index 'pickup_disjunction' is on the same route as the
-    performed node from the disjunction of index 'delivery_disjunction'.
-    """
-    return _pywrapcp.RoutingModel_AddPickupAndDeliverySets(self, pickup_disjunction, delivery_disjunction)
-
-
-
-def AddRequiredTypeAlternativesWhenAddingType(self, dependent_type: int, required_type_alternatives: absl::flat_hash_set< int >) ‑> void -
-
-

If type_D depends on type_R when adding type_D, any node_D of type_D and -VisitTypePolicy TYPE_ADDED_TO_VEHICLE or -TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED requires at least one type_R on its -vehicle at the time node_D is visited.

-
- -Expand source code - -
def AddRequiredTypeAlternativesWhenAddingType(self, dependent_type: "int", required_type_alternatives: "absl::flat_hash_set< int >") -> "void":
-    r"""
-    If type_D depends on type_R when adding type_D, any node_D of type_D and
-    VisitTypePolicy TYPE_ADDED_TO_VEHICLE or
-    TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED requires at least one type_R on its
-    vehicle at the time node_D is visited.
-    """
-    return _pywrapcp.RoutingModel_AddRequiredTypeAlternativesWhenAddingType(self, dependent_type, required_type_alternatives)
-
-
-
-def AddRequiredTypeAlternativesWhenRemovingType(self, dependent_type: int, required_type_alternatives: absl::flat_hash_set< int >) ‑> void -
-
-

The following requirements apply when visiting dependent nodes that remove -their type from the route, i.e. type_R must be on the vehicle when type_D -of VisitTypePolicy ADDED_TYPE_REMOVED_FROM_VEHICLE, -TYPE_ON_VEHICLE_UP_TO_VISIT or TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED is -visited.

-
- -Expand source code - -
def AddRequiredTypeAlternativesWhenRemovingType(self, dependent_type: "int", required_type_alternatives: "absl::flat_hash_set< int >") -> "void":
-    r"""
-    The following requirements apply when visiting dependent nodes that remove
-    their type from the route, i.e. type_R must be on the vehicle when type_D
-    of VisitTypePolicy ADDED_TYPE_REMOVED_FROM_VEHICLE,
-    TYPE_ON_VEHICLE_UP_TO_VISIT or TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED is
-    visited.
-    """
-    return _pywrapcp.RoutingModel_AddRequiredTypeAlternativesWhenRemovingType(self, dependent_type, required_type_alternatives)
-
-
-
-def AddSameVehicleRequiredTypeAlternatives(self, dependent_type: int, required_type_alternatives: absl::flat_hash_set< int >) ‑> void -
-
-

Requirements: -NOTE: As of 2019-04, cycles in the requirement graph are not supported, -and lead to the dependent nodes being skipped if possible (otherwise -the model is considered infeasible). -The following functions specify that "dependent_type" requires at least -one of the types in "required_type_alternatives".

-

For same-vehicle requirements, a node of dependent type type_D requires at -least one node of type type_R among the required alternatives on the same -route.

-
- -Expand source code - -
def AddSameVehicleRequiredTypeAlternatives(self, dependent_type: "int", required_type_alternatives: "absl::flat_hash_set< int >") -> "void":
-    r"""
-    Requirements:
-    NOTE: As of 2019-04, cycles in the requirement graph are not supported,
-    and lead to the dependent nodes being skipped if possible (otherwise
-    the model is considered infeasible).
-    The following functions specify that "dependent_type" requires at least
-    one of the types in "required_type_alternatives".
-
-    For same-vehicle requirements, a node of dependent type type_D requires at
-    least one node of type type_R among the required alternatives on the same
-    route.
-    """
-    return _pywrapcp.RoutingModel_AddSameVehicleRequiredTypeAlternatives(self, dependent_type, required_type_alternatives)
-
-
-
-def AddSearchMonitor(self, monitor: SearchMonitor) ‑> void -
-
-

Adds a search monitor to the search used to solve the routing model.

-
- -Expand source code - -
def AddSearchMonitor(self, monitor: "SearchMonitor") -> "void":
-    r""" Adds a search monitor to the search used to solve the routing model."""
-    return _pywrapcp.RoutingModel_AddSearchMonitor(self, monitor)
-
-
-
-def AddSoftSameVehicleConstraint(self, indices: std::vector< int64_t > const &, cost: int64_t) ‑> void -
-
-

Adds a soft constraint to force a set of variable indices to be on the -same vehicle. If all nodes are not on the same vehicle, each extra vehicle -used adds 'cost' to the cost function.

-
- -Expand source code - -
def AddSoftSameVehicleConstraint(self, indices: "std::vector< int64_t > const &", cost: "int64_t") -> "void":
-    r"""
-    Adds a soft constraint to force a set of variable indices to be on the
-    same vehicle. If all nodes are not on the same vehicle, each extra vehicle
-    used adds 'cost' to the cost function.
-    """
-    return _pywrapcp.RoutingModel_AddSoftSameVehicleConstraint(self, indices, cost)
-
-
-
-def AddTemporalTypeIncompatibility(self, type1: int, type2: int) ‑> void -
-
-
-
- -Expand source code - -
def AddTemporalTypeIncompatibility(self, type1: "int", type2: "int") -> "void":
-    return _pywrapcp.RoutingModel_AddTemporalTypeIncompatibility(self, type1, type2)
-
-
-
-def AddToAssignment(self, var: IntVar) ‑> void -
-
-

Adds an extra variable to the vehicle routing assignment.

-
- -Expand source code - -
def AddToAssignment(self, var: "IntVar") -> "void":
-    r""" Adds an extra variable to the vehicle routing assignment."""
-    return _pywrapcp.RoutingModel_AddToAssignment(self, var)
-
-
-
-def AddVariableMaximizedByFinalizer(self, var: IntVar) ‑> void -
-
-

Adds a variable to maximize in the solution finalizer (see above for -information on the solution finalizer).

-
- -Expand source code - -
def AddVariableMaximizedByFinalizer(self, var: "IntVar") -> "void":
-    r"""
-    Adds a variable to maximize in the solution finalizer (see above for
-    information on the solution finalizer).
-    """
-    return _pywrapcp.RoutingModel_AddVariableMaximizedByFinalizer(self, var)
-
-
-
-def AddVariableMinimizedByFinalizer(self, var: IntVar) ‑> void -
-
-

Adds a variable to minimize in the solution finalizer. The solution -finalizer is called each time a solution is found during the search and -allows to instantiate secondary variables (such as dimension cumul -variables).

-
- -Expand source code - -
def AddVariableMinimizedByFinalizer(self, var: "IntVar") -> "void":
-    r"""
-    Adds a variable to minimize in the solution finalizer. The solution
-    finalizer is called each time a solution is found during the search and
-    allows to instantiate secondary variables (such as dimension cumul
-    variables).
-    """
-    return _pywrapcp.RoutingModel_AddVariableMinimizedByFinalizer(self, var)
-
-
-
-def AddVariableTargetToFinalizer(self, var: IntVar, target: int64_t) ‑> void -
-
-

Add a variable to set the closest possible to the target value in the -solution finalizer.

-
- -Expand source code - -
def AddVariableTargetToFinalizer(self, var: "IntVar", target: "int64_t") -> "void":
-    r"""
-    Add a variable to set the closest possible to the target value in the
-    solution finalizer.
-    """
-    return _pywrapcp.RoutingModel_AddVariableTargetToFinalizer(self, var, target)
-
-
-
-def AddVectorDimension(self, values: std::vector< int64_t >, capacity: int64_t, fix_start_cumul_to_zero: bool, name: std::string const &) ‑> std::pair< int,bool > -
-
-

Creates a dimension where the transit variable is constrained to be -equal to 'values[i]' for node i; 'capacity' is the upper bound of -the cumul variables. 'name' is the name used to reference the dimension; -this name is used to get cumul and transit variables from the routing -model. -Returns a pair consisting of an index to the registered unary transit -callback and a bool denoting whether the dimension has been created. -It is false if a dimension with the same name has already been created -(and doesn't create the new dimension but still register a new callback).

-
- -Expand source code - -
def AddVectorDimension(self, values: "std::vector< int64_t >", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
-    r"""
-    Creates a dimension where the transit variable is constrained to be
-    equal to 'values[i]' for node i; 'capacity' is the upper bound of
-    the cumul variables. 'name' is the name used to reference the dimension;
-    this name is used to get cumul and transit variables from the routing
-    model.
-    Returns a pair consisting of an index to the registered unary transit
-    callback and a bool denoting whether the dimension has been created.
-    It is false if a dimension with the same name has already been created
-    (and doesn't create the new dimension but still register a new callback).
-    """
-    return _pywrapcp.RoutingModel_AddVectorDimension(self, values, capacity, fix_start_cumul_to_zero, name)
-
-
-
-def AddWeightedVariableMinimizedByFinalizer(self, var: IntVar, cost: int64_t) ‑> void -
-
-

Adds a variable to minimize in the solution finalizer, with a weighted -priority: the higher the more priority it has.

-
- -Expand source code - -
def AddWeightedVariableMinimizedByFinalizer(self, var: "IntVar", cost: "int64_t") -> "void":
-    r"""
-    Adds a variable to minimize in the solution finalizer, with a weighted
-    priority: the higher the more priority it has.
-    """
-    return _pywrapcp.RoutingModel_AddWeightedVariableMinimizedByFinalizer(self, var, cost)
-
-
-
-def ApplyLocks(self, locks: std::vector< int64_t > const &) ‑> operations_research::IntVar * -
-
-

Applies a lock chain to the next search. 'locks' represents an ordered -vector of nodes representing a partial route which will be fixed during -the next search; it will constrain next variables such that: -next[locks[i]] == locks[i+1].

-

Returns the next variable at the end of the locked chain; this variable is -not locked. An assignment containing the locks can be obtained by calling -PreAssignment().

-
- -Expand source code - -
def ApplyLocks(self, locks: "std::vector< int64_t > const &") -> "operations_research::IntVar *":
-    r"""
-    Applies a lock chain to the next search. 'locks' represents an ordered
-    vector of nodes representing a partial route which will be fixed during
-    the next search; it will constrain next variables such that:
-    next[locks[i]] == locks[i+1].
-
-    Returns the next variable at the end of the locked chain; this variable is
-    not locked. An assignment containing the locks can be obtained by calling
-    PreAssignment().
-    """
-    return _pywrapcp.RoutingModel_ApplyLocks(self, locks)
-
-
-
-def ApplyLocksToAllVehicles(self, locks: std::vector< std::vector< int64_t > > const &, close_routes: bool) ‑> bool -
-
-

Applies lock chains to all vehicles to the next search, such that locks[p] -is the lock chain for route p. Returns false if the locks do not contain -valid routes; expects that the routes do not contain the depots, -i.e. there are empty vectors in place of empty routes. -If close_routes is set to true, adds the end nodes to the route of each -vehicle and deactivates other nodes. -An assignment containing the locks can be obtained by calling -PreAssignment().

-
- -Expand source code - -
def ApplyLocksToAllVehicles(self, locks: "std::vector< std::vector< int64_t > > const &", close_routes: "bool") -> "bool":
-    r"""
-    Applies lock chains to all vehicles to the next search, such that locks[p]
-    is the lock chain for route p. Returns false if the locks do not contain
-    valid routes; expects that the routes do not contain the depots,
-    i.e. there are empty vectors in place of empty routes.
-    If close_routes is set to true, adds the end nodes to the route of each
-    vehicle and deactivates other nodes.
-    An assignment containing the locks can be obtained by calling
-    PreAssignment().
-    """
-    return _pywrapcp.RoutingModel_ApplyLocksToAllVehicles(self, locks, close_routes)
-
-
-
-def ArcIsMoreConstrainedThanArc(self, _from: int64_t, to1: int64_t, to2: int64_t) ‑> bool -
-
-

Returns whether the arc from->to1 is more constrained than from->to2, -taking into account, in order: -- whether the destination node isn't an end node -- whether the destination node is mandatory -- whether the destination node is bound to the same vehicle as the source -- the "primary constrained" dimension (see SetPrimaryConstrainedDimension) -It then breaks ties using, in order: -- the arc cost (taking unperformed penalties into account) -- the size of the vehicle vars of "to1" and "to2" (lowest size wins) -- the value: the lowest value of the indices to1 and to2 wins. -See the .cc for details. -The more constrained arc is typically preferable when building a -first solution. This method is intended to be used as a callback for the -BestValueByComparisonSelector value selector.

-

Args

-
-
from
-
the variable index of the source node
-
to1
-
the variable index of the first candidate destination node.
-
to2
-
the variable index of the second candidate destination node.
-
-
- -Expand source code - -
def ArcIsMoreConstrainedThanArc(self, _from: "int64_t", to1: "int64_t", to2: "int64_t") -> "bool":
-    r"""
-    Returns whether the arc from->to1 is more constrained than from->to2,
-    taking into account, in order:
-    - whether the destination node isn't an end node
-    - whether the destination node is mandatory
-    - whether the destination node is bound to the same vehicle as the source
-    - the "primary constrained" dimension (see SetPrimaryConstrainedDimension)
-    It then breaks ties using, in order:
-    - the arc cost (taking unperformed penalties into account)
-    - the size of the vehicle vars of "to1" and "to2" (lowest size wins)
-    - the value: the lowest value of the indices to1 and to2 wins.
-    See the .cc for details.
-    The more constrained arc is typically preferable when building a
-    first solution. This method is intended to be used as a callback for the
-    BestValueByComparisonSelector value selector.
-    Args:
-      from: the variable index of the source node
-      to1: the variable index of the first candidate destination node.
-      to2: the variable index of the second candidate destination node.
-    """
-    return _pywrapcp.RoutingModel_ArcIsMoreConstrainedThanArc(self, _from, to1, to2)
-
-
-
-def AreEmptyRouteCostsConsideredForVehicle(self, vehicle: int) ‑> bool -
-
-
-
- -Expand source code - -
def AreEmptyRouteCostsConsideredForVehicle(self, vehicle: "int") -> "bool":
-    return _pywrapcp.RoutingModel_AreEmptyRouteCostsConsideredForVehicle(self, vehicle)
-
-
-
-def AssignmentToRoutes(self, assignment: Assignment, routes: std::vector< std::vector< int64_t > > *const) ‑> void -
-
-

Converts the solution in the given assignment to routes for all vehicles. -Expects that assignment contains a valid solution (i.e. routes for all -vehicles end with an end index for that vehicle).

-
- -Expand source code - -
def AssignmentToRoutes(self, assignment: "Assignment", routes: "std::vector< std::vector< int64_t > > *const") -> "void":
-    r"""
-    Converts the solution in the given assignment to routes for all vehicles.
-    Expects that assignment contains a valid solution (i.e. routes for all
-    vehicles end with an end index for that vehicle).
-    """
-    return _pywrapcp.RoutingModel_AssignmentToRoutes(self, assignment, routes)
-
-
-
-def CheckLimit(self) ‑> bool -
-
-

Returns true if the search limit has been crossed.

-
- -Expand source code - -
def CheckLimit(self) -> "bool":
-    r""" Returns true if the search limit has been crossed."""
-    return _pywrapcp.RoutingModel_CheckLimit(self)
-
-
-
-def CloseModel(self) ‑> void -
-
-

Closes the current routing model; after this method is called, no -modification to the model can be done, but RoutesToAssignment becomes -available. Note that CloseModel() is automatically called by Solve() and -other methods that produce solution. -This is equivalent to calling -CloseModelWithParameters(DefaultRoutingSearchParameters()).

-
- -Expand source code - -
def CloseModel(self) -> "void":
-    r"""
-    Closes the current routing model; after this method is called, no
-    modification to the model can be done, but RoutesToAssignment becomes
-    available. Note that CloseModel() is automatically called by Solve() and
-    other methods that produce solution.
-    This is equivalent to calling
-    CloseModelWithParameters(DefaultRoutingSearchParameters()).
-    """
-    return _pywrapcp.RoutingModel_CloseModel(self)
-
-
-
-def CloseModelWithParameters(self, search_parameters: operations_research::RoutingSearchParameters const &) ‑> void -
-
-

Same as above taking search parameters (as of 10/2015 some the parameters -have to be set when closing the model).

-
- -Expand source code - -
def CloseModelWithParameters(self, search_parameters: "operations_research::RoutingSearchParameters const &") -> "void":
-    r"""
-    Same as above taking search parameters (as of 10/2015 some the parameters
-    have to be set when closing the model).
-    """
-    return _pywrapcp.RoutingModel_CloseModelWithParameters(self, search_parameters)
-
-
-
-def CloseVisitTypes(self) ‑> void -
-
-

This function should be called once all node visit types have been set and -prior to adding any incompatibilities/requirements. -"close" types.

-
- -Expand source code - -
def CloseVisitTypes(self) -> "void":
-    r"""
-    This function should be called once all node visit types have been set and
-    prior to adding any incompatibilities/requirements.
-    "close" types.
-    """
-    return _pywrapcp.RoutingModel_CloseVisitTypes(self)
-
-
-
-def CompactAndCheckAssignment(self, assignment: Assignment) ‑> operations_research::Assignment * -
-
-

Same as CompactAssignment() but also checks the validity of the final -compact solution; if it is not valid, no attempts to repair it are made -(instead, the method returns nullptr).

-
- -Expand source code - -
def CompactAndCheckAssignment(self, assignment: "Assignment") -> "operations_research::Assignment *":
-    r"""
-    Same as CompactAssignment() but also checks the validity of the final
-    compact solution; if it is not valid, no attempts to repair it are made
-    (instead, the method returns nullptr).
-    """
-    return _pywrapcp.RoutingModel_CompactAndCheckAssignment(self, assignment)
-
-
-
-def CompactAssignment(self, assignment: Assignment) ‑> operations_research::Assignment * -
-
-

Converts the solution in the given assignment to routes for all vehicles. -If the returned vector is route_indices, route_indices[i][j] is the index -for jth location visited on route i. Note that contrary to -AssignmentToRoutes, the vectors do include start and end locations. -Returns a compacted version of the given assignment, in which all vehicles -with id lower or equal to some N have non-empty routes, and all vehicles -with id greater than N have empty routes. Does not take ownership of the -returned object. -If found, the cost of the compact assignment is the same as in the -original assignment and it preserves the values of 'active' variables. -Returns nullptr if a compact assignment was not found. -This method only works in homogenous mode, and it only swaps equivalent -vehicles (vehicles with the same start and end nodes). When creating the -compact assignment, the empty plan is replaced by the route assigned to -the compatible vehicle with the highest id. Note that with more complex -constraints on vehicle variables, this method might fail even if a compact -solution exists. -This method changes the vehicle and dimension variables as necessary. -While compacting the solution, only basic checks on vehicle variables are -performed; if one of these checks fails no attempts to repair it are made -(instead, the method returns nullptr).

-
- -Expand source code - -
def CompactAssignment(self, assignment: "Assignment") -> "operations_research::Assignment *":
-    r"""
-    Converts the solution in the given assignment to routes for all vehicles.
-    If the returned vector is route_indices, route_indices[i][j] is the index
-    for jth location visited on route i. Note that contrary to
-    AssignmentToRoutes, the vectors do include start and end locations.
-    Returns a compacted version of the given assignment, in which all vehicles
-    with id lower or equal to some N have non-empty routes, and all vehicles
-    with id greater than N have empty routes. Does not take ownership of the
-    returned object.
-    If found, the cost of the compact assignment is the same as in the
-    original assignment and it preserves the values of 'active' variables.
-    Returns nullptr if a compact assignment was not found.
-    This method only works in homogenous mode, and it only swaps equivalent
-    vehicles (vehicles with the same start and end nodes). When creating the
-    compact assignment, the empty plan is replaced by the route assigned to
-    the compatible vehicle with the highest id. Note that with more complex
-    constraints on vehicle variables, this method might fail even if a compact
-    solution exists.
-    This method changes the vehicle and dimension variables as necessary.
-    While compacting the solution, only basic checks on vehicle variables are
-    performed; if one of these checks fails no attempts to repair it are made
-    (instead, the method returns nullptr).
-    """
-    return _pywrapcp.RoutingModel_CompactAssignment(self, assignment)
-
-
-
-def ComputeLowerBound(self) ‑> int64_t -
-
-

Computes a lower bound to the routing problem solving a linear assignment -problem. The routing model must be closed before calling this method. -Note that problems with node disjunction constraints (including optional -nodes) and non-homogenous costs are not supported (the method returns 0 in -these cases).

-
- -Expand source code - -
def ComputeLowerBound(self) -> "int64_t":
-    r"""
-    Computes a lower bound to the routing problem solving a linear assignment
-    problem. The routing model must be closed before calling this method.
-    Note that problems with node disjunction constraints (including optional
-    nodes) and non-homogenous costs are not supported (the method returns 0 in
-    these cases).
-    """
-    return _pywrapcp.RoutingModel_ComputeLowerBound(self)
-
-
-
-def ConsiderEmptyRouteCostsForVehicle(self, consider_costs: bool, vehicle: int) ‑> void -
-
-
-
- -Expand source code - -
def ConsiderEmptyRouteCostsForVehicle(self, consider_costs: "bool", vehicle: "int") -> "void":
-    return _pywrapcp.RoutingModel_ConsiderEmptyRouteCostsForVehicle(self, consider_costs, vehicle)
-
-
-
-def CostVar(self) ‑> operations_research::IntVar * -
-
-

Returns the global cost variable which is being minimized.

-
- -Expand source code - -
def CostVar(self) -> "operations_research::IntVar *":
-    r""" Returns the global cost variable which is being minimized."""
-    return _pywrapcp.RoutingModel_CostVar(self)
-
-
-
-def CostsAreHomogeneousAcrossVehicles(self) ‑> bool -
-
-

Whether costs are homogeneous across all vehicles.

-
- -Expand source code - -
def CostsAreHomogeneousAcrossVehicles(self) -> "bool":
-    r""" Whether costs are homogeneous across all vehicles."""
-    return _pywrapcp.RoutingModel_CostsAreHomogeneousAcrossVehicles(self)
-
-
-
-def DebugOutputAssignment(self, solution_assignment: Assignment, dimension_to_print: std::string const &) ‑> std::string -
-
-

Print some debugging information about an assignment, including the -feasible intervals of the CumulVar for dimension "dimension_to_print" -at each step of the routes. -If "dimension_to_print" is omitted, all dimensions will be printed.

-
- -Expand source code - -
def DebugOutputAssignment(self, solution_assignment: "Assignment", dimension_to_print: "std::string const &") -> "std::string":
-    r"""
-    Print some debugging information about an assignment, including the
-    feasible intervals of the CumulVar for dimension "dimension_to_print"
-    at each step of the routes.
-    If "dimension_to_print" is omitted, all dimensions will be printed.
-    """
-    return _pywrapcp.RoutingModel_DebugOutputAssignment(self, solution_assignment, dimension_to_print)
-
-
-
-def End(self, vehicle: int) ‑> int64_t -
-
-

Returns the variable index of the ending node of a vehicle route.

-
- -Expand source code - -
def End(self, vehicle: "int") -> "int64_t":
-    r""" Returns the variable index of the ending node of a vehicle route."""
-    return _pywrapcp.RoutingModel_End(self, vehicle)
-
-
-
-def GetAllDimensionNames(self) ‑> std::vector< std::string > -
-
-

Outputs the names of all dimensions added to the routing engine.

-
- -Expand source code - -
def GetAllDimensionNames(self) -> "std::vector< std::string >":
-    r""" Outputs the names of all dimensions added to the routing engine."""
-    return _pywrapcp.RoutingModel_GetAllDimensionNames(self)
-
-
-
-def GetAmortizedLinearCostFactorOfVehicles(self) ‑> std::vector< int64_t > const & -
-
-
-
- -Expand source code - -
def GetAmortizedLinearCostFactorOfVehicles(self) -> "std::vector< int64_t > const &":
-    return _pywrapcp.RoutingModel_GetAmortizedLinearCostFactorOfVehicles(self)
-
-
-
-def GetAmortizedQuadraticCostFactorOfVehicles(self) ‑> std::vector< int64_t > const & -
-
-
-
- -Expand source code - -
def GetAmortizedQuadraticCostFactorOfVehicles(self) -> "std::vector< int64_t > const &":
-    return _pywrapcp.RoutingModel_GetAmortizedQuadraticCostFactorOfVehicles(self)
-
-
-
-def GetArcCostForClass(self, from_index: int64_t, to_index: int64_t, cost_class_index: int64_t) ‑> int64_t -
-
-

Returns the cost of the segment between two nodes for a given cost -class. Input are variable indices of nodes and the cost class. -Unlike GetArcCostForVehicle(), if cost_class is kNoCost, then the -returned cost won't necessarily be zero: only some of the components -of the cost that depend on the cost class will be omited. See the code -for details.

-
- -Expand source code - -
def GetArcCostForClass(self, from_index: "int64_t", to_index: "int64_t", cost_class_index: "int64_t") -> "int64_t":
-    r"""
-    Returns the cost of the segment between two nodes for a given cost
-    class. Input are variable indices of nodes and the cost class.
-    Unlike GetArcCostForVehicle(), if cost_class is kNoCost, then the
-    returned cost won't necessarily be zero: only some of the components
-    of the cost that depend on the cost class will be omited. See the code
-    for details.
-    """
-    return _pywrapcp.RoutingModel_GetArcCostForClass(self, from_index, to_index, cost_class_index)
-
-
-
-def GetArcCostForFirstSolution(self, from_index: int64_t, to_index: int64_t) ‑> int64_t -
-
-

Returns the cost of the arc in the context of the first solution strategy. -This is typically a simplification of the actual cost; see the .cc.

-
- -Expand source code - -
def GetArcCostForFirstSolution(self, from_index: "int64_t", to_index: "int64_t") -> "int64_t":
-    r"""
-    Returns the cost of the arc in the context of the first solution strategy.
-    This is typically a simplification of the actual cost; see the .cc.
-    """
-    return _pywrapcp.RoutingModel_GetArcCostForFirstSolution(self, from_index, to_index)
-
-
-
-def GetArcCostForVehicle(self, from_index: int64_t, to_index: int64_t, vehicle: int64_t) ‑> int64_t -
-
-

Returns the cost of the transit arc between two nodes for a given vehicle. -Input are variable indices of node. This returns 0 if vehicle < 0.

-
- -Expand source code - -
def GetArcCostForVehicle(self, from_index: "int64_t", to_index: "int64_t", vehicle: "int64_t") -> "int64_t":
-    r"""
-    Returns the cost of the transit arc between two nodes for a given vehicle.
-    Input are variable indices of node. This returns 0 if vehicle < 0.
-    """
-    return _pywrapcp.RoutingModel_GetArcCostForVehicle(self, from_index, to_index, vehicle)
-
-
-
-def GetAutomaticFirstSolutionStrategy(self) ‑> operations_research::FirstSolutionStrategy::Value -
-
-

Returns the automatic first solution strategy selected.

-
- -Expand source code - -
def GetAutomaticFirstSolutionStrategy(self) -> "operations_research::FirstSolutionStrategy::Value":
-    r""" Returns the automatic first solution strategy selected."""
-    return _pywrapcp.RoutingModel_GetAutomaticFirstSolutionStrategy(self)
-
-
-
-def GetCostClassIndexOfVehicle(self, vehicle: int64_t) ‑> operations_research::RoutingModel::CostClassIndex -
-
-

Get the cost class index of the given vehicle.

-
- -Expand source code - -
def GetCostClassIndexOfVehicle(self, vehicle: "int64_t") -> "operations_research::RoutingModel::CostClassIndex":
-    r""" Get the cost class index of the given vehicle."""
-    return _pywrapcp.RoutingModel_GetCostClassIndexOfVehicle(self, vehicle)
-
-
-
-def GetCostClassesCount(self) ‑> int -
-
-

Returns the number of different cost classes in the model.

-
- -Expand source code - -
def GetCostClassesCount(self) -> "int":
-    r""" Returns the number of different cost classes in the model."""
-    return _pywrapcp.RoutingModel_GetCostClassesCount(self)
-
-
-
-def GetDeliveryIndexPairs(self, node_index: int64_t) ‑> std::vector< std::pair< int,int > > const & -
-
-

Same as above for deliveries.

-
- -Expand source code - -
def GetDeliveryIndexPairs(self, node_index: "int64_t") -> "std::vector< std::pair< int,int > > const &":
-    r""" Same as above for deliveries."""
-    return _pywrapcp.RoutingModel_GetDeliveryIndexPairs(self, node_index)
-
-
-
-def GetDepot(self) ‑> int64_t -
-
-

Returns the variable index of the first starting or ending node of all -routes. If all routes start -and end at the same node (single depot), this -is the node returned.

-
- -Expand source code - -
def GetDepot(self) -> "int64_t":
-    r"""
-    Returns the variable index of the first starting or ending node of all
-    routes. If all routes start  and end at the same node (single depot), this
-    is the node returned.
-    """
-    return _pywrapcp.RoutingModel_GetDepot(self)
-
-
-
-def GetDimensionOrDie(self, dimension_name: std::string const &) ‑> operations_research::RoutingDimension const & -
-
-

Returns a dimension from its name. Dies if the dimension does not exist.

-
- -Expand source code - -
def GetDimensionOrDie(self, dimension_name: "std::string const &") -> "operations_research::RoutingDimension const &":
-    r""" Returns a dimension from its name. Dies if the dimension does not exist."""
-    return _pywrapcp.RoutingModel_GetDimensionOrDie(self, dimension_name)
-
-
-
-def GetDimensions(self) ‑> std::vector< operations_research::RoutingDimension * > const & -
-
-

Returns all dimensions of the model.

-
- -Expand source code - -
def GetDimensions(self) -> "std::vector< operations_research::RoutingDimension * > const &":
-    r""" Returns all dimensions of the model."""
-    return _pywrapcp.RoutingModel_GetDimensions(self)
-
-
-
-def GetDimensionsWithSoftOrSpanCosts(self) ‑> std::vector< operations_research::RoutingDimension * > -
-
-

Returns dimensions with soft or vehicle span costs.

-
- -Expand source code - -
def GetDimensionsWithSoftOrSpanCosts(self) -> "std::vector< operations_research::RoutingDimension * >":
-    r""" Returns dimensions with soft or vehicle span costs."""
-    return _pywrapcp.RoutingModel_GetDimensionsWithSoftOrSpanCosts(self)
-
-
-
-def GetDisjunctionIndices(self, index: int64_t) ‑> std::vector< operations_research::RoutingModel::DisjunctionIndex > const & -
-
-

Returns the indices of the disjunctions to which an index belongs.

-
- -Expand source code - -
def GetDisjunctionIndices(self, index: "int64_t") -> "std::vector< operations_research::RoutingModel::DisjunctionIndex > const &":
-    r""" Returns the indices of the disjunctions to which an index belongs."""
-    return _pywrapcp.RoutingModel_GetDisjunctionIndices(self, index)
-
-
-
-def GetDisjunctionMaxCardinality(self, index: operations_research::RoutingModel::DisjunctionIndex) ‑> int64_t -
-
-

Returns the maximum number of possible active nodes of the node -disjunction of index 'index'.

-
- -Expand source code - -
def GetDisjunctionMaxCardinality(self, index: "operations_research::RoutingModel::DisjunctionIndex") -> "int64_t":
-    r"""
-    Returns the maximum number of possible active nodes of the node
-    disjunction of index 'index'.
-    """
-    return _pywrapcp.RoutingModel_GetDisjunctionMaxCardinality(self, index)
-
-
-
-def GetDisjunctionPenalty(self, index: operations_research::RoutingModel::DisjunctionIndex) ‑> int64_t -
-
-

Returns the penalty of the node disjunction of index 'index'.

-
- -Expand source code - -
def GetDisjunctionPenalty(self, index: "operations_research::RoutingModel::DisjunctionIndex") -> "int64_t":
-    r""" Returns the penalty of the node disjunction of index 'index'."""
-    return _pywrapcp.RoutingModel_GetDisjunctionPenalty(self, index)
-
-
-
-def GetFixedCostOfVehicle(self, vehicle: int) ‑> int64_t -
-
-

Returns the route fixed cost taken into account if the route of the -vehicle is not empty, aka there's at least one node on the route other -than the first and last nodes.

-
- -Expand source code - -
def GetFixedCostOfVehicle(self, vehicle: "int") -> "int64_t":
-    r"""
-    Returns the route fixed cost taken into account if the route of the
-    vehicle is not empty, aka there's at least one node on the route other
-    than the first and last nodes.
-    """
-    return _pywrapcp.RoutingModel_GetFixedCostOfVehicle(self, vehicle)
-
-
-
-def GetGlobalDimensionCumulOptimizers(self) ‑> std::vector< std::unique_ptr< operations_research::GlobalDimensionCumulOptimizer > > const & -
-
-

Returns [global|local]dimension_optimizers, which are empty if the model -has not been closed.

-
- -Expand source code - -
def GetGlobalDimensionCumulOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::GlobalDimensionCumulOptimizer > > const &":
-    r"""
-    Returns [global|local]_dimension_optimizers_, which are empty if the model
-    has not been closed.
-    """
-    return _pywrapcp.RoutingModel_GetGlobalDimensionCumulOptimizers(self)
-
-
-
-def GetHardTypeIncompatibilitiesOfType(self, type: int) ‑> absl::flat_hash_set< int > const & -
-
-

Returns visit types incompatible with a given type.

-
- -Expand source code - -
def GetHardTypeIncompatibilitiesOfType(self, type: "int") -> "absl::flat_hash_set< int > const &":
-    r""" Returns visit types incompatible with a given type."""
-    return _pywrapcp.RoutingModel_GetHardTypeIncompatibilitiesOfType(self, type)
-
-
-
-def GetHomogeneousCost(self, from_index: int64_t, to_index: int64_t) ‑> int64_t -
-
-

Returns the cost of the segment between two nodes supposing all vehicle -costs are the same (returns the cost for the first vehicle otherwise).

-
- -Expand source code - -
def GetHomogeneousCost(self, from_index: "int64_t", to_index: "int64_t") -> "int64_t":
-    r"""
-    Returns the cost of the segment between two nodes supposing all vehicle
-    costs are the same (returns the cost for the first vehicle otherwise).
-    """
-    return _pywrapcp.RoutingModel_GetHomogeneousCost(self, from_index, to_index)
-
-
-
-def GetLocalDimensionCumulMPOptimizers(self) ‑> std::vector< std::unique_ptr< operations_research::LocalDimensionCumulOptimizer > > const & -
-
-
-
- -Expand source code - -
def GetLocalDimensionCumulMPOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::LocalDimensionCumulOptimizer > > const &":
-    return _pywrapcp.RoutingModel_GetLocalDimensionCumulMPOptimizers(self)
-
-
-
-def GetLocalDimensionCumulOptimizers(self) ‑> std::vector< std::unique_ptr< operations_research::LocalDimensionCumulOptimizer > > const & -
-
-
-
- -Expand source code - -
def GetLocalDimensionCumulOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::LocalDimensionCumulOptimizer > > const &":
-    return _pywrapcp.RoutingModel_GetLocalDimensionCumulOptimizers(self)
-
-
-
-def GetMaximumNumberOfActiveVehicles(self) ‑> int -
-
-

Returns the maximum number of active vehicles.

-
- -Expand source code - -
def GetMaximumNumberOfActiveVehicles(self) -> "int":
-    r""" Returns the maximum number of active vehicles."""
-    return _pywrapcp.RoutingModel_GetMaximumNumberOfActiveVehicles(self)
-
-
-
-def GetMutableDimension(self, dimension_name: std::string const &) ‑> operations_research::RoutingDimension * -
-
-

Returns a dimension from its name. Returns nullptr if the dimension does -not exist.

-
- -Expand source code - -
def GetMutableDimension(self, dimension_name: "std::string const &") -> "operations_research::RoutingDimension *":
-    r"""
-    Returns a dimension from its name. Returns nullptr if the dimension does
-    not exist.
-    """
-    return _pywrapcp.RoutingModel_GetMutableDimension(self, dimension_name)
-
-
-
-def GetMutableGlobalCumulOptimizer(self, dimension: RoutingDimension) ‑> operations_research::GlobalDimensionCumulOptimizer * -
-
-

Returns the global/local dimension cumul optimizer for a given dimension, -or nullptr if there is none.

-
- -Expand source code - -
def GetMutableGlobalCumulOptimizer(self, dimension: "RoutingDimension") -> "operations_research::GlobalDimensionCumulOptimizer *":
-    r"""
-    Returns the global/local dimension cumul optimizer for a given dimension,
-    or nullptr if there is none.
-    """
-    return _pywrapcp.RoutingModel_GetMutableGlobalCumulOptimizer(self, dimension)
-
-
-
-def GetMutableLocalCumulMPOptimizer(self, dimension: RoutingDimension) ‑> operations_research::LocalDimensionCumulOptimizer * -
-
-
-
- -Expand source code - -
def GetMutableLocalCumulMPOptimizer(self, dimension: "RoutingDimension") -> "operations_research::LocalDimensionCumulOptimizer *":
-    return _pywrapcp.RoutingModel_GetMutableLocalCumulMPOptimizer(self, dimension)
-
-
-
-def GetMutableLocalCumulOptimizer(self, dimension: RoutingDimension) ‑> operations_research::LocalDimensionCumulOptimizer * -
-
-
-
- -Expand source code - -
def GetMutableLocalCumulOptimizer(self, dimension: "RoutingDimension") -> "operations_research::LocalDimensionCumulOptimizer *":
-    return _pywrapcp.RoutingModel_GetMutableLocalCumulOptimizer(self, dimension)
-
-
-
-def GetNonZeroCostClassesCount(self) ‑> int -
-
-

Ditto, minus the 'always zero', built-in cost class.

-
- -Expand source code - -
def GetNonZeroCostClassesCount(self) -> "int":
-    r""" Ditto, minus the 'always zero', built-in cost class."""
-    return _pywrapcp.RoutingModel_GetNonZeroCostClassesCount(self)
-
-
-
-def GetNumOfSingletonNodes(self) ‑> int -
-
-

Returns the number of non-start/end nodes which do not appear in a -pickup/delivery pair.

-
- -Expand source code - -
def GetNumOfSingletonNodes(self) -> "int":
-    r"""
-    Returns the number of non-start/end nodes which do not appear in a
-    pickup/delivery pair.
-    """
-    return _pywrapcp.RoutingModel_GetNumOfSingletonNodes(self)
-
-
-
-def GetNumberOfDecisionsInFirstSolution(self, search_parameters: operations_research::RoutingSearchParameters const &) ‑> int64_t -
-
-

Returns statistics on first solution search, number of decisions sent to -filters, number of decisions rejected by filters.

-
- -Expand source code - -
def GetNumberOfDecisionsInFirstSolution(self, search_parameters: "operations_research::RoutingSearchParameters const &") -> "int64_t":
-    r"""
-    Returns statistics on first solution search, number of decisions sent to
-    filters, number of decisions rejected by filters.
-    """
-    return _pywrapcp.RoutingModel_GetNumberOfDecisionsInFirstSolution(self, search_parameters)
-
-
-
-def GetNumberOfDisjunctions(self) ‑> int -
-
-

Returns the number of node disjunctions in the model.

-
- -Expand source code - -
def GetNumberOfDisjunctions(self) -> "int":
-    r""" Returns the number of node disjunctions in the model."""
-    return _pywrapcp.RoutingModel_GetNumberOfDisjunctions(self)
-
-
-
-def GetNumberOfRejectsInFirstSolution(self, search_parameters: operations_research::RoutingSearchParameters const &) ‑> int64_t -
-
-
-
- -Expand source code - -
def GetNumberOfRejectsInFirstSolution(self, search_parameters: "operations_research::RoutingSearchParameters const &") -> "int64_t":
-    return _pywrapcp.RoutingModel_GetNumberOfRejectsInFirstSolution(self, search_parameters)
-
-
-
-def GetNumberOfVisitTypes(self) ‑> int -
-
-
-
- -Expand source code - -
def GetNumberOfVisitTypes(self) -> "int":
-    return _pywrapcp.RoutingModel_GetNumberOfVisitTypes(self)
-
-
-
-def GetPairIndicesOfType(self, type: int) ‑> std::vector< int > const & -
-
-
-
- -Expand source code - -
def GetPairIndicesOfType(self, type: "int") -> "std::vector< int > const &":
-    return _pywrapcp.RoutingModel_GetPairIndicesOfType(self, type)
-
-
-
-def GetPerfectBinaryDisjunctions(self) ‑> std::vector< std::pair< int64_t,int64_t > > -
-
-

Returns the list of all perfect binary disjunctions, as pairs of variable -indices: a disjunction is "perfect" when its variables do not appear in -any other disjunction. Each pair is sorted (lowest variable index first), -and the output vector is also sorted (lowest pairs first).

-
- -Expand source code - -
def GetPerfectBinaryDisjunctions(self) -> "std::vector< std::pair< int64_t,int64_t > >":
-    r"""
-    Returns the list of all perfect binary disjunctions, as pairs of variable
-    indices: a disjunction is "perfect" when its variables do not appear in
-    any other disjunction. Each pair is sorted (lowest variable index first),
-    and the output vector is also sorted (lowest pairs first).
-    """
-    return _pywrapcp.RoutingModel_GetPerfectBinaryDisjunctions(self)
-
-
-
-def GetPickupAndDeliveryPolicyOfVehicle(self, vehicle: int) ‑> operations_research::RoutingModel::PickupAndDeliveryPolicy -
-
-
-
- -Expand source code - -
def GetPickupAndDeliveryPolicyOfVehicle(self, vehicle: "int") -> "operations_research::RoutingModel::PickupAndDeliveryPolicy":
-    return _pywrapcp.RoutingModel_GetPickupAndDeliveryPolicyOfVehicle(self, vehicle)
-
-
-
-def GetPickupIndexPairs(self, node_index: int64_t) ‑> std::vector< std::pair< int,int > > const & -
-
-

Returns pairs for which the node is a pickup; the first element of each -pair is the index in the pickup and delivery pairs list in which the -pickup appears, the second element is its index in the pickups list.

-
- -Expand source code - -
def GetPickupIndexPairs(self, node_index: "int64_t") -> "std::vector< std::pair< int,int > > const &":
-    r"""
-    Returns pairs for which the node is a pickup; the first element of each
-    pair is the index in the pickup and delivery pairs list in which the
-    pickup appears, the second element is its index in the pickups list.
-    """
-    return _pywrapcp.RoutingModel_GetPickupIndexPairs(self, node_index)
-
-
-
-def GetPrimaryConstrainedDimension(self) ‑> std::string const & -
-
-

Get the primary constrained dimension, or an empty string if it is unset.

-
- -Expand source code - -
def GetPrimaryConstrainedDimension(self) -> "std::string const &":
-    r""" Get the primary constrained dimension, or an empty string if it is unset."""
-    return _pywrapcp.RoutingModel_GetPrimaryConstrainedDimension(self)
-
-
-
-def GetRequiredTypeAlternativesWhenAddingType(self, type: int) ‑> std::vector< absl::flat_hash_set< int > > const & -
-
-

Returns the set of requirement alternatives when adding the given type.

-
- -Expand source code - -
def GetRequiredTypeAlternativesWhenAddingType(self, type: "int") -> "std::vector< absl::flat_hash_set< int > > const &":
-    r""" Returns the set of requirement alternatives when adding the given type."""
-    return _pywrapcp.RoutingModel_GetRequiredTypeAlternativesWhenAddingType(self, type)
-
-
-
-def GetRequiredTypeAlternativesWhenRemovingType(self, type: int) ‑> std::vector< absl::flat_hash_set< int > > const & -
-
-

Returns the set of requirement alternatives when removing the given type.

-
- -Expand source code - -
def GetRequiredTypeAlternativesWhenRemovingType(self, type: "int") -> "std::vector< absl::flat_hash_set< int > > const &":
-    r""" Returns the set of requirement alternatives when removing the given type."""
-    return _pywrapcp.RoutingModel_GetRequiredTypeAlternativesWhenRemovingType(self, type)
-
-
-
-def GetSameVehicleIndicesOfIndex(self, node: int) ‑> std::vector< int > const & -
-
-

Returns variable indices of nodes constrained to be on the same route.

-
- -Expand source code - -
def GetSameVehicleIndicesOfIndex(self, node: "int") -> "std::vector< int > const &":
-    r""" Returns variable indices of nodes constrained to be on the same route."""
-    return _pywrapcp.RoutingModel_GetSameVehicleIndicesOfIndex(self, node)
-
-
-
-def GetSameVehicleRequiredTypeAlternativesOfType(self, type: int) ‑> std::vector< absl::flat_hash_set< int > > const & -
-
-

Returns the set of same-vehicle requirement alternatives for the given -type.

-
- -Expand source code - -
def GetSameVehicleRequiredTypeAlternativesOfType(self, type: "int") -> "std::vector< absl::flat_hash_set< int > > const &":
-    r"""
-    Returns the set of same-vehicle requirement alternatives for the given
-    type.
-    """
-    return _pywrapcp.RoutingModel_GetSameVehicleRequiredTypeAlternativesOfType(self, type)
-
-
-
-def GetSingleNodesOfType(self, type: int) ‑> std::vector< int > const & -
-
-
-
- -Expand source code - -
def GetSingleNodesOfType(self, type: "int") -> "std::vector< int > const &":
-    return _pywrapcp.RoutingModel_GetSingleNodesOfType(self, type)
-
-
-
-def GetTemporalTypeIncompatibilitiesOfType(self, type: int) ‑> absl::flat_hash_set< int > const & -
-
-
-
- -Expand source code - -
def GetTemporalTypeIncompatibilitiesOfType(self, type: "int") -> "absl::flat_hash_set< int > const &":
-    return _pywrapcp.RoutingModel_GetTemporalTypeIncompatibilitiesOfType(self, type)
-
-
-
-def GetVehicleClassIndexOfVehicle(self, vehicle: int64_t) ‑> operations_research::RoutingModel::VehicleClassIndex -
-
-
-
- -Expand source code - -
def GetVehicleClassIndexOfVehicle(self, vehicle: "int64_t") -> "operations_research::RoutingModel::VehicleClassIndex":
-    return _pywrapcp.RoutingModel_GetVehicleClassIndexOfVehicle(self, vehicle)
-
-
-
-def GetVehicleClassesCount(self) ‑> int -
-
-

Returns the number of different vehicle classes in the model.

-
- -Expand source code - -
def GetVehicleClassesCount(self) -> "int":
-    r""" Returns the number of different vehicle classes in the model."""
-    return _pywrapcp.RoutingModel_GetVehicleClassesCount(self)
-
-
-
-def GetVehicleTypeContainer(self) ‑> operations_research::RoutingModel::VehicleTypeContainer const & -
-
-
-
- -Expand source code - -
def GetVehicleTypeContainer(self) -> "operations_research::RoutingModel::VehicleTypeContainer const &":
-    return _pywrapcp.RoutingModel_GetVehicleTypeContainer(self)
-
-
-
-def GetVisitType(self, index: int64_t) ‑> int -
-
-
-
- -Expand source code - -
def GetVisitType(self, index: "int64_t") -> "int":
-    return _pywrapcp.RoutingModel_GetVisitType(self, index)
-
-
-
-def GetVisitTypePolicy(self, index: int64_t) ‑> operations_research::RoutingModel::VisitTypePolicy -
-
-
-
- -Expand source code - -
def GetVisitTypePolicy(self, index: "int64_t") -> "operations_research::RoutingModel::VisitTypePolicy":
-    return _pywrapcp.RoutingModel_GetVisitTypePolicy(self, index)
-
-
-
-def HasDimension(self, dimension_name: std::string const &) ‑> bool -
-
-

Returns true if a dimension exists for a given dimension name.

-
- -Expand source code - -
def HasDimension(self, dimension_name: "std::string const &") -> "bool":
-    r""" Returns true if a dimension exists for a given dimension name."""
-    return _pywrapcp.RoutingModel_HasDimension(self, dimension_name)
-
-
-
-def HasHardTypeIncompatibilities(self) ‑> bool -
-
-

Returns true iff any hard (resp. temporal) type incompatibilities have -been added to the model.

-
- -Expand source code - -
def HasHardTypeIncompatibilities(self) -> "bool":
-    r"""
-    Returns true iff any hard (resp. temporal) type incompatibilities have
-    been added to the model.
-    """
-    return _pywrapcp.RoutingModel_HasHardTypeIncompatibilities(self)
-
-
-
-def HasSameVehicleTypeRequirements(self) ‑> bool -
-
-

Returns true iff any same-route (resp. temporal) type requirements have -been added to the model.

-
- -Expand source code - -
def HasSameVehicleTypeRequirements(self) -> "bool":
-    r"""
-    Returns true iff any same-route (resp. temporal) type requirements have
-    been added to the model.
-    """
-    return _pywrapcp.RoutingModel_HasSameVehicleTypeRequirements(self)
-
-
-
-def HasTemporalTypeIncompatibilities(self) ‑> bool -
-
-
-
- -Expand source code - -
def HasTemporalTypeIncompatibilities(self) -> "bool":
-    return _pywrapcp.RoutingModel_HasTemporalTypeIncompatibilities(self)
-
-
-
-def HasTemporalTypeRequirements(self) ‑> bool -
-
-
-
- -Expand source code - -
def HasTemporalTypeRequirements(self) -> "bool":
-    return _pywrapcp.RoutingModel_HasTemporalTypeRequirements(self)
-
-
-
-def HasTypeRegulations(self) ‑> bool -
-
-

Returns true iff the model has any incompatibilities or requirements set -on node types.

-
- -Expand source code - -
def HasTypeRegulations(self) -> "bool":
-    r"""
-    Returns true iff the model has any incompatibilities or requirements set
-    on node types.
-    """
-    return _pywrapcp.RoutingModel_HasTypeRegulations(self)
-
-
-
-def HasVehicleWithCostClassIndex(self, cost_class_index: operations_research::RoutingModel::CostClassIndex) ‑> bool -
-
-

Returns true iff the model contains a vehicle with the given -cost_class_index.

-
- -Expand source code - -
def HasVehicleWithCostClassIndex(self, cost_class_index: "operations_research::RoutingModel::CostClassIndex") -> "bool":
-    r"""
-    Returns true iff the model contains a vehicle with the given
-    cost_class_index.
-    """
-    return _pywrapcp.RoutingModel_HasVehicleWithCostClassIndex(self, cost_class_index)
-
-
-
-def IgnoreDisjunctionsAlreadyForcedToZero(self) ‑> void -
-
-

SPECIAL: Makes the solver ignore all the disjunctions whose active -variables are all trivially zero (i.e. Max() == 0), by setting their -max_cardinality to 0. -This can be useful when using the BaseBinaryDisjunctionNeighborhood -operators, in the context of arc-based routing.

-
- -Expand source code - -
def IgnoreDisjunctionsAlreadyForcedToZero(self) -> "void":
-    r"""
-    SPECIAL: Makes the solver ignore all the disjunctions whose active
-    variables are all trivially zero (i.e. Max() == 0), by setting their
-    max_cardinality to 0.
-    This can be useful when using the BaseBinaryDisjunctionNeighborhood
-    operators, in the context of arc-based routing.
-    """
-    return _pywrapcp.RoutingModel_IgnoreDisjunctionsAlreadyForcedToZero(self)
-
-
-
-def IsEnd(self, index: int64_t) ‑> bool -
-
-

Returns true if 'index' represents the last node of a route.

-
- -Expand source code - -
def IsEnd(self, index: "int64_t") -> "bool":
-    r""" Returns true if 'index' represents the last node of a route."""
-    return _pywrapcp.RoutingModel_IsEnd(self, index)
-
-
-
-def IsMatchingModel(self) ‑> bool -
-
-

Returns true if a vehicle/node matching problem is detected.

-
- -Expand source code - -
def IsMatchingModel(self) -> "bool":
-    r""" Returns true if a vehicle/node matching problem is detected."""
-    return _pywrapcp.RoutingModel_IsMatchingModel(self)
-
-
-
-def IsStart(self, index: int64_t) ‑> bool -
-
-

Returns true if 'index' represents the first node of a route.

-
- -Expand source code - -
def IsStart(self, index: "int64_t") -> "bool":
-    r""" Returns true if 'index' represents the first node of a route."""
-    return _pywrapcp.RoutingModel_IsStart(self, index)
-
-
-
-def IsVehicleAllowedForIndex(self, vehicle: int, index: int64_t) ‑> bool -
-
-

Returns true if a vehicle is allowed to visit a given node.

-
- -Expand source code - -
def IsVehicleAllowedForIndex(self, vehicle: "int", index: "int64_t") -> "bool":
-    r""" Returns true if a vehicle is allowed to visit a given node."""
-    return _pywrapcp.RoutingModel_IsVehicleAllowedForIndex(self, vehicle, index)
-
-
-
-def IsVehicleUsed(self, assignment: Assignment, vehicle: int) ‑> bool -
-
-

Returns true if the route of 'vehicle' is non empty in 'assignment'.

-
- -Expand source code - -
def IsVehicleUsed(self, assignment: "Assignment", vehicle: "int") -> "bool":
-    r""" Returns true if the route of 'vehicle' is non empty in 'assignment'."""
-    return _pywrapcp.RoutingModel_IsVehicleUsed(self, assignment, vehicle)
-
-
-
-def MakeGuidedSlackFinalizer(self, dimension: RoutingDimension, initializer: std::function< int64_t (int64_t) >) ‑> operations_research::DecisionBuilder * -
-
-

The next few members are in the public section only for testing purposes.

-

MakeGuidedSlackFinalizer creates a DecisionBuilder for the slacks of a -dimension using a callback to choose which values to start with. -The finalizer works only when all next variables in the model have -been fixed. It has the following two characteristics: -1. It follows the routes defined by the nexts variables when choosing a -variable to make a decision on. -2. When it comes to choose a value for the slack of node i, the decision -builder first calls the callback with argument i, and supposingly the -returned value is x it creates decisions slack[i] = x, slack[i] = x + -1, slack[i] = x - 1, slack[i] = x + 2, etc.

-
- -Expand source code - -
def MakeGuidedSlackFinalizer(self, dimension: "RoutingDimension", initializer: "std::function< int64_t (int64_t) >") -> "operations_research::DecisionBuilder *":
-    r"""
-    The next few members are in the public section only for testing purposes.
-
-    MakeGuidedSlackFinalizer creates a DecisionBuilder for the slacks of a
-    dimension using a callback to choose which values to start with.
-    The finalizer works only when all next variables in the model have
-    been fixed. It has the following two characteristics:
-    1. It follows the routes defined by the nexts variables when choosing a
-       variable to make a decision on.
-    2. When it comes to choose a value for the slack of node i, the decision
-       builder first calls the callback with argument i, and supposingly the
-       returned value is x it creates decisions slack[i] = x, slack[i] = x +
-       1, slack[i] = x - 1, slack[i] = x + 2, etc.
-    """
-    return _pywrapcp.RoutingModel_MakeGuidedSlackFinalizer(self, dimension, initializer)
-
-
-
-def MakePathSpansAndTotalSlacks(self, dimension: RoutingDimension, spans: std::vector< operations_research::IntVar * >, total_slacks: std::vector< operations_research::IntVar * >) ‑> operations_research::Constraint * -
-
-

For every vehicle of the routing model: -- if total_slacks[vehicle] is not nullptr, constrains it to be the sum of -slacks on that vehicle, that is, -dimension->CumulVar(end) - dimension->CumulVar(start) - -sum_{node in path of vehicle} dimension->FixedTransitVar(node). -- if spans[vehicle] is not nullptr, constrains it to be -dimension->CumulVar(end) - dimension->CumulVar(start) -This does stronger propagation than a decomposition, and takes breaks into -account.

-
- -Expand source code - -
def MakePathSpansAndTotalSlacks(self, dimension: "RoutingDimension", spans: "std::vector< operations_research::IntVar * >", total_slacks: "std::vector< operations_research::IntVar * >") -> "operations_research::Constraint *":
-    r"""
-    For every vehicle of the routing model:
-    - if total_slacks[vehicle] is not nullptr, constrains it to be the sum of
-      slacks on that vehicle, that is,
-      dimension->CumulVar(end) - dimension->CumulVar(start) -
-      sum_{node in path of vehicle} dimension->FixedTransitVar(node).
-    - if spans[vehicle] is not nullptr, constrains it to be
-      dimension->CumulVar(end) - dimension->CumulVar(start)
-    This does stronger propagation than a decomposition, and takes breaks into
-    account.
-    """
-    return _pywrapcp.RoutingModel_MakePathSpansAndTotalSlacks(self, dimension, spans, total_slacks)
-
-
-
-def MakeSelfDependentDimensionFinalizer(self, dimension: RoutingDimension) ‑> operations_research::DecisionBuilder * -
-
-

MakeSelfDependentDimensionFinalizer is a finalizer for the slacks of a -self-dependent dimension. It makes an extensive use of the caches of the -state dependent transits. -In detail, MakeSelfDependentDimensionFinalizer returns a composition of a -local search decision builder with a greedy descent operator for the cumul -of the start of each route and a guided slack finalizer. Provided there -are no time windows and the maximum slacks are large enough, once the -cumul of the start of route is fixed, the guided finalizer can find -optimal values of the slacks for the rest of the route in time -proportional to the length of the route. Therefore the composed finalizer -generally works in time O(log(t)nm), where t is the latest possible -departute time, n is the number of nodes in the network and m is the -number of vehicles.

-
- -Expand source code - -
def MakeSelfDependentDimensionFinalizer(self, dimension: "RoutingDimension") -> "operations_research::DecisionBuilder *":
-    r"""
-    MakeSelfDependentDimensionFinalizer is a finalizer for the slacks of a
-    self-dependent dimension. It makes an extensive use of the caches of the
-    state dependent transits.
-    In detail, MakeSelfDependentDimensionFinalizer returns a composition of a
-    local search decision builder with a greedy descent operator for the cumul
-    of the start of each route and a guided slack finalizer. Provided there
-    are no time windows and the maximum slacks are large enough, once the
-    cumul of the start of route is fixed, the guided finalizer can find
-    optimal values of the slacks for the rest of the route in time
-    proportional to the length of the route. Therefore the composed finalizer
-    generally works in time O(log(t)*n*m), where t is the latest possible
-    departute time, n is the number of nodes in the network and m is the
-    number of vehicles.
-    """
-    return _pywrapcp.RoutingModel_MakeSelfDependentDimensionFinalizer(self, dimension)
-
-
-
-def MutablePreAssignment(self) ‑> operations_research::Assignment * -
-
-
-
- -Expand source code - -
def MutablePreAssignment(self) -> "operations_research::Assignment *":
-    return _pywrapcp.RoutingModel_MutablePreAssignment(self)
-
-
-
-def Next(self, assignment: Assignment, index: int64_t) ‑> int64_t -
-
-

Assignment inspection -Returns the variable index of the node directly after the node -corresponding to 'index' in 'assignment'.

-
- -Expand source code - -
def Next(self, assignment: "Assignment", index: "int64_t") -> "int64_t":
-    r"""
-    Assignment inspection
-    Returns the variable index of the node directly after the node
-    corresponding to 'index' in 'assignment'.
-    """
-    return _pywrapcp.RoutingModel_Next(self, assignment, index)
-
-
-
-def NextVar(self, index: int64_t) ‑> operations_research::IntVar * -
-
-

Returns the next variable of the node corresponding to index. Note that -NextVar(index) == index is equivalent to ActiveVar(index) == 0.

-
- -Expand source code - -
def NextVar(self, index: "int64_t") -> "operations_research::IntVar *":
-    r"""
-    Returns the next variable of the node corresponding to index. Note that
-    NextVar(index) == index is equivalent to ActiveVar(index) == 0.
-    """
-    return _pywrapcp.RoutingModel_NextVar(self, index)
-
-
-
-def PackCumulsOfOptimizerDimensionsFromAssignment(self, original_assignment: Assignment, duration_limit: absl::Duration) ‑> operations_research::Assignment const * -
-
-

For every dimension in the model with an optimizer in -local/global_dimension_optimizers_, this method tries to pack the cumul -values of the dimension, such that: -- The cumul costs (span costs, soft lower and upper bound costs, etc) are -minimized. -- The cumuls of the ends of the routes are minimized for this given -minimal cumul cost. -- Given these minimal end cumuls, the route start cumuls are maximized. -Returns the assignment resulting from allocating these packed cumuls with -the solver, and nullptr if these cumuls could not be set by the solver.

-
- -Expand source code - -
def PackCumulsOfOptimizerDimensionsFromAssignment(self, original_assignment: "Assignment", duration_limit: "absl::Duration") -> "operations_research::Assignment const *":
-    r"""
-    For every dimension in the model with an optimizer in
-    local/global_dimension_optimizers_, this method tries to pack the cumul
-    values of the dimension, such that:
-    - The cumul costs (span costs, soft lower and upper bound costs, etc) are
-      minimized.
-    - The cumuls of the ends of the routes are minimized for this given
-      minimal cumul cost.
-    - Given these minimal end cumuls, the route start cumuls are maximized.
-    Returns the assignment resulting from allocating these packed cumuls with
-    the solver, and nullptr if these cumuls could not be set by the solver.
-    """
-    return _pywrapcp.RoutingModel_PackCumulsOfOptimizerDimensionsFromAssignment(self, original_assignment, duration_limit)
-
-
-
-def PreAssignment(self) ‑> operations_research::Assignment const *const -
-
-

Returns an assignment used to fix some of the variables of the problem. -In practice, this assignment locks partial routes of the problem. This -can be used in the context of locking the parts of the routes which have -already been driven in online routing problems.

-
- -Expand source code - -
def PreAssignment(self) -> "operations_research::Assignment const *const":
-    r"""
-    Returns an assignment used to fix some of the variables of the problem.
-    In practice, this assignment locks partial routes of the problem. This
-    can be used in the context of locking the parts of the routes which have
-    already been driven in online routing problems.
-    """
-    return _pywrapcp.RoutingModel_PreAssignment(self)
-
-
-
-def ReadAssignment(self, file_name: std::string const &) ‑> operations_research::Assignment * -
-
-

Reads an assignment from a file and returns the current solution. -Returns nullptr if the file cannot be opened or if the assignment is not -valid.

-
- -Expand source code - -
def ReadAssignment(self, file_name: "std::string const &") -> "operations_research::Assignment *":
-    r"""
-    Reads an assignment from a file and returns the current solution.
-    Returns nullptr if the file cannot be opened or if the assignment is not
-    valid.
-    """
-    return _pywrapcp.RoutingModel_ReadAssignment(self, file_name)
-
-
-
-def ReadAssignmentFromRoutes(self, routes: std::vector< std::vector< int64_t > > const &, ignore_inactive_indices: bool) ‑> operations_research::Assignment * -
-
-

Restores the routes as the current solution. Returns nullptr if the -solution cannot be restored (routes do not contain a valid solution). Note -that calling this method will run the solver to assign values to the -dimension variables; this may take considerable amount of time, especially -when using dimensions with slack.

-
- -Expand source code - -
def ReadAssignmentFromRoutes(self, routes: "std::vector< std::vector< int64_t > > const &", ignore_inactive_indices: "bool") -> "operations_research::Assignment *":
-    r"""
-    Restores the routes as the current solution. Returns nullptr if the
-    solution cannot be restored (routes do not contain a valid solution). Note
-    that calling this method will run the solver to assign values to the
-    dimension variables; this may take considerable amount of time, especially
-    when using dimensions with slack.
-    """
-    return _pywrapcp.RoutingModel_ReadAssignmentFromRoutes(self, routes, ignore_inactive_indices)
-
-
-
-def RegisterPositiveTransitCallback(self, callback: operations_research::RoutingModel::TransitCallback2) ‑> int -
-
-
-
- -Expand source code - -
def RegisterPositiveTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback2") -> "int":
-    return _pywrapcp.RoutingModel_RegisterPositiveTransitCallback(self, callback)
-
-
-
-def RegisterPositiveUnaryTransitCallback(self, callback: operations_research::RoutingModel::TransitCallback1) ‑> int -
-
-
-
- -Expand source code - -
def RegisterPositiveUnaryTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback1") -> "int":
-    return _pywrapcp.RoutingModel_RegisterPositiveUnaryTransitCallback(self, callback)
-
-
-
-def RegisterTransitCallback(self, callback: operations_research::RoutingModel::TransitCallback2) ‑> int -
-
-
-
- -Expand source code - -
def RegisterTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback2") -> "int":
-    return _pywrapcp.RoutingModel_RegisterTransitCallback(self, callback)
-
-
-
-def RegisterTransitMatrix(self, values: std::vector< std::vector< int64_t > >) ‑> int -
-
-
-
- -Expand source code - -
def RegisterTransitMatrix(self, values: "std::vector< std::vector< int64_t > >") -> "int":
-    return _pywrapcp.RoutingModel_RegisterTransitMatrix(self, values)
-
-
-
-def RegisterUnaryTransitCallback(self, callback: operations_research::RoutingModel::TransitCallback1) ‑> int -
-
-
-
- -Expand source code - -
def RegisterUnaryTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback1") -> "int":
-    return _pywrapcp.RoutingModel_RegisterUnaryTransitCallback(self, callback)
-
-
-
-def RegisterUnaryTransitVector(self, values: std::vector< int64_t >) ‑> int -
-
-

Registers 'callback' and returns its index.

-
- -Expand source code - -
def RegisterUnaryTransitVector(self, values: "std::vector< int64_t >") -> "int":
-    r""" Registers 'callback' and returns its index."""
-    return _pywrapcp.RoutingModel_RegisterUnaryTransitVector(self, values)
-
-
-
-def RemainingTime(self) ‑> absl::Duration -
-
-

Returns the time left in the search limit.

-
- -Expand source code - -
def RemainingTime(self) -> "absl::Duration":
-    r""" Returns the time left in the search limit."""
-    return _pywrapcp.RoutingModel_RemainingTime(self)
-
-
-
-def RestoreAssignment(self, solution: Assignment) ‑> operations_research::Assignment * -
-
-

Restores an assignment as a solution in the routing model and returns the -new solution. Returns nullptr if the assignment is not valid.

-
- -Expand source code - -
def RestoreAssignment(self, solution: "Assignment") -> "operations_research::Assignment *":
-    r"""
-    Restores an assignment as a solution in the routing model and returns the
-    new solution. Returns nullptr if the assignment is not valid.
-    """
-    return _pywrapcp.RoutingModel_RestoreAssignment(self, solution)
-
-
-
-def RoutesToAssignment(self, routes: std::vector< std::vector< int64_t > > const &, ignore_inactive_indices: bool, close_routes: bool, assignment: Assignment) ‑> bool -
-
-

Fills an assignment from a specification of the routes of the -vehicles. The routes are specified as lists of variable indices that -appear on the routes of the vehicles. The indices of the outer vector in -'routes' correspond to vehicles IDs, the inner vector contains the -variable indices on the routes for the given vehicle. The inner vectors -must not contain the start and end indices, as these are determined by the -routing model. -Sets the value of NextVars in the assignment, adding the -variables to the assignment if necessary. The method does not touch other -variables in the assignment. The method can only be called after the model -is closed. -With ignore_inactive_indices set to false, this method will -fail (return nullptr) in case some of the route contain indices that are -deactivated in the model; when set to true, these indices will be -skipped. -Returns true if routes were successfully -loaded. However, such assignment still might not be a valid -solution to the routing problem due to more complex constraints; -it is advisible to call solver()->CheckSolution() afterwards.

-
- -Expand source code - -
def RoutesToAssignment(self, routes: "std::vector< std::vector< int64_t > > const &", ignore_inactive_indices: "bool", close_routes: "bool", assignment: "Assignment") -> "bool":
-    r"""
-    Fills an assignment from a specification of the routes of the
-    vehicles. The routes are specified as lists of variable indices that
-    appear on the routes of the vehicles. The indices of the outer vector in
-    'routes' correspond to vehicles IDs, the inner vector contains the
-    variable indices on the routes for the given vehicle. The inner vectors
-    must not contain the start and end indices, as these are determined by the
-    routing model.  Sets the value of NextVars in the assignment, adding the
-    variables to the assignment if necessary. The method does not touch other
-    variables in the assignment. The method can only be called after the model
-    is closed.  With ignore_inactive_indices set to false, this method will
-    fail (return nullptr) in case some of the route contain indices that are
-    deactivated in the model; when set to true, these indices will be
-    skipped.  Returns true if routes were successfully
-    loaded. However, such assignment still might not be a valid
-    solution to the routing problem due to more complex constraints;
-    it is advisible to call solver()->CheckSolution() afterwards.
-    """
-    return _pywrapcp.RoutingModel_RoutesToAssignment(self, routes, ignore_inactive_indices, close_routes, assignment)
-
-
-
-def SetAllowedVehiclesForIndex(self, vehicles: std::vector< int > const &, index: int64_t) ‑> void -
-
-

Sets the vehicles which can visit a given node. If the node is in a -disjunction, this will not prevent it from being unperformed. -Specifying an empty vector of vehicles has no effect (all vehicles -will be allowed to visit the node).

-
- -Expand source code - -
def SetAllowedVehiclesForIndex(self, vehicles: "std::vector< int > const &", index: "int64_t") -> "void":
-    r"""
-    Sets the vehicles which can visit a given node. If the node is in a
-    disjunction, this will not prevent it from being unperformed.
-    Specifying an empty vector of vehicles has no effect (all vehicles
-    will be allowed to visit the node).
-    """
-    return _pywrapcp.RoutingModel_SetAllowedVehiclesForIndex(self, vehicles, index)
-
-
-
-def SetAmortizedCostFactorsOfAllVehicles(self, linear_cost_factor: int64_t, quadratic_cost_factor: int64_t) ‑> void -
-
-

The following methods set the linear and quadratic cost factors of -vehicles (must be positive values). The default value of these parameters -is zero for all vehicles.

-

When set, the cost_ of the model will contain terms aiming at reducing the -number of vehicles used in the model, by adding the following to the -objective for every vehicle v: -INDICATOR(v used in the model) * -[linear_cost_factor_of_vehicle_[v] -- quadratic_cost_factor_of_vehicle_[v]*(square of length of route v)] -i.e. for every used vehicle, we add the linear factor as fixed cost, and -subtract the square of the route length multiplied by the quadratic -factor. This second term aims at making the routes as dense as possible.

-

Sets the linear and quadratic cost factor of all vehicles.

-
- -Expand source code - -
def SetAmortizedCostFactorsOfAllVehicles(self, linear_cost_factor: "int64_t", quadratic_cost_factor: "int64_t") -> "void":
-    r"""
-    The following methods set the linear and quadratic cost factors of
-    vehicles (must be positive values). The default value of these parameters
-    is zero for all vehicles.
-
-    When set, the cost_ of the model will contain terms aiming at reducing the
-    number of vehicles used in the model, by adding the following to the
-    objective for every vehicle v:
-    INDICATOR(v used in the model) *
-      [linear_cost_factor_of_vehicle_[v]
-       - quadratic_cost_factor_of_vehicle_[v]*(square of length of route v)]
-    i.e. for every used vehicle, we add the linear factor as fixed cost, and
-    subtract the square of the route length multiplied by the quadratic
-    factor. This second term aims at making the routes as dense as possible.
-
-    Sets the linear and quadratic cost factor of all vehicles.
-    """
-    return _pywrapcp.RoutingModel_SetAmortizedCostFactorsOfAllVehicles(self, linear_cost_factor, quadratic_cost_factor)
-
-
-
-def SetAmortizedCostFactorsOfVehicle(self, linear_cost_factor: int64_t, quadratic_cost_factor: int64_t, vehicle: int) ‑> void -
-
-

Sets the linear and quadratic cost factor of the given vehicle.

-
- -Expand source code - -
def SetAmortizedCostFactorsOfVehicle(self, linear_cost_factor: "int64_t", quadratic_cost_factor: "int64_t", vehicle: "int") -> "void":
-    r""" Sets the linear and quadratic cost factor of the given vehicle."""
-    return _pywrapcp.RoutingModel_SetAmortizedCostFactorsOfVehicle(self, linear_cost_factor, quadratic_cost_factor, vehicle)
-
-
-
-def SetArcCostEvaluatorOfAllVehicles(self, evaluator_index: int) ‑> void -
-
-

Sets the cost function of the model such that the cost of a segment of a -route between node 'from' and 'to' is evaluator(from, to), whatever the -route or vehicle performing the route.

-
- -Expand source code - -
def SetArcCostEvaluatorOfAllVehicles(self, evaluator_index: "int") -> "void":
-    r"""
-    Sets the cost function of the model such that the cost of a segment of a
-    route between node 'from' and 'to' is evaluator(from, to), whatever the
-    route or vehicle performing the route.
-    """
-    return _pywrapcp.RoutingModel_SetArcCostEvaluatorOfAllVehicles(self, evaluator_index)
-
-
-
-def SetArcCostEvaluatorOfVehicle(self, evaluator_index: int, vehicle: int) ‑> void -
-
-

Sets the cost function for a given vehicle route.

-
- -Expand source code - -
def SetArcCostEvaluatorOfVehicle(self, evaluator_index: "int", vehicle: "int") -> "void":
-    r""" Sets the cost function for a given vehicle route."""
-    return _pywrapcp.RoutingModel_SetArcCostEvaluatorOfVehicle(self, evaluator_index, vehicle)
-
-
-
-def SetAssignmentFromOtherModelAssignment(self, target_assignment: Assignment, source_model: RoutingModel, source_assignment: Assignment) ‑> void -
-
-

Given a "source_model" and its "source_assignment", resets -"target_assignment" with the IntVar variables (nexts_, and vehicle_vars_ -if costs aren't homogeneous across vehicles) of "this" model, with the -values set according to those in "other_assignment". -The objective_element of target_assignment is set to this->cost_.

-
- -Expand source code - -
def SetAssignmentFromOtherModelAssignment(self, target_assignment: "Assignment", source_model: "RoutingModel", source_assignment: "Assignment") -> "void":
-    r"""
-    Given a "source_model" and its "source_assignment", resets
-    "target_assignment" with the IntVar variables (nexts_, and vehicle_vars_
-    if costs aren't homogeneous across vehicles) of "this" model, with the
-    values set according to those in "other_assignment".
-    The objective_element of target_assignment is set to this->cost_.
-    """
-    return _pywrapcp.RoutingModel_SetAssignmentFromOtherModelAssignment(self, target_assignment, source_model, source_assignment)
-
-
-
-def SetFirstSolutionEvaluator(self, evaluator: operations_research::Solver::IndexEvaluator2) ‑> void -
-
-

Gets/sets the evaluator used during the search. Only relevant when -RoutingSearchParameters.first_solution_strategy = EVALUATOR_STRATEGY. -Takes ownership of evaluator.

-
- -Expand source code - -
def SetFirstSolutionEvaluator(self, evaluator: "operations_research::Solver::IndexEvaluator2") -> "void":
-    r"""
-    Gets/sets the evaluator used during the search. Only relevant when
-    RoutingSearchParameters.first_solution_strategy = EVALUATOR_STRATEGY.
-    Takes ownership of evaluator.
-    """
-    return _pywrapcp.RoutingModel_SetFirstSolutionEvaluator(self, evaluator)
-
-
-
-def SetFixedCostOfAllVehicles(self, cost: int64_t) ‑> void -
-
-

Sets the fixed cost of all vehicle routes. It is equivalent to calling -SetFixedCostOfVehicle on all vehicle routes.

-
- -Expand source code - -
def SetFixedCostOfAllVehicles(self, cost: "int64_t") -> "void":
-    r"""
-    Sets the fixed cost of all vehicle routes. It is equivalent to calling
-    SetFixedCostOfVehicle on all vehicle routes.
-    """
-    return _pywrapcp.RoutingModel_SetFixedCostOfAllVehicles(self, cost)
-
-
-
-def SetFixedCostOfVehicle(self, cost: int64_t, vehicle: int) ‑> void -
-
-

Sets the fixed cost of one vehicle route.

-
- -Expand source code - -
def SetFixedCostOfVehicle(self, cost: "int64_t", vehicle: "int") -> "void":
-    r""" Sets the fixed cost of one vehicle route."""
-    return _pywrapcp.RoutingModel_SetFixedCostOfVehicle(self, cost, vehicle)
-
-
-
-def SetMaximumNumberOfActiveVehicles(self, max_active_vehicles: int) ‑> void -
-
-

Constrains the maximum number of active vehicles, aka the number of -vehicles which do not have an empty route. For instance, this can be used -to limit the number of routes in the case where there are fewer drivers -than vehicles and that the fleet of vehicle is heterogeneous.

-
- -Expand source code - -
def SetMaximumNumberOfActiveVehicles(self, max_active_vehicles: "int") -> "void":
-    r"""
-    Constrains the maximum number of active vehicles, aka the number of
-    vehicles which do not have an empty route. For instance, this can be used
-    to limit the number of routes in the case where there are fewer drivers
-    than vehicles and that the fleet of vehicle is heterogeneous.
-    """
-    return _pywrapcp.RoutingModel_SetMaximumNumberOfActiveVehicles(self, max_active_vehicles)
-
-
-
-def SetPickupAndDeliveryPolicyOfAllVehicles(self, policy: operations_research::RoutingModel::PickupAndDeliveryPolicy) ‑> void -
-
-

Sets the Pickup and delivery policy of all vehicles. It is equivalent to -calling SetPickupAndDeliveryPolicyOfVehicle on all vehicles.

-
- -Expand source code - -
def SetPickupAndDeliveryPolicyOfAllVehicles(self, policy: "operations_research::RoutingModel::PickupAndDeliveryPolicy") -> "void":
-    r"""
-    Sets the Pickup and delivery policy of all vehicles. It is equivalent to
-    calling SetPickupAndDeliveryPolicyOfVehicle on all vehicles.
-    """
-    return _pywrapcp.RoutingModel_SetPickupAndDeliveryPolicyOfAllVehicles(self, policy)
-
-
-
-def SetPickupAndDeliveryPolicyOfVehicle(self, policy: operations_research::RoutingModel::PickupAndDeliveryPolicy, vehicle: int) ‑> void -
-
-
-
- -Expand source code - -
def SetPickupAndDeliveryPolicyOfVehicle(self, policy: "operations_research::RoutingModel::PickupAndDeliveryPolicy", vehicle: "int") -> "void":
-    return _pywrapcp.RoutingModel_SetPickupAndDeliveryPolicyOfVehicle(self, policy, vehicle)
-
-
-
-def SetPrimaryConstrainedDimension(self, dimension_name: std::string const &) ‑> void -
-
-

Set the given dimension as "primary constrained". As of August 2013, this -is only used by ArcIsMoreConstrainedThanArc(). -"dimension" must be the name of an existing dimension, or be empty, in -which case there will not be a primary dimension after this call.

-
- -Expand source code - -
def SetPrimaryConstrainedDimension(self, dimension_name: "std::string const &") -> "void":
-    r"""
-    Set the given dimension as "primary constrained". As of August 2013, this
-    is only used by ArcIsMoreConstrainedThanArc().
-    "dimension" must be the name of an existing dimension, or be empty, in
-    which case there will not be a primary dimension after this call.
-    """
-    return _pywrapcp.RoutingModel_SetPrimaryConstrainedDimension(self, dimension_name)
-
-
-
-def SetVisitType(self, index: int64_t, type: int, type_policy: operations_research::RoutingModel::VisitTypePolicy) ‑> void -
-
-
-
- -Expand source code - -
def SetVisitType(self, index: "int64_t", type: "int", type_policy: "operations_research::RoutingModel::VisitTypePolicy") -> "void":
-    return _pywrapcp.RoutingModel_SetVisitType(self, index, type, type_policy)
-
-
-
-def Size(self) ‑> int64_t -
-
-

Returns the number of next variables in the model.

-
- -Expand source code - -
def Size(self) -> "int64_t":
-    r""" Returns the number of next variables in the model."""
-    return _pywrapcp.RoutingModel_Size(self)
-
-
-
-def Solve(self, assignment: Assignment = None) ‑> operations_research::Assignment const * -
-
-

Solves the current routing model; closes the current model. -This is equivalent to calling -SolveWithParameters(DefaultRoutingSearchParameters()) -or -SolveFromAssignmentWithParameters(assignment, -DefaultRoutingSearchParameters()).

-
- -Expand source code - -
def Solve(self, assignment: "Assignment"=None) -> "operations_research::Assignment const *":
-    r"""
-    Solves the current routing model; closes the current model.
-    This is equivalent to calling
-    SolveWithParameters(DefaultRoutingSearchParameters())
-    or
-    SolveFromAssignmentWithParameters(assignment,
-                                      DefaultRoutingSearchParameters()).
-    """
-    return _pywrapcp.RoutingModel_Solve(self, assignment)
-
-
-
-def SolveFromAssignmentWithParameters(self, assignment: Assignment, search_parameters: operations_research::RoutingSearchParameters const &, solutions: std::vector< operations_research::Assignment const * > * = None) ‑> operations_research::Assignment const * -
-
-

Same as above, except that if assignment is not null, it will be used as -the initial solution.

-
- -Expand source code - -
def SolveFromAssignmentWithParameters(self, assignment: "Assignment", search_parameters: "operations_research::RoutingSearchParameters const &", solutions: "std::vector< operations_research::Assignment const * > *"=None) -> "operations_research::Assignment const *":
-    r"""
-    Same as above, except that if assignment is not null, it will be used as
-    the initial solution.
-    """
-    return _pywrapcp.RoutingModel_SolveFromAssignmentWithParameters(self, assignment, search_parameters, solutions)
-
-
-
-def SolveFromAssignmentsWithParameters(self, assignments: std::vector< operations_research::Assignment const * > const &, search_parameters: operations_research::RoutingSearchParameters const &, solutions: std::vector< operations_research::Assignment const * > * = None) ‑> operations_research::Assignment const * -
-
-

Same as above but will try all assignments in order as first solutions -until one succeeds.

-
- -Expand source code - -
def SolveFromAssignmentsWithParameters(self, assignments: "std::vector< operations_research::Assignment const * > const &", search_parameters: "operations_research::RoutingSearchParameters const &", solutions: "std::vector< operations_research::Assignment const * > *"=None) -> "operations_research::Assignment const *":
-    r"""
-    Same as above but will try all assignments in order as first solutions
-    until one succeeds.
-    """
-    return _pywrapcp.RoutingModel_SolveFromAssignmentsWithParameters(self, assignments, search_parameters, solutions)
-
-
-
-def SolveWithParameters(self, search_parameters: operations_research::RoutingSearchParameters const &, solutions: std::vector< operations_research::Assignment const * > * = None) ‑> operations_research::Assignment const * -
-
-

Solves the current routing model with the given parameters. If 'solutions' -is specified, it will contain the k best solutions found during the search -(from worst to best, including the one returned by this method), where k -corresponds to the 'number_of_solutions_to_collect' in -'search_parameters'. Note that the Assignment returned by the method and -the ones in solutions are owned by the underlying solver and should not be -deleted.

-
- -Expand source code - -
def SolveWithParameters(self, search_parameters: "operations_research::RoutingSearchParameters const &", solutions: "std::vector< operations_research::Assignment const * > *"=None) -> "operations_research::Assignment const *":
-    r"""
-    Solves the current routing model with the given parameters. If 'solutions'
-    is specified, it will contain the k best solutions found during the search
-    (from worst to best, including the one returned by this method), where k
-    corresponds to the 'number_of_solutions_to_collect' in
-    'search_parameters'. Note that the Assignment returned by the method and
-    the ones in solutions are owned by the underlying solver and should not be
-    deleted.
-    """
-    return _pywrapcp.RoutingModel_SolveWithParameters(self, search_parameters, solutions)
-
-
-
-def Start(self, vehicle: int) ‑> int64_t -
-
-

Model inspection. -Returns the variable index of the starting node of a vehicle route.

-
- -Expand source code - -
def Start(self, vehicle: "int") -> "int64_t":
-    r"""
-    Model inspection.
-    Returns the variable index of the starting node of a vehicle route.
-    """
-    return _pywrapcp.RoutingModel_Start(self, vehicle)
-
-
-
-def TransitCallback(self, callback_index: int) ‑> operations_research::RoutingModel::TransitCallback2 const & -
-
-
-
- -Expand source code - -
def TransitCallback(self, callback_index: "int") -> "operations_research::RoutingModel::TransitCallback2 const &":
-    return _pywrapcp.RoutingModel_TransitCallback(self, callback_index)
-
-
-
-def UnaryTransitCallbackOrNull(self, callback_index: int) ‑> operations_research::RoutingModel::TransitCallback1 const & -
-
-
-
- -Expand source code - -
def UnaryTransitCallbackOrNull(self, callback_index: "int") -> "operations_research::RoutingModel::TransitCallback1 const &":
-    return _pywrapcp.RoutingModel_UnaryTransitCallbackOrNull(self, callback_index)
-
-
-
-def UnperformedPenalty(self, var_index: int64_t) ‑> int64_t -
-
-

Get the "unperformed" penalty of a node. This is only well defined if the -node is only part of a single Disjunction involving only itself, and that -disjunction has a penalty. In all other cases, including forced active -nodes, this returns 0.

-
- -Expand source code - -
def UnperformedPenalty(self, var_index: "int64_t") -> "int64_t":
-    r"""
-    Get the "unperformed" penalty of a node. This is only well defined if the
-    node is only part of a single Disjunction involving only itself, and that
-    disjunction has a penalty. In all other cases, including forced active
-    nodes, this returns 0.
-    """
-    return _pywrapcp.RoutingModel_UnperformedPenalty(self, var_index)
-
-
-
-def UnperformedPenaltyOrValue(self, default_value: int64_t, var_index: int64_t) ‑> int64_t -
-
-

Same as above except that it returns default_value instead of 0 when -penalty is not well defined (default value is passed as first argument to -simplify the usage of the method in a callback).

-
- -Expand source code - -
def UnperformedPenaltyOrValue(self, default_value: "int64_t", var_index: "int64_t") -> "int64_t":
-    r"""
-    Same as above except that it returns default_value instead of 0 when
-    penalty is not well defined (default value is passed as first argument to
-    simplify the usage of the method in a callback).
-    """
-    return _pywrapcp.RoutingModel_UnperformedPenaltyOrValue(self, default_value, var_index)
-
-
-
-def VehicleCostsConsideredVar(self, vehicle: int) ‑> operations_research::IntVar * -
-
-

Returns the variable specifying whether or not costs are considered for -vehicle.

-
- -Expand source code - -
def VehicleCostsConsideredVar(self, vehicle: "int") -> "operations_research::IntVar *":
-    r"""
-    Returns the variable specifying whether or not costs are considered for
-    vehicle.
-    """
-    return _pywrapcp.RoutingModel_VehicleCostsConsideredVar(self, vehicle)
-
-
-
-def VehicleIndex(self, index: int64_t) ‑> int -
-
-

Returns the vehicle of the given start/end index, and -1 if the given -index is not a vehicle start/end.

-
- -Expand source code - -
def VehicleIndex(self, index: "int64_t") -> "int":
-    r"""
-    Returns the vehicle of the given start/end index, and -1 if the given
-    index is not a vehicle start/end.
-    """
-    return _pywrapcp.RoutingModel_VehicleIndex(self, index)
-
-
-
-def VehicleVar(self, index: int64_t) ‑> operations_research::IntVar * -
-
-

Returns the vehicle variable of the node corresponding to index. Note that -VehicleVar(index) == -1 is equivalent to ActiveVar(index) == 0.

-
- -Expand source code - -
def VehicleVar(self, index: "int64_t") -> "operations_research::IntVar *":
-    r"""
-    Returns the vehicle variable of the node corresponding to index. Note that
-    VehicleVar(index) == -1 is equivalent to ActiveVar(index) == 0.
-    """
-    return _pywrapcp.RoutingModel_VehicleVar(self, index)
-
-
-
-def WriteAssignment(self, file_name: std::string const &) ‑> bool -
-
-

Writes the current solution to a file containing an AssignmentProto. -Returns false if the file cannot be opened or if there is no current -solution.

-
- -Expand source code - -
def WriteAssignment(self, file_name: "std::string const &") -> "bool":
-    r"""
-    Writes the current solution to a file containing an AssignmentProto.
-    Returns false if the file cannot be opened or if there is no current
-    solution.
-    """
-    return _pywrapcp.RoutingModel_WriteAssignment(self, file_name)
-
-
-
-def nodes(self) ‑> int -
-
-

Sizes and indices -Returns the number of nodes in the model.

-
- -Expand source code - -
def nodes(self) -> "int":
-    r"""
-    Sizes and indices
-    Returns the number of nodes in the model.
-    """
-    return _pywrapcp.RoutingModel_nodes(self)
-
-
-
-def solver(self) ‑> operations_research::Solver * -
-
-

Returns a vector cumul_bounds, for which cumul_bounds[i][j] is a pair -containing the minimum and maximum of the CumulVar of the jth node on -route i. -- cumul_bounds[i][j].first is the minimum. -- cumul_bounds[i][j].second is the maximum. -Returns the underlying constraint solver. Can be used to add extra -constraints and/or modify search algoithms.

-
- -Expand source code - -
def solver(self) -> "operations_research::Solver *":
-    r"""
-    Returns a vector cumul_bounds, for which cumul_bounds[i][j] is a pair
-    containing the minimum and maximum of the CumulVar of the jth node on
-    route i.
-    - cumul_bounds[i][j].first is the minimum.
-    - cumul_bounds[i][j].second is the maximum.
-    Returns the underlying constraint solver. Can be used to add extra
-    constraints and/or modify search algoithms.
-    """
-    return _pywrapcp.RoutingModel_solver(self)
-
-
-
-def status(self) ‑> operations_research::RoutingModel::Status -
-
-

Returns the current status of the routing model.

-
- -Expand source code - -
def status(self) -> "operations_research::RoutingModel::Status":
-    r""" Returns the current status of the routing model."""
-    return _pywrapcp.RoutingModel_status(self)
-
-
-
-def vehicles(self) ‑> int -
-
-

Returns the number of vehicle routes in the model.

-
- -Expand source code - -
def vehicles(self) -> "int":
-    r""" Returns the number of vehicle routes in the model."""
-    return _pywrapcp.RoutingModel_vehicles(self)
-
-
-
-
-
-class RoutingModelVisitor -
-
-

Routing model visitor.

-
- -Expand source code - -
class RoutingModelVisitor(BaseObject):
-    r""" Routing model visitor."""
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self):
-        _pywrapcp.RoutingModelVisitor_swiginit(self, _pywrapcp.new_RoutingModelVisitor())
-    __swig_destroy__ = _pywrapcp.delete_RoutingModelVisitor
-
-

Ancestors

- -

Class variables

-
-
var kLightElement
-
-
-
-
var kLightElement2
-
-
-
-
var kRemoveValues
-
-
-
-
-

Inherited members

- -
-
-class SearchLimit -(*args, **kwargs) -
-
-

Base class of all search limits.

-
- -Expand source code - -
class SearchLimit(SearchMonitor):
-    r""" Base class of all search limits."""
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
-    __repr__ = _swig_repr
-    __swig_destroy__ = _pywrapcp.delete_SearchLimit
-
-    def Crossed(self) -> "bool":
-        r""" Returns true if the limit has been crossed."""
-        return _pywrapcp.SearchLimit_Crossed(self)
-
-    def Check(self) -> "bool":
-        r"""
-        This method is called to check the status of the limit. A return
-        value of true indicates that we have indeed crossed the limit. In
-        that case, this method will not be called again and the remaining
-        search will be discarded.
-        """
-        return _pywrapcp.SearchLimit_Check(self)
-
-    def Init(self) -> "void":
-        r""" This method is called when the search limit is initialized."""
-        return _pywrapcp.SearchLimit_Init(self)
-
-    def EnterSearch(self) -> "void":
-        r""" Internal methods."""
-        return _pywrapcp.SearchLimit_EnterSearch(self)
-
-    def BeginNextDecision(self, b: "DecisionBuilder") -> "void":
-        return _pywrapcp.SearchLimit_BeginNextDecision(self, b)
-
-    def RefuteDecision(self, d: "Decision") -> "void":
-        return _pywrapcp.SearchLimit_RefuteDecision(self, d)
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.SearchLimit_DebugString(self)
-
-

Ancestors

- -

Methods

-
-
-def Check(self) ‑> bool -
-
-

This method is called to check the status of the limit. A return -value of true indicates that we have indeed crossed the limit. In -that case, this method will not be called again and the remaining -search will be discarded.

-
- -Expand source code - -
def Check(self) -> "bool":
-    r"""
-    This method is called to check the status of the limit. A return
-    value of true indicates that we have indeed crossed the limit. In
-    that case, this method will not be called again and the remaining
-    search will be discarded.
-    """
-    return _pywrapcp.SearchLimit_Check(self)
-
-
-
-def Crossed(self) ‑> bool -
-
-

Returns true if the limit has been crossed.

-
- -Expand source code - -
def Crossed(self) -> "bool":
-    r""" Returns true if the limit has been crossed."""
-    return _pywrapcp.SearchLimit_Crossed(self)
-
-
-
-def DebugString(self) ‑> std::string -
-
-
-
- -Expand source code - -
def DebugString(self) -> "std::string":
-    return _pywrapcp.SearchLimit_DebugString(self)
-
-
-
-def EnterSearch(self) ‑> void -
-
-

Internal methods.

-
- -Expand source code - -
def EnterSearch(self) -> "void":
-    r""" Internal methods."""
-    return _pywrapcp.SearchLimit_EnterSearch(self)
-
-
-
-def Init(self) ‑> void -
-
-

This method is called when the search limit is initialized.

-
- -Expand source code - -
def Init(self) -> "void":
-    r""" This method is called when the search limit is initialized."""
-    return _pywrapcp.SearchLimit_Init(self)
-
-
-
-

Inherited members

- -
-
-class SearchMonitor -(s: Solver) -
-
-

A search monitor is a simple set of callbacks to monitor all search events

-
- -Expand source code - -
class SearchMonitor(BaseObject):
-    r""" A search monitor is a simple set of callbacks to monitor all search events"""
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, s: "Solver"):
-        if self.__class__ == SearchMonitor:
-            _self = None
-        else:
-            _self = self
-        _pywrapcp.SearchMonitor_swiginit(self, _pywrapcp.new_SearchMonitor(_self, s))
-    __swig_destroy__ = _pywrapcp.delete_SearchMonitor
-
-    def EnterSearch(self) -> "void":
-        r""" Beginning of the search."""
-        return _pywrapcp.SearchMonitor_EnterSearch(self)
-
-    def RestartSearch(self) -> "void":
-        r""" Restart the search."""
-        return _pywrapcp.SearchMonitor_RestartSearch(self)
-
-    def ExitSearch(self) -> "void":
-        r""" End of the search."""
-        return _pywrapcp.SearchMonitor_ExitSearch(self)
-
-    def BeginNextDecision(self, b: "DecisionBuilder") -> "void":
-        r""" Before calling DecisionBuilder::Next."""
-        return _pywrapcp.SearchMonitor_BeginNextDecision(self, b)
-
-    def EndNextDecision(self, b: "DecisionBuilder", d: "Decision") -> "void":
-        r""" After calling DecisionBuilder::Next, along with the returned decision."""
-        return _pywrapcp.SearchMonitor_EndNextDecision(self, b, d)
-
-    def ApplyDecision(self, d: "Decision") -> "void":
-        r""" Before applying the decision."""
-        return _pywrapcp.SearchMonitor_ApplyDecision(self, d)
-
-    def RefuteDecision(self, d: "Decision") -> "void":
-        r""" Before refuting the decision."""
-        return _pywrapcp.SearchMonitor_RefuteDecision(self, d)
-
-    def AfterDecision(self, d: "Decision", apply: "bool") -> "void":
-        r"""
-        Just after refuting or applying the decision, apply is true after Apply.
-        This is called only if the Apply() or Refute() methods have not failed.
-        """
-        return _pywrapcp.SearchMonitor_AfterDecision(self, d, apply)
-
-    def BeginFail(self) -> "void":
-        r""" Just when the failure occurs."""
-        return _pywrapcp.SearchMonitor_BeginFail(self)
-
-    def EndFail(self) -> "void":
-        r""" After completing the backtrack."""
-        return _pywrapcp.SearchMonitor_EndFail(self)
-
-    def BeginInitialPropagation(self) -> "void":
-        r""" Before the initial propagation."""
-        return _pywrapcp.SearchMonitor_BeginInitialPropagation(self)
-
-    def EndInitialPropagation(self) -> "void":
-        r""" After the initial propagation."""
-        return _pywrapcp.SearchMonitor_EndInitialPropagation(self)
-
-    def AcceptSolution(self) -> "bool":
-        r"""
-        This method is called when a solution is found. It asserts whether the
-        solution is valid. A value of false indicates that the solution
-        should be discarded.
-        """
-        return _pywrapcp.SearchMonitor_AcceptSolution(self)
-
-    def AtSolution(self) -> "bool":
-        r"""
-        This method is called when a valid solution is found. If the
-        return value is true, then search will resume after. If the result
-        is false, then search will stop there.
-        """
-        return _pywrapcp.SearchMonitor_AtSolution(self)
-
-    def NoMoreSolutions(self) -> "void":
-        r""" When the search tree is finished."""
-        return _pywrapcp.SearchMonitor_NoMoreSolutions(self)
-
-    def LocalOptimum(self) -> "bool":
-        r"""
-        When a local optimum is reached. If 'true' is returned, the last solution
-        is discarded and the search proceeds with the next one.
-        """
-        return _pywrapcp.SearchMonitor_LocalOptimum(self)
-
-    def AcceptDelta(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
         
-        return _pywrapcp.SearchMonitor_AcceptDelta(self, delta, deltadelta)
+            DefaultPhaseParameters()
+    
 
-    def AcceptNeighbor(self) -> "void":
-        r""" After accepting a neighbor during local search."""
-        return _pywrapcp.SearchMonitor_AcceptNeighbor(self)
+                
+ View Source +
    def __init__(self):
+        _pywrapcp.DefaultPhaseParameters_swiginit(self, _pywrapcp.new_DefaultPhaseParameters())
+
- def solver(self) -> "operations_research::Solver *": - return _pywrapcp.SearchMonitor_solver(self) +
- def __repr__(self) -> "std::string": - return _pywrapcp.SearchMonitor___repr__(self) - - def __str__(self) -> "std::string": - return _pywrapcp.SearchMonitor___str__(self) - def __disown__(self): - self.this.disown() - _pywrapcp.disown_SearchMonitor(self) - return weakref.proxy(self)
-
-

Ancestors

- -

Subclasses

- -

Methods

-
-
-def AcceptDelta(self, delta: Assignment, deltadelta: Assignment) ‑> bool -
-
-
-
- -Expand source code - -
def AcceptDelta(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
     
-    return _pywrapcp.SearchMonitor_AcceptDelta(self, delta, deltadelta)
-
-
-
-def AcceptNeighbor(self) ‑> void -
-
-

After accepting a neighbor during local search.

-
- -Expand source code - -
def AcceptNeighbor(self) -> "void":
-    r""" After accepting a neighbor during local search."""
-    return _pywrapcp.SearchMonitor_AcceptNeighbor(self)
-
-
-
-def AcceptSolution(self) ‑> bool -
-
-

This method is called when a solution is found. It asserts whether the -solution is valid. A value of false indicates that the solution -should be discarded.

-
- -Expand source code - -
def AcceptSolution(self) -> "bool":
-    r"""
-    This method is called when a solution is found. It asserts whether the
-    solution is valid. A value of false indicates that the solution
-    should be discarded.
-    """
-    return _pywrapcp.SearchMonitor_AcceptSolution(self)
-
-
-
-def AfterDecision(self, d: Decision, apply: bool) ‑> void -
-
-

Just after refuting or applying the decision, apply is true after Apply. -This is called only if the Apply() or Refute() methods have not failed.

-
- -Expand source code - -
def AfterDecision(self, d: "Decision", apply: "bool") -> "void":
-    r"""
-    Just after refuting or applying the decision, apply is true after Apply.
-    This is called only if the Apply() or Refute() methods have not failed.
-    """
-    return _pywrapcp.SearchMonitor_AfterDecision(self, d, apply)
-
-
-
-def ApplyDecision(self, d: Decision) ‑> void -
-
-

Before applying the decision.

-
- -Expand source code - -
def ApplyDecision(self, d: "Decision") -> "void":
-    r""" Before applying the decision."""
-    return _pywrapcp.SearchMonitor_ApplyDecision(self, d)
-
-
-
-def AtSolution(self) ‑> bool -
-
-

This method is called when a valid solution is found. If the -return value is true, then search will resume after. If the result -is false, then search will stop there.

-
- -Expand source code - -
def AtSolution(self) -> "bool":
-    r"""
-    This method is called when a valid solution is found. If the
-    return value is true, then search will resume after. If the result
-    is false, then search will stop there.
-    """
-    return _pywrapcp.SearchMonitor_AtSolution(self)
-
-
-
-def BeginFail(self) ‑> void -
-
-

Just when the failure occurs.

-
- -Expand source code - -
def BeginFail(self) -> "void":
-    r""" Just when the failure occurs."""
-    return _pywrapcp.SearchMonitor_BeginFail(self)
-
-
-
-def BeginInitialPropagation(self) ‑> void -
-
-

Before the initial propagation.

-
- -Expand source code - -
def BeginInitialPropagation(self) -> "void":
-    r""" Before the initial propagation."""
-    return _pywrapcp.SearchMonitor_BeginInitialPropagation(self)
-
-
-
-def BeginNextDecision(self, b: DecisionBuilder) ‑> void -
-
-

Before calling DecisionBuilder::Next.

-
- -Expand source code - -
def BeginNextDecision(self, b: "DecisionBuilder") -> "void":
-    r""" Before calling DecisionBuilder::Next."""
-    return _pywrapcp.SearchMonitor_BeginNextDecision(self, b)
-
-
-
-def EndFail(self) ‑> void -
-
-

After completing the backtrack.

-
- -Expand source code - -
def EndFail(self) -> "void":
-    r""" After completing the backtrack."""
-    return _pywrapcp.SearchMonitor_EndFail(self)
-
-
-
-def EndInitialPropagation(self) ‑> void -
-
-

After the initial propagation.

-
- -Expand source code - -
def EndInitialPropagation(self) -> "void":
-    r""" After the initial propagation."""
-    return _pywrapcp.SearchMonitor_EndInitialPropagation(self)
-
-
-
-def EndNextDecision(self, b: DecisionBuilder, d: Decision) ‑> void -
-
-

After calling DecisionBuilder::Next, along with the returned decision.

-
- -Expand source code - -
def EndNextDecision(self, b: "DecisionBuilder", d: "Decision") -> "void":
-    r""" After calling DecisionBuilder::Next, along with the returned decision."""
-    return _pywrapcp.SearchMonitor_EndNextDecision(self, b, d)
-
-
-
-def EnterSearch(self) ‑> void -
-
-

Beginning of the search.

-
- -Expand source code - -
def EnterSearch(self) -> "void":
-    r""" Beginning of the search."""
-    return _pywrapcp.SearchMonitor_EnterSearch(self)
-
-
-
-def ExitSearch(self) ‑> void -
-
-

End of the search.

-
- -Expand source code - -
def ExitSearch(self) -> "void":
-    r""" End of the search."""
-    return _pywrapcp.SearchMonitor_ExitSearch(self)
-
-
-
-def LocalOptimum(self) ‑> bool -
-
-

When a local optimum is reached. If 'true' is returned, the last solution -is discarded and the search proceeds with the next one.

-
- -Expand source code - -
def LocalOptimum(self) -> "bool":
-    r"""
-    When a local optimum is reached. If 'true' is returned, the last solution
-    is discarded and the search proceeds with the next one.
-    """
-    return _pywrapcp.SearchMonitor_LocalOptimum(self)
-
-
-
-def NoMoreSolutions(self) ‑> void -
-
-

When the search tree is finished.

-
- -Expand source code - -
def NoMoreSolutions(self) -> "void":
-    r""" When the search tree is finished."""
-    return _pywrapcp.SearchMonitor_NoMoreSolutions(self)
-
-
-
-def RefuteDecision(self, d: Decision) ‑> void -
-
-

Before refuting the decision.

-
- -Expand source code - -
def RefuteDecision(self, d: "Decision") -> "void":
-    r""" Before refuting the decision."""
-    return _pywrapcp.SearchMonitor_RefuteDecision(self, d)
-
-
-
-def RestartSearch(self) ‑> void -
-
-

Restart the search.

-
- -Expand source code - -
def RestartSearch(self) -> "void":
-    r""" Restart the search."""
-    return _pywrapcp.SearchMonitor_RestartSearch(self)
-
-
-
-def solver(self) ‑> operations_research::Solver * -
-
-
-
- -Expand source code - -
def solver(self) -> "operations_research::Solver *":
-    return _pywrapcp.SearchMonitor_solver(self)
-
-
-
-

Inherited members

- -
-
-class SequenceVar -(*args, **kwargs) -
-
-

A sequence variable is a variable whose domain is a set of possible -orderings of the interval variables. It allows ordering of tasks. It -has two sets of methods: ComputePossibleFirstsAndLasts(), which -returns the list of interval variables that can be ranked first or -last; and RankFirst/RankNotFirst/RankLast/RankNotLast, which can be -used to create the search decision.

-
- -Expand source code - -
class SequenceVar(PropagationBaseObject):
-    r"""
-    A sequence variable is a variable whose domain is a set of possible
-    orderings of the interval variables. It allows ordering of tasks. It
-    has two sets of methods: ComputePossibleFirstsAndLasts(), which
-    returns the list of interval variables that can be ranked first or
-    last; and RankFirst/RankNotFirst/RankLast/RankNotLast, which can be
-    used to create the search decision.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined")
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.SequenceVar_DebugString(self)
-
-    def RankFirst(self, index: "int") -> "void":
-        r"""
-        Ranks the index_th interval var first of all unranked interval
-        vars. After that, it will no longer be considered ranked.
-        """
-        return _pywrapcp.SequenceVar_RankFirst(self, index)
-
-    def RankNotFirst(self, index: "int") -> "void":
-        r"""
-        Indicates that the index_th interval var will not be ranked first
-        of all currently unranked interval vars.
-        """
-        return _pywrapcp.SequenceVar_RankNotFirst(self, index)
-
-    def RankLast(self, index: "int") -> "void":
-        r"""
-        Ranks the index_th interval var first of all unranked interval
-        vars. After that, it will no longer be considered ranked.
-        """
-        return _pywrapcp.SequenceVar_RankLast(self, index)
-
-    def RankNotLast(self, index: "int") -> "void":
-        r"""
-        Indicates that the index_th interval var will not be ranked first
-        of all currently unranked interval vars.
-        """
-        return _pywrapcp.SequenceVar_RankNotLast(self, index)
-
-    def Interval(self, index: "int") -> "operations_research::IntervalVar *":
-        r""" Returns the index_th interval of the sequence."""
-        return _pywrapcp.SequenceVar_Interval(self, index)
-
-    def Next(self, index: "int") -> "operations_research::IntVar *":
-        r""" Returns the next of the index_th interval of the sequence."""
-        return _pywrapcp.SequenceVar_Next(self, index)
-
-    def Size(self) -> "int64_t":
-        r""" Returns the number of interval vars in the sequence."""
-        return _pywrapcp.SequenceVar_Size(self)
-
-    def __repr__(self) -> "std::string":
-        return _pywrapcp.SequenceVar___repr__(self)
-
-    def __str__(self) -> "std::string":
-        return _pywrapcp.SequenceVar___str__(self)
-
-

Ancestors

- -

Methods

-
-
-def DebugString(self) ‑> std::string -
-
-
-
- -Expand source code - -
def DebugString(self) -> "std::string":
-    return _pywrapcp.SequenceVar_DebugString(self)
-
-
-
-def Interval(self, index: int) ‑> operations_research::IntervalVar * -
-
-

Returns the index_th interval of the sequence.

-
- -Expand source code - -
def Interval(self, index: "int") -> "operations_research::IntervalVar *":
-    r""" Returns the index_th interval of the sequence."""
-    return _pywrapcp.SequenceVar_Interval(self, index)
-
-
-
-def Next(self, index: int) ‑> operations_research::IntVar * -
-
-

Returns the next of the index_th interval of the sequence.

-
- -Expand source code - -
def Next(self, index: "int") -> "operations_research::IntVar *":
-    r""" Returns the next of the index_th interval of the sequence."""
-    return _pywrapcp.SequenceVar_Next(self, index)
-
-
-
-def RankFirst(self, index: int) ‑> void -
-
-

Ranks the index_th interval var first of all unranked interval -vars. After that, it will no longer be considered ranked.

-
- -Expand source code - -
def RankFirst(self, index: "int") -> "void":
-    r"""
-    Ranks the index_th interval var first of all unranked interval
-    vars. After that, it will no longer be considered ranked.
-    """
-    return _pywrapcp.SequenceVar_RankFirst(self, index)
-
-
-
-def RankLast(self, index: int) ‑> void -
-
-

Ranks the index_th interval var first of all unranked interval -vars. After that, it will no longer be considered ranked.

-
- -Expand source code - -
def RankLast(self, index: "int") -> "void":
-    r"""
-    Ranks the index_th interval var first of all unranked interval
-    vars. After that, it will no longer be considered ranked.
-    """
-    return _pywrapcp.SequenceVar_RankLast(self, index)
-
-
-
-def RankNotFirst(self, index: int) ‑> void -
-
-

Indicates that the index_th interval var will not be ranked first -of all currently unranked interval vars.

-
- -Expand source code - -
def RankNotFirst(self, index: "int") -> "void":
-    r"""
-    Indicates that the index_th interval var will not be ranked first
-    of all currently unranked interval vars.
-    """
-    return _pywrapcp.SequenceVar_RankNotFirst(self, index)
-
-
-
-def RankNotLast(self, index: int) ‑> void -
-
-

Indicates that the index_th interval var will not be ranked first -of all currently unranked interval vars.

-
- -Expand source code - -
def RankNotLast(self, index: "int") -> "void":
-    r"""
-    Indicates that the index_th interval var will not be ranked first
-    of all currently unranked interval vars.
-    """
-    return _pywrapcp.SequenceVar_RankNotLast(self, index)
-
-
-
-def Size(self) ‑> int64_t -
-
-

Returns the number of interval vars in the sequence.

-
- -Expand source code - -
def Size(self) -> "int64_t":
-    r""" Returns the number of interval vars in the sequence."""
-    return _pywrapcp.SequenceVar_Size(self)
-
-
-
-

Inherited members

- -
-
-class SequenceVarContainer -(*args, **kwargs) -
-
-
-
- -Expand source code - -
class SequenceVarContainer(object):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined")
-    __repr__ = _swig_repr
-
-    def Contains(self, var: "SequenceVar") -> "bool":
-        return _pywrapcp.SequenceVarContainer_Contains(self, var)
-
-    def Element(self, index: "int") -> "operations_research::SequenceVarElement *":
-        return _pywrapcp.SequenceVarContainer_Element(self, index)
-
-    def Size(self) -> "int":
-        return _pywrapcp.SequenceVarContainer_Size(self)
-
-    def Store(self) -> "void":
-        return _pywrapcp.SequenceVarContainer_Store(self)
-
-    def Restore(self) -> "void":
-        return _pywrapcp.SequenceVarContainer_Restore(self)
-
-    def __eq__(self, container: "SequenceVarContainer") -> "bool":
-        r"""
-        Returns true if this and 'container' both represent the same V* -> E map.
-        Runs in linear time; requires that the == operator on the type E is well
-        defined.
-        """
-        return _pywrapcp.SequenceVarContainer___eq__(self, container)
-
-    def __ne__(self, container: "SequenceVarContainer") -> "bool":
-        return _pywrapcp.SequenceVarContainer___ne__(self, container)
-    __swig_destroy__ = _pywrapcp.delete_SequenceVarContainer
-
-

Instance variables

-
-
var thisown
-
-

The membership flag

-
- -Expand source code - -
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-
-
-

Methods

-
-
-def Contains(self, var: SequenceVar) ‑> bool -
-
-
-
- -Expand source code - -
def Contains(self, var: "SequenceVar") -> "bool":
-    return _pywrapcp.SequenceVarContainer_Contains(self, var)
-
-
-
-def Element(self, index: int) ‑> operations_research::SequenceVarElement * -
-
-
-
- -Expand source code - -
def Element(self, index: "int") -> "operations_research::SequenceVarElement *":
-    return _pywrapcp.SequenceVarContainer_Element(self, index)
-
-
-
-def Restore(self) ‑> void -
-
-
-
- -Expand source code - -
def Restore(self) -> "void":
-    return _pywrapcp.SequenceVarContainer_Restore(self)
-
-
-
-def Size(self) ‑> int -
-
-
-
- -Expand source code - -
def Size(self) -> "int":
-    return _pywrapcp.SequenceVarContainer_Size(self)
-
-
-
-def Store(self) ‑> void -
-
-
-
- -Expand source code - -
def Store(self) -> "void":
-    return _pywrapcp.SequenceVarContainer_Store(self)
-
-
-
-
-
-class SequenceVarElement -(*args, **kwargs) -
-
-

The SequenceVarElement stores a partial representation of ranked -interval variables in the underlying sequence variable. -This representation consists of three vectors: -- the forward sequence. That is the list of interval variables -ranked first in the sequence. -The first element of the backward -sequence is the first interval in the sequence variable. -- the backward sequence. That is the list of interval variables -ranked last in the sequence. The first element of the backward -sequence is the last interval in the sequence variable. -- The list of unperformed interval variables. -Furthermore, if all performed variables are ranked, then by -convention, the forward_sequence will contain all such variables -and the backward_sequence will be empty.

-
- -Expand source code - -
class SequenceVarElement(AssignmentElement):
-    r"""
-    The SequenceVarElement stores a partial representation of ranked
-    interval variables in the underlying sequence variable.
-    This representation consists of three vectors:
-      - the forward sequence. That is the list of interval variables
-        ranked first in the sequence.  The first element of the backward
-        sequence is the first interval in the sequence variable.
-      - the backward sequence. That is the list of interval variables
-        ranked last in the sequence. The first element of the backward
-        sequence is the last interval in the sequence variable.
-      - The list of unperformed interval variables.
-     Furthermore, if all performed variables are ranked, then by
-     convention, the forward_sequence will contain all such variables
-     and the backward_sequence will be empty.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined")
-    __repr__ = _swig_repr
-
-    def Var(self) -> "operations_research::SequenceVar *":
-        return _pywrapcp.SequenceVarElement_Var(self)
-
-    def ForwardSequence(self) -> "std::vector< int > const &":
-        return _pywrapcp.SequenceVarElement_ForwardSequence(self)
-
-    def BackwardSequence(self) -> "std::vector< int > const &":
-        return _pywrapcp.SequenceVarElement_BackwardSequence(self)
-
-    def Unperformed(self) -> "std::vector< int > const &":
-        return _pywrapcp.SequenceVarElement_Unperformed(self)
-
-    def SetSequence(self, forward_sequence: "std::vector< int > const &", backward_sequence: "std::vector< int > const &", unperformed: "std::vector< int > const &") -> "void":
-        return _pywrapcp.SequenceVarElement_SetSequence(self, forward_sequence, backward_sequence, unperformed)
-
-    def SetForwardSequence(self, forward_sequence: "std::vector< int > const &") -> "void":
-        return _pywrapcp.SequenceVarElement_SetForwardSequence(self, forward_sequence)
-
-    def SetBackwardSequence(self, backward_sequence: "std::vector< int > const &") -> "void":
-        return _pywrapcp.SequenceVarElement_SetBackwardSequence(self, backward_sequence)
-
-    def SetUnperformed(self, unperformed: "std::vector< int > const &") -> "void":
-        return _pywrapcp.SequenceVarElement_SetUnperformed(self, unperformed)
-
-    def __eq__(self, element: "SequenceVarElement") -> "bool":
-        return _pywrapcp.SequenceVarElement___eq__(self, element)
-
-    def __ne__(self, element: "SequenceVarElement") -> "bool":
-        return _pywrapcp.SequenceVarElement___ne__(self, element)
-    __swig_destroy__ = _pywrapcp.delete_SequenceVarElement
-
-

Ancestors

- -

Methods

-
-
-def BackwardSequence(self) ‑> std::vector< int > const & -
-
-
-
- -Expand source code - -
def BackwardSequence(self) -> "std::vector< int > const &":
-    return _pywrapcp.SequenceVarElement_BackwardSequence(self)
-
-
-
-def ForwardSequence(self) ‑> std::vector< int > const & -
-
-
-
- -Expand source code - -
def ForwardSequence(self) -> "std::vector< int > const &":
-    return _pywrapcp.SequenceVarElement_ForwardSequence(self)
-
-
-
-def SetBackwardSequence(self, backward_sequence: std::vector< int > const &) ‑> void -
-
-
-
- -Expand source code - -
def SetBackwardSequence(self, backward_sequence: "std::vector< int > const &") -> "void":
-    return _pywrapcp.SequenceVarElement_SetBackwardSequence(self, backward_sequence)
-
-
-
-def SetForwardSequence(self, forward_sequence: std::vector< int > const &) ‑> void -
-
-
-
- -Expand source code - -
def SetForwardSequence(self, forward_sequence: "std::vector< int > const &") -> "void":
-    return _pywrapcp.SequenceVarElement_SetForwardSequence(self, forward_sequence)
-
-
-
-def SetSequence(self, forward_sequence: std::vector< int > const &, backward_sequence: std::vector< int > const &, unperformed: std::vector< int > const &) ‑> void -
-
-
-
- -Expand source code - -
def SetSequence(self, forward_sequence: "std::vector< int > const &", backward_sequence: "std::vector< int > const &", unperformed: "std::vector< int > const &") -> "void":
-    return _pywrapcp.SequenceVarElement_SetSequence(self, forward_sequence, backward_sequence, unperformed)
-
-
-
-def SetUnperformed(self, unperformed: std::vector< int > const &) ‑> void -
-
-
-
- -Expand source code - -
def SetUnperformed(self, unperformed: "std::vector< int > const &") -> "void":
-    return _pywrapcp.SequenceVarElement_SetUnperformed(self, unperformed)
-
-
-
-def Unperformed(self) ‑> std::vector< int > const & -
-
-
-
- -Expand source code - -
def Unperformed(self) -> "std::vector< int > const &":
-    return _pywrapcp.SequenceVarElement_Unperformed(self)
-
-
-
-def Var(self) ‑> operations_research::SequenceVar * -
-
-
-
- -Expand source code - -
def Var(self) -> "operations_research::SequenceVar *":
-    return _pywrapcp.SequenceVarElement_Var(self)
-
-
-
-

Inherited members

- -
-
-class SequenceVarLocalSearchOperator -(*args, **kwargs) -
-
-

Base operator class for operators manipulating variables.

-
- -Expand source code - -
class SequenceVarLocalSearchOperator(SequenceVarLocalSearchOperatorTemplate):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
-    __repr__ = _swig_repr
-
-

Ancestors

- -

Inherited members

- -
-
-class SequenceVarLocalSearchOperatorTemplate -(*args, **kwargs) -
-
-

Base operator class for operators manipulating variables.

-
- -Expand source code - -
class SequenceVarLocalSearchOperatorTemplate(LocalSearchOperator):
-    r""" Base operator class for operators manipulating variables."""
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
-    __repr__ = _swig_repr
-
-    def Start(self, assignment: "Assignment") -> "void":
-        r"""
-        This method should not be overridden. Override OnStart() instead which is
-        called before exiting this method.
-        """
-        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_Start(self, assignment)
-
-    def IsIncremental(self) -> "bool":
-        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_IsIncremental(self)
-
-    def Size(self) -> "int":
-        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_Size(self)
-
-    def Value(self, index: "int64_t") -> "std::vector< int > const &":
-        r"""
-        Returns the value in the current assignment of the variable of given
-        index.
-        """
-        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_Value(self, index)
-
-    def OldValue(self, index: "int64_t") -> "std::vector< int > const &":
-        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_OldValue(self, index)
-
-    def SetValue(self, index: "int64_t", value: "std::vector< int > const &") -> "void":
-        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_SetValue(self, index, value)
-
-    def OnStart(self) -> "void":
-        r"""
-        Called by Start() after synchronizing the operator with the current
-        assignment. Should be overridden instead of Start() to avoid calling
-        VarLocalSearchOperator::Start explicitly.
-        """
-        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_OnStart(self)
-
-

Ancestors

- -

Subclasses

- -

Methods

-
-
-def IsIncremental(self) ‑> bool -
-
-
-
- -Expand source code - -
def IsIncremental(self) -> "bool":
-    return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_IsIncremental(self)
-
-
-
-def OldValue(self, index: int64_t) ‑> std::vector< int > const & -
-
-
-
- -Expand source code - -
def OldValue(self, index: "int64_t") -> "std::vector< int > const &":
-    return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_OldValue(self, index)
-
-
-
-def OnStart(self) ‑> void -
-
-

Called by Start() after synchronizing the operator with the current -assignment. Should be overridden instead of Start() to avoid calling -VarLocalSearchOperator::Start explicitly.

-
- -Expand source code - -
def OnStart(self) -> "void":
-    r"""
-    Called by Start() after synchronizing the operator with the current
-    assignment. Should be overridden instead of Start() to avoid calling
-    VarLocalSearchOperator::Start explicitly.
-    """
-    return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_OnStart(self)
-
-
-
-def SetValue(self, index: int64_t, value: std::vector< int > const &) ‑> void -
-
-
-
- -Expand source code - -
def SetValue(self, index: "int64_t", value: "std::vector< int > const &") -> "void":
-    return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_SetValue(self, index, value)
-
-
-
-def Size(self) ‑> int -
-
-
-
- -Expand source code - -
def Size(self) -> "int":
-    return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_Size(self)
-
-
-
-def Start(self, assignment: Assignment) ‑> void -
-
-

This method should not be overridden. Override OnStart() instead which is -called before exiting this method.

-
- -Expand source code - -
def Start(self, assignment: "Assignment") -> "void":
-    r"""
-    This method should not be overridden. Override OnStart() instead which is
-    called before exiting this method.
-    """
-    return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_Start(self, assignment)
-
-
-
-def Value(self, index: int64_t) ‑> std::vector< int > const & -
-
-

Returns the value in the current assignment of the variable of given -index.

-
- -Expand source code - -
def Value(self, index: "int64_t") -> "std::vector< int > const &":
-    r"""
-    Returns the value in the current assignment of the variable of given
-    index.
-    """
-    return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_Value(self, index)
-
-
-
-

Inherited members

- -
-
-class SolutionCollector -(*args, **kwargs) -
-
-

This class is the root class of all solution collectors. -It implements a basic query API to be used independently -of the collector used.

-
- -Expand source code - -
class SolutionCollector(SearchMonitor):
-    r"""
-    This class is the root class of all solution collectors.
-    It implements a basic query API to be used independently
-    of the collector used.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined")
-    __repr__ = _swig_repr
-
-    def DebugString(self) -> "std::string":
-        return _pywrapcp.SolutionCollector_DebugString(self)
-
-    def Add(self, *args) -> "void":
-        return _pywrapcp.SolutionCollector_Add(self, *args)
-
-    def AddObjective(self, objective: "IntVar") -> "void":
-        return _pywrapcp.SolutionCollector_AddObjective(self, objective)
-
-    def EnterSearch(self) -> "void":
-        r""" Beginning of the search."""
-        return _pywrapcp.SolutionCollector_EnterSearch(self)
-
-    def SolutionCount(self) -> "int":
-        r""" Returns how many solutions were stored during the search."""
-        return _pywrapcp.SolutionCollector_SolutionCount(self)
-
-    def Solution(self, n: "int") -> "operations_research::Assignment *":
-        r""" Returns the nth solution."""
-        return _pywrapcp.SolutionCollector_Solution(self, n)
-
-    def WallTime(self, n: "int") -> "int64_t":
-        r""" Returns the wall time in ms for the nth solution."""
-        return _pywrapcp.SolutionCollector_WallTime(self, n)
-
-    def Branches(self, n: "int") -> "int64_t":
-        r""" Returns the number of branches when the nth solution was found."""
-        return _pywrapcp.SolutionCollector_Branches(self, n)
-
-    def Failures(self, n: "int") -> "int64_t":
-        r"""
-        Returns the number of failures encountered at the time of the nth
-        solution.
-        """
-        return _pywrapcp.SolutionCollector_Failures(self, n)
-
-    def ObjectiveValue(self, n: "int") -> "int64_t":
-        r""" Returns the objective value of the nth solution."""
-        return _pywrapcp.SolutionCollector_ObjectiveValue(self, n)
-
-    def Value(self, n: "int", var: "IntVar") -> "int64_t":
-        r""" This is a shortcut to get the Value of 'var' in the nth solution."""
-        return _pywrapcp.SolutionCollector_Value(self, n, var)
-
-    def StartValue(self, n: "int", var: "IntervalVar") -> "int64_t":
-        r""" This is a shortcut to get the StartValue of 'var' in the nth solution."""
-        return _pywrapcp.SolutionCollector_StartValue(self, n, var)
-
-    def EndValue(self, n: "int", var: "IntervalVar") -> "int64_t":
-        r""" This is a shortcut to get the EndValue of 'var' in the nth solution."""
-        return _pywrapcp.SolutionCollector_EndValue(self, n, var)
-
-    def DurationValue(self, n: "int", var: "IntervalVar") -> "int64_t":
-        r""" This is a shortcut to get the DurationValue of 'var' in the nth solution."""
-        return _pywrapcp.SolutionCollector_DurationValue(self, n, var)
-
-    def PerformedValue(self, n: "int", var: "IntervalVar") -> "int64_t":
-        r""" This is a shortcut to get the PerformedValue of 'var' in the nth solution."""
-        return _pywrapcp.SolutionCollector_PerformedValue(self, n, var)
-
-    def ForwardSequence(self, n: "int", var: "SequenceVar") -> "std::vector< int > const &":
-        r"""
-        This is a shortcut to get the ForwardSequence of 'var' in the
-        nth solution. The forward sequence is the list of ranked interval
-        variables starting from the start of the sequence.
-        """
-        return _pywrapcp.SolutionCollector_ForwardSequence(self, n, var)
-
-    def BackwardSequence(self, n: "int", var: "SequenceVar") -> "std::vector< int > const &":
-        r"""
-        This is a shortcut to get the BackwardSequence of 'var' in the
-        nth solution. The backward sequence is the list of ranked interval
-        variables starting from the end of the sequence.
-        """
-        return _pywrapcp.SolutionCollector_BackwardSequence(self, n, var)
-
-    def Unperformed(self, n: "int", var: "SequenceVar") -> "std::vector< int > const &":
-        r"""
-        This is a shortcut to get the list of unperformed of 'var' in the
-        nth solution.
-        """
-        return _pywrapcp.SolutionCollector_Unperformed(self, n, var)
-
-

Ancestors

- -

Methods

-
-
-def Add(self, *args) ‑> void -
-
-
-
- -Expand source code - -
def Add(self, *args) -> "void":
-    return _pywrapcp.SolutionCollector_Add(self, *args)
-
-
-
-def AddObjective(self, objective: IntVar) ‑> void -
-
-
-
- -Expand source code - -
def AddObjective(self, objective: "IntVar") -> "void":
-    return _pywrapcp.SolutionCollector_AddObjective(self, objective)
-
-
-
-def BackwardSequence(self, n: int, var: SequenceVar) ‑> std::vector< int > const & -
-
-

This is a shortcut to get the BackwardSequence of 'var' in the -nth solution. The backward sequence is the list of ranked interval -variables starting from the end of the sequence.

-
- -Expand source code - -
def BackwardSequence(self, n: "int", var: "SequenceVar") -> "std::vector< int > const &":
-    r"""
-    This is a shortcut to get the BackwardSequence of 'var' in the
-    nth solution. The backward sequence is the list of ranked interval
-    variables starting from the end of the sequence.
-    """
-    return _pywrapcp.SolutionCollector_BackwardSequence(self, n, var)
-
-
-
-def Branches(self, n: int) ‑> int64_t -
-
-

Returns the number of branches when the nth solution was found.

-
- -Expand source code - -
def Branches(self, n: "int") -> "int64_t":
-    r""" Returns the number of branches when the nth solution was found."""
-    return _pywrapcp.SolutionCollector_Branches(self, n)
-
-
-
-def DebugString(self) ‑> std::string -
-
-
-
- -Expand source code - -
def DebugString(self) -> "std::string":
-    return _pywrapcp.SolutionCollector_DebugString(self)
-
-
-
-def DurationValue(self, n: int, var: IntervalVar) ‑> int64_t -
-
-

This is a shortcut to get the DurationValue of 'var' in the nth solution.

-
- -Expand source code - -
def DurationValue(self, n: "int", var: "IntervalVar") -> "int64_t":
-    r""" This is a shortcut to get the DurationValue of 'var' in the nth solution."""
-    return _pywrapcp.SolutionCollector_DurationValue(self, n, var)
-
-
-
-def EndValue(self, n: int, var: IntervalVar) ‑> int64_t -
-
-

This is a shortcut to get the EndValue of 'var' in the nth solution.

-
- -Expand source code - -
def EndValue(self, n: "int", var: "IntervalVar") -> "int64_t":
-    r""" This is a shortcut to get the EndValue of 'var' in the nth solution."""
-    return _pywrapcp.SolutionCollector_EndValue(self, n, var)
-
-
-
-def Failures(self, n: int) ‑> int64_t -
-
-

Returns the number of failures encountered at the time of the nth -solution.

-
- -Expand source code - -
def Failures(self, n: "int") -> "int64_t":
-    r"""
-    Returns the number of failures encountered at the time of the nth
-    solution.
-    """
-    return _pywrapcp.SolutionCollector_Failures(self, n)
-
-
-
-def ForwardSequence(self, n: int, var: SequenceVar) ‑> std::vector< int > const & -
-
-

This is a shortcut to get the ForwardSequence of 'var' in the -nth solution. The forward sequence is the list of ranked interval -variables starting from the start of the sequence.

-
- -Expand source code - -
def ForwardSequence(self, n: "int", var: "SequenceVar") -> "std::vector< int > const &":
-    r"""
-    This is a shortcut to get the ForwardSequence of 'var' in the
-    nth solution. The forward sequence is the list of ranked interval
-    variables starting from the start of the sequence.
-    """
-    return _pywrapcp.SolutionCollector_ForwardSequence(self, n, var)
-
-
-
-def ObjectiveValue(self, n: int) ‑> int64_t -
-
-

Returns the objective value of the nth solution.

-
- -Expand source code - -
def ObjectiveValue(self, n: "int") -> "int64_t":
-    r""" Returns the objective value of the nth solution."""
-    return _pywrapcp.SolutionCollector_ObjectiveValue(self, n)
-
-
-
-def PerformedValue(self, n: int, var: IntervalVar) ‑> int64_t -
-
-

This is a shortcut to get the PerformedValue of 'var' in the nth solution.

-
- -Expand source code - -
def PerformedValue(self, n: "int", var: "IntervalVar") -> "int64_t":
-    r""" This is a shortcut to get the PerformedValue of 'var' in the nth solution."""
-    return _pywrapcp.SolutionCollector_PerformedValue(self, n, var)
-
-
-
-def Solution(self, n: int) ‑> operations_research::Assignment * -
-
-

Returns the nth solution.

-
- -Expand source code - -
def Solution(self, n: "int") -> "operations_research::Assignment *":
-    r""" Returns the nth solution."""
-    return _pywrapcp.SolutionCollector_Solution(self, n)
-
-
-
-def SolutionCount(self) ‑> int -
-
-

Returns how many solutions were stored during the search.

-
- -Expand source code - -
def SolutionCount(self) -> "int":
-    r""" Returns how many solutions were stored during the search."""
-    return _pywrapcp.SolutionCollector_SolutionCount(self)
-
-
-
-def StartValue(self, n: int, var: IntervalVar) ‑> int64_t -
-
-

This is a shortcut to get the StartValue of 'var' in the nth solution.

-
- -Expand source code - -
def StartValue(self, n: "int", var: "IntervalVar") -> "int64_t":
-    r""" This is a shortcut to get the StartValue of 'var' in the nth solution."""
-    return _pywrapcp.SolutionCollector_StartValue(self, n, var)
-
-
-
-def Unperformed(self, n: int, var: SequenceVar) ‑> std::vector< int > const & -
-
-

This is a shortcut to get the list of unperformed of 'var' in the -nth solution.

-
- -Expand source code - -
def Unperformed(self, n: "int", var: "SequenceVar") -> "std::vector< int > const &":
-    r"""
-    This is a shortcut to get the list of unperformed of 'var' in the
-    nth solution.
-    """
-    return _pywrapcp.SolutionCollector_Unperformed(self, n, var)
-
-
-
-def Value(self, n: int, var: IntVar) ‑> int64_t -
-
-

This is a shortcut to get the Value of 'var' in the nth solution.

-
- -Expand source code - -
def Value(self, n: "int", var: "IntVar") -> "int64_t":
-    r""" This is a shortcut to get the Value of 'var' in the nth solution."""
-    return _pywrapcp.SolutionCollector_Value(self, n, var)
-
-
-
-def WallTime(self, n: int) ‑> int64_t -
-
-

Returns the wall time in ms for the nth solution.

-
- -Expand source code - -
def WallTime(self, n: "int") -> "int64_t":
-    r""" Returns the wall time in ms for the nth solution."""
-    return _pywrapcp.SolutionCollector_WallTime(self, n)
-
-
-
-

Inherited members

- -
-
-class Solver -(*args) -
-
-

Solver Class

-

A solver represents the main computation engine. It implements the entire -range of Constraint Programming protocols: -- Reversibility -- Propagation -- Search

-

Usually, Constraint Programming code consists of -- the creation of the Solver, -- the creation of the decision variables of the model, -- the creation of the constraints of the model and their addition to the -solver() through the AddConstraint() method, -- the creation of the main DecisionBuilder class, -- the launch of the solve() method with the decision builder.

-

For the time being, Solver is neither MT_SAFE nor MT_HOT.

-
- -Expand source code - -
class Solver(object):
-    r"""
-    Solver Class
-
-    A solver represents the main computation engine. It implements the entire
-    range of Constraint Programming protocols:
-      - Reversibility
-      - Propagation
-      - Search
-
-    Usually, Constraint Programming code consists of
-      - the creation of the Solver,
-      - the creation of the decision variables of the model,
-      - the creation of the constraints of the model and their addition to the
-        solver() through the AddConstraint() method,
-      - the creation of the main DecisionBuilder class,
-      - the launch of the solve() method with the decision builder.
-
-    For the time being, Solver is neither MT_SAFE nor MT_HOT.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-    INT_VAR_DEFAULT = _pywrapcp.Solver_INT_VAR_DEFAULT
-    r""" The default behavior is CHOOSE_FIRST_UNBOUND."""
-    INT_VAR_SIMPLE = _pywrapcp.Solver_INT_VAR_SIMPLE
-    r""" The simple selection is CHOOSE_FIRST_UNBOUND."""
-    CHOOSE_FIRST_UNBOUND = _pywrapcp.Solver_CHOOSE_FIRST_UNBOUND
-    r"""
-    Select the first unbound variable.
-    Variables are considered in the order of the vector of IntVars used
-    to create the selector.
-    """
-    CHOOSE_RANDOM = _pywrapcp.Solver_CHOOSE_RANDOM
-    r""" Randomly select one of the remaining unbound variables."""
-    CHOOSE_MIN_SIZE_LOWEST_MIN = _pywrapcp.Solver_CHOOSE_MIN_SIZE_LOWEST_MIN
-    r"""
-    Among unbound variables, select the variable with the smallest size,
-    i.e., the smallest number of possible values.
-    In case of a tie, the selected variables is the one with the lowest min
-    value.
-    In case of a tie, the first one is selected, first being defined by the
-    order in the vector of IntVars used to create the selector.
-    """
-    CHOOSE_MIN_SIZE_HIGHEST_MIN = _pywrapcp.Solver_CHOOSE_MIN_SIZE_HIGHEST_MIN
-    r"""
-    Among unbound variables, select the variable with the smallest size,
-    i.e., the smallest number of possible values.
-    In case of a tie, the selected variable is the one with the highest min
-    value.
-    In case of a tie, the first one is selected, first being defined by the
-    order in the vector of IntVars used to create the selector.
-    """
-    CHOOSE_MIN_SIZE_LOWEST_MAX = _pywrapcp.Solver_CHOOSE_MIN_SIZE_LOWEST_MAX
-    r"""
-    Among unbound variables, select the variable with the smallest size,
-    i.e., the smallest number of possible values.
-    In case of a tie, the selected variables is the one with the lowest max
-    value.
-    In case of a tie, the first one is selected, first being defined by the
-    order in the vector of IntVars used to create the selector.
-    """
-    CHOOSE_MIN_SIZE_HIGHEST_MAX = _pywrapcp.Solver_CHOOSE_MIN_SIZE_HIGHEST_MAX
-    r"""
-    Among unbound variables, select the variable with the smallest size,
-    i.e., the smallest number of possible values.
-    In case of a tie, the selected variable is the one with the highest max
-    value.
-    In case of a tie, the first one is selected, first being defined by the
-    order in the vector of IntVars used to create the selector.
-    """
-    CHOOSE_LOWEST_MIN = _pywrapcp.Solver_CHOOSE_LOWEST_MIN
-    r"""
-    Among unbound variables, select the variable with the smallest minimal
-    value.
-    In case of a tie, the first one is selected, "first" defined by the
-    order in the vector of IntVars used to create the selector.
-    """
-    CHOOSE_HIGHEST_MAX = _pywrapcp.Solver_CHOOSE_HIGHEST_MAX
-    r"""
-    Among unbound variables, select the variable with the highest maximal
-    value.
-    In case of a tie, the first one is selected, first being defined by the
-    order in the vector of IntVars used to create the selector.
-    """
-    CHOOSE_MIN_SIZE = _pywrapcp.Solver_CHOOSE_MIN_SIZE
-    r"""
-    Among unbound variables, select the variable with the smallest size.
-    In case of a tie, the first one is selected, first being defined by the
-    order in the vector of IntVars used to create the selector.
-    """
-    CHOOSE_MAX_SIZE = _pywrapcp.Solver_CHOOSE_MAX_SIZE
-    r"""
-    Among unbound variables, select the variable with the highest size.
-    In case of a tie, the first one is selected, first being defined by the
-    order in the vector of IntVars used to create the selector.
-    """
-    CHOOSE_MAX_REGRET_ON_MIN = _pywrapcp.Solver_CHOOSE_MAX_REGRET_ON_MIN
-    r"""
-    Among unbound variables, select the variable with the largest
-    gap between the first and the second values of the domain.
-    """
-    CHOOSE_PATH = _pywrapcp.Solver_CHOOSE_PATH
-    r"""
-    Selects the next unbound variable on a path, the path being defined by
-    the variables: var[i] corresponds to the index of the next of i.
-    """
-    INT_VALUE_DEFAULT = _pywrapcp.Solver_INT_VALUE_DEFAULT
-    r""" The default behavior is ASSIGN_MIN_VALUE."""
-    INT_VALUE_SIMPLE = _pywrapcp.Solver_INT_VALUE_SIMPLE
-    r""" The simple selection is ASSIGN_MIN_VALUE."""
-    ASSIGN_MIN_VALUE = _pywrapcp.Solver_ASSIGN_MIN_VALUE
-    r""" Selects the min value of the selected variable."""
-    ASSIGN_MAX_VALUE = _pywrapcp.Solver_ASSIGN_MAX_VALUE
-    r""" Selects the max value of the selected variable."""
-    ASSIGN_RANDOM_VALUE = _pywrapcp.Solver_ASSIGN_RANDOM_VALUE
-    r""" Selects randomly one of the possible values of the selected variable."""
-    ASSIGN_CENTER_VALUE = _pywrapcp.Solver_ASSIGN_CENTER_VALUE
-    r"""
-    Selects the first possible value which is the closest to the center
-    of the domain of the selected variable.
-    The center is defined as (min + max) / 2.
-    """
-    SPLIT_LOWER_HALF = _pywrapcp.Solver_SPLIT_LOWER_HALF
-    r"""
-    Split the domain in two around the center, and choose the lower
-    part first.
-    """
-    SPLIT_UPPER_HALF = _pywrapcp.Solver_SPLIT_UPPER_HALF
-    r"""
-    Split the domain in two around the center, and choose the lower
-    part first.
-    """
-    SEQUENCE_DEFAULT = _pywrapcp.Solver_SEQUENCE_DEFAULT
-    SEQUENCE_SIMPLE = _pywrapcp.Solver_SEQUENCE_SIMPLE
-    CHOOSE_MIN_SLACK_RANK_FORWARD = _pywrapcp.Solver_CHOOSE_MIN_SLACK_RANK_FORWARD
-    CHOOSE_RANDOM_RANK_FORWARD = _pywrapcp.Solver_CHOOSE_RANDOM_RANK_FORWARD
-    INTERVAL_DEFAULT = _pywrapcp.Solver_INTERVAL_DEFAULT
-    r""" The default is INTERVAL_SET_TIMES_FORWARD."""
-    INTERVAL_SIMPLE = _pywrapcp.Solver_INTERVAL_SIMPLE
-    r""" The simple is INTERVAL_SET_TIMES_FORWARD."""
-    INTERVAL_SET_TIMES_FORWARD = _pywrapcp.Solver_INTERVAL_SET_TIMES_FORWARD
-    r"""
-    Selects the variable with the lowest starting time of all variables,
-    and fixes its starting time to this lowest value.
-    """
-    INTERVAL_SET_TIMES_BACKWARD = _pywrapcp.Solver_INTERVAL_SET_TIMES_BACKWARD
-    r"""
-    Selects the variable with the highest ending time of all variables,
-    and fixes the ending time to this highest values.
-    """
-    TWOOPT = _pywrapcp.Solver_TWOOPT
-    r"""
-    Operator which reverses a sub-chain of a path. It is called TwoOpt
-    because it breaks two arcs on the path; resulting paths are called
-    two-optimal.
-    Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5
-    (where (1, 5) are first and last nodes of the path and can therefore not
-    be moved):
-      1 -> [3 -> 2] -> 4  -> 5
-      1 -> [4 -> 3  -> 2] -> 5
-      1 ->  2 -> [4 -> 3] -> 5
-    """
-    OROPT = _pywrapcp.Solver_OROPT
-    r"""
-    Relocate: OROPT and RELOCATE.
-    Operator which moves a sub-chain of a path to another position; the
-    specified chain length is the fixed length of the chains being moved.
-    When this length is 1, the operator simply moves a node to another
-    position.
-    Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5, for a chain
-    length of 2 (where (1, 5) are first and last nodes of the path and can
-    therefore not be moved):
-      1 ->  4 -> [2 -> 3] -> 5
-      1 -> [3 -> 4] -> 2  -> 5
-
-    Using Relocate with chain lengths of 1, 2 and 3 together is equivalent
-    to the OrOpt operator on a path. The OrOpt operator is a limited
-     version of 3Opt (breaks 3 arcs on a path).
-    """
-    RELOCATE = _pywrapcp.Solver_RELOCATE
-    r""" Relocate neighborhood with length of 1 (see OROPT comment)."""
-    EXCHANGE = _pywrapcp.Solver_EXCHANGE
-    r"""
-    Operator which exchanges the positions of two nodes.
-    Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5
-    (where (1, 5) are first and last nodes of the path and can therefore not
-    be moved):
-      1 -> [3] -> [2] ->  4  -> 5
-      1 -> [4] ->  3  -> [2] -> 5
-      1 ->  2  -> [4] -> [3] -> 5
-    """
-    CROSS = _pywrapcp.Solver_CROSS
-    r"""
-    Operator which cross exchanges the starting chains of 2 paths, including
-    exchanging the whole paths.
-    First and last nodes are not moved.
-    Possible neighbors for the paths 1 -> 2 -> 3 -> 4 -> 5 and 6 -> 7 -> 8
-    (where (1, 5) and (6, 8) are first and last nodes of the paths and can
-    therefore not be moved):
-      1 -> [7] -> 3 -> 4 -> 5  6 -> [2] -> 8
-      1 -> [7] -> 4 -> 5       6 -> [2 -> 3] -> 8
-      1 -> [7] -> 5            6 -> [2 -> 3 -> 4] -> 8
-    """
-    MAKEACTIVE = _pywrapcp.Solver_MAKEACTIVE
-    r"""
-    Operator which inserts an inactive node into a path.
-    Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive
-    (where 1 and 4 are first and last nodes of the path) are:
-      1 -> [5] ->  2  ->  3  -> 4
-      1 ->  2  -> [5] ->  3  -> 4
-      1 ->  2  ->  3  -> [5] -> 4
-    """
-    MAKEINACTIVE = _pywrapcp.Solver_MAKEINACTIVE
-    r"""
-    Operator which makes path nodes inactive.
-    Possible neighbors for the path 1 -> 2 -> 3 -> 4 (where 1 and 4 are
-    first and last nodes of the path) are:
-      1 -> 3 -> 4 with 2 inactive
-      1 -> 2 -> 4 with 3 inactive
-    """
-    MAKECHAININACTIVE = _pywrapcp.Solver_MAKECHAININACTIVE
-    r"""
-    Operator which makes a "chain" of path nodes inactive.
-    Possible neighbors for the path 1 -> 2 -> 3 -> 4 (where 1 and 4 are
-    first and last nodes of the path) are:
-      1 -> 3 -> 4 with 2 inactive
-      1 -> 2 -> 4 with 3 inactive
-      1 -> 4 with 2 and 3 inactive
-    """
-    SWAPACTIVE = _pywrapcp.Solver_SWAPACTIVE
-    r"""
-    Operator which replaces an active node by an inactive one.
-    Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive
-    (where 1 and 4 are first and last nodes of the path) are:
-      1 -> [5] ->  3  -> 4 with 2 inactive
-      1 ->  2  -> [5] -> 4 with 3 inactive
-    """
-    EXTENDEDSWAPACTIVE = _pywrapcp.Solver_EXTENDEDSWAPACTIVE
-    r"""
-    Operator which makes an inactive node active and an active one inactive.
-    It is similar to SwapActiveOperator except that it tries to insert the
-    inactive node in all possible positions instead of just the position of
-    the node made inactive.
-    Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive
-    (where 1 and 4 are first and last nodes of the path) are:
-      1 -> [5] ->  3  -> 4 with 2 inactive
-      1 ->  3  -> [5] -> 4 with 2 inactive
-      1 -> [5] ->  2  -> 4 with 3 inactive
-      1 ->  2  -> [5] -> 4 with 3 inactive
-    """
-    PATHLNS = _pywrapcp.Solver_PATHLNS
-    r"""
-    Operator which relaxes two sub-chains of three consecutive arcs each.
-    Each sub-chain is defined by a start node and the next three arcs. Those
-    six arcs are relaxed to build a new neighbor.
-    PATHLNS explores all possible pairs of starting nodes and so defines
-    n^2 neighbors, n being the number of nodes.
-    Note that the two sub-chains can be part of the same path; they even may
-    overlap.
-    """
-    FULLPATHLNS = _pywrapcp.Solver_FULLPATHLNS
-    r"""
-    Operator which relaxes one entire path and all inactive nodes, thus
-    defining num_paths neighbors.
-    """
-    UNACTIVELNS = _pywrapcp.Solver_UNACTIVELNS
-    r"""
-    Operator which relaxes all inactive nodes and one sub-chain of six
-    consecutive arcs. That way the path can be improved by inserting
-    inactive nodes or swapping arcs.
-    """
-    INCREMENT = _pywrapcp.Solver_INCREMENT
-    r"""
-    Operator which defines one neighbor per variable. Each neighbor tries to
-    increment by one the value of the corresponding variable. When a new
-    solution is found the neighborhood is rebuilt from scratch, i.e., tries
-    to increment values in the variable order.
-    Consider for instance variables x and y. x is incremented one by one to
-    its max, and when it is not possible to increment x anymore, y is
-    incremented once. If this is a solution, then next neighbor tries to
-    increment x.
-    """
-    DECREMENT = _pywrapcp.Solver_DECREMENT
-    r"""
-    Operator which defines a neighborhood to decrement values.
-    The behavior is the same as INCREMENT, except values are decremented
-    instead of incremented.
-    """
-    SIMPLELNS = _pywrapcp.Solver_SIMPLELNS
-    r"""
-    Operator which defines one neighbor per variable. Each neighbor relaxes
-    one variable.
-    When a new solution is found the neighborhood is rebuilt from scratch.
-    Consider for instance variables x and y. First x is relaxed and the
-    solver is looking for the best possible solution (with only x relaxed).
-    Then y is relaxed, and the solver is looking for a new solution.
-    If a new solution is found, then the next variable to be relaxed is x.
-    """
-    GE = _pywrapcp.Solver_GE
-    r""" Move is accepted when the current objective value >= objective.Min."""
-    LE = _pywrapcp.Solver_LE
-    r""" Move is accepted when the current objective value <= objective.Max."""
-    EQ = _pywrapcp.Solver_EQ
-    r"""
-    Move is accepted when the current objective value is in the interval
-    objective.Min .. objective.Max.
-    """
-    DELAYED_PRIORITY = _pywrapcp.Solver_DELAYED_PRIORITY
-    r"""
-    DELAYED_PRIORITY is the lowest priority: Demons will be processed after
-    VAR_PRIORITY and NORMAL_PRIORITY demons.
-    """
-    VAR_PRIORITY = _pywrapcp.Solver_VAR_PRIORITY
-    r""" VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY."""
-    NORMAL_PRIORITY = _pywrapcp.Solver_NORMAL_PRIORITY
-    r""" NORMAL_PRIORITY is the highest priority: Demons will be processed first."""
-
-    def __init__(self, *args):
-        _pywrapcp.Solver_swiginit(self, _pywrapcp.new_Solver(*args))
-
-        self.__python_constraints = []
-
-
-
-    __swig_destroy__ = _pywrapcp.delete_Solver
-
-    def Parameters(self) -> "operations_research::ConstraintSolverParameters":
-        r""" Stored Parameters."""
-        return _pywrapcp.Solver_Parameters(self)
-
-    @staticmethod
-    def DefaultSolverParameters() -> "operations_research::ConstraintSolverParameters":
-        r""" Create a ConstraintSolverParameters proto with all the default values."""
-        return _pywrapcp.Solver_DefaultSolverParameters()
-
-    def AddConstraint(self, c: "Constraint") -> "void":
-        r"""
-        Adds the constraint 'c' to the model.
-
-        After calling this method, and until there is a backtrack that undoes the
-        addition, any assignment of variables to values must satisfy the given
-        constraint in order to be considered feasible. There are two fairly
-        different use cases:
-
-        - the most common use case is modeling: the given constraint is really
-        part of the problem that the user is trying to solve. In this use case,
-        AddConstraint is called outside of search (i.e., with state() ==
-        OUTSIDE_SEARCH). Most users should only use AddConstraint in this
-        way. In this case, the constraint will belong to the model forever: it
-        cannot not be removed by backtracking.
-
-        - a rarer use case is that 'c' is not a real constraint of the model. It
-        may be a constraint generated by a branching decision (a constraint whose
-        goal is to restrict the search space), a symmetry breaking constraint (a
-        constraint that does restrict the search space, but in a way that cannot
-        have an impact on the quality of the solutions in the subtree), or an
-        inferred constraint that, while having no semantic value to the model (it
-        does not restrict the set of solutions), is worth having because we
-        believe it may strengthen the propagation. In these cases, it happens
-        that the constraint is added during the search (i.e., with state() ==
-        IN_SEARCH or state() == IN_ROOT_NODE). When a constraint is
-        added during a search, it applies only to the subtree of the search tree
-        rooted at the current node, and will be automatically removed by
-        backtracking.
-
-        This method does not take ownership of the constraint. If the constraint
-        has been created by any factory method (Solver::MakeXXX), it will
-        automatically be deleted. However, power users who implement their own
-        constraints should do: solver.AddConstraint(solver.RevAlloc(new
-        MyConstraint(...));
-        """
-        return _pywrapcp.Solver_AddConstraint(self, c)
-
-    def Solve(self, *args) -> "bool":
-        return _pywrapcp.Solver_Solve(self, *args)
-
-    def NewSearch(self, *args) -> "void":
-        return _pywrapcp.Solver_NewSearch(self, *args)
-
-    def NextSolution(self) -> "bool":
-        return _pywrapcp.Solver_NextSolution(self)
-
-    def RestartSearch(self) -> "void":
-        return _pywrapcp.Solver_RestartSearch(self)
-
-    def EndSearch(self) -> "void":
-        return _pywrapcp.Solver_EndSearch(self)
-
-    def SolveAndCommit(self, *args) -> "bool":
-        return _pywrapcp.Solver_SolveAndCommit(self, *args)
-
-    def CheckAssignment(self, solution: "Assignment") -> "bool":
-        r""" Checks whether the given assignment satisfies all relevant constraints."""
-        return _pywrapcp.Solver_CheckAssignment(self, solution)
-
-    def CheckConstraint(self, ct: "Constraint") -> "bool":
-        r"""
-        Checks whether adding this constraint will lead to an immediate
-        failure. It will return false if the model is already inconsistent, or if
-        adding the constraint makes it inconsistent.
-        """
-        return _pywrapcp.Solver_CheckConstraint(self, ct)
-
-    def Fail(self) -> "void":
-        r""" Abandon the current branch in the search tree. A backtrack will follow."""
-        return _pywrapcp.Solver_Fail(self)
-
-    @staticmethod
-    def MemoryUsage() -> "int64_t":
-        r""" Current memory usage in bytes"""
-        return _pywrapcp.Solver_MemoryUsage()
-
-    def WallTime(self) -> "int64_t":
-        r"""
-        DEPRECATED: Use Now() instead.
-        Time elapsed, in ms since the creation of the solver.
-        """
-        return _pywrapcp.Solver_WallTime(self)
 
-    def Branches(self) -> "int64_t":
-        r""" The number of branches explored since the creation of the solver."""
-        return _pywrapcp.Solver_Branches(self)
-
-    def Solutions(self) -> "int64_t":
-        r""" The number of solutions found since the start of the search."""
-        return _pywrapcp.Solver_Solutions(self)
-
-    def Failures(self) -> "int64_t":
-        r""" The number of failures encountered since the creation of the solver."""
-        return _pywrapcp.Solver_Failures(self)
-
-    def AcceptedNeighbors(self) -> "int64_t":
-        r""" The number of accepted neighbors."""
-        return _pywrapcp.Solver_AcceptedNeighbors(self)
-
-    def Stamp(self) -> "uint64_t":
-        r"""
-        The stamp indicates how many moves in the search tree we have performed.
-        It is useful to detect if we need to update same lazy structures.
-        """
-        return _pywrapcp.Solver_Stamp(self)
-
-    def FailStamp(self) -> "uint64_t":
-        r""" The fail_stamp() is incremented after each backtrack."""
-        return _pywrapcp.Solver_FailStamp(self)
-
-    def IntVar(self, *args) -> "operations_research::IntVar *":
-        r"""
-        *Overload 1:*
-        MakeIntVar will create the best range based int var for the bounds given.
-
-        |
-
-        *Overload 2:*
-        MakeIntVar will create a variable with the given sparse domain.
-
-        |
+                            
+                            
+
#   - *Overload 3:* - MakeIntVar will create a variable with the given sparse domain. + thisown +
- | +

The membership flag

+
- *Overload 4:* - MakeIntVar will create the best range based int var for the bounds given. - | +
+
+
#   - *Overload 5:* - MakeIntVar will create a variable with the given sparse domain. + CHOOSE_MAX_SUM_IMPACT = 0 +
- | + - *Overload 6:* - MakeIntVar will create a variable with the given sparse domain. - """ - return _pywrapcp.Solver_IntVar(self, *args) +
+
+
#   - def BoolVar(self, *args) -> "operations_research::IntVar *": - r""" - *Overload 1:* - MakeBoolVar will create a variable with a {0, 1} domain. + CHOOSE_MAX_AVERAGE_IMPACT = 1 +
- | + - *Overload 2:* - MakeBoolVar will create a variable with a {0, 1} domain. - """ - return _pywrapcp.Solver_BoolVar(self, *args) +
+
+
#   - def IntConst(self, *args) -> "operations_research::IntVar *": - r""" - *Overload 1:* - IntConst will create a constant expression. + CHOOSE_MAX_VALUE_IMPACT = 2 +
- | + - *Overload 2:* - IntConst will create a constant expression. - """ - return _pywrapcp.Solver_IntConst(self, *args) +
+
+
#   - def Sum(self, vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::IntExpr *": - r""" sum of all vars.""" - return _pywrapcp.Solver_Sum(self, vars) + SELECT_MIN_IMPACT = 0 +
- def ScalProd(self, *args) -> "operations_research::IntExpr *": - r""" - *Overload 1:* - scalar product + - | +
+
+
#   - *Overload 2:* - scalar product - """ - return _pywrapcp.Solver_ScalProd(self, *args) + SELECT_MAX_IMPACT = 1 +
- def MonotonicElement(self, values: "operations_research::Solver::IndexEvaluator1", increasing: "bool", index: "IntVar") -> "operations_research::IntExpr *": - r""" - Function based element. The constraint takes ownership of the - callback. The callback must be monotonic. It must be able to - cope with any possible value in the domain of 'index' - (potentially negative ones too). Furtermore, monotonicity is not - checked. Thus giving a non-monotonic function, or specifying an - incorrect increasing parameter will result in undefined behavior. - """ - return _pywrapcp.Solver_MonotonicElement(self, values, increasing, index) + - def Element(self, *args) -> "operations_research::IntExpr *": - r""" - *Overload 1:* - values[index] +
+
+
#   - | + NONE = 0 +
- *Overload 2:* - values[index] + - | +
+
+
#   - *Overload 3:* - Function-based element. The constraint takes ownership of the - callback. The callback must be able to cope with any possible - value in the domain of 'index' (potentially negative ones too). + NORMAL = 1 +
- | + - *Overload 4:* - 2D version of function-based element expression, values(expr1, expr2). +
+
+
#   - | + VERBOSE = 2 +
- *Overload 5:* - vars[expr] - """ - return _pywrapcp.Solver_Element(self, *args) + - def IndexExpression(self, vars: "std::vector< operations_research::IntVar * > const &", value: "int64_t") -> "operations_research::IntExpr *": - r""" - Returns the expression expr such that vars[expr] == value. - It assumes that vars are all different. - """ - return _pywrapcp.Solver_IndexExpression(self, vars, value) +
+
+
#   - def Min(self, *args) -> "operations_research::IntExpr *": - r""" - *Overload 1:* - std::min(vars) + var_selection_schema +
- | +

This parameter describes how the next variable to instantiate will be chosen.

+
- *Overload 2:* - std::min (left, right) - | +
+
+
#   - *Overload 3:* - std::min(expr, value) + value_selection_schema +
- | +

This parameter describes which value to select for a given var.

+
- *Overload 4:* - std::min(expr, value) - """ - return _pywrapcp.Solver_Min(self, *args) - def Max(self, *args) -> "operations_research::IntExpr *": - r""" - *Overload 1:* - std::max(vars) +
+
+
#   - | + initialization_splits +
- *Overload 2:* - std::max(left, right) +

Maximum number of intervals that the initialization of impacts will scan per variable.

+
- | - *Overload 3:* - std::max(expr, value) +
+
+
#   - | + run_all_heuristics +
- *Overload 4:* - std::max(expr, value) - """ - return _pywrapcp.Solver_Max(self, *args) +

The default phase will run heuristics periodically. This parameter indicates if we should run all heuristics, or a randomly selected one.

+
- def ConvexPiecewiseExpr(self, expr: "IntExpr", early_cost: "int64_t", early_date: "int64_t", late_date: "int64_t", late_cost: "int64_t") -> "operations_research::IntExpr *": - r""" Convex piecewise function.""" - return _pywrapcp.Solver_ConvexPiecewiseExpr(self, expr, early_cost, early_date, late_date, late_cost) - def SemiContinuousExpr(self, expr: "IntExpr", fixed_charge: "int64_t", step: "int64_t") -> "operations_research::IntExpr *": - r""" - Semi continuous Expression (x <= 0 -> f(x) = 0; x > 0 -> f(x) = ax + b) - a >= 0 and b >= 0 - """ - return _pywrapcp.Solver_SemiContinuousExpr(self, expr, fixed_charge, step) +
+
+
#   - def ConditionalExpression(self, condition: "IntVar", expr: "IntExpr", unperformed_value: "int64_t") -> "operations_research::IntExpr *": - r""" Conditional Expr condition ? expr : unperformed_value""" - return _pywrapcp.Solver_ConditionalExpression(self, condition, expr, unperformed_value) + heuristic_period +
- def TrueConstraint(self) -> "operations_research::Constraint *": - r""" This constraint always succeeds.""" - return _pywrapcp.Solver_TrueConstraint(self) +

The distance in nodes between each run of the heuristics. A negative or null value will mean that we will not run heuristics at all.

+
- def FalseConstraint(self, *args) -> "operations_research::Constraint *": - return _pywrapcp.Solver_FalseConstraint(self, *args) - def IsEqualCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *": - r""" boolvar == (var == value)""" - return _pywrapcp.Solver_IsEqualCstCt(self, var, value, boolvar) +
+
+
#   - def IsEqualCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *": - r""" status var of (var == value)""" - return _pywrapcp.Solver_IsEqualCstVar(self, var, value) + heuristic_num_failures_limit +
- def IsEqualCt(self, v1: "IntExpr", v2: "IntExpr", b: "IntVar") -> "operations_research::Constraint *": - r""" b == (v1 == v2)""" - return _pywrapcp.Solver_IsEqualCt(self, v1, v2, b) +

The failure limit for each heuristic that we run.

+
- def IsEqualVar(self, v1: "IntExpr", v2: "IntExpr") -> "operations_research::IntVar *": - r""" status var of (v1 == v2)""" - return _pywrapcp.Solver_IsEqualVar(self, v1, v2) - def IsDifferentCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *": - r""" boolvar == (var != value)""" - return _pywrapcp.Solver_IsDifferentCstCt(self, var, value, boolvar) +
+
+
#   - def IsDifferentCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *": - r""" status var of (var != value)""" - return _pywrapcp.Solver_IsDifferentCstVar(self, var, value) + persistent_impact +
- def IsDifferentVar(self, v1: "IntExpr", v2: "IntExpr") -> "operations_research::IntVar *": - r""" status var of (v1 != v2)""" - return _pywrapcp.Solver_IsDifferentVar(self, v1, v2) +

Whether to keep the impact from the first search for other searches, or to recompute the impact for each new search.

+
- def IsDifferentCt(self, v1: "IntExpr", v2: "IntExpr", b: "IntVar") -> "operations_research::Constraint *": - r""" b == (v1 != v2)""" - return _pywrapcp.Solver_IsDifferentCt(self, v1, v2, b) - def IsLessOrEqualCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *": - r""" boolvar == (var <= value)""" - return _pywrapcp.Solver_IsLessOrEqualCstCt(self, var, value, boolvar) +
+
+
#   - def IsLessOrEqualCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *": - r""" status var of (var <= value)""" - return _pywrapcp.Solver_IsLessOrEqualCstVar(self, var, value) + random_seed +
+ +

Seed used to initialize the random part in some heuristics.

+
+ + +
+
+
#   + + display_level +
+ +

This represents the amount of information displayed by the default search. NONE means no display, VERBOSE means extra information.

+
+ + +
+
+
#   + + decision_builder +
+ +

When defined, this overrides the default impact based decision builder.

+
+ + +
+
+
+
+ #   + + + class + Solver: +
+ +
+ View Source +
class Solver(object):
+    r""" Solver Class A solver represents the main computation engine. It implements the entire range of Constraint Programming protocols:   - Reversibility   - Propagation   - Search Usually, Constraint Programming code consists of   - the creation of the Solver,   - the creation of the decision variables of the model,   - the creation of the constraints of the model and their addition to the     solver() through the AddConstraint() method,   - the creation of the main DecisionBuilder class,   - the launch of the solve() method with the decision builder. For the time being, Solver is neither MT_SAFE nor MT_HOT."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+    INT_VAR_DEFAULT = _pywrapcp.Solver_INT_VAR_DEFAULT
+    r""" The default behavior is CHOOSE_FIRST_UNBOUND."""
+    INT_VAR_SIMPLE = _pywrapcp.Solver_INT_VAR_SIMPLE
+    r""" The simple selection is CHOOSE_FIRST_UNBOUND."""
+    CHOOSE_FIRST_UNBOUND = _pywrapcp.Solver_CHOOSE_FIRST_UNBOUND
+    r""" Select the first unbound variable. Variables are considered in the order of the vector of IntVars used to create the selector."""
+    CHOOSE_RANDOM = _pywrapcp.Solver_CHOOSE_RANDOM
+    r""" Randomly select one of the remaining unbound variables."""
+    CHOOSE_MIN_SIZE_LOWEST_MIN = _pywrapcp.Solver_CHOOSE_MIN_SIZE_LOWEST_MIN
+    r""" Among unbound variables, select the variable with the smallest size, i.e., the smallest number of possible values. In case of a tie, the selected variables is the one with the lowest min value. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector."""
+    CHOOSE_MIN_SIZE_HIGHEST_MIN = _pywrapcp.Solver_CHOOSE_MIN_SIZE_HIGHEST_MIN
+    r""" Among unbound variables, select the variable with the smallest size, i.e., the smallest number of possible values. In case of a tie, the selected variable is the one with the highest min value. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector."""
+    CHOOSE_MIN_SIZE_LOWEST_MAX = _pywrapcp.Solver_CHOOSE_MIN_SIZE_LOWEST_MAX
+    r""" Among unbound variables, select the variable with the smallest size, i.e., the smallest number of possible values. In case of a tie, the selected variables is the one with the lowest max value. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector."""
+    CHOOSE_MIN_SIZE_HIGHEST_MAX = _pywrapcp.Solver_CHOOSE_MIN_SIZE_HIGHEST_MAX
+    r""" Among unbound variables, select the variable with the smallest size, i.e., the smallest number of possible values. In case of a tie, the selected variable is the one with the highest max value. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector."""
+    CHOOSE_LOWEST_MIN = _pywrapcp.Solver_CHOOSE_LOWEST_MIN
+    r""" Among unbound variables, select the variable with the smallest minimal value. In case of a tie, the first one is selected, "first" defined by the order in the vector of IntVars used to create the selector."""
+    CHOOSE_HIGHEST_MAX = _pywrapcp.Solver_CHOOSE_HIGHEST_MAX
+    r""" Among unbound variables, select the variable with the highest maximal value. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector."""
+    CHOOSE_MIN_SIZE = _pywrapcp.Solver_CHOOSE_MIN_SIZE
+    r""" Among unbound variables, select the variable with the smallest size. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector."""
+    CHOOSE_MAX_SIZE = _pywrapcp.Solver_CHOOSE_MAX_SIZE
+    r""" Among unbound variables, select the variable with the highest size. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector."""
+    CHOOSE_MAX_REGRET_ON_MIN = _pywrapcp.Solver_CHOOSE_MAX_REGRET_ON_MIN
+    r""" Among unbound variables, select the variable with the largest gap between the first and the second values of the domain."""
+    CHOOSE_PATH = _pywrapcp.Solver_CHOOSE_PATH
+    r""" Selects the next unbound variable on a path, the path being defined by the variables: var[i] corresponds to the index of the next of i."""
+    INT_VALUE_DEFAULT = _pywrapcp.Solver_INT_VALUE_DEFAULT
+    r""" The default behavior is ASSIGN_MIN_VALUE."""
+    INT_VALUE_SIMPLE = _pywrapcp.Solver_INT_VALUE_SIMPLE
+    r""" The simple selection is ASSIGN_MIN_VALUE."""
+    ASSIGN_MIN_VALUE = _pywrapcp.Solver_ASSIGN_MIN_VALUE
+    r""" Selects the min value of the selected variable."""
+    ASSIGN_MAX_VALUE = _pywrapcp.Solver_ASSIGN_MAX_VALUE
+    r""" Selects the max value of the selected variable."""
+    ASSIGN_RANDOM_VALUE = _pywrapcp.Solver_ASSIGN_RANDOM_VALUE
+    r""" Selects randomly one of the possible values of the selected variable."""
+    ASSIGN_CENTER_VALUE = _pywrapcp.Solver_ASSIGN_CENTER_VALUE
+    r""" Selects the first possible value which is the closest to the center of the domain of the selected variable. The center is defined as (min + max) / 2."""
+    SPLIT_LOWER_HALF = _pywrapcp.Solver_SPLIT_LOWER_HALF
+    r""" Split the domain in two around the center, and choose the lower part first."""
+    SPLIT_UPPER_HALF = _pywrapcp.Solver_SPLIT_UPPER_HALF
+    r""" Split the domain in two around the center, and choose the lower part first."""
+    SEQUENCE_DEFAULT = _pywrapcp.Solver_SEQUENCE_DEFAULT
+    SEQUENCE_SIMPLE = _pywrapcp.Solver_SEQUENCE_SIMPLE
+    CHOOSE_MIN_SLACK_RANK_FORWARD = _pywrapcp.Solver_CHOOSE_MIN_SLACK_RANK_FORWARD
+    CHOOSE_RANDOM_RANK_FORWARD = _pywrapcp.Solver_CHOOSE_RANDOM_RANK_FORWARD
+    INTERVAL_DEFAULT = _pywrapcp.Solver_INTERVAL_DEFAULT
+    r""" The default is INTERVAL_SET_TIMES_FORWARD."""
+    INTERVAL_SIMPLE = _pywrapcp.Solver_INTERVAL_SIMPLE
+    r""" The simple is INTERVAL_SET_TIMES_FORWARD."""
+    INTERVAL_SET_TIMES_FORWARD = _pywrapcp.Solver_INTERVAL_SET_TIMES_FORWARD
+    r""" Selects the variable with the lowest starting time of all variables, and fixes its starting time to this lowest value."""
+    INTERVAL_SET_TIMES_BACKWARD = _pywrapcp.Solver_INTERVAL_SET_TIMES_BACKWARD
+    r""" Selects the variable with the highest ending time of all variables, and fixes the ending time to this highest values."""
+    TWOOPT = _pywrapcp.Solver_TWOOPT
+    r""" Operator which reverses a sub-chain of a path. It is called TwoOpt because it breaks two arcs on the path; resulting paths are called two-optimal. Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5 (where (1, 5) are first and last nodes of the path and can therefore not be moved):   1 -> [3 -> 2] -> 4  -> 5   1 -> [4 -> 3  -> 2] -> 5   1 ->  2 -> [4 -> 3] -> 5"""
+    OROPT = _pywrapcp.Solver_OROPT
+    r""" Relocate: OROPT and RELOCATE. Operator which moves a sub-chain of a path to another position; the specified chain length is the fixed length of the chains being moved. When this length is 1, the operator simply moves a node to another position. Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5, for a chain length of 2 (where (1, 5) are first and last nodes of the path and can therefore not be moved):   1 ->  4 -> [2 -> 3] -> 5   1 -> [3 -> 4] -> 2  -> 5 Using Relocate with chain lengths of 1, 2 and 3 together is equivalent to the OrOpt operator on a path. The OrOpt operator is a limited  version of 3Opt (breaks 3 arcs on a path)."""
+    RELOCATE = _pywrapcp.Solver_RELOCATE
+    r""" Relocate neighborhood with length of 1 (see OROPT comment)."""
+    EXCHANGE = _pywrapcp.Solver_EXCHANGE
+    r""" Operator which exchanges the positions of two nodes. Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5 (where (1, 5) are first and last nodes of the path and can therefore not be moved):   1 -> [3] -> [2] ->  4  -> 5   1 -> [4] ->  3  -> [2] -> 5   1 ->  2  -> [4] -> [3] -> 5"""
+    CROSS = _pywrapcp.Solver_CROSS
+    r""" Operator which cross exchanges the starting chains of 2 paths, including exchanging the whole paths. First and last nodes are not moved. Possible neighbors for the paths 1 -> 2 -> 3 -> 4 -> 5 and 6 -> 7 -> 8 (where (1, 5) and (6, 8) are first and last nodes of the paths and can therefore not be moved):   1 -> [7] -> 3 -> 4 -> 5  6 -> [2] -> 8   1 -> [7] -> 4 -> 5       6 -> [2 -> 3] -> 8   1 -> [7] -> 5            6 -> [2 -> 3 -> 4] -> 8"""
+    MAKEACTIVE = _pywrapcp.Solver_MAKEACTIVE
+    r""" Operator which inserts an inactive node into a path. Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive (where 1 and 4 are first and last nodes of the path) are:   1 -> [5] ->  2  ->  3  -> 4   1 ->  2  -> [5] ->  3  -> 4   1 ->  2  ->  3  -> [5] -> 4"""
+    MAKEINACTIVE = _pywrapcp.Solver_MAKEINACTIVE
+    r""" Operator which makes path nodes inactive. Possible neighbors for the path 1 -> 2 -> 3 -> 4 (where 1 and 4 are first and last nodes of the path) are:   1 -> 3 -> 4 with 2 inactive   1 -> 2 -> 4 with 3 inactive"""
+    MAKECHAININACTIVE = _pywrapcp.Solver_MAKECHAININACTIVE
+    r""" Operator which makes a "chain" of path nodes inactive. Possible neighbors for the path 1 -> 2 -> 3 -> 4 (where 1 and 4 are first and last nodes of the path) are:   1 -> 3 -> 4 with 2 inactive   1 -> 2 -> 4 with 3 inactive   1 -> 4 with 2 and 3 inactive"""
+    SWAPACTIVE = _pywrapcp.Solver_SWAPACTIVE
+    r""" Operator which replaces an active node by an inactive one. Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive (where 1 and 4 are first and last nodes of the path) are:   1 -> [5] ->  3  -> 4 with 2 inactive   1 ->  2  -> [5] -> 4 with 3 inactive"""
+    EXTENDEDSWAPACTIVE = _pywrapcp.Solver_EXTENDEDSWAPACTIVE
+    r""" Operator which makes an inactive node active and an active one inactive. It is similar to SwapActiveOperator except that it tries to insert the inactive node in all possible positions instead of just the position of the node made inactive. Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive (where 1 and 4 are first and last nodes of the path) are:   1 -> [5] ->  3  -> 4 with 2 inactive   1 ->  3  -> [5] -> 4 with 2 inactive   1 -> [5] ->  2  -> 4 with 3 inactive   1 ->  2  -> [5] -> 4 with 3 inactive"""
+    PATHLNS = _pywrapcp.Solver_PATHLNS
+    r""" Operator which relaxes two sub-chains of three consecutive arcs each. Each sub-chain is defined by a start node and the next three arcs. Those six arcs are relaxed to build a new neighbor. PATHLNS explores all possible pairs of starting nodes and so defines n^2 neighbors, n being the number of nodes. Note that the two sub-chains can be part of the same path; they even may overlap."""
+    FULLPATHLNS = _pywrapcp.Solver_FULLPATHLNS
+    r""" Operator which relaxes one entire path and all inactive nodes, thus defining num_paths neighbors."""
+    UNACTIVELNS = _pywrapcp.Solver_UNACTIVELNS
+    r""" Operator which relaxes all inactive nodes and one sub-chain of six consecutive arcs. That way the path can be improved by inserting inactive nodes or swapping arcs."""
+    INCREMENT = _pywrapcp.Solver_INCREMENT
+    r""" Operator which defines one neighbor per variable. Each neighbor tries to increment by one the value of the corresponding variable. When a new solution is found the neighborhood is rebuilt from scratch, i.e., tries to increment values in the variable order. Consider for instance variables x and y. x is incremented one by one to its max, and when it is not possible to increment x anymore, y is incremented once. If this is a solution, then next neighbor tries to increment x."""
+    DECREMENT = _pywrapcp.Solver_DECREMENT
+    r""" Operator which defines a neighborhood to decrement values. The behavior is the same as INCREMENT, except values are decremented instead of incremented."""
+    SIMPLELNS = _pywrapcp.Solver_SIMPLELNS
+    r""" Operator which defines one neighbor per variable. Each neighbor relaxes one variable. When a new solution is found the neighborhood is rebuilt from scratch. Consider for instance variables x and y. First x is relaxed and the solver is looking for the best possible solution (with only x relaxed). Then y is relaxed, and the solver is looking for a new solution. If a new solution is found, then the next variable to be relaxed is x."""
+    GE = _pywrapcp.Solver_GE
+    r""" Move is accepted when the current objective value >= objective.Min."""
+    LE = _pywrapcp.Solver_LE
+    r""" Move is accepted when the current objective value <= objective.Max."""
+    EQ = _pywrapcp.Solver_EQ
+    r""" Move is accepted when the current objective value is in the interval objective.Min .. objective.Max."""
+    DELAYED_PRIORITY = _pywrapcp.Solver_DELAYED_PRIORITY
+    r""" DELAYED_PRIORITY is the lowest priority: Demons will be processed after VAR_PRIORITY and NORMAL_PRIORITY demons."""
+    VAR_PRIORITY = _pywrapcp.Solver_VAR_PRIORITY
+    r""" VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY."""
+    NORMAL_PRIORITY = _pywrapcp.Solver_NORMAL_PRIORITY
+    r""" NORMAL_PRIORITY is the highest priority: Demons will be processed first."""
+
+    def __init__(self, *args):
+        _pywrapcp.Solver_swiginit(self, _pywrapcp.new_Solver(*args))
+
+        self.__python_constraints = []
+
+
+
+    __swig_destroy__ = _pywrapcp.delete_Solver
+
+    def Parameters(self) -> "operations_research::ConstraintSolverParameters":
+        r""" Stored Parameters."""
+        return _pywrapcp.Solver_Parameters(self)
+
+    @staticmethod
+    def DefaultSolverParameters() -> "operations_research::ConstraintSolverParameters":
+        r""" Create a ConstraintSolverParameters proto with all the default values."""
+        return _pywrapcp.Solver_DefaultSolverParameters()
+
+    def AddConstraint(self, c: "Constraint") -> "void":
+        r""" Adds the constraint 'c' to the model. After calling this method, and until there is a backtrack that undoes the addition, any assignment of variables to values must satisfy the given constraint in order to be considered feasible. There are two fairly different use cases: - the most common use case is modeling: the given constraint is really part of the problem that the user is trying to solve. In this use case, AddConstraint is called outside of search (i.e., with state() == OUTSIDE_SEARCH). Most users should only use AddConstraint in this way. In this case, the constraint will belong to the model forever: it cannot not be removed by backtracking. - a rarer use case is that 'c' is not a real constraint of the model. It may be a constraint generated by a branching decision (a constraint whose goal is to restrict the search space), a symmetry breaking constraint (a constraint that does restrict the search space, but in a way that cannot have an impact on the quality of the solutions in the subtree), or an inferred constraint that, while having no semantic value to the model (it does not restrict the set of solutions), is worth having because we believe it may strengthen the propagation. In these cases, it happens that the constraint is added during the search (i.e., with state() == IN_SEARCH or state() == IN_ROOT_NODE). When a constraint is added during a search, it applies only to the subtree of the search tree rooted at the current node, and will be automatically removed by backtracking. This method does not take ownership of the constraint. If the constraint has been created by any factory method (Solver::MakeXXX), it will automatically be deleted. However, power users who implement their own constraints should do: solver.AddConstraint(solver.RevAlloc(new MyConstraint(...));"""
+        return _pywrapcp.Solver_AddConstraint(self, c)
+
+    def Solve(self, *args) -> "bool":
+        return _pywrapcp.Solver_Solve(self, *args)
+
+    def NewSearch(self, *args) -> "void":
+        return _pywrapcp.Solver_NewSearch(self, *args)
+
+    def NextSolution(self) -> "bool":
+        return _pywrapcp.Solver_NextSolution(self)
+
+    def RestartSearch(self) -> "void":
+        return _pywrapcp.Solver_RestartSearch(self)
+
+    def EndSearch(self) -> "void":
+        return _pywrapcp.Solver_EndSearch(self)
+
+    def SolveAndCommit(self, *args) -> "bool":
+        return _pywrapcp.Solver_SolveAndCommit(self, *args)
+
+    def CheckAssignment(self, solution: "Assignment") -> "bool":
+        r""" Checks whether the given assignment satisfies all relevant constraints."""
+        return _pywrapcp.Solver_CheckAssignment(self, solution)
+
+    def CheckConstraint(self, ct: "Constraint") -> "bool":
+        r""" Checks whether adding this constraint will lead to an immediate failure. It will return false if the model is already inconsistent, or if adding the constraint makes it inconsistent."""
+        return _pywrapcp.Solver_CheckConstraint(self, ct)
+
+    def Fail(self) -> "void":
+        r""" Abandon the current branch in the search tree. A backtrack will follow."""
+        return _pywrapcp.Solver_Fail(self)
+
+    @staticmethod
+    def MemoryUsage() -> "int64_t":
+        r""" Current memory usage in bytes"""
+        return _pywrapcp.Solver_MemoryUsage()
+
+    def WallTime(self) -> "int64_t":
+        r""" DEPRECATED: Use Now() instead. Time elapsed, in ms since the creation of the solver."""
+        return _pywrapcp.Solver_WallTime(self)
+
+    def Branches(self) -> "int64_t":
+        r""" The number of branches explored since the creation of the solver."""
+        return _pywrapcp.Solver_Branches(self)
+
+    def Solutions(self) -> "int64_t":
+        r""" The number of solutions found since the start of the search."""
+        return _pywrapcp.Solver_Solutions(self)
 
-    def IsLessOrEqualVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
-        r""" status var of (left <= right)"""
-        return _pywrapcp.Solver_IsLessOrEqualVar(self, left, right)
+    def Failures(self) -> "int64_t":
+        r""" The number of failures encountered since the creation of the solver."""
+        return _pywrapcp.Solver_Failures(self)
 
-    def IsLessOrEqualCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
-        r""" b == (left <= right)"""
-        return _pywrapcp.Solver_IsLessOrEqualCt(self, left, right, b)
+    def AcceptedNeighbors(self) -> "int64_t":
+        r""" The number of accepted neighbors."""
+        return _pywrapcp.Solver_AcceptedNeighbors(self)
 
-    def IsGreaterOrEqualCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
-        r""" boolvar == (var >= value)"""
-        return _pywrapcp.Solver_IsGreaterOrEqualCstCt(self, var, value, boolvar)
+    def Stamp(self) -> "uint64_t":
+        r""" The stamp indicates how many moves in the search tree we have performed. It is useful to detect if we need to update same lazy structures."""
+        return _pywrapcp.Solver_Stamp(self)
 
-    def IsGreaterOrEqualCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
-        r""" status var of (var >= value)"""
-        return _pywrapcp.Solver_IsGreaterOrEqualCstVar(self, var, value)
+    def FailStamp(self) -> "uint64_t":
+        r""" The fail_stamp() is incremented after each backtrack."""
+        return _pywrapcp.Solver_FailStamp(self)
 
-    def IsGreaterOrEqualVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
-        r""" status var of (left >= right)"""
-        return _pywrapcp.Solver_IsGreaterOrEqualVar(self, left, right)
+    def IntVar(self, *args) -> "operations_research::IntVar *":
+        r"""
+        *Overload 1:*
+        MakeIntVar will create the best range based int var for the bounds given.
 
-    def IsGreaterOrEqualCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
-        r""" b == (left >= right)"""
-        return _pywrapcp.Solver_IsGreaterOrEqualCt(self, left, right, b)
+        |
 
-    def IsGreaterCstCt(self, v: "IntExpr", c: "int64_t", b: "IntVar") -> "operations_research::Constraint *":
-        r""" b == (v > c)"""
-        return _pywrapcp.Solver_IsGreaterCstCt(self, v, c, b)
+        *Overload 2:*
+        MakeIntVar will create a variable with the given sparse domain.
 
-    def IsGreaterCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
-        r""" status var of (var > value)"""
-        return _pywrapcp.Solver_IsGreaterCstVar(self, var, value)
-
-    def IsGreaterVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
-        r""" status var of (left > right)"""
-        return _pywrapcp.Solver_IsGreaterVar(self, left, right)
-
-    def IsGreaterCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
-        r""" b == (left > right)"""
-        return _pywrapcp.Solver_IsGreaterCt(self, left, right, b)
+        |
 
-    def IsLessCstCt(self, v: "IntExpr", c: "int64_t", b: "IntVar") -> "operations_research::Constraint *":
-        r""" b == (v < c)"""
-        return _pywrapcp.Solver_IsLessCstCt(self, v, c, b)
+        *Overload 3:*
+        MakeIntVar will create a variable with the given sparse domain.
 
-    def IsLessCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
-        r""" status var of (var < value)"""
-        return _pywrapcp.Solver_IsLessCstVar(self, var, value)
+        |
 
-    def IsLessVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
-        r""" status var of (left < right)"""
-        return _pywrapcp.Solver_IsLessVar(self, left, right)
+        *Overload 4:*
+        MakeIntVar will create the best range based int var for the bounds given.
 
-    def IsLessCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
-        r""" b == (left < right)"""
-        return _pywrapcp.Solver_IsLessCt(self, left, right, b)
+        |
 
-    def SumLessOrEqual(self, vars: "std::vector< operations_research::IntVar * > const &", cst: "int64_t") -> "operations_research::Constraint *":
-        r""" Variation on arrays."""
-        return _pywrapcp.Solver_SumLessOrEqual(self, vars, cst)
+        *Overload 5:*
+        MakeIntVar will create a variable with the given sparse domain.
 
-    def SumGreaterOrEqual(self, vars: "std::vector< operations_research::IntVar * > const &", cst: "int64_t") -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_SumGreaterOrEqual(self, vars, cst)
+        |
 
-    def SumEquality(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_SumEquality(self, *args)
+        *Overload 6:*
+        MakeIntVar will create a variable with the given sparse domain.
+        """
+        return _pywrapcp.Solver_IntVar(self, *args)
 
-    def ScalProdEquality(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_ScalProdEquality(self, *args)
+    def BoolVar(self, *args) -> "operations_research::IntVar *":
+        r"""
+        *Overload 1:*
+        MakeBoolVar will create a variable with a {0, 1} domain.
 
-    def ScalProdGreaterOrEqual(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_ScalProdGreaterOrEqual(self, *args)
+        |
 
-    def ScalProdLessOrEqual(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_ScalProdLessOrEqual(self, *args)
+        *Overload 2:*
+        MakeBoolVar will create a variable with a {0, 1} domain.
+        """
+        return _pywrapcp.Solver_BoolVar(self, *args)
 
-    def MinEquality(self, vars: "std::vector< operations_research::IntVar * > const &", min_var: "IntVar") -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_MinEquality(self, vars, min_var)
+    def IntConst(self, *args) -> "operations_research::IntVar *":
+        r"""
+        *Overload 1:*
+        IntConst will create a constant expression.
 
-    def MaxEquality(self, vars: "std::vector< operations_research::IntVar * > const &", max_var: "IntVar") -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_MaxEquality(self, vars, max_var)
+        |
 
-    def ElementEquality(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_ElementEquality(self, *args)
+        *Overload 2:*
+        IntConst will create a constant expression.
+        """
+        return _pywrapcp.Solver_IntConst(self, *args)
 
-    def AbsEquality(self, var: "IntVar", abs_var: "IntVar") -> "operations_research::Constraint *":
-        r""" Creates the constraint abs(var) == abs_var."""
-        return _pywrapcp.Solver_AbsEquality(self, var, abs_var)
+    def Sum(self, vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::IntExpr *":
+        r""" sum of all vars."""
+        return _pywrapcp.Solver_Sum(self, vars)
 
-    def IndexOfConstraint(self, vars: "std::vector< operations_research::IntVar * > const &", index: "IntVar", target: "int64_t") -> "operations_research::Constraint *":
-        r"""
-        This constraint is a special case of the element constraint with
-        an array of integer variables, where the variables are all
-        different and the index variable is constrained such that
-        vars[index] == target.
-        """
-        return _pywrapcp.Solver_IndexOfConstraint(self, vars, index, target)
+    def ScalProd(self, *args) -> "operations_research::IntExpr *":
+        r"""
+        *Overload 1:*
+        scalar product
 
-    def ConstraintInitialPropagateCallback(self, ct: "Constraint") -> "operations_research::Demon *":
-        r"""
-        This method is a specialized case of the MakeConstraintDemon
-        method to call the InitiatePropagate of the constraint 'ct'.
-        """
-        return _pywrapcp.Solver_ConstraintInitialPropagateCallback(self, ct)
+        |
 
-    def DelayedConstraintInitialPropagateCallback(self, ct: "Constraint") -> "operations_research::Demon *":
-        r"""
-        This method is a specialized case of the MakeConstraintDemon
-        method to call the InitiatePropagate of the constraint 'ct' with
-        low priority.
-        """
-        return _pywrapcp.Solver_DelayedConstraintInitialPropagateCallback(self, ct)
+        *Overload 2:*
+        scalar product
+        """
+        return _pywrapcp.Solver_ScalProd(self, *args)
 
-    def ClosureDemon(self, closure: "operations_research::Solver::Closure") -> "operations_research::Demon *":
-        r""" Creates a demon from a closure."""
-        return _pywrapcp.Solver_ClosureDemon(self, closure)
+    def MonotonicElement(self, values: "operations_research::Solver::IndexEvaluator1", increasing: "bool", index: "IntVar") -> "operations_research::IntExpr *":
+        r""" Function based element. The constraint takes ownership of the callback.  The callback must be monotonic. It must be able to cope with any possible value in the domain of 'index' (potentially negative ones too). Furtermore, monotonicity is not checked. Thus giving a non-monotonic function, or specifying an incorrect increasing parameter will result in undefined behavior."""
+        return _pywrapcp.Solver_MonotonicElement(self, values, increasing, index)
 
-    def BetweenCt(self, expr: "IntExpr", l: "int64_t", u: "int64_t") -> "operations_research::Constraint *":
-        r""" (l <= expr <= u)"""
-        return _pywrapcp.Solver_BetweenCt(self, expr, l, u)
+    def Element(self, *args) -> "operations_research::IntExpr *":
+        r"""
+        *Overload 1:*
+        values[index]
 
-    def IsBetweenCt(self, expr: "IntExpr", l: "int64_t", u: "int64_t", b: "IntVar") -> "operations_research::Constraint *":
-        r""" b == (l <= expr <= u)"""
-        return _pywrapcp.Solver_IsBetweenCt(self, expr, l, u, b)
+        |
 
-    def IsBetweenVar(self, v: "IntExpr", l: "int64_t", u: "int64_t") -> "operations_research::IntVar *":
-        return _pywrapcp.Solver_IsBetweenVar(self, v, l, u)
+        *Overload 2:*
+        values[index]
 
-    def MemberCt(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_MemberCt(self, *args)
+        |
 
-    def NotMemberCt(self, *args) -> "operations_research::Constraint *":
-        r"""
-        *Overload 1:*
-        expr not in set.
+        *Overload 3:*
+        Function-based element. The constraint takes ownership of the callback. The callback must be able to cope with any possible value in the domain of 'index' (potentially negative ones too).
 
-        |
+        |
 
-        *Overload 2:*
-        expr should not be in the list of forbidden intervals [start[i]..end[i]].
+        *Overload 4:*
+        2D version of function-based element expression, values(expr1, expr2).
 
-        |
+        |
 
-        *Overload 3:*
-        expr should not be in the list of forbidden intervals [start[i]..end[i]].
-        """
-        return _pywrapcp.Solver_NotMemberCt(self, *args)
+        *Overload 5:*
+        vars[expr]
+        """
+        return _pywrapcp.Solver_Element(self, *args)
 
-    def IsMemberCt(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_IsMemberCt(self, *args)
+    def IndexExpression(self, vars: "std::vector< operations_research::IntVar * > const &", value: "int64_t") -> "operations_research::IntExpr *":
+        r""" Returns the expression expr such that vars[expr] == value. It assumes that vars are all different."""
+        return _pywrapcp.Solver_IndexExpression(self, vars, value)
 
-    def IsMemberVar(self, *args) -> "operations_research::IntVar *":
-        return _pywrapcp.Solver_IsMemberVar(self, *args)
-
-    def Count(self, *args) -> "operations_research::Constraint *":
-        r"""
-        *Overload 1:*
-        |{i | vars[i] == value}| == max_count
+    def Min(self, *args) -> "operations_research::IntExpr *":
+        r"""
+        *Overload 1:*
+        std::min(vars)
 
-        |
+        |
 
-        *Overload 2:*
-        |{i | vars[i] == value}| == max_count
-        """
-        return _pywrapcp.Solver_Count(self, *args)
-
-    def Distribute(self, *args) -> "operations_research::Constraint *":
-        r"""
-        *Overload 1:*
-        Aggregated version of count:  |{i | v[i] == values[j]}| == cards[j]
-
-        |
-
-        *Overload 2:*
-        Aggregated version of count:  |{i | v[i] == values[j]}| == cards[j]
-
-        |
-
-        *Overload 3:*
-        Aggregated version of count:  |{i | v[i] == j}| == cards[j]
-
-        |
-
-        *Overload 4:*
-        Aggregated version of count with bounded cardinalities:
-        forall j in 0 .. card_size - 1: card_min <= |{i | v[i] == j}| <= card_max
-
-        |
-
-        *Overload 5:*
-        Aggregated version of count with bounded cardinalities:
-        forall j in 0 .. card_size - 1:
-           card_min[j] <= |{i | v[i] == j}| <= card_max[j]
-
-        |
-
-        *Overload 6:*
-        Aggregated version of count with bounded cardinalities:
-        forall j in 0 .. card_size - 1:
-           card_min[j] <= |{i | v[i] == j}| <= card_max[j]
-
-        |
-
-        *Overload 7:*
-        Aggregated version of count with bounded cardinalities:
-        forall j in 0 .. card_size - 1:
-           card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j]
-
-        |
-
-        *Overload 8:*
-        Aggregated version of count with bounded cardinalities:
-        forall j in 0 .. card_size - 1:
-           card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j]
-        """
-        return _pywrapcp.Solver_Distribute(self, *args)
-
-    def Deviation(self, vars: "std::vector< operations_research::IntVar * > const &", deviation_var: "IntVar", total_sum: "int64_t") -> "operations_research::Constraint *":
-        r"""
-        Deviation constraint:
-        sum_i |n * vars[i] - total_sum| <= deviation_var and
-        sum_i vars[i] == total_sum
-        n = #vars
-        """
-        return _pywrapcp.Solver_Deviation(self, vars, deviation_var, total_sum)
-
-    def AllDifferent(self, *args) -> "operations_research::Constraint *":
-        r"""
-        *Overload 1:*
-        All variables are pairwise different. This corresponds to the
-        stronger version of the propagation algorithm.
-
-        |
-
-        *Overload 2:*
-        All variables are pairwise different.  If 'stronger_propagation'
-        is true, stronger, and potentially slower propagation will
-        occur. This API will be deprecated in the future.
-        """
-        return _pywrapcp.Solver_AllDifferent(self, *args)
-
-    def AllDifferentExcept(self, vars: "std::vector< operations_research::IntVar * > const &", escape_value: "int64_t") -> "operations_research::Constraint *":
-        r"""
-        All variables are pairwise different, unless they are assigned to
-        the escape value.
-        """
-        return _pywrapcp.Solver_AllDifferentExcept(self, vars, escape_value)
-
-    def SortingConstraint(self, vars: "std::vector< operations_research::IntVar * > const &", sorted: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-        r"""
-        Creates a constraint binding the arrays of variables "vars" and
-        "sorted_vars": sorted_vars[0] must be equal to the minimum of all
-        variables in vars, and so on: the value of sorted_vars[i] must be
-        equal to the i-th value of variables invars.
-
-        This constraint propagates in both directions: from "vars" to
-        "sorted_vars" and vice-versa.
-
-        Behind the scenes, this constraint maintains that:
-          - sorted is always increasing.
-          - whatever the values of vars, there exists a permutation that
-            injects its values into the sorted variables.
-
-        For more info, please have a look at:
-          https://mpi-inf.mpg.de/~mehlhorn/ftp/Mehlhorn-Thiel.pdf
-        """
-        return _pywrapcp.Solver_SortingConstraint(self, vars, sorted)
-
-    def LexicalLess(self, left: "std::vector< operations_research::IntVar * > const &", right: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-        r"""
-        Creates a constraint that enforces that left is lexicographically less
-        than right.
-        """
-        return _pywrapcp.Solver_LexicalLess(self, left, right)
-
-    def LexicalLessOrEqual(self, left: "std::vector< operations_research::IntVar * > const &", right: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-        r"""
-        Creates a constraint that enforces that left is lexicographically less
-        than or equal to right.
-        """
-        return _pywrapcp.Solver_LexicalLessOrEqual(self, left, right)
-
-    def InversePermutationConstraint(self, left: "std::vector< operations_research::IntVar * > const &", right: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-        r"""
-        Creates a constraint that enforces that 'left' and 'right' both
-        represent permutations of [0..left.size()-1], and that 'right' is
-        the inverse permutation of 'left', i.e. for all i in
-        [0..left.size()-1], right[left[i]] = i.
-        """
-        return _pywrapcp.Solver_InversePermutationConstraint(self, left, right)
-
-    def NullIntersect(self, first_vars: "std::vector< operations_research::IntVar * > const &", second_vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-        r"""
-        Creates a constraint that states that all variables in the first
-        vector are different from all variables in the second
-        group. Thus the set of values in the first vector does not
-        intersect with the set of values in the second vector.
-        """
-        return _pywrapcp.Solver_NullIntersect(self, first_vars, second_vars)
-
-    def NullIntersectExcept(self, first_vars: "std::vector< operations_research::IntVar * > const &", second_vars: "std::vector< operations_research::IntVar * > const &", escape_value: "int64_t") -> "operations_research::Constraint *":
-        r"""
-        Creates a constraint that states that all variables in the first
-        vector are different from all variables from the second group,
-        unless they are assigned to the escape value. Thus the set of
-        values in the first vector minus the escape value does not
-        intersect with the set of values in the second vector.
-        """
-        return _pywrapcp.Solver_NullIntersectExcept(self, first_vars, second_vars, escape_value)
-
-    def Circuit(self, nexts: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-        r""" Force the "nexts" variable to create a complete Hamiltonian path."""
-        return _pywrapcp.Solver_Circuit(self, nexts)
-
-    def SubCircuit(self, nexts: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-        r"""
-        Force the "nexts" variable to create a complete Hamiltonian path
-        for those that do not loop upon themselves.
-        """
-        return _pywrapcp.Solver_SubCircuit(self, nexts)
-
-    def DelayedPathCumul(self, nexts: "std::vector< operations_research::IntVar * > const &", active: "std::vector< operations_research::IntVar * > const &", cumuls: "std::vector< operations_research::IntVar * > const &", transits: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-        r"""
-        Delayed version of the same constraint: propagation on the nexts variables
-        is delayed until all constraints have propagated.
-        """
-        return _pywrapcp.Solver_DelayedPathCumul(self, nexts, active, cumuls, transits)
-
-    def PathCumul(self, *args) -> "operations_research::Constraint *":
-        r"""
-        *Overload 1:*
-        Creates a constraint which accumulates values along a path such that:
-        cumuls[next[i]] = cumuls[i] + transits[i].
-        Active variables indicate if the corresponding next variable is active;
-        this could be useful to model unperformed nodes in a routing problem.
-
-        |
-
-        *Overload 2:*
-        Creates a constraint which accumulates values along a path such that:
-        cumuls[next[i]] = cumuls[i] + transit_evaluator(i, next[i]).
-        Active variables indicate if the corresponding next variable is active;
-        this could be useful to model unperformed nodes in a routing problem.
-        Ownership of transit_evaluator is taken and it must be a repeatable
-        callback.
-
-        |
-
-        *Overload 3:*
-        Creates a constraint which accumulates values along a path such that:
-        cumuls[next[i]] = cumuls[i] + transit_evaluator(i, next[i]) + slacks[i].
-        Active variables indicate if the corresponding next variable is active;
-        this could be useful to model unperformed nodes in a routing problem.
-        Ownership of transit_evaluator is taken and it must be a repeatable
-        callback.
-        """
-        return _pywrapcp.Solver_PathCumul(self, *args)
-
-    def AllowedAssignments(self, *args) -> "operations_research::Constraint *":
-        r"""
-        *Overload 1:*
-        This method creates a constraint where the graph of the relation
-        between the variables is given in extension. There are 'arity'
-        variables involved in the relation and the graph is given by a
-        integer tuple set.
-
-        |
-
-        *Overload 2:*
-        Compatibility layer for Python API.
-        """
-        return _pywrapcp.Solver_AllowedAssignments(self, *args)
-
-    def TransitionConstraint(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_TransitionConstraint(self, *args)
-
-    def NonOverlappingBoxesConstraint(self, *args) -> "operations_research::Constraint *":
-        return _pywrapcp.Solver_NonOverlappingBoxesConstraint(self, *args)
-
-    def Pack(self, vars: "std::vector< operations_research::IntVar * > const &", number_of_bins: "int") -> "operations_research::Pack *":
-        r"""
-        This constraint packs all variables onto 'number_of_bins'
-        variables.  For any given variable, a value of 'number_of_bins'
-        indicates that the variable is not assigned to any bin.
-        Dimensions, i.e., cumulative constraints on this packing, can be
-        added directly from the pack class.
-        """
-        return _pywrapcp.Solver_Pack(self, vars, number_of_bins)
-
-    def FixedDurationIntervalVar(self, *args) -> "operations_research::IntervalVar *":
-        r"""
-        *Overload 1:*
-        Creates an interval var with a fixed duration. The duration must
-        be greater than 0. If optional is true, then the interval can be
-        performed or unperformed. If optional is false, then the interval
-        is always performed.
-
-        |
-
-        *Overload 2:*
-        Creates a performed interval var with a fixed duration. The duration must
-        be greater than 0.
-
-        |
-
-        *Overload 3:*
-        Creates an interval var with a fixed duration, and performed_variable.
-        The duration must be greater than 0.
-        """
-        return _pywrapcp.Solver_FixedDurationIntervalVar(self, *args)
-
-    def FixedInterval(self, start: "int64_t", duration: "int64_t", name: "std::string const &") -> "operations_research::IntervalVar *":
-        r""" Creates a fixed and performed interval."""
-        return _pywrapcp.Solver_FixedInterval(self, start, duration, name)
-
-    def IntervalVar(self, start_min: "int64_t", start_max: "int64_t", duration_min: "int64_t", duration_max: "int64_t", end_min: "int64_t", end_max: "int64_t", optional: "bool", name: "std::string const &") -> "operations_research::IntervalVar *":
-        r"""
-        Creates an interval var by specifying the bounds on start,
-        duration, and end.
-        """
-        return _pywrapcp.Solver_IntervalVar(self, start_min, start_max, duration_min, duration_max, end_min, end_max, optional, name)
-
-    def MirrorInterval(self, interval_var: "IntervalVar") -> "operations_research::IntervalVar *":
-        r"""
-        Creates an interval var that is the mirror image of the given one, that
-        is, the interval var obtained by reversing the axis.
-        """
-        return _pywrapcp.Solver_MirrorInterval(self, interval_var)
-
-    def FixedDurationStartSyncedOnStartIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
-        r"""
-        Creates an interval var with a fixed duration whose start is
-        synchronized with the start of another interval, with a given
-        offset. The performed status is also in sync with the performed
-        status of the given interval variable.
-        """
-        return _pywrapcp.Solver_FixedDurationStartSyncedOnStartIntervalVar(self, interval_var, duration, offset)
-
-    def FixedDurationStartSyncedOnEndIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
-        r"""
-        Creates an interval var with a fixed duration whose start is
-        synchronized with the end of another interval, with a given
-        offset. The performed status is also in sync with the performed
-        status of the given interval variable.
-        """
-        return _pywrapcp.Solver_FixedDurationStartSyncedOnEndIntervalVar(self, interval_var, duration, offset)
-
-    def FixedDurationEndSyncedOnStartIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
-        r"""
-        Creates an interval var with a fixed duration whose end is
-        synchronized with the start of another interval, with a given
-        offset. The performed status is also in sync with the performed
-        status of the given interval variable.
-        """
-        return _pywrapcp.Solver_FixedDurationEndSyncedOnStartIntervalVar(self, interval_var, duration, offset)
-
-    def FixedDurationEndSyncedOnEndIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
-        r"""
-        Creates an interval var with a fixed duration whose end is
-        synchronized with the end of another interval, with a given
-        offset. The performed status is also in sync with the performed
-        status of the given interval variable.
-        """
-        return _pywrapcp.Solver_FixedDurationEndSyncedOnEndIntervalVar(self, interval_var, duration, offset)
-
-    def IntervalRelaxedMin(self, interval_var: "IntervalVar") -> "operations_research::IntervalVar *":
-        r"""
-         Creates and returns an interval variable that wraps around the given one,
-         relaxing the min start and end. Relaxing means making unbounded when
-         optional. If the variable is non-optional, this method returns
-         interval_var.
-
-         More precisely, such an interval variable behaves as follows:
-        When the underlying must be performed, the returned interval variable
-             behaves exactly as the underlying;
-        When the underlying may or may not be performed, the returned interval
-             variable behaves like the underlying, except that it is unbounded on
-             the min side;
-        When the underlying cannot be performed, the returned interval variable
-             is of duration 0 and must be performed in an interval unbounded on
-             both sides.
-
-         This is very useful to implement propagators that may only modify
-         the start max or end max.
-        """
-        return _pywrapcp.Solver_IntervalRelaxedMin(self, interval_var)
-
-    def IntervalRelaxedMax(self, interval_var: "IntervalVar") -> "operations_research::IntervalVar *":
-        r"""
-         Creates and returns an interval variable that wraps around the given one,
-         relaxing the max start and end. Relaxing means making unbounded when
-         optional. If the variable is non optional, this method returns
-         interval_var.
-
-         More precisely, such an interval variable behaves as follows:
-        When the underlying must be performed, the returned interval variable
-             behaves exactly as the underlying;
-        When the underlying may or may not be performed, the returned interval
-             variable behaves like the underlying, except that it is unbounded on
-             the max side;
-        When the underlying cannot be performed, the returned interval variable
-             is of duration 0 and must be performed in an interval unbounded on
-             both sides.
-
-         This is very useful for implementing propagators that may only modify
-         the start min or end min.
-        """
-        return _pywrapcp.Solver_IntervalRelaxedMax(self, interval_var)
-
-    def TemporalDisjunction(self, *args) -> "operations_research::Constraint *":
-        r"""
-        *Overload 1:*
-        This constraint implements a temporal disjunction between two
-        interval vars t1 and t2. 'alt' indicates which alternative was
-        chosen (alt == 0 is equivalent to t1 before t2).
-
-        |
-
-        *Overload 2:*
-        This constraint implements a temporal disjunction between two
-        interval vars.
-        """
-        return _pywrapcp.Solver_TemporalDisjunction(self, *args)
-
-    def DisjunctiveConstraint(self, intervals: "std::vector< operations_research::IntervalVar * > const &", name: "std::string const &") -> "operations_research::DisjunctiveConstraint *":
-        r"""
-        This constraint forces all interval vars into an non-overlapping
-        sequence. Intervals with zero duration can be scheduled anywhere.
-        """
-        return _pywrapcp.Solver_DisjunctiveConstraint(self, intervals, name)
-
-    def Cumulative(self, *args) -> "operations_research::Constraint *":
-        r"""
-        *Overload 1:*
-        This constraint forces that, for any integer t, the sum of the demands
-        corresponding to an interval containing t does not exceed the given
-        capacity.
-
-        Intervals and demands should be vectors of equal size.
-
-        Demands should only contain non-negative values. Zero values are
-        supported, and the corresponding intervals are filtered out, as they
-        neither impact nor are impacted by this constraint.
-
-        |
-
-        *Overload 2:*
-        This constraint forces that, for any integer t, the sum of the demands
-        corresponding to an interval containing t does not exceed the given
-        capacity.
-
-        Intervals and demands should be vectors of equal size.
-
-        Demands should only contain non-negative values. Zero values are
-        supported, and the corresponding intervals are filtered out, as they
-        neither impact nor are impacted by this constraint.
-
-        |
-
-        *Overload 3:*
-        This constraint forces that, for any integer t, the sum of the demands
-        corresponding to an interval containing t does not exceed the given
-        capacity.
-
-        Intervals and demands should be vectors of equal size.
-
-        Demands should only contain non-negative values. Zero values are
-        supported, and the corresponding intervals are filtered out, as they
-        neither impact nor are impacted by this constraint.
-
-        |
-
-        *Overload 4:*
-        This constraint enforces that, for any integer t, the sum of the demands
-        corresponding to an interval containing t does not exceed the given
-        capacity.
-
-        Intervals and demands should be vectors of equal size.
-
-        Demands should only contain non-negative values. Zero values are
-        supported, and the corresponding intervals are filtered out, as they
-        neither impact nor are impacted by this constraint.
-
-        |
-
-        *Overload 5:*
-        This constraint enforces that, for any integer t, the sum of demands
-        corresponding to an interval containing t does not exceed the given
-        capacity.
-
-        Intervals and demands should be vectors of equal size.
-
-        Demands should be positive.
-
-        |
-
-        *Overload 6:*
-        This constraint enforces that, for any integer t, the sum of demands
-        corresponding to an interval containing t does not exceed the given
-        capacity.
-
-        Intervals and demands should be vectors of equal size.
-
-        Demands should be positive.
-        """
-        return _pywrapcp.Solver_Cumulative(self, *args)
-
-    def Cover(self, vars: "std::vector< operations_research::IntervalVar * > const &", target_var: "IntervalVar") -> "operations_research::Constraint *":
-        r"""
-        This constraint states that the target_var is the convex hull of
-        the intervals. If none of the interval variables is performed,
-        then the target var is unperformed too. Also, if the target
-        variable is unperformed, then all the intervals variables are
-        unperformed too.
-        """
-        return _pywrapcp.Solver_Cover(self, vars, target_var)
-
-    def Assignment(self, *args) -> "operations_research::Assignment *":
-        r"""
-        *Overload 1:*
-        This method creates an empty assignment.
-
-        |
-
-        *Overload 2:*
-        This method creates an assignment which is a copy of 'a'.
-        """
-        return _pywrapcp.Solver_Assignment(self, *args)
-
-    def FirstSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
-        r"""
-        *Overload 1:*
-        Collect the first solution of the search.
+        *Overload 2:*
+        std::min (left, right)
 
-        |
+        |
+
+        *Overload 3:*
+        std::min(expr, value)
+
+        |
+
+        *Overload 4:*
+        std::min(expr, value)
+        """
+        return _pywrapcp.Solver_Min(self, *args)
+
+    def Max(self, *args) -> "operations_research::IntExpr *":
+        r"""
+        *Overload 1:*
+        std::max(vars)
+
+        |
+
+        *Overload 2:*
+        std::max(left, right)
+
+        |
+
+        *Overload 3:*
+        std::max(expr, value)
+
+        |
+
+        *Overload 4:*
+        std::max(expr, value)
+        """
+        return _pywrapcp.Solver_Max(self, *args)
+
+    def ConvexPiecewiseExpr(self, expr: "IntExpr", early_cost: "int64_t", early_date: "int64_t", late_date: "int64_t", late_cost: "int64_t") -> "operations_research::IntExpr *":
+        r""" Convex piecewise function."""
+        return _pywrapcp.Solver_ConvexPiecewiseExpr(self, expr, early_cost, early_date, late_date, late_cost)
+
+    def SemiContinuousExpr(self, expr: "IntExpr", fixed_charge: "int64_t", step: "int64_t") -> "operations_research::IntExpr *":
+        r""" Semi continuous Expression (x <= 0 -> f(x) = 0; x > 0 -> f(x) = ax + b) a >= 0 and b >= 0"""
+        return _pywrapcp.Solver_SemiContinuousExpr(self, expr, fixed_charge, step)
+
+    def ConditionalExpression(self, condition: "IntVar", expr: "IntExpr", unperformed_value: "int64_t") -> "operations_research::IntExpr *":
+        r""" Conditional Expr condition ? expr : unperformed_value"""
+        return _pywrapcp.Solver_ConditionalExpression(self, condition, expr, unperformed_value)
+
+    def TrueConstraint(self) -> "operations_research::Constraint *":
+        r""" This constraint always succeeds."""
+        return _pywrapcp.Solver_TrueConstraint(self)
+
+    def FalseConstraint(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_FalseConstraint(self, *args)
+
+    def IsEqualCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
+        r""" boolvar == (var == value)"""
+        return _pywrapcp.Solver_IsEqualCstCt(self, var, value, boolvar)
+
+    def IsEqualCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
+        r""" status var of (var == value)"""
+        return _pywrapcp.Solver_IsEqualCstVar(self, var, value)
+
+    def IsEqualCt(self, v1: "IntExpr", v2: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (v1 == v2)"""
+        return _pywrapcp.Solver_IsEqualCt(self, v1, v2, b)
+
+    def IsEqualVar(self, v1: "IntExpr", v2: "IntExpr") -> "operations_research::IntVar *":
+        r""" status var of (v1 == v2)"""
+        return _pywrapcp.Solver_IsEqualVar(self, v1, v2)
+
+    def IsDifferentCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
+        r""" boolvar == (var != value)"""
+        return _pywrapcp.Solver_IsDifferentCstCt(self, var, value, boolvar)
+
+    def IsDifferentCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
+        r""" status var of (var != value)"""
+        return _pywrapcp.Solver_IsDifferentCstVar(self, var, value)
+
+    def IsDifferentVar(self, v1: "IntExpr", v2: "IntExpr") -> "operations_research::IntVar *":
+        r""" status var of (v1 != v2)"""
+        return _pywrapcp.Solver_IsDifferentVar(self, v1, v2)
+
+    def IsDifferentCt(self, v1: "IntExpr", v2: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (v1 != v2)"""
+        return _pywrapcp.Solver_IsDifferentCt(self, v1, v2, b)
+
+    def IsLessOrEqualCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
+        r""" boolvar == (var <= value)"""
+        return _pywrapcp.Solver_IsLessOrEqualCstCt(self, var, value, boolvar)
+
+    def IsLessOrEqualCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
+        r""" status var of (var <= value)"""
+        return _pywrapcp.Solver_IsLessOrEqualCstVar(self, var, value)
+
+    def IsLessOrEqualVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
+        r""" status var of (left <= right)"""
+        return _pywrapcp.Solver_IsLessOrEqualVar(self, left, right)
+
+    def IsLessOrEqualCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (left <= right)"""
+        return _pywrapcp.Solver_IsLessOrEqualCt(self, left, right, b)
+
+    def IsGreaterOrEqualCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
+        r""" boolvar == (var >= value)"""
+        return _pywrapcp.Solver_IsGreaterOrEqualCstCt(self, var, value, boolvar)
+
+    def IsGreaterOrEqualCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
+        r""" status var of (var >= value)"""
+        return _pywrapcp.Solver_IsGreaterOrEqualCstVar(self, var, value)
+
+    def IsGreaterOrEqualVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
+        r""" status var of (left >= right)"""
+        return _pywrapcp.Solver_IsGreaterOrEqualVar(self, left, right)
+
+    def IsGreaterOrEqualCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (left >= right)"""
+        return _pywrapcp.Solver_IsGreaterOrEqualCt(self, left, right, b)
+
+    def IsGreaterCstCt(self, v: "IntExpr", c: "int64_t", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (v > c)"""
+        return _pywrapcp.Solver_IsGreaterCstCt(self, v, c, b)
+
+    def IsGreaterCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
+        r""" status var of (var > value)"""
+        return _pywrapcp.Solver_IsGreaterCstVar(self, var, value)
+
+    def IsGreaterVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
+        r""" status var of (left > right)"""
+        return _pywrapcp.Solver_IsGreaterVar(self, left, right)
+
+    def IsGreaterCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (left > right)"""
+        return _pywrapcp.Solver_IsGreaterCt(self, left, right, b)
+
+    def IsLessCstCt(self, v: "IntExpr", c: "int64_t", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (v < c)"""
+        return _pywrapcp.Solver_IsLessCstCt(self, v, c, b)
+
+    def IsLessCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
+        r""" status var of (var < value)"""
+        return _pywrapcp.Solver_IsLessCstVar(self, var, value)
+
+    def IsLessVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
+        r""" status var of (left < right)"""
+        return _pywrapcp.Solver_IsLessVar(self, left, right)
+
+    def IsLessCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (left < right)"""
+        return _pywrapcp.Solver_IsLessCt(self, left, right, b)
+
+    def SumLessOrEqual(self, vars: "std::vector< operations_research::IntVar * > const &", cst: "int64_t") -> "operations_research::Constraint *":
+        r""" Variation on arrays."""
+        return _pywrapcp.Solver_SumLessOrEqual(self, vars, cst)
+
+    def SumGreaterOrEqual(self, vars: "std::vector< operations_research::IntVar * > const &", cst: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_SumGreaterOrEqual(self, vars, cst)
+
+    def SumEquality(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_SumEquality(self, *args)
+
+    def ScalProdEquality(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_ScalProdEquality(self, *args)
+
+    def ScalProdGreaterOrEqual(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_ScalProdGreaterOrEqual(self, *args)
+
+    def ScalProdLessOrEqual(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_ScalProdLessOrEqual(self, *args)
+
+    def MinEquality(self, vars: "std::vector< operations_research::IntVar * > const &", min_var: "IntVar") -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_MinEquality(self, vars, min_var)
+
+    def MaxEquality(self, vars: "std::vector< operations_research::IntVar * > const &", max_var: "IntVar") -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_MaxEquality(self, vars, max_var)
+
+    def ElementEquality(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_ElementEquality(self, *args)
+
+    def AbsEquality(self, var: "IntVar", abs_var: "IntVar") -> "operations_research::Constraint *":
+        r""" Creates the constraint abs(var) == abs_var."""
+        return _pywrapcp.Solver_AbsEquality(self, var, abs_var)
+
+    def IndexOfConstraint(self, vars: "std::vector< operations_research::IntVar * > const &", index: "IntVar", target: "int64_t") -> "operations_research::Constraint *":
+        r""" This constraint is a special case of the element constraint with an array of integer variables, where the variables are all different and the index variable is constrained such that vars[index] == target."""
+        return _pywrapcp.Solver_IndexOfConstraint(self, vars, index, target)
+
+    def ConstraintInitialPropagateCallback(self, ct: "Constraint") -> "operations_research::Demon *":
+        r""" This method is a specialized case of the MakeConstraintDemon method to call the InitiatePropagate of the constraint 'ct'."""
+        return _pywrapcp.Solver_ConstraintInitialPropagateCallback(self, ct)
+
+    def DelayedConstraintInitialPropagateCallback(self, ct: "Constraint") -> "operations_research::Demon *":
+        r""" This method is a specialized case of the MakeConstraintDemon method to call the InitiatePropagate of the constraint 'ct' with low priority."""
+        return _pywrapcp.Solver_DelayedConstraintInitialPropagateCallback(self, ct)
+
+    def ClosureDemon(self, closure: "operations_research::Solver::Closure") -> "operations_research::Demon *":
+        r""" Creates a demon from a closure."""
+        return _pywrapcp.Solver_ClosureDemon(self, closure)
+
+    def BetweenCt(self, expr: "IntExpr", l: "int64_t", u: "int64_t") -> "operations_research::Constraint *":
+        r""" (l <= expr <= u)"""
+        return _pywrapcp.Solver_BetweenCt(self, expr, l, u)
+
+    def IsBetweenCt(self, expr: "IntExpr", l: "int64_t", u: "int64_t", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (l <= expr <= u)"""
+        return _pywrapcp.Solver_IsBetweenCt(self, expr, l, u, b)
+
+    def IsBetweenVar(self, v: "IntExpr", l: "int64_t", u: "int64_t") -> "operations_research::IntVar *":
+        return _pywrapcp.Solver_IsBetweenVar(self, v, l, u)
+
+    def MemberCt(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_MemberCt(self, *args)
+
+    def NotMemberCt(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        expr not in set.
+
+        |
+
+        *Overload 2:*
+        expr should not be in the list of forbidden intervals [start[i]..end[i]].
+
+        |
+
+        *Overload 3:*
+        expr should not be in the list of forbidden intervals [start[i]..end[i]].
+        """
+        return _pywrapcp.Solver_NotMemberCt(self, *args)
+
+    def IsMemberCt(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_IsMemberCt(self, *args)
+
+    def IsMemberVar(self, *args) -> "operations_research::IntVar *":
+        return _pywrapcp.Solver_IsMemberVar(self, *args)
+
+    def Count(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        |{i | vars[i] == value}| == max_count
+
+        |
+
+        *Overload 2:*
+        |{i | vars[i] == value}| == max_count
+        """
+        return _pywrapcp.Solver_Count(self, *args)
+
+    def Distribute(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        Aggregated version of count:  |{i | v[i] == values[j]}| == cards[j]
+
+        |
+
+        *Overload 2:*
+        Aggregated version of count:  |{i | v[i] == values[j]}| == cards[j]
+
+        |
+
+        *Overload 3:*
+        Aggregated version of count:  |{i | v[i] == j}| == cards[j]
+
+        |
+
+        *Overload 4:*
+        Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1: card_min <= |{i | v[i] == j}| <= card_max
+
+        |
+
+        *Overload 5:*
+        Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1:    card_min[j] <= |{i | v[i] == j}| <= card_max[j]
+
+        |
+
+        *Overload 6:*
+        Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1:    card_min[j] <= |{i | v[i] == j}| <= card_max[j]
+
+        |
+
+        *Overload 7:*
+        Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1:    card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j]
+
+        |
+
+        *Overload 8:*
+        Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1:    card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j]
+        """
+        return _pywrapcp.Solver_Distribute(self, *args)
+
+    def Deviation(self, vars: "std::vector< operations_research::IntVar * > const &", deviation_var: "IntVar", total_sum: "int64_t") -> "operations_research::Constraint *":
+        r""" Deviation constraint: sum_i |n * vars[i] - total_sum| <= deviation_var and sum_i vars[i] == total_sum n = #vars"""
+        return _pywrapcp.Solver_Deviation(self, vars, deviation_var, total_sum)
+
+    def AllDifferent(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        All variables are pairwise different. This corresponds to the stronger version of the propagation algorithm.
+
+        |
+
+        *Overload 2:*
+        All variables are pairwise different.  If 'stronger_propagation' is true, stronger, and potentially slower propagation will occur. This API will be deprecated in the future.
+        """
+        return _pywrapcp.Solver_AllDifferent(self, *args)
+
+    def AllDifferentExcept(self, vars: "std::vector< operations_research::IntVar * > const &", escape_value: "int64_t") -> "operations_research::Constraint *":
+        r""" All variables are pairwise different, unless they are assigned to the escape value."""
+        return _pywrapcp.Solver_AllDifferentExcept(self, vars, escape_value)
+
+    def SortingConstraint(self, vars: "std::vector< operations_research::IntVar * > const &", sorted: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Creates a constraint binding the arrays of variables "vars" and "sorted_vars": sorted_vars[0] must be equal to the minimum of all variables in vars, and so on: the value of sorted_vars[i] must be equal to the i-th value of variables invars. This constraint propagates in both directions: from "vars" to "sorted_vars" and vice-versa. Behind the scenes, this constraint maintains that:   - sorted is always increasing.   - whatever the values of vars, there exists a permutation that     injects its values into the sorted variables. For more info, please have a look at:   https://mpi-inf.mpg.de/~mehlhorn/ftp/Mehlhorn-Thiel.pdf"""
+        return _pywrapcp.Solver_SortingConstraint(self, vars, sorted)
+
+    def LexicalLess(self, left: "std::vector< operations_research::IntVar * > const &", right: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Creates a constraint that enforces that left is lexicographically less than right."""
+        return _pywrapcp.Solver_LexicalLess(self, left, right)
+
+    def LexicalLessOrEqual(self, left: "std::vector< operations_research::IntVar * > const &", right: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Creates a constraint that enforces that left is lexicographically less than or equal to right."""
+        return _pywrapcp.Solver_LexicalLessOrEqual(self, left, right)
+
+    def InversePermutationConstraint(self, left: "std::vector< operations_research::IntVar * > const &", right: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Creates a constraint that enforces that 'left' and 'right' both represent permutations of [0..left.size()-1], and that 'right' is the inverse permutation of 'left', i.e. for all i in [0..left.size()-1], right[left[i]] = i."""
+        return _pywrapcp.Solver_InversePermutationConstraint(self, left, right)
+
+    def NullIntersect(self, first_vars: "std::vector< operations_research::IntVar * > const &", second_vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Creates a constraint that states that all variables in the first vector are different from all variables in the second group. Thus the set of values in the first vector does not intersect with the set of values in the second vector."""
+        return _pywrapcp.Solver_NullIntersect(self, first_vars, second_vars)
+
+    def NullIntersectExcept(self, first_vars: "std::vector< operations_research::IntVar * > const &", second_vars: "std::vector< operations_research::IntVar * > const &", escape_value: "int64_t") -> "operations_research::Constraint *":
+        r""" Creates a constraint that states that all variables in the first vector are different from all variables from the second group, unless they are assigned to the escape value. Thus the set of values in the first vector minus the escape value does not intersect with the set of values in the second vector."""
+        return _pywrapcp.Solver_NullIntersectExcept(self, first_vars, second_vars, escape_value)
+
+    def Circuit(self, nexts: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Force the "nexts" variable to create a complete Hamiltonian path."""
+        return _pywrapcp.Solver_Circuit(self, nexts)
+
+    def SubCircuit(self, nexts: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Force the "nexts" variable to create a complete Hamiltonian path for those that do not loop upon themselves."""
+        return _pywrapcp.Solver_SubCircuit(self, nexts)
+
+    def DelayedPathCumul(self, nexts: "std::vector< operations_research::IntVar * > const &", active: "std::vector< operations_research::IntVar * > const &", cumuls: "std::vector< operations_research::IntVar * > const &", transits: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Delayed version of the same constraint: propagation on the nexts variables is delayed until all constraints have propagated."""
+        return _pywrapcp.Solver_DelayedPathCumul(self, nexts, active, cumuls, transits)
+
+    def PathCumul(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        Creates a constraint which accumulates values along a path such that: cumuls[next[i]] = cumuls[i] + transits[i]. Active variables indicate if the corresponding next variable is active; this could be useful to model unperformed nodes in a routing problem.
+
+        |
+
+        *Overload 2:*
+        Creates a constraint which accumulates values along a path such that: cumuls[next[i]] = cumuls[i] + transit_evaluator(i, next[i]). Active variables indicate if the corresponding next variable is active; this could be useful to model unperformed nodes in a routing problem. Ownership of transit_evaluator is taken and it must be a repeatable callback.
+
+        |
+
+        *Overload 3:*
+        Creates a constraint which accumulates values along a path such that: cumuls[next[i]] = cumuls[i] + transit_evaluator(i, next[i]) + slacks[i]. Active variables indicate if the corresponding next variable is active; this could be useful to model unperformed nodes in a routing problem. Ownership of transit_evaluator is taken and it must be a repeatable callback.
+        """
+        return _pywrapcp.Solver_PathCumul(self, *args)
+
+    def AllowedAssignments(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        This method creates a constraint where the graph of the relation between the variables is given in extension. There are 'arity' variables involved in the relation and the graph is given by a integer tuple set.
+
+        |
+
+        *Overload 2:*
+        Compatibility layer for Python API.
+        """
+        return _pywrapcp.Solver_AllowedAssignments(self, *args)
+
+    def TransitionConstraint(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_TransitionConstraint(self, *args)
+
+    def NonOverlappingBoxesConstraint(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_NonOverlappingBoxesConstraint(self, *args)
+
+    def Pack(self, vars: "std::vector< operations_research::IntVar * > const &", number_of_bins: "int") -> "operations_research::Pack *":
+        r""" This constraint packs all variables onto 'number_of_bins' variables.  For any given variable, a value of 'number_of_bins' indicates that the variable is not assigned to any bin. Dimensions, i.e., cumulative constraints on this packing, can be added directly from the pack class."""
+        return _pywrapcp.Solver_Pack(self, vars, number_of_bins)
+
+    def FixedDurationIntervalVar(self, *args) -> "operations_research::IntervalVar *":
+        r"""
+        *Overload 1:*
+        Creates an interval var with a fixed duration. The duration must be greater than 0. If optional is true, then the interval can be performed or unperformed. If optional is false, then the interval is always performed.
+
+        |
+
+        *Overload 2:*
+        Creates a performed interval var with a fixed duration. The duration must be greater than 0.
+
+        |
+
+        *Overload 3:*
+        Creates an interval var with a fixed duration, and performed_variable. The duration must be greater than 0.
+        """
+        return _pywrapcp.Solver_FixedDurationIntervalVar(self, *args)
+
+    def FixedInterval(self, start: "int64_t", duration: "int64_t", name: "std::string const &") -> "operations_research::IntervalVar *":
+        r""" Creates a fixed and performed interval."""
+        return _pywrapcp.Solver_FixedInterval(self, start, duration, name)
+
+    def IntervalVar(self, start_min: "int64_t", start_max: "int64_t", duration_min: "int64_t", duration_max: "int64_t", end_min: "int64_t", end_max: "int64_t", optional: "bool", name: "std::string const &") -> "operations_research::IntervalVar *":
+        r""" Creates an interval var by specifying the bounds on start, duration, and end."""
+        return _pywrapcp.Solver_IntervalVar(self, start_min, start_max, duration_min, duration_max, end_min, end_max, optional, name)
+
+    def MirrorInterval(self, interval_var: "IntervalVar") -> "operations_research::IntervalVar *":
+        r""" Creates an interval var that is the mirror image of the given one, that is, the interval var obtained by reversing the axis."""
+        return _pywrapcp.Solver_MirrorInterval(self, interval_var)
+
+    def FixedDurationStartSyncedOnStartIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
+        r""" Creates an interval var with a fixed duration whose start is synchronized with the start of another interval, with a given offset. The performed status is also in sync with the performed status of the given interval variable."""
+        return _pywrapcp.Solver_FixedDurationStartSyncedOnStartIntervalVar(self, interval_var, duration, offset)
+
+    def FixedDurationStartSyncedOnEndIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
+        r""" Creates an interval var with a fixed duration whose start is synchronized with the end of another interval, with a given offset. The performed status is also in sync with the performed status of the given interval variable."""
+        return _pywrapcp.Solver_FixedDurationStartSyncedOnEndIntervalVar(self, interval_var, duration, offset)
+
+    def FixedDurationEndSyncedOnStartIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
+        r""" Creates an interval var with a fixed duration whose end is synchronized with the start of another interval, with a given offset. The performed status is also in sync with the performed status of the given interval variable."""
+        return _pywrapcp.Solver_FixedDurationEndSyncedOnStartIntervalVar(self, interval_var, duration, offset)
+
+    def FixedDurationEndSyncedOnEndIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
+        r""" Creates an interval var with a fixed duration whose end is synchronized with the end of another interval, with a given offset. The performed status is also in sync with the performed status of the given interval variable."""
+        return _pywrapcp.Solver_FixedDurationEndSyncedOnEndIntervalVar(self, interval_var, duration, offset)
+
+    def IntervalRelaxedMin(self, interval_var: "IntervalVar") -> "operations_research::IntervalVar *":
+        r""" Creates and returns an interval variable that wraps around the given one, relaxing the min start and end. Relaxing means making unbounded when optional. If the variable is non-optional, this method returns interval_var. More precisely, such an interval variable behaves as follows: * When the underlying must be performed, the returned interval variable     behaves exactly as the underlying; * When the underlying may or may not be performed, the returned interval     variable behaves like the underlying, except that it is unbounded on     the min side; * When the underlying cannot be performed, the returned interval variable     is of duration 0 and must be performed in an interval unbounded on     both sides. This is very useful to implement propagators that may only modify the start max or end max."""
+        return _pywrapcp.Solver_IntervalRelaxedMin(self, interval_var)
+
+    def IntervalRelaxedMax(self, interval_var: "IntervalVar") -> "operations_research::IntervalVar *":
+        r""" Creates and returns an interval variable that wraps around the given one, relaxing the max start and end. Relaxing means making unbounded when optional. If the variable is non optional, this method returns interval_var. More precisely, such an interval variable behaves as follows: * When the underlying must be performed, the returned interval variable     behaves exactly as the underlying; * When the underlying may or may not be performed, the returned interval     variable behaves like the underlying, except that it is unbounded on     the max side; * When the underlying cannot be performed, the returned interval variable     is of duration 0 and must be performed in an interval unbounded on     both sides. This is very useful for implementing propagators that may only modify the start min or end min."""
+        return _pywrapcp.Solver_IntervalRelaxedMax(self, interval_var)
+
+    def TemporalDisjunction(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        This constraint implements a temporal disjunction between two interval vars t1 and t2. 'alt' indicates which alternative was chosen (alt == 0 is equivalent to t1 before t2).
+
+        |
+
+        *Overload 2:*
+        This constraint implements a temporal disjunction between two interval vars.
+        """
+        return _pywrapcp.Solver_TemporalDisjunction(self, *args)
+
+    def DisjunctiveConstraint(self, intervals: "std::vector< operations_research::IntervalVar * > const &", name: "std::string const &") -> "operations_research::DisjunctiveConstraint *":
+        r""" This constraint forces all interval vars into an non-overlapping sequence. Intervals with zero duration can be scheduled anywhere."""
+        return _pywrapcp.Solver_DisjunctiveConstraint(self, intervals, name)
+
+    def Cumulative(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        This constraint forces that, for any integer t, the sum of the demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should only contain non-negative values. Zero values are supported, and the corresponding intervals are filtered out, as they neither impact nor are impacted by this constraint.
+
+        |
+
+        *Overload 2:*
+        This constraint forces that, for any integer t, the sum of the demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should only contain non-negative values. Zero values are supported, and the corresponding intervals are filtered out, as they neither impact nor are impacted by this constraint.
+
+        |
+
+        *Overload 3:*
+        This constraint forces that, for any integer t, the sum of the demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should only contain non-negative values. Zero values are supported, and the corresponding intervals are filtered out, as they neither impact nor are impacted by this constraint.
+
+        |
+
+        *Overload 4:*
+        This constraint enforces that, for any integer t, the sum of the demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should only contain non-negative values. Zero values are supported, and the corresponding intervals are filtered out, as they neither impact nor are impacted by this constraint.
+
+        |
+
+        *Overload 5:*
+        This constraint enforces that, for any integer t, the sum of demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should be positive.
+
+        |
+
+        *Overload 6:*
+        This constraint enforces that, for any integer t, the sum of demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should be positive.
+        """
+        return _pywrapcp.Solver_Cumulative(self, *args)
+
+    def Cover(self, vars: "std::vector< operations_research::IntervalVar * > const &", target_var: "IntervalVar") -> "operations_research::Constraint *":
+        r""" This constraint states that the target_var is the convex hull of the intervals. If none of the interval variables is performed, then the target var is unperformed too. Also, if the target variable is unperformed, then all the intervals variables are unperformed too."""
+        return _pywrapcp.Solver_Cover(self, vars, target_var)
+
+    def Assignment(self, *args) -> "operations_research::Assignment *":
+        r"""
+        *Overload 1:*
+        This method creates an empty assignment.
+
+        |
+
+        *Overload 2:*
+        This method creates an assignment which is a copy of 'a'.
+        """
+        return _pywrapcp.Solver_Assignment(self, *args)
+
+    def FirstSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
+        r"""
+        *Overload 1:*
+        Collect the first solution of the search.
+
+        |
+
+        *Overload 2:*
+        Collect the first solution of the search. The variables will need to be added later.
+        """
+        return _pywrapcp.Solver_FirstSolutionCollector(self, *args)
+
+    def LastSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
+        r"""
+        *Overload 1:*
+        Collect the last solution of the search.
+
+        |
+
+        *Overload 2:*
+        Collect the last solution of the search. The variables will need to be added later.
+        """
+        return _pywrapcp.Solver_LastSolutionCollector(self, *args)
+
+    def BestValueSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
+        r"""
+        *Overload 1:*
+        Collect the solution corresponding to the optimal value of the objective of 'assignment'; if 'assignment' does not have an objective no solution is collected. This collector only collects one solution corresponding to the best objective value (the first one found).
+
+        |
+
+        *Overload 2:*
+        Collect the solution corresponding to the optimal value of the objective of 'assignment'; if 'assignment' does not have an objective no solution is collected. This collector only collects one solution corresponding to the best objective value (the first one found). The variables will need to be added later.
+        """
+        return _pywrapcp.Solver_BestValueSolutionCollector(self, *args)
+
+    def AllSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
+        r"""
+        *Overload 1:*
+        Collect all solutions of the search.
+
+        |
+
+        *Overload 2:*
+        Collect all solutions of the search. The variables will need to be added later.
+        """
+        return _pywrapcp.Solver_AllSolutionCollector(self, *args)
+
+    def Minimize(self, v: "IntVar", step: "int64_t") -> "operations_research::OptimizeVar *":
+        r""" Creates a minimization objective."""
+        return _pywrapcp.Solver_Minimize(self, v, step)
+
+    def Maximize(self, v: "IntVar", step: "int64_t") -> "operations_research::OptimizeVar *":
+        r""" Creates a maximization objective."""
+        return _pywrapcp.Solver_Maximize(self, v, step)
+
+    def Optimize(self, maximize: "bool", v: "IntVar", step: "int64_t") -> "operations_research::OptimizeVar *":
+        r""" Creates a objective with a given sense (true = maximization)."""
+        return _pywrapcp.Solver_Optimize(self, maximize, v, step)
+
+    def WeightedMinimize(self, *args) -> "operations_research::OptimizeVar *":
+        r"""
+        *Overload 1:*
+        Creates a minimization weighted objective. The actual objective is scalar_prod(sub_objectives, weights).
+
+        |
+
+        *Overload 2:*
+        Creates a minimization weighted objective. The actual objective is scalar_prod(sub_objectives, weights).
+        """
+        return _pywrapcp.Solver_WeightedMinimize(self, *args)
+
+    def WeightedMaximize(self, *args) -> "operations_research::OptimizeVar *":
+        r"""
+        *Overload 1:*
+        Creates a maximization weigthed objective.
+
+        |
+
+        *Overload 2:*
+        Creates a maximization weigthed objective.
+        """
+        return _pywrapcp.Solver_WeightedMaximize(self, *args)
+
+    def WeightedOptimize(self, *args) -> "operations_research::OptimizeVar *":
+        r"""
+        *Overload 1:*
+        Creates a weighted objective with a given sense (true = maximization).
+
+        |
+
+        *Overload 2:*
+        Creates a weighted objective with a given sense (true = maximization).
+        """
+        return _pywrapcp.Solver_WeightedOptimize(self, *args)
+
+    def TabuSearch(self, maximize: "bool", v: "IntVar", step: "int64_t", vars: "std::vector< operations_research::IntVar * > const &", keep_tenure: "int64_t", forbid_tenure: "int64_t", tabu_factor: "double") -> "operations_research::SearchMonitor *":
+        r""" MetaHeuristics which try to get the search out of local optima. Creates a Tabu Search monitor. In the context of local search the behavior is similar to MakeOptimize(), creating an objective in a given sense. The behavior differs once a local optimum is reached: thereafter solutions which degrade the value of the objective are allowed if they are not "tabu". A solution is "tabu" if it doesn't respect the following rules: - improving the best solution found so far - variables in the "keep" list must keep their value, variables in the "forbid" list must not take the value they have in the list. Variables with new values enter the tabu lists after each new solution found and leave the lists after a given number of iterations (called tenure). Only the variables passed to the method can enter the lists. The tabu criterion is softened by the tabu factor which gives the number of "tabu" violations which is tolerated; a factor of 1 means no violations allowed; a factor of 0 means all violations are allowed."""
+        return _pywrapcp.Solver_TabuSearch(self, maximize, v, step, vars, keep_tenure, forbid_tenure, tabu_factor)
+
+    def SimulatedAnnealing(self, maximize: "bool", v: "IntVar", step: "int64_t", initial_temperature: "int64_t") -> "operations_research::SearchMonitor *":
+        r""" Creates a Simulated Annealing monitor."""
+        return _pywrapcp.Solver_SimulatedAnnealing(self, maximize, v, step, initial_temperature)
+
+    def LubyRestart(self, scale_factor: "int") -> "operations_research::SearchMonitor *":
+        r""" This search monitor will restart the search periodically. At the iteration n, it will restart after scale_factor * Luby(n) failures where Luby is the Luby Strategy (i.e. 1 1 2 1 1 2 4 1 1 2 1 1 2 4 8...)."""
+        return _pywrapcp.Solver_LubyRestart(self, scale_factor)
+
+    def ConstantRestart(self, frequency: "int") -> "operations_research::SearchMonitor *":
+        r""" This search monitor will restart the search periodically after 'frequency' failures."""
+        return _pywrapcp.Solver_ConstantRestart(self, frequency)
+
+    def TimeLimit(self, *args) -> "operations_research::RegularLimit *":
+        return _pywrapcp.Solver_TimeLimit(self, *args)
+
+    def BranchesLimit(self, branches: "int64_t") -> "operations_research::RegularLimit *":
+        r""" Creates a search limit that constrains the number of branches explored in the search tree."""
+        return _pywrapcp.Solver_BranchesLimit(self, branches)
+
+    def FailuresLimit(self, failures: "int64_t") -> "operations_research::RegularLimit *":
+        r""" Creates a search limit that constrains the number of failures that can happen when exploring the search tree."""
+        return _pywrapcp.Solver_FailuresLimit(self, failures)
+
+    def SolutionsLimit(self, solutions: "int64_t") -> "operations_research::RegularLimit *":
+        r""" Creates a search limit that constrains the number of solutions found during the search."""
+        return _pywrapcp.Solver_SolutionsLimit(self, solutions)
+
+    def Limit(self, *args) -> "operations_research::SearchLimit *":
+        r"""
+        *Overload 1:*
+        Limits the search with the 'time', 'branches', 'failures' and 'solutions' limits. 'smart_time_check' reduces the calls to the wall
+
+        |
+
+        *Overload 2:*
+        Creates a search limit from its protobuf description
+
+        |
+
+        *Overload 3:*
+        Creates a search limit that is reached when either of the underlying limit is reached. That is, the returned limit is more stringent than both argument limits.
+        """
+        return _pywrapcp.Solver_Limit(self, *args)
+
+    def CustomLimit(self, limiter: "std::function< bool () >") -> "operations_research::SearchLimit *":
+        r""" Callback-based search limit. Search stops when limiter returns true; if this happens at a leaf the corresponding solution will be rejected."""
+        return _pywrapcp.Solver_CustomLimit(self, limiter)
+
+    def SearchLog(self, *args) -> "operations_research::SearchMonitor *":
+        return _pywrapcp.Solver_SearchLog(self, *args)
+
+    def SearchTrace(self, prefix: "std::string const &") -> "operations_research::SearchMonitor *":
+        r""" Creates a search monitor that will trace precisely the behavior of the search. Use this only for low level debugging."""
+        return _pywrapcp.Solver_SearchTrace(self, prefix)
+
+    def PrintModelVisitor(self) -> "operations_research::ModelVisitor *":
+        r""" Prints the model."""
+        return _pywrapcp.Solver_PrintModelVisitor(self)
+
+    def StatisticsModelVisitor(self) -> "operations_research::ModelVisitor *":
+        r""" Displays some nice statistics on the model."""
+        return _pywrapcp.Solver_StatisticsModelVisitor(self)
+
+    def AssignVariableValue(self, var: "IntVar", val: "int64_t") -> "operations_research::Decision *":
+        r""" Decisions."""
+        return _pywrapcp.Solver_AssignVariableValue(self, var, val)
+
+    def VariableLessOrEqualValue(self, var: "IntVar", value: "int64_t") -> "operations_research::Decision *":
+        return _pywrapcp.Solver_VariableLessOrEqualValue(self, var, value)
+
+    def VariableGreaterOrEqualValue(self, var: "IntVar", value: "int64_t") -> "operations_research::Decision *":
+        return _pywrapcp.Solver_VariableGreaterOrEqualValue(self, var, value)
+
+    def SplitVariableDomain(self, var: "IntVar", val: "int64_t", start_with_lower_half: "bool") -> "operations_research::Decision *":
+        return _pywrapcp.Solver_SplitVariableDomain(self, var, val, start_with_lower_half)
+
+    def AssignVariableValueOrFail(self, var: "IntVar", value: "int64_t") -> "operations_research::Decision *":
+        return _pywrapcp.Solver_AssignVariableValueOrFail(self, var, value)
+
+    def AssignVariablesValues(self, vars: "std::vector< operations_research::IntVar * > const &", values: "std::vector< int64_t > const &") -> "operations_research::Decision *":
+        return _pywrapcp.Solver_AssignVariablesValues(self, vars, values)
+
+    def FailDecision(self) -> "operations_research::Decision *":
+        return _pywrapcp.Solver_FailDecision(self)
+
+    def Decision(self, apply: "operations_research::Solver::Action", refute: "operations_research::Solver::Action") -> "operations_research::Decision *":
+        return _pywrapcp.Solver_Decision(self, apply, refute)
+
+    def Compose(self, dbs: "std::vector< operations_research::DecisionBuilder * > const &") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_Compose(self, dbs)
+
+    def Try(self, dbs: "std::vector< operations_research::DecisionBuilder * > const &") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_Try(self, dbs)
+
+    def DefaultPhase(self, *args) -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_DefaultPhase(self, *args)
+
+    def ScheduleOrPostpone(self, var: "IntervalVar", est: "int64_t", marker: "int64_t *const") -> "operations_research::Decision *":
+        r""" Returns a decision that tries to schedule a task at a given time. On the Apply branch, it will set that interval var as performed and set its start to 'est'. On the Refute branch, it will just update the 'marker' to 'est' + 1. This decision is used in the INTERVAL_SET_TIMES_FORWARD strategy."""
+        return _pywrapcp.Solver_ScheduleOrPostpone(self, var, est, marker)
+
+    def ScheduleOrExpedite(self, var: "IntervalVar", est: "int64_t", marker: "int64_t *const") -> "operations_research::Decision *":
+        r""" Returns a decision that tries to schedule a task at a given time. On the Apply branch, it will set that interval var as performed and set its end to 'est'. On the Refute branch, it will just update the 'marker' to 'est' - 1. This decision is used in the INTERVAL_SET_TIMES_BACKWARD strategy."""
+        return _pywrapcp.Solver_ScheduleOrExpedite(self, var, est, marker)
+
+    def RankFirstInterval(self, sequence: "SequenceVar", index: "int") -> "operations_research::Decision *":
+        r""" Returns a decision that tries to rank first the ith interval var in the sequence variable."""
+        return _pywrapcp.Solver_RankFirstInterval(self, sequence, index)
+
+    def RankLastInterval(self, sequence: "SequenceVar", index: "int") -> "operations_research::Decision *":
+        r""" Returns a decision that tries to rank last the ith interval var in the sequence variable."""
+        return _pywrapcp.Solver_RankLastInterval(self, sequence, index)
+
+    def Phase(self, *args) -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_Phase(self, *args)
+
+    def DecisionBuilderFromAssignment(self, assignment: "Assignment", db: "DecisionBuilder", vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::DecisionBuilder *":
+        r""" Returns a decision builder for which the left-most leaf corresponds to assignment, the rest of the tree being explored using 'db'."""
+        return _pywrapcp.Solver_DecisionBuilderFromAssignment(self, assignment, db, vars)
+
+    def ConstraintAdder(self, ct: "Constraint") -> "operations_research::DecisionBuilder *":
+        r""" Returns a decision builder that will add the given constraint to the model."""
+        return _pywrapcp.Solver_ConstraintAdder(self, ct)
+
+    def SolveOnce(self, db: "DecisionBuilder", monitors: "std::vector< operations_research::SearchMonitor * > const &") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_SolveOnce(self, db, monitors)
+
+    def NestedOptimize(self, *args) -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_NestedOptimize(self, *args)
+
+    def RestoreAssignment(self, assignment: "Assignment") -> "operations_research::DecisionBuilder *":
+        r""" Returns a DecisionBuilder which restores an Assignment (calls void Assignment::Restore())"""
+        return _pywrapcp.Solver_RestoreAssignment(self, assignment)
+
+    def StoreAssignment(self, assignment: "Assignment") -> "operations_research::DecisionBuilder *":
+        r""" Returns a DecisionBuilder which stores an Assignment (calls void Assignment::Store())"""
+        return _pywrapcp.Solver_StoreAssignment(self, assignment)
+
+    def Operator(self, *args) -> "operations_research::LocalSearchOperator *":
+        return _pywrapcp.Solver_Operator(self, *args)
+
+    def RandomLnsOperator(self, *args) -> "operations_research::LocalSearchOperator *":
+        return _pywrapcp.Solver_RandomLnsOperator(self, *args)
+
+    def MoveTowardTargetOperator(self, *args) -> "operations_research::LocalSearchOperator *":
+        r"""
+        *Overload 1:*
+        Creates a local search operator that tries to move the assignment of some variables toward a target. The target is given as an Assignment. This operator generates neighbors in which the only difference compared to the current state is that one variable that belongs to the target assignment is set to its target value.
+
+        |
+
+        *Overload 2:*
+        Creates a local search operator that tries to move the assignment of some variables toward a target. The target is given either as two vectors: a vector of variables and a vector of associated target values. The two vectors should be of the same length. This operator generates neighbors in which the only difference compared to the current state is that one variable that belongs to the given vector is set to its target value.
+        """
+        return _pywrapcp.Solver_MoveTowardTargetOperator(self, *args)
+
+    def ConcatenateOperators(self, *args) -> "operations_research::LocalSearchOperator *":
+        return _pywrapcp.Solver_ConcatenateOperators(self, *args)
+
+    def RandomConcatenateOperators(self, *args) -> "operations_research::LocalSearchOperator *":
+        r"""
+        *Overload 1:*
+        Randomized version of local search concatenator; calls a random operator at each call to MakeNextNeighbor().
+
+        |
+
+        *Overload 2:*
+        Randomized version of local search concatenator; calls a random operator at each call to MakeNextNeighbor(). The provided seed is used to initialize the random number generator.
+        """
+        return _pywrapcp.Solver_RandomConcatenateOperators(self, *args)
+
+    def NeighborhoodLimit(self, op: "LocalSearchOperator", limit: "int64_t") -> "operations_research::LocalSearchOperator *":
+        r""" Creates a local search operator that wraps another local search operator and limits the number of neighbors explored (i.e., calls to MakeNextNeighbor from the current solution (between two calls to Start()). When this limit is reached, MakeNextNeighbor() returns false. The counter is cleared when Start() is called."""
+        return _pywrapcp.Solver_NeighborhoodLimit(self, op, limit)
+
+    def LocalSearchPhase(self, *args) -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_LocalSearchPhase(self, *args)
+
+    def LocalSearchPhaseParameters(self, *args) -> "operations_research::LocalSearchPhaseParameters *":
+        return _pywrapcp.Solver_LocalSearchPhaseParameters(self, *args)
+
+    def SearchDepth(self) -> "int":
+        r""" Gets the search depth of the current active search. Returns -1 if there is no active search opened."""
+        return _pywrapcp.Solver_SearchDepth(self)
+
+    def SearchLeftDepth(self) -> "int":
+        r""" Gets the search left depth of the current active search. Returns -1 if there is no active search opened."""
+        return _pywrapcp.Solver_SearchLeftDepth(self)
+
+    def SolveDepth(self) -> "int":
+        r""" Gets the number of nested searches. It returns 0 outside search, 1 during the top level search, 2 or more in case of nested searches."""
+        return _pywrapcp.Solver_SolveDepth(self)
+
+    def Rand64(self, size: "int64_t") -> "int64_t":
+        r""" Returns a random value between 0 and 'size' - 1;"""
+        return _pywrapcp.Solver_Rand64(self, size)
+
+    def Rand32(self, size: "int32_t") -> "int32_t":
+        r""" Returns a random value between 0 and 'size' - 1;"""
+        return _pywrapcp.Solver_Rand32(self, size)
+
+    def ReSeed(self, seed: "int32_t") -> "void":
+        r""" Reseed the solver random generator."""
+        return _pywrapcp.Solver_ReSeed(self, seed)
+
+    def LocalSearchProfile(self) -> "std::string":
+        r""" Returns local search profiling information in a human readable format."""
+        return _pywrapcp.Solver_LocalSearchProfile(self)
+
+    def Constraints(self) -> "int":
+        r""" Counts the number of constraints that have been added to the solver before the search."""
+        return _pywrapcp.Solver_Constraints(self)
+
+    def Accept(self, visitor: "operations_research::ModelVisitor *const") -> "void":
+        r""" Accepts the given model visitor."""
+        return _pywrapcp.Solver_Accept(self, visitor)
+
+    def FinishCurrentSearch(self) -> "void":
+        r""" Tells the solver to kill or restart the current search."""
+        return _pywrapcp.Solver_FinishCurrentSearch(self)
+
+    def RestartCurrentSearch(self) -> "void":
+        return _pywrapcp.Solver_RestartCurrentSearch(self)
+
+    def ShouldFail(self) -> "void":
+        r""" These methods are only useful for the SWIG wrappers, which need a way to externally cause the Solver to fail."""
+        return _pywrapcp.Solver_ShouldFail(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.Solver___str__(self)
+
+    def Add(self, ct):
+      if isinstance(ct, PyConstraint):
+        self.__python_constraints.append(ct)
+      self.AddConstraint(ct)
+
+
+    def TreeNoCycle(self, nexts: "std::vector< operations_research::IntVar * > const &", active: "std::vector< operations_research::IntVar * > const &", callback: "operations_research::Solver::IndexFilter1"=0) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_TreeNoCycle(self, nexts, active, callback)
+
+    def SearchLogWithCallback(self, period: "int", callback: "std::function< std::string () >") -> "operations_research::SearchMonitor *":
+        return _pywrapcp.Solver_SearchLogWithCallback(self, period, callback)
+
+    def ElementFunction(self, values: "std::function< int64_t (int64_t) >", index: "IntVar") -> "operations_research::IntExpr *":
+        return _pywrapcp.Solver_ElementFunction(self, values, index)
+
+    def VarEvalValStrPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_evaluator: "std::function< int64_t (int64_t) >", val_str: "operations_research::Solver::IntValueStrategy") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_VarEvalValStrPhase(self, vars, var_evaluator, val_str)
+
+    def VarStrValEvalPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_str: "operations_research::Solver::IntVarStrategy", val_eval: "operations_research::Solver::IndexEvaluator2") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_VarStrValEvalPhase(self, vars, var_str, val_eval)
+
+    def VarEvalValEvalPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_eval: "std::function< int64_t (int64_t) >", val_eval: "operations_research::Solver::IndexEvaluator2") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_VarEvalValEvalPhase(self, vars, var_eval, val_eval)
+
+    def VarStrValEvalTieBreakPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_str: "operations_research::Solver::IntVarStrategy", val_eval: "operations_research::Solver::IndexEvaluator2", tie_breaker: "std::function< int64_t (int64_t) >") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_VarStrValEvalTieBreakPhase(self, vars, var_str, val_eval, tie_breaker)
+
+    def VarEvalValEvalTieBreakPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_eval: "std::function< int64_t (int64_t) >", val_eval: "operations_research::Solver::IndexEvaluator2", tie_breaker: "std::function< int64_t (int64_t) >") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_VarEvalValEvalTieBreakPhase(self, vars, var_eval, val_eval, tie_breaker)
+
+    def EvalEvalStrPhase(self, vars: "std::vector< operations_research::IntVar * > const &", evaluator: "operations_research::Solver::IndexEvaluator2", str: "operations_research::Solver::EvaluatorStrategy") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_EvalEvalStrPhase(self, vars, evaluator, str)
+
+    def EvalEvalStrTieBreakPhase(self, vars: "std::vector< operations_research::IntVar * > const &", evaluator: "operations_research::Solver::IndexEvaluator2", tie_breaker: "operations_research::Solver::IndexEvaluator1", str: "operations_research::Solver::EvaluatorStrategy") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_EvalEvalStrTieBreakPhase(self, vars, evaluator, tie_breaker, str)
+
+    def GuidedLocalSearch(self, *args) -> "operations_research::SearchMonitor *":
+        return _pywrapcp.Solver_GuidedLocalSearch(self, *args)
+
+    def SumObjectiveFilter(self, vars: "std::vector< operations_research::IntVar * > const &", values: "operations_research::Solver::IndexEvaluator2", filter_enum: "operations_research::Solver::LocalSearchFilterBound") -> "operations_research::LocalSearchFilter *":
+        return _pywrapcp.Solver_SumObjectiveFilter(self, vars, values, filter_enum)
+
+ +
+ +

Solver Class A solver represents the main computation engine. It implements the entire range of Constraint Programming protocols: - Reversibility - Propagation - Search Usually, Constraint Programming code consists of - the creation of the Solver, - the creation of the decision variables of the model, - the creation of the constraints of the model and their addition to the solver() through the AddConstraint() method, - the creation of the main DecisionBuilder class, - the launch of the solve() method with the decision builder. For the time being, Solver is neither MT_SAFE nor MT_HOT.

+
+ + +
+
#   + + + Solver(*args) +
+ +
+ View Source +
    def __init__(self, *args):
+        _pywrapcp.Solver_swiginit(self, _pywrapcp.new_Solver(*args))
+
+        self.__python_constraints = []
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + INT_VAR_DEFAULT = 0 +
+ +

The default behavior is CHOOSE_FIRST_UNBOUND.

+
+ + +
+
+
#   + + INT_VAR_SIMPLE = 1 +
+ +

The simple selection is CHOOSE_FIRST_UNBOUND.

+
+ + +
+
+
#   + + CHOOSE_FIRST_UNBOUND = 2 +
+ +

Select the first unbound variable. Variables are considered in the order of the vector of IntVars used to create the selector.

+
+ + +
+
+
#   + + CHOOSE_RANDOM = 3 +
+ +

Randomly select one of the remaining unbound variables.

+
+ + +
+
+
#   + + CHOOSE_MIN_SIZE_LOWEST_MIN = 4 +
+ +

Among unbound variables, select the variable with the smallest size, i.e., the smallest number of possible values. In case of a tie, the selected variables is the one with the lowest min value. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector.

+
+ + +
+
+
#   + + CHOOSE_MIN_SIZE_HIGHEST_MIN = 5 +
+ +

Among unbound variables, select the variable with the smallest size, i.e., the smallest number of possible values. In case of a tie, the selected variable is the one with the highest min value. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector.

+
+ + +
+
+
#   + + CHOOSE_MIN_SIZE_LOWEST_MAX = 6 +
+ +

Among unbound variables, select the variable with the smallest size, i.e., the smallest number of possible values. In case of a tie, the selected variables is the one with the lowest max value. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector.

+
+ + +
+
+
#   + + CHOOSE_MIN_SIZE_HIGHEST_MAX = 7 +
+ +

Among unbound variables, select the variable with the smallest size, i.e., the smallest number of possible values. In case of a tie, the selected variable is the one with the highest max value. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector.

+
+ + +
+
+
#   + + CHOOSE_LOWEST_MIN = 8 +
+ +

Among unbound variables, select the variable with the smallest minimal value. In case of a tie, the first one is selected, "first" defined by the order in the vector of IntVars used to create the selector.

+
+ + +
+
+
#   + + CHOOSE_HIGHEST_MAX = 9 +
+ +

Among unbound variables, select the variable with the highest maximal value. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector.

+
+ + +
+
+
#   + + CHOOSE_MIN_SIZE = 10 +
+ +

Among unbound variables, select the variable with the smallest size. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector.

+
+ + +
+
+
#   + + CHOOSE_MAX_SIZE = 11 +
+ +

Among unbound variables, select the variable with the highest size. In case of a tie, the first one is selected, first being defined by the order in the vector of IntVars used to create the selector.

+
+ + +
+
+
#   + + CHOOSE_MAX_REGRET_ON_MIN = 12 +
+ +

Among unbound variables, select the variable with the largest gap between the first and the second values of the domain.

+
+ + +
+
+
#   + + CHOOSE_PATH = 13 +
+ +

Selects the next unbound variable on a path, the path being defined by the variables: var[i] corresponds to the index of the next of i.

+
+ + +
+
+
#   + + INT_VALUE_DEFAULT = 0 +
+ +

The default behavior is ASSIGN_MIN_VALUE.

+
+ + +
+
+
#   + + INT_VALUE_SIMPLE = 1 +
+ +

The simple selection is ASSIGN_MIN_VALUE.

+
+ + +
+
+
#   + + ASSIGN_MIN_VALUE = 2 +
+ +

Selects the min value of the selected variable.

+
+ + +
+
+
#   + + ASSIGN_MAX_VALUE = 3 +
+ +

Selects the max value of the selected variable.

+
+ + +
+
+
#   + + ASSIGN_RANDOM_VALUE = 4 +
+ +

Selects randomly one of the possible values of the selected variable.

+
+ + +
+
+
#   + + ASSIGN_CENTER_VALUE = 5 +
+ +

Selects the first possible value which is the closest to the center of the domain of the selected variable. The center is defined as (min + max) / 2.

+
+ + +
+
+
#   + + SPLIT_LOWER_HALF = 6 +
+ +

Split the domain in two around the center, and choose the lower part first.

+
+ + +
+
+
#   + + SPLIT_UPPER_HALF = 7 +
+ +

Split the domain in two around the center, and choose the lower part first.

+
+ + +
+
+
#   + + SEQUENCE_DEFAULT = 0 +
+ + + +
+
+
#   + + SEQUENCE_SIMPLE = 1 +
+ + + +
+
+
#   + + CHOOSE_MIN_SLACK_RANK_FORWARD = 2 +
+ + + +
+
+
#   + + CHOOSE_RANDOM_RANK_FORWARD = 3 +
+ + + +
+
+
#   + + INTERVAL_DEFAULT = 0 +
+ +

The default is INTERVAL_SET_TIMES_FORWARD.

+
+ + +
+
+
#   + + INTERVAL_SIMPLE = 1 +
+ +

The simple is INTERVAL_SET_TIMES_FORWARD.

+
+ + +
+
+
#   + + INTERVAL_SET_TIMES_FORWARD = 2 +
+ +

Selects the variable with the lowest starting time of all variables, and fixes its starting time to this lowest value.

+
+ + +
+
+
#   + + INTERVAL_SET_TIMES_BACKWARD = 3 +
+ +

Selects the variable with the highest ending time of all variables, and fixes the ending time to this highest values.

+
+ + +
+
+
#   + + TWOOPT = 0 +
+ +

Operator which reverses a sub-chain of a path. It is called TwoOpt because it breaks two arcs on the path; resulting paths are called two-optimal. Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5 (where (1, 5) are first and last nodes of the path and can therefore not be moved): 1 -> [3 -> 2] -> 4 -> 5 1 -> [4 -> 3 -> 2] -> 5 1 -> 2 -> [4 -> 3] -> 5

+
+ + +
+
+
#   + + OROPT = 1 +
+ +

Relocate: OROPT and RELOCATE. Operator which moves a sub-chain of a path to another position; the specified chain length is the fixed length of the chains being moved. When this length is 1, the operator simply moves a node to another position. Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5, for a chain length of 2 (where (1, 5) are first and last nodes of the path and can therefore not be moved): 1 -> 4 -> [2 -> 3] -> 5 1 -> [3 -> 4] -> 2 -> 5 Using Relocate with chain lengths of 1, 2 and 3 together is equivalent to the OrOpt operator on a path. The OrOpt operator is a limited version of 3Opt (breaks 3 arcs on a path).

+
+ + +
+
+
#   + + RELOCATE = 2 +
+ +

Relocate neighborhood with length of 1 (see OROPT comment).

+
+ + +
+
+
#   + + EXCHANGE = 3 +
+ +

Operator which exchanges the positions of two nodes. Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5 (where (1, 5) are first and last nodes of the path and can therefore not be moved): 1 -> [3] -> [2] -> 4 -> 5 1 -> [4] -> 3 -> [2] -> 5 1 -> 2 -> [4] -> [3] -> 5

+
+ + +
+
+
#   + + CROSS = 4 +
+ +

Operator which cross exchanges the starting chains of 2 paths, including exchanging the whole paths. First and last nodes are not moved. Possible neighbors for the paths 1 -> 2 -> 3 -> 4 -> 5 and 6 -> 7 -> 8 (where (1, 5) and (6, 8) are first and last nodes of the paths and can therefore not be moved): 1 -> [7] -> 3 -> 4 -> 5 6 -> [2] -> 8 1 -> [7] -> 4 -> 5 6 -> [2 -> 3] -> 8 1 -> [7] -> 5 6 -> [2 -> 3 -> 4] -> 8

+
+ + +
+
+
#   + + MAKEACTIVE = 5 +
+ +

Operator which inserts an inactive node into a path. Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive (where 1 and 4 are first and last nodes of the path) are: 1 -> [5] -> 2 -> 3 -> 4 1 -> 2 -> [5] -> 3 -> 4 1 -> 2 -> 3 -> [5] -> 4

+
+ + +
+
+
#   + + MAKEINACTIVE = 6 +
+ +

Operator which makes path nodes inactive. Possible neighbors for the path 1 -> 2 -> 3 -> 4 (where 1 and 4 are first and last nodes of the path) are: 1 -> 3 -> 4 with 2 inactive 1 -> 2 -> 4 with 3 inactive

+
+ + +
+
+
#   + + MAKECHAININACTIVE = 7 +
+ +

Operator which makes a "chain" of path nodes inactive. Possible neighbors for the path 1 -> 2 -> 3 -> 4 (where 1 and 4 are first and last nodes of the path) are: 1 -> 3 -> 4 with 2 inactive 1 -> 2 -> 4 with 3 inactive 1 -> 4 with 2 and 3 inactive

+
+ + +
+
+
#   + + SWAPACTIVE = 8 +
+ +

Operator which replaces an active node by an inactive one. Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive (where 1 and 4 are first and last nodes of the path) are: 1 -> [5] -> 3 -> 4 with 2 inactive 1 -> 2 -> [5] -> 4 with 3 inactive

+
+ + +
+
+
#   + + EXTENDEDSWAPACTIVE = 9 +
+ +

Operator which makes an inactive node active and an active one inactive. It is similar to SwapActiveOperator except that it tries to insert the inactive node in all possible positions instead of just the position of the node made inactive. Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive (where 1 and 4 are first and last nodes of the path) are: 1 -> [5] -> 3 -> 4 with 2 inactive 1 -> 3 -> [5] -> 4 with 2 inactive 1 -> [5] -> 2 -> 4 with 3 inactive 1 -> 2 -> [5] -> 4 with 3 inactive

+
+ + +
+
+
#   + + PATHLNS = 10 +
+ +

Operator which relaxes two sub-chains of three consecutive arcs each. Each sub-chain is defined by a start node and the next three arcs. Those six arcs are relaxed to build a new neighbor. PATHLNS explores all possible pairs of starting nodes and so defines n^2 neighbors, n being the number of nodes. Note that the two sub-chains can be part of the same path; they even may overlap.

+
+ + +
+
+
#   + + FULLPATHLNS = 11 +
+ +

Operator which relaxes one entire path and all inactive nodes, thus defining num_paths neighbors.

+
+ + +
+
+
#   + + UNACTIVELNS = 12 +
+ +

Operator which relaxes all inactive nodes and one sub-chain of six consecutive arcs. That way the path can be improved by inserting inactive nodes or swapping arcs.

+
+ + +
+
+
#   + + INCREMENT = 13 +
+ +

Operator which defines one neighbor per variable. Each neighbor tries to increment by one the value of the corresponding variable. When a new solution is found the neighborhood is rebuilt from scratch, i.e., tries to increment values in the variable order. Consider for instance variables x and y. x is incremented one by one to its max, and when it is not possible to increment x anymore, y is incremented once. If this is a solution, then next neighbor tries to increment x.

+
+ + +
+
+
#   + + DECREMENT = 14 +
+ +

Operator which defines a neighborhood to decrement values. The behavior is the same as INCREMENT, except values are decremented instead of incremented.

+
+ + +
+
+
#   + + SIMPLELNS = 15 +
+ +

Operator which defines one neighbor per variable. Each neighbor relaxes one variable. When a new solution is found the neighborhood is rebuilt from scratch. Consider for instance variables x and y. First x is relaxed and the solver is looking for the best possible solution (with only x relaxed). Then y is relaxed, and the solver is looking for a new solution. If a new solution is found, then the next variable to be relaxed is x.

+
+ + +
+
+
#   + + GE = 0 +
+ +

Move is accepted when the current objective value >= objective.Min.

+
+ + +
+
+
#   + + LE = 1 +
+ +

Move is accepted when the current objective value <= objective.Max.

+
+ + +
+
+
#   + + EQ = 2 +
+ +

Move is accepted when the current objective value is in the interval objective.Min .. objective.Max.

+
+ + +
+
+
#   + + DELAYED_PRIORITY = 0 +
+ +

DELAYED_PRIORITY is the lowest priority: Demons will be processed after VAR_PRIORITY and NORMAL_PRIORITY demons.

+
+ + +
+
+
#   + + VAR_PRIORITY = 1 +
+ +

VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY.

+
+ + +
+
+
#   + + NORMAL_PRIORITY = 2 +
+ +

NORMAL_PRIORITY is the highest priority: Demons will be processed first.

+
+ + +
+
+
#   + + + def + Parameters(self) -> 'operations_research::ConstraintSolverParameters': +
+ +
+ View Source +
    def Parameters(self) -> "operations_research::ConstraintSolverParameters":
+        r""" Stored Parameters."""
+        return _pywrapcp.Solver_Parameters(self)
+
+ +
+ +

Stored Parameters.

+
+ + +
+
+
#   + +
@staticmethod
+ + def + DefaultSolverParameters() -> 'operations_research::ConstraintSolverParameters': +
+ +
+ View Source +
    @staticmethod
+    def DefaultSolverParameters() -> "operations_research::ConstraintSolverParameters":
+        r""" Create a ConstraintSolverParameters proto with all the default values."""
+        return _pywrapcp.Solver_DefaultSolverParameters()
+
+ +
+ +

Create a ConstraintSolverParameters proto with all the default values.

+
+ + +
+
+
#   + + + def + AddConstraint(self, c: pywrapcp.Constraint) -> 'void': +
+ +
+ View Source +
    def AddConstraint(self, c: "Constraint") -> "void":
+        r""" Adds the constraint 'c' to the model. After calling this method, and until there is a backtrack that undoes the addition, any assignment of variables to values must satisfy the given constraint in order to be considered feasible. There are two fairly different use cases: - the most common use case is modeling: the given constraint is really part of the problem that the user is trying to solve. In this use case, AddConstraint is called outside of search (i.e., with state() == OUTSIDE_SEARCH). Most users should only use AddConstraint in this way. In this case, the constraint will belong to the model forever: it cannot not be removed by backtracking. - a rarer use case is that 'c' is not a real constraint of the model. It may be a constraint generated by a branching decision (a constraint whose goal is to restrict the search space), a symmetry breaking constraint (a constraint that does restrict the search space, but in a way that cannot have an impact on the quality of the solutions in the subtree), or an inferred constraint that, while having no semantic value to the model (it does not restrict the set of solutions), is worth having because we believe it may strengthen the propagation. In these cases, it happens that the constraint is added during the search (i.e., with state() == IN_SEARCH or state() == IN_ROOT_NODE). When a constraint is added during a search, it applies only to the subtree of the search tree rooted at the current node, and will be automatically removed by backtracking. This method does not take ownership of the constraint. If the constraint has been created by any factory method (Solver::MakeXXX), it will automatically be deleted. However, power users who implement their own constraints should do: solver.AddConstraint(solver.RevAlloc(new MyConstraint(...));"""
+        return _pywrapcp.Solver_AddConstraint(self, c)
+
+ +
+ +

Adds the constraint 'c' to the model. After calling this method, and until there is a backtrack that undoes the addition, any assignment of variables to values must satisfy the given constraint in order to be considered feasible. There are two fairly different use cases: - the most common use case is modeling: the given constraint is really part of the problem that the user is trying to solve. In this use case, AddConstraint is called outside of search (i.e., with state() == OUTSIDE_SEARCH). Most users should only use AddConstraint in this way. In this case, the constraint will belong to the model forever: it cannot not be removed by backtracking. - a rarer use case is that 'c' is not a real constraint of the model. It may be a constraint generated by a branching decision (a constraint whose goal is to restrict the search space), a symmetry breaking constraint (a constraint that does restrict the search space, but in a way that cannot have an impact on the quality of the solutions in the subtree), or an inferred constraint that, while having no semantic value to the model (it does not restrict the set of solutions), is worth having because we believe it may strengthen the propagation. In these cases, it happens that the constraint is added during the search (i.e., with state() == IN_SEARCH or state() == IN_ROOT_NODE). When a constraint is added during a search, it applies only to the subtree of the search tree rooted at the current node, and will be automatically removed by backtracking. This method does not take ownership of the constraint. If the constraint has been created by any factory method (Solver::MakeXXX), it will automatically be deleted. However, power users who implement their own constraints should do: solver.AddConstraint(solver.RevAlloc(new MyConstraint(...));

+
+ + +
+
+
#   + + + def + Solve(self, *args) -> bool: +
+ +
+ View Source +
    def Solve(self, *args) -> "bool":
+        return _pywrapcp.Solver_Solve(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + NewSearch(self, *args) -> 'void': +
+ +
+ View Source +
    def NewSearch(self, *args) -> "void":
+        return _pywrapcp.Solver_NewSearch(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + NextSolution(self) -> bool: +
+ +
+ View Source +
    def NextSolution(self) -> "bool":
+        return _pywrapcp.Solver_NextSolution(self)
+
+ +
+ + + +
+
+
#   + + + def + RestartSearch(self) -> 'void': +
+ +
+ View Source +
    def RestartSearch(self) -> "void":
+        return _pywrapcp.Solver_RestartSearch(self)
+
+ +
+ + + +
+
+
#   + + + def + EndSearch(self) -> 'void': +
+ +
+ View Source +
    def EndSearch(self) -> "void":
+        return _pywrapcp.Solver_EndSearch(self)
+
+ +
+ + + +
+
+
#   + + + def + SolveAndCommit(self, *args) -> bool: +
+ +
+ View Source +
    def SolveAndCommit(self, *args) -> "bool":
+        return _pywrapcp.Solver_SolveAndCommit(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + CheckAssignment(self, solution: pywrapcp.Assignment) -> bool: +
+ +
+ View Source +
    def CheckAssignment(self, solution: "Assignment") -> "bool":
+        r""" Checks whether the given assignment satisfies all relevant constraints."""
+        return _pywrapcp.Solver_CheckAssignment(self, solution)
+
+ +
+ +

Checks whether the given assignment satisfies all relevant constraints.

+
+ + +
+
+
#   + + + def + CheckConstraint(self, ct: pywrapcp.Constraint) -> bool: +
+ +
+ View Source +
    def CheckConstraint(self, ct: "Constraint") -> "bool":
+        r""" Checks whether adding this constraint will lead to an immediate failure. It will return false if the model is already inconsistent, or if adding the constraint makes it inconsistent."""
+        return _pywrapcp.Solver_CheckConstraint(self, ct)
+
+ +
+ +

Checks whether adding this constraint will lead to an immediate failure. It will return false if the model is already inconsistent, or if adding the constraint makes it inconsistent.

+
+ + +
+
+
#   + + + def + Fail(self) -> 'void': +
+ +
+ View Source +
    def Fail(self) -> "void":
+        r""" Abandon the current branch in the search tree. A backtrack will follow."""
+        return _pywrapcp.Solver_Fail(self)
+
+ +
+ +

Abandon the current branch in the search tree. A backtrack will follow.

+
+ + +
+
+
#   + +
@staticmethod
+ + def + MemoryUsage() -> 'int64_t': +
+ +
+ View Source +
    @staticmethod
+    def MemoryUsage() -> "int64_t":
+        r""" Current memory usage in bytes"""
+        return _pywrapcp.Solver_MemoryUsage()
+
+ +
+ +

Current memory usage in bytes

+
+ + +
+
+
#   + + + def + WallTime(self) -> 'int64_t': +
+ +
+ View Source +
    def WallTime(self) -> "int64_t":
+        r""" DEPRECATED: Use Now() instead. Time elapsed, in ms since the creation of the solver."""
+        return _pywrapcp.Solver_WallTime(self)
+
+ +
+ +

DEPRECATED: Use Now() instead. Time elapsed, in ms since the creation of the solver.

+
+ + +
+
+
#   + + + def + Branches(self) -> 'int64_t': +
+ +
+ View Source +
    def Branches(self) -> "int64_t":
+        r""" The number of branches explored since the creation of the solver."""
+        return _pywrapcp.Solver_Branches(self)
+
+ +
+ +

The number of branches explored since the creation of the solver.

+
+ + +
+
+
#   + + + def + Solutions(self) -> 'int64_t': +
+ +
+ View Source +
    def Solutions(self) -> "int64_t":
+        r""" The number of solutions found since the start of the search."""
+        return _pywrapcp.Solver_Solutions(self)
+
+ +
+ +

The number of solutions found since the start of the search.

+
+ + +
+
+
#   + + + def + Failures(self) -> 'int64_t': +
+ +
+ View Source +
    def Failures(self) -> "int64_t":
+        r""" The number of failures encountered since the creation of the solver."""
+        return _pywrapcp.Solver_Failures(self)
+
+ +
+ +

The number of failures encountered since the creation of the solver.

+
+ + +
+
+
#   + + + def + AcceptedNeighbors(self) -> 'int64_t': +
+ +
+ View Source +
    def AcceptedNeighbors(self) -> "int64_t":
+        r""" The number of accepted neighbors."""
+        return _pywrapcp.Solver_AcceptedNeighbors(self)
+
+ +
+ +

The number of accepted neighbors.

+
+ + +
+
+
#   + + + def + Stamp(self) -> 'uint64_t': +
+ +
+ View Source +
    def Stamp(self) -> "uint64_t":
+        r""" The stamp indicates how many moves in the search tree we have performed. It is useful to detect if we need to update same lazy structures."""
+        return _pywrapcp.Solver_Stamp(self)
+
+ +
+ +

The stamp indicates how many moves in the search tree we have performed. It is useful to detect if we need to update same lazy structures.

+
+ + +
+
+
#   + + + def + FailStamp(self) -> 'uint64_t': +
+ +
+ View Source +
    def FailStamp(self) -> "uint64_t":
+        r""" The fail_stamp() is incremented after each backtrack."""
+        return _pywrapcp.Solver_FailStamp(self)
+
+ +
+ +

The fail_stamp() is incremented after each backtrack.

+
+ + +
+
+
#   + + + def + IntVar(self, *args) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def IntVar(self, *args) -> "operations_research::IntVar *":
+        r"""
+        *Overload 1:*
+        MakeIntVar will create the best range based int var for the bounds given.
+
+        |
+
+        *Overload 2:*
+        MakeIntVar will create a variable with the given sparse domain.
+
+        |
+
+        *Overload 3:*
+        MakeIntVar will create a variable with the given sparse domain.
+
+        |
+
+        *Overload 4:*
+        MakeIntVar will create the best range based int var for the bounds given.
+
+        |
+
+        *Overload 5:*
+        MakeIntVar will create a variable with the given sparse domain.
+
+        |
+
+        *Overload 6:*
+        MakeIntVar will create a variable with the given sparse domain.
+        """
+        return _pywrapcp.Solver_IntVar(self, *args)
+
+ +
+ +

Overload 1: +MakeIntVar will create the best range based int var for the bounds given.

- *Overload 2:* - Collect the first solution of the search. The variables will need to - be added later. - """ - return _pywrapcp.Solver_FirstSolutionCollector(self, *args) - - def LastSolutionCollector(self, *args) -> "operations_research::SolutionCollector *": - r""" - *Overload 1:* - Collect the last solution of the search. - - | - - *Overload 2:* - Collect the last solution of the search. The variables will need to - be added later. - """ - return _pywrapcp.Solver_LastSolutionCollector(self, *args) - - def BestValueSolutionCollector(self, *args) -> "operations_research::SolutionCollector *": - r""" - *Overload 1:* - Collect the solution corresponding to the optimal value of the objective - of 'assignment'; if 'assignment' does not have an objective no solution is - collected. This collector only collects one solution corresponding to the - best objective value (the first one found). - - | - - *Overload 2:* - Collect the solution corresponding to the optimal value of the - objective of 'assignment'; if 'assignment' does not have an objective no - solution is collected. This collector only collects one solution - corresponding to the best objective value (the first one - found). The variables will need to be added later. - """ - return _pywrapcp.Solver_BestValueSolutionCollector(self, *args) - - def AllSolutionCollector(self, *args) -> "operations_research::SolutionCollector *": - r""" - *Overload 1:* - Collect all solutions of the search. - - | - - *Overload 2:* - Collect all solutions of the search. The variables will need to - be added later. - """ - return _pywrapcp.Solver_AllSolutionCollector(self, *args) - - def Minimize(self, v: "IntVar", step: "int64_t") -> "operations_research::OptimizeVar *": - r""" Creates a minimization objective.""" - return _pywrapcp.Solver_Minimize(self, v, step) - - def Maximize(self, v: "IntVar", step: "int64_t") -> "operations_research::OptimizeVar *": - r""" Creates a maximization objective.""" - return _pywrapcp.Solver_Maximize(self, v, step) - - def Optimize(self, maximize: "bool", v: "IntVar", step: "int64_t") -> "operations_research::OptimizeVar *": - r""" Creates a objective with a given sense (true = maximization).""" - return _pywrapcp.Solver_Optimize(self, maximize, v, step) - - def WeightedMinimize(self, *args) -> "operations_research::OptimizeVar *": - r""" - *Overload 1:* - Creates a minimization weighted objective. The actual objective is - scalar_prod(sub_objectives, weights). - - | - - *Overload 2:* - Creates a minimization weighted objective. The actual objective is - scalar_prod(sub_objectives, weights). - """ - return _pywrapcp.Solver_WeightedMinimize(self, *args) - - def WeightedMaximize(self, *args) -> "operations_research::OptimizeVar *": - r""" - *Overload 1:* - Creates a maximization weigthed objective. - - | - - *Overload 2:* - Creates a maximization weigthed objective. - """ - return _pywrapcp.Solver_WeightedMaximize(self, *args) - - def WeightedOptimize(self, *args) -> "operations_research::OptimizeVar *": - r""" - *Overload 1:* - Creates a weighted objective with a given sense (true = maximization). - - | - - *Overload 2:* - Creates a weighted objective with a given sense (true = maximization). - """ - return _pywrapcp.Solver_WeightedOptimize(self, *args) - - def TabuSearch(self, maximize: "bool", v: "IntVar", step: "int64_t", vars: "std::vector< operations_research::IntVar * > const &", keep_tenure: "int64_t", forbid_tenure: "int64_t", tabu_factor: "double") -> "operations_research::SearchMonitor *": - r""" - MetaHeuristics which try to get the search out of local optima. - Creates a Tabu Search monitor. - In the context of local search the behavior is similar to MakeOptimize(), - creating an objective in a given sense. The behavior differs once a local - optimum is reached: thereafter solutions which degrade the value of the - objective are allowed if they are not "tabu". A solution is "tabu" if it - doesn't respect the following rules: - - improving the best solution found so far - - variables in the "keep" list must keep their value, variables in the - "forbid" list must not take the value they have in the list. - Variables with new values enter the tabu lists after each new solution - found and leave the lists after a given number of iterations (called - tenure). Only the variables passed to the method can enter the lists. - The tabu criterion is softened by the tabu factor which gives the number - of "tabu" violations which is tolerated; a factor of 1 means no violations - allowed; a factor of 0 means all violations are allowed. - """ - return _pywrapcp.Solver_TabuSearch(self, maximize, v, step, vars, keep_tenure, forbid_tenure, tabu_factor) - - def SimulatedAnnealing(self, maximize: "bool", v: "IntVar", step: "int64_t", initial_temperature: "int64_t") -> "operations_research::SearchMonitor *": - r""" Creates a Simulated Annealing monitor.""" - return _pywrapcp.Solver_SimulatedAnnealing(self, maximize, v, step, initial_temperature) - - def LubyRestart(self, scale_factor: "int") -> "operations_research::SearchMonitor *": - r""" - This search monitor will restart the search periodically. - At the iteration n, it will restart after scale_factor * Luby(n) failures - where Luby is the Luby Strategy (i.e. 1 1 2 1 1 2 4 1 1 2 1 1 2 4 8...). - """ - return _pywrapcp.Solver_LubyRestart(self, scale_factor) - - def ConstantRestart(self, frequency: "int") -> "operations_research::SearchMonitor *": - r""" - This search monitor will restart the search periodically after 'frequency' - failures. - """ - return _pywrapcp.Solver_ConstantRestart(self, frequency) - - def TimeLimit(self, *args) -> "operations_research::RegularLimit *": - return _pywrapcp.Solver_TimeLimit(self, *args) - - def BranchesLimit(self, branches: "int64_t") -> "operations_research::RegularLimit *": - r""" - Creates a search limit that constrains the number of branches - explored in the search tree. - """ - return _pywrapcp.Solver_BranchesLimit(self, branches) - - def FailuresLimit(self, failures: "int64_t") -> "operations_research::RegularLimit *": - r""" - Creates a search limit that constrains the number of failures - that can happen when exploring the search tree. - """ - return _pywrapcp.Solver_FailuresLimit(self, failures) - - def SolutionsLimit(self, solutions: "int64_t") -> "operations_research::RegularLimit *": - r""" - Creates a search limit that constrains the number of solutions found - during the search. - """ - return _pywrapcp.Solver_SolutionsLimit(self, solutions) - - def Limit(self, *args) -> "operations_research::SearchLimit *": - r""" - *Overload 1:* - Limits the search with the 'time', 'branches', 'failures' and - 'solutions' limits. 'smart_time_check' reduces the calls to the wall - - | - - *Overload 2:* - Creates a search limit from its protobuf description - - | - - *Overload 3:* - Creates a search limit that is reached when either of the underlying limit - is reached. That is, the returned limit is more stringent than both - argument limits. - """ - return _pywrapcp.Solver_Limit(self, *args) - - def CustomLimit(self, limiter: "std::function< bool () >") -> "operations_research::SearchLimit *": - r""" - Callback-based search limit. Search stops when limiter returns true; if - this happens at a leaf the corresponding solution will be rejected. - """ - return _pywrapcp.Solver_CustomLimit(self, limiter) - - def SearchLog(self, *args) -> "operations_research::SearchMonitor *": - return _pywrapcp.Solver_SearchLog(self, *args) - - def SearchTrace(self, prefix: "std::string const &") -> "operations_research::SearchMonitor *": - r""" - Creates a search monitor that will trace precisely the behavior of the - search. Use this only for low level debugging. - """ - return _pywrapcp.Solver_SearchTrace(self, prefix) - - def PrintModelVisitor(self) -> "operations_research::ModelVisitor *": - r""" Prints the model.""" - return _pywrapcp.Solver_PrintModelVisitor(self) - - def StatisticsModelVisitor(self) -> "operations_research::ModelVisitor *": - r""" Displays some nice statistics on the model.""" - return _pywrapcp.Solver_StatisticsModelVisitor(self) - - def AssignVariableValue(self, var: "IntVar", val: "int64_t") -> "operations_research::Decision *": - r""" Decisions.""" - return _pywrapcp.Solver_AssignVariableValue(self, var, val) - - def VariableLessOrEqualValue(self, var: "IntVar", value: "int64_t") -> "operations_research::Decision *": - return _pywrapcp.Solver_VariableLessOrEqualValue(self, var, value) - - def VariableGreaterOrEqualValue(self, var: "IntVar", value: "int64_t") -> "operations_research::Decision *": - return _pywrapcp.Solver_VariableGreaterOrEqualValue(self, var, value) - - def SplitVariableDomain(self, var: "IntVar", val: "int64_t", start_with_lower_half: "bool") -> "operations_research::Decision *": - return _pywrapcp.Solver_SplitVariableDomain(self, var, val, start_with_lower_half) - - def AssignVariableValueOrFail(self, var: "IntVar", value: "int64_t") -> "operations_research::Decision *": - return _pywrapcp.Solver_AssignVariableValueOrFail(self, var, value) - - def AssignVariablesValues(self, vars: "std::vector< operations_research::IntVar * > const &", values: "std::vector< int64_t > const &") -> "operations_research::Decision *": - return _pywrapcp.Solver_AssignVariablesValues(self, vars, values) - - def FailDecision(self) -> "operations_research::Decision *": - return _pywrapcp.Solver_FailDecision(self) - - def Decision(self, apply: "operations_research::Solver::Action", refute: "operations_research::Solver::Action") -> "operations_research::Decision *": - return _pywrapcp.Solver_Decision(self, apply, refute) - - def Compose(self, dbs: "std::vector< operations_research::DecisionBuilder * > const &") -> "operations_research::DecisionBuilder *": - return _pywrapcp.Solver_Compose(self, dbs) - - def Try(self, dbs: "std::vector< operations_research::DecisionBuilder * > const &") -> "operations_research::DecisionBuilder *": - return _pywrapcp.Solver_Try(self, dbs) - - def DefaultPhase(self, *args) -> "operations_research::DecisionBuilder *": - return _pywrapcp.Solver_DefaultPhase(self, *args) - - def ScheduleOrPostpone(self, var: "IntervalVar", est: "int64_t", marker: "int64_t *const") -> "operations_research::Decision *": - r""" - Returns a decision that tries to schedule a task at a given time. - On the Apply branch, it will set that interval var as performed and set - its start to 'est'. On the Refute branch, it will just update the - 'marker' to 'est' + 1. This decision is used in the - INTERVAL_SET_TIMES_FORWARD strategy. - """ - return _pywrapcp.Solver_ScheduleOrPostpone(self, var, est, marker) - - def ScheduleOrExpedite(self, var: "IntervalVar", est: "int64_t", marker: "int64_t *const") -> "operations_research::Decision *": - r""" - Returns a decision that tries to schedule a task at a given time. - On the Apply branch, it will set that interval var as performed and set - its end to 'est'. On the Refute branch, it will just update the - 'marker' to 'est' - 1. This decision is used in the - INTERVAL_SET_TIMES_BACKWARD strategy. - """ - return _pywrapcp.Solver_ScheduleOrExpedite(self, var, est, marker) - - def RankFirstInterval(self, sequence: "SequenceVar", index: "int") -> "operations_research::Decision *": - r""" - Returns a decision that tries to rank first the ith interval var - in the sequence variable. - """ - return _pywrapcp.Solver_RankFirstInterval(self, sequence, index) - - def RankLastInterval(self, sequence: "SequenceVar", index: "int") -> "operations_research::Decision *": - r""" - Returns a decision that tries to rank last the ith interval var - in the sequence variable. - """ - return _pywrapcp.Solver_RankLastInterval(self, sequence, index) - - def Phase(self, *args) -> "operations_research::DecisionBuilder *": - return _pywrapcp.Solver_Phase(self, *args) - - def DecisionBuilderFromAssignment(self, assignment: "Assignment", db: "DecisionBuilder", vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::DecisionBuilder *": - r""" - Returns a decision builder for which the left-most leaf corresponds - to assignment, the rest of the tree being explored using 'db'. - """ - return _pywrapcp.Solver_DecisionBuilderFromAssignment(self, assignment, db, vars) - - def ConstraintAdder(self, ct: "Constraint") -> "operations_research::DecisionBuilder *": - r""" - Returns a decision builder that will add the given constraint to - the model. - """ - return _pywrapcp.Solver_ConstraintAdder(self, ct) - - def SolveOnce(self, db: "DecisionBuilder", monitors: "std::vector< operations_research::SearchMonitor * > const &") -> "operations_research::DecisionBuilder *": - return _pywrapcp.Solver_SolveOnce(self, db, monitors) - - def NestedOptimize(self, *args) -> "operations_research::DecisionBuilder *": - return _pywrapcp.Solver_NestedOptimize(self, *args) - - def RestoreAssignment(self, assignment: "Assignment") -> "operations_research::DecisionBuilder *": - r""" - Returns a DecisionBuilder which restores an Assignment - (calls void Assignment::Restore()) - """ - return _pywrapcp.Solver_RestoreAssignment(self, assignment) - - def StoreAssignment(self, assignment: "Assignment") -> "operations_research::DecisionBuilder *": - r""" - Returns a DecisionBuilder which stores an Assignment - (calls void Assignment::Store()) - """ - return _pywrapcp.Solver_StoreAssignment(self, assignment) - - def Operator(self, *args) -> "operations_research::LocalSearchOperator *": - return _pywrapcp.Solver_Operator(self, *args) - - def RandomLnsOperator(self, *args) -> "operations_research::LocalSearchOperator *": - return _pywrapcp.Solver_RandomLnsOperator(self, *args) - - def MoveTowardTargetOperator(self, *args) -> "operations_research::LocalSearchOperator *": - r""" - *Overload 1:* - Creates a local search operator that tries to move the assignment of some - variables toward a target. The target is given as an Assignment. This - operator generates neighbors in which the only difference compared to the - current state is that one variable that belongs to the target assignment - is set to its target value. - - | - - *Overload 2:* - Creates a local search operator that tries to move the assignment of some - variables toward a target. The target is given either as two vectors: a - vector of variables and a vector of associated target values. The two - vectors should be of the same length. This operator generates neighbors in - which the only difference compared to the current state is that one - variable that belongs to the given vector is set to its target value. - """ - return _pywrapcp.Solver_MoveTowardTargetOperator(self, *args) - - def ConcatenateOperators(self, *args) -> "operations_research::LocalSearchOperator *": - return _pywrapcp.Solver_ConcatenateOperators(self, *args) - - def RandomConcatenateOperators(self, *args) -> "operations_research::LocalSearchOperator *": - r""" - *Overload 1:* - Randomized version of local search concatenator; calls a random operator - at each call to MakeNextNeighbor(). - - | - - *Overload 2:* - Randomized version of local search concatenator; calls a random operator - at each call to MakeNextNeighbor(). The provided seed is used to - initialize the random number generator. - """ - return _pywrapcp.Solver_RandomConcatenateOperators(self, *args) - - def NeighborhoodLimit(self, op: "LocalSearchOperator", limit: "int64_t") -> "operations_research::LocalSearchOperator *": - r""" - Creates a local search operator that wraps another local search - operator and limits the number of neighbors explored (i.e., calls - to MakeNextNeighbor from the current solution (between two calls - to Start()). When this limit is reached, MakeNextNeighbor() - returns false. The counter is cleared when Start() is called. - """ - return _pywrapcp.Solver_NeighborhoodLimit(self, op, limit) - - def LocalSearchPhase(self, *args) -> "operations_research::DecisionBuilder *": - return _pywrapcp.Solver_LocalSearchPhase(self, *args) - - def LocalSearchPhaseParameters(self, *args) -> "operations_research::LocalSearchPhaseParameters *": - return _pywrapcp.Solver_LocalSearchPhaseParameters(self, *args) - - def SearchDepth(self) -> "int": - r""" - Gets the search depth of the current active search. Returns -1 if - there is no active search opened. - """ - return _pywrapcp.Solver_SearchDepth(self) - - def SearchLeftDepth(self) -> "int": - r""" - Gets the search left depth of the current active search. Returns -1 if - there is no active search opened. - """ - return _pywrapcp.Solver_SearchLeftDepth(self) - - def SolveDepth(self) -> "int": - r""" - Gets the number of nested searches. It returns 0 outside search, - 1 during the top level search, 2 or more in case of nested searches. - """ - return _pywrapcp.Solver_SolveDepth(self) - - def Rand64(self, size: "int64_t") -> "int64_t": - r""" Returns a random value between 0 and 'size' - 1;""" - return _pywrapcp.Solver_Rand64(self, size) - - def Rand32(self, size: "int32_t") -> "int32_t": - r""" Returns a random value between 0 and 'size' - 1;""" - return _pywrapcp.Solver_Rand32(self, size) - - def ReSeed(self, seed: "int32_t") -> "void": - r""" Reseed the solver random generator.""" - return _pywrapcp.Solver_ReSeed(self, seed) - - def LocalSearchProfile(self) -> "std::string": - r""" Returns local search profiling information in a human readable format.""" - return _pywrapcp.Solver_LocalSearchProfile(self) - - def Constraints(self) -> "int": - r""" - Counts the number of constraints that have been added - to the solver before the search. - """ - return _pywrapcp.Solver_Constraints(self) - - def Accept(self, visitor: "operations_research::ModelVisitor *const") -> "void": - r""" Accepts the given model visitor.""" - return _pywrapcp.Solver_Accept(self, visitor) - - def FinishCurrentSearch(self) -> "void": - r""" Tells the solver to kill or restart the current search.""" - return _pywrapcp.Solver_FinishCurrentSearch(self) - - def RestartCurrentSearch(self) -> "void": - return _pywrapcp.Solver_RestartCurrentSearch(self) - - def ShouldFail(self) -> "void": - r""" - These methods are only useful for the SWIG wrappers, which need a way - to externally cause the Solver to fail. - """ - return _pywrapcp.Solver_ShouldFail(self) - - def __str__(self) -> "std::string": - return _pywrapcp.Solver___str__(self) - - def Add(self, ct): - if isinstance(ct, PyConstraint): - self.__python_constraints.append(ct) - self.AddConstraint(ct) - - - def TreeNoCycle(self, nexts: "std::vector< operations_research::IntVar * > const &", active: "std::vector< operations_research::IntVar * > const &", callback: "operations_research::Solver::IndexFilter1"=0) -> "operations_research::Constraint *": - return _pywrapcp.Solver_TreeNoCycle(self, nexts, active, callback) - - def SearchLogWithCallback(self, period: "int", callback: "std::function< std::string () >") -> "operations_research::SearchMonitor *": - return _pywrapcp.Solver_SearchLogWithCallback(self, period, callback) - - def ElementFunction(self, values: "std::function< int64_t (int64_t) >", index: "IntVar") -> "operations_research::IntExpr *": - return _pywrapcp.Solver_ElementFunction(self, values, index) - - def VarEvalValStrPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_evaluator: "std::function< int64_t (int64_t) >", val_str: "operations_research::Solver::IntValueStrategy") -> "operations_research::DecisionBuilder *": - return _pywrapcp.Solver_VarEvalValStrPhase(self, vars, var_evaluator, val_str) - - def VarStrValEvalPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_str: "operations_research::Solver::IntVarStrategy", val_eval: "operations_research::Solver::IndexEvaluator2") -> "operations_research::DecisionBuilder *": - return _pywrapcp.Solver_VarStrValEvalPhase(self, vars, var_str, val_eval) - - def VarEvalValEvalPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_eval: "std::function< int64_t (int64_t) >", val_eval: "operations_research::Solver::IndexEvaluator2") -> "operations_research::DecisionBuilder *": - return _pywrapcp.Solver_VarEvalValEvalPhase(self, vars, var_eval, val_eval) - - def VarStrValEvalTieBreakPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_str: "operations_research::Solver::IntVarStrategy", val_eval: "operations_research::Solver::IndexEvaluator2", tie_breaker: "std::function< int64_t (int64_t) >") -> "operations_research::DecisionBuilder *": - return _pywrapcp.Solver_VarStrValEvalTieBreakPhase(self, vars, var_str, val_eval, tie_breaker) - - def VarEvalValEvalTieBreakPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_eval: "std::function< int64_t (int64_t) >", val_eval: "operations_research::Solver::IndexEvaluator2", tie_breaker: "std::function< int64_t (int64_t) >") -> "operations_research::DecisionBuilder *": - return _pywrapcp.Solver_VarEvalValEvalTieBreakPhase(self, vars, var_eval, val_eval, tie_breaker) - - def EvalEvalStrPhase(self, vars: "std::vector< operations_research::IntVar * > const &", evaluator: "operations_research::Solver::IndexEvaluator2", str: "operations_research::Solver::EvaluatorStrategy") -> "operations_research::DecisionBuilder *": - return _pywrapcp.Solver_EvalEvalStrPhase(self, vars, evaluator, str) - - def EvalEvalStrTieBreakPhase(self, vars: "std::vector< operations_research::IntVar * > const &", evaluator: "operations_research::Solver::IndexEvaluator2", tie_breaker: "operations_research::Solver::IndexEvaluator1", str: "operations_research::Solver::EvaluatorStrategy") -> "operations_research::DecisionBuilder *": - return _pywrapcp.Solver_EvalEvalStrTieBreakPhase(self, vars, evaluator, tie_breaker, str) - - def GuidedLocalSearch(self, *args) -> "operations_research::SearchMonitor *": - return _pywrapcp.Solver_GuidedLocalSearch(self, *args) - - def SumObjectiveFilter(self, vars: "std::vector< operations_research::IntVar * > const &", values: "operations_research::Solver::IndexEvaluator2", filter_enum: "operations_research::Solver::LocalSearchFilterBound") -> "operations_research::LocalSearchFilter *": - return _pywrapcp.Solver_SumObjectiveFilter(self, vars, values, filter_enum)
- -

Class variables

-
-
var ASSIGN_CENTER_VALUE
-
-

Selects the first possible value which is the closest to the center -of the domain of the selected variable. -The center is defined as (min + max) / 2.

-
-
var ASSIGN_MAX_VALUE
-
-

Selects the max value of the selected variable.

-
-
var ASSIGN_MIN_VALUE
-
-

Selects the min value of the selected variable.

-
-
var ASSIGN_RANDOM_VALUE
-
-

Selects randomly one of the possible values of the selected variable.

-
-
var CHOOSE_FIRST_UNBOUND
-
-

Select the first unbound variable. -Variables are considered in the order of the vector of IntVars used -to create the selector.

-
-
var CHOOSE_HIGHEST_MAX
-
-

Among unbound variables, select the variable with the highest maximal -value. -In case of a tie, the first one is selected, first being defined by the -order in the vector of IntVars used to create the selector.

-
-
var CHOOSE_LOWEST_MIN
-
-

Among unbound variables, select the variable with the smallest minimal -value. -In case of a tie, the first one is selected, "first" defined by the -order in the vector of IntVars used to create the selector.

-
-
var CHOOSE_MAX_REGRET_ON_MIN
-
-

Among unbound variables, select the variable with the largest -gap between the first and the second values of the domain.

-
-
var CHOOSE_MAX_SIZE
-
-

Among unbound variables, select the variable with the highest size. -In case of a tie, the first one is selected, first being defined by the -order in the vector of IntVars used to create the selector.

-
-
var CHOOSE_MIN_SIZE
-
-

Among unbound variables, select the variable with the smallest size. -In case of a tie, the first one is selected, first being defined by the -order in the vector of IntVars used to create the selector.

-
-
var CHOOSE_MIN_SIZE_HIGHEST_MAX
-
-

Among unbound variables, select the variable with the smallest size, -i.e., the smallest number of possible values. -In case of a tie, the selected variable is the one with the highest max -value. -In case of a tie, the first one is selected, first being defined by the -order in the vector of IntVars used to create the selector.

-
-
var CHOOSE_MIN_SIZE_HIGHEST_MIN
-
-

Among unbound variables, select the variable with the smallest size, -i.e., the smallest number of possible values. -In case of a tie, the selected variable is the one with the highest min -value. -In case of a tie, the first one is selected, first being defined by the -order in the vector of IntVars used to create the selector.

-
-
var CHOOSE_MIN_SIZE_LOWEST_MAX
-
-

Among unbound variables, select the variable with the smallest size, -i.e., the smallest number of possible values. -In case of a tie, the selected variables is the one with the lowest max -value. -In case of a tie, the first one is selected, first being defined by the -order in the vector of IntVars used to create the selector.

-
-
var CHOOSE_MIN_SIZE_LOWEST_MIN
-
-

Among unbound variables, select the variable with the smallest size, -i.e., the smallest number of possible values. -In case of a tie, the selected variables is the one with the lowest min -value. -In case of a tie, the first one is selected, first being defined by the -order in the vector of IntVars used to create the selector.

-
-
var CHOOSE_MIN_SLACK_RANK_FORWARD
-
-
-
-
var CHOOSE_PATH
-
-

Selects the next unbound variable on a path, the path being defined by -the variables: var[i] corresponds to the index of the next of i.

-
-
var CHOOSE_RANDOM
-
-

Randomly select one of the remaining unbound variables.

-
-
var CHOOSE_RANDOM_RANK_FORWARD
-
-
-
-
var CROSS
-
-

Operator which cross exchanges the starting chains of 2 paths, including -exchanging the whole paths. -First and last nodes are not moved. -Possible neighbors for the paths 1 -> 2 -> 3 -> 4 -> 5 and 6 -> 7 -> 8 -(where (1, 5) and (6, 8) are first and last nodes of the paths and can -therefore not be moved): -1 -> [7] -> 3 -> 4 -> 5 -6 -> [2] -> 8 -1 -> [7] -> 4 -> 5 -6 -> [2 -> 3] -> 8 -1 -> [7] -> 5 -6 -> [2 -> 3 -> 4] -> 8

-
-
var DECREMENT
-
-

Operator which defines a neighborhood to decrement values. -The behavior is the same as INCREMENT, except values are decremented -instead of incremented.

-
-
var DELAYED_PRIORITY
-
-

DELAYED_PRIORITY is the lowest priority: Demons will be processed after -VAR_PRIORITY and NORMAL_PRIORITY demons.

-
-
var EQ
-
-

Move is accepted when the current objective value is in the interval -objective.Min .. objective.Max.

-
-
var EXCHANGE
-
-

Operator which exchanges the positions of two nodes. -Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5 -(where (1, 5) are first and last nodes of the path and can therefore not -be moved): -1 -> [3] -> [2] -> -4 --> 5 -1 -> [4] -> -3 --> [2] -> 5 -1 -> -2 --> [4] -> [3] -> 5

-
-
var EXTENDEDSWAPACTIVE
-
-

Operator which makes an inactive node active and an active one inactive. -It is similar to SwapActiveOperator except that it tries to insert the -inactive node in all possible positions instead of just the position of -the node made inactive. -Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive -(where 1 and 4 are first and last nodes of the path) are: -1 -> [5] -> -3 --> 4 with 2 inactive -1 -> -3 --> [5] -> 4 with 2 inactive -1 -> [5] -> -2 --> 4 with 3 inactive -1 -> -2 --> [5] -> 4 with 3 inactive

-
-
var FULLPATHLNS
-
-

Operator which relaxes one entire path and all inactive nodes, thus -defining num_paths neighbors.

-
-
var GE
-
-

Move is accepted when the current objective value >= objective.Min.

-
-
var INCREMENT
-
-

Operator which defines one neighbor per variable. Each neighbor tries to -increment by one the value of the corresponding variable. When a new -solution is found the neighborhood is rebuilt from scratch, i.e., tries -to increment values in the variable order. -Consider for instance variables x and y. x is incremented one by one to -its max, and when it is not possible to increment x anymore, y is -incremented once. If this is a solution, then next neighbor tries to -increment x.

-
-
var INTERVAL_DEFAULT
-
-

The default is INTERVAL_SET_TIMES_FORWARD.

-
-
var INTERVAL_SET_TIMES_BACKWARD
-
-

Selects the variable with the highest ending time of all variables, -and fixes the ending time to this highest values.

-
-
var INTERVAL_SET_TIMES_FORWARD
-
-

Selects the variable with the lowest starting time of all variables, -and fixes its starting time to this lowest value.

-
-
var INTERVAL_SIMPLE
-
-

The simple is INTERVAL_SET_TIMES_FORWARD.

-
-
var INT_VALUE_DEFAULT
-
-

The default behavior is ASSIGN_MIN_VALUE.

-
-
var INT_VALUE_SIMPLE
-
-

The simple selection is ASSIGN_MIN_VALUE.

-
-
var INT_VAR_DEFAULT
-
-

The default behavior is CHOOSE_FIRST_UNBOUND.

-
-
var INT_VAR_SIMPLE
-
-

The simple selection is CHOOSE_FIRST_UNBOUND.

-
-
var LE
-
-

Move is accepted when the current objective value <= objective.Max.

-
-
var MAKEACTIVE
-
-

Operator which inserts an inactive node into a path. -Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive -(where 1 and 4 are first and last nodes of the path) are: -1 -> [5] -> -2 --> -3 --> 4 -1 -> -2 --> [5] -> -3 --> 4 -1 -> -2 --> -3 --> [5] -> 4

-
-
var MAKECHAININACTIVE
-
-

Operator which makes a "chain" of path nodes inactive. -Possible neighbors for the path 1 -> 2 -> 3 -> 4 (where 1 and 4 are -first and last nodes of the path) are: -1 -> 3 -> 4 with 2 inactive -1 -> 2 -> 4 with 3 inactive -1 -> 4 with 2 and 3 inactive

-
-
var MAKEINACTIVE
-
-

Operator which makes path nodes inactive. -Possible neighbors for the path 1 -> 2 -> 3 -> 4 (where 1 and 4 are -first and last nodes of the path) are: -1 -> 3 -> 4 with 2 inactive -1 -> 2 -> 4 with 3 inactive

-
-
var NORMAL_PRIORITY
-
-

NORMAL_PRIORITY is the highest priority: Demons will be processed first.

-
-
var OROPT
-
-

Relocate: OROPT and RELOCATE. -Operator which moves a sub-chain of a path to another position; the -specified chain length is the fixed length of the chains being moved. -When this length is 1, the operator simply moves a node to another -position. -Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5, for a chain -length of 2 (where (1, 5) are first and last nodes of the path and can -therefore not be moved): -1 -> -4 -> [2 -> 3] -> 5 -1 -> [3 -> 4] -> 2 --> 5

-

Using Relocate with chain lengths of 1, 2 and 3 together is equivalent -to the OrOpt operator on a path. The OrOpt operator is a limited -version of 3Opt (breaks 3 arcs on a path).

-
-
var PATHLNS
-
-

Operator which relaxes two sub-chains of three consecutive arcs each. -Each sub-chain is defined by a start node and the next three arcs. Those -six arcs are relaxed to build a new neighbor. -PATHLNS explores all possible pairs of starting nodes and so defines -n^2 neighbors, n being the number of nodes. -Note that the two sub-chains can be part of the same path; they even may -overlap.

-
-
var RELOCATE
-
-

Relocate neighborhood with length of 1 (see OROPT comment).

-
-
var SEQUENCE_DEFAULT
-
-
-
-
var SEQUENCE_SIMPLE
-
-
-
-
var SIMPLELNS
-
-

Operator which defines one neighbor per variable. Each neighbor relaxes -one variable. -When a new solution is found the neighborhood is rebuilt from scratch. -Consider for instance variables x and y. First x is relaxed and the -solver is looking for the best possible solution (with only x relaxed). -Then y is relaxed, and the solver is looking for a new solution. -If a new solution is found, then the next variable to be relaxed is x.

-
-
var SPLIT_LOWER_HALF
-
-

Split the domain in two around the center, and choose the lower -part first.

-
-
var SPLIT_UPPER_HALF
-
-

Split the domain in two around the center, and choose the lower -part first.

-
-
var SWAPACTIVE
-
-

Operator which replaces an active node by an inactive one. -Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive -(where 1 and 4 are first and last nodes of the path) are: -1 -> [5] -> -3 --> 4 with 2 inactive -1 -> -2 --> [5] -> 4 with 3 inactive

-
-
var TWOOPT
-
-

Operator which reverses a sub-chain of a path. It is called TwoOpt -because it breaks two arcs on the path; resulting paths are called -two-optimal. -Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5 -(where (1, 5) are first and last nodes of the path and can therefore not -be moved): -1 -> [3 -> 2] -> 4 --> 5 -1 -> [4 -> 3 --> 2] -> 5 -1 -> -2 -> [4 -> 3] -> 5

-
-
var UNACTIVELNS
-
-

Operator which relaxes all inactive nodes and one sub-chain of six -consecutive arcs. That way the path can be improved by inserting -inactive nodes or swapping arcs.

-
-
var VAR_PRIORITY
-
-

VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY.

-
-
-

Static methods

-
-
-def DefaultSolverParameters() ‑> operations_research::ConstraintSolverParameters -
-
-

Create a ConstraintSolverParameters proto with all the default values.

-
- -Expand source code - -
@staticmethod
-def DefaultSolverParameters() -> "operations_research::ConstraintSolverParameters":
-    r""" Create a ConstraintSolverParameters proto with all the default values."""
-    return _pywrapcp.Solver_DefaultSolverParameters()
-
-
-
-def MemoryUsage() ‑> int64_t -
-
-

Current memory usage in bytes

-
- -Expand source code - -
@staticmethod
-def MemoryUsage() -> "int64_t":
-    r""" Current memory usage in bytes"""
-    return _pywrapcp.Solver_MemoryUsage()
-
-
-
-

Instance variables

-
-
var thisown
-
-

The membership flag

-
- -Expand source code - -
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-
-
-

Methods

-
-
-def AbsEquality(self, var: IntVar, abs_var: IntVar) ‑> operations_research::Constraint * -
-
-

Creates the constraint abs(var) == abs_var.

-
- -Expand source code - -
def AbsEquality(self, var: "IntVar", abs_var: "IntVar") -> "operations_research::Constraint *":
-    r""" Creates the constraint abs(var) == abs_var."""
-    return _pywrapcp.Solver_AbsEquality(self, var, abs_var)
-
-
-
-def Accept(self, visitor: operations_research::ModelVisitor *const) ‑> void -
-
-

Accepts the given model visitor.

-
- -Expand source code - -
def Accept(self, visitor: "operations_research::ModelVisitor *const") -> "void":
-    r""" Accepts the given model visitor."""
-    return _pywrapcp.Solver_Accept(self, visitor)
-
-
-
-def AcceptedNeighbors(self) ‑> int64_t -
-
-

The number of accepted neighbors.

-
- -Expand source code - -
def AcceptedNeighbors(self) -> "int64_t":
-    r""" The number of accepted neighbors."""
-    return _pywrapcp.Solver_AcceptedNeighbors(self)
-
-
-
-def Add(self, ct) -
-
-
-
- -Expand source code - -
def Add(self, ct):
-  if isinstance(ct, PyConstraint):
-    self.__python_constraints.append(ct)
-  self.AddConstraint(ct)
-
-
-
-def AddConstraint(self, c: Constraint) ‑> void -
-
-

Adds the constraint 'c' to the model.

-

After calling this method, and until there is a backtrack that undoes the -addition, any assignment of variables to values must satisfy the given -constraint in order to be considered feasible. There are two fairly -different use cases:

-
    -
  • -

    the most common use case is modeling: the given constraint is really -part of the problem that the user is trying to solve. In this use case, -AddConstraint is called outside of search (i.e., with state() == -OUTSIDE_SEARCH). Most users should only use AddConstraint in this -way. In this case, the constraint will belong to the model forever: it -cannot not be removed by backtracking.

    -
  • -
  • -

    a rarer use case is that 'c' is not a real constraint of the model. It -may be a constraint generated by a branching decision (a constraint whose -goal is to restrict the search space), a symmetry breaking constraint (a -constraint that does restrict the search space, but in a way that cannot -have an impact on the quality of the solutions in the subtree), or an -inferred constraint that, while having no semantic value to the model (it -does not restrict the set of solutions), is worth having because we -believe it may strengthen the propagation. In these cases, it happens -that the constraint is added during the search (i.e., with state() == -IN_SEARCH or state() == IN_ROOT_NODE). When a constraint is -added during a search, it applies only to the subtree of the search tree -rooted at the current node, and will be automatically removed by -backtracking.

    -
  • -
-

This method does not take ownership of the constraint. If the constraint -has been created by any factory method (Solver::MakeXXX), it will -automatically be deleted. However, power users who implement their own -constraints should do: solver.AddConstraint(solver.RevAlloc(new -MyConstraint(…));

-
- -Expand source code - -
def AddConstraint(self, c: "Constraint") -> "void":
-    r"""
-    Adds the constraint 'c' to the model.
-
-    After calling this method, and until there is a backtrack that undoes the
-    addition, any assignment of variables to values must satisfy the given
-    constraint in order to be considered feasible. There are two fairly
-    different use cases:
-
-    - the most common use case is modeling: the given constraint is really
-    part of the problem that the user is trying to solve. In this use case,
-    AddConstraint is called outside of search (i.e., with state() ==
-    OUTSIDE_SEARCH). Most users should only use AddConstraint in this
-    way. In this case, the constraint will belong to the model forever: it
-    cannot not be removed by backtracking.
-
-    - a rarer use case is that 'c' is not a real constraint of the model. It
-    may be a constraint generated by a branching decision (a constraint whose
-    goal is to restrict the search space), a symmetry breaking constraint (a
-    constraint that does restrict the search space, but in a way that cannot
-    have an impact on the quality of the solutions in the subtree), or an
-    inferred constraint that, while having no semantic value to the model (it
-    does not restrict the set of solutions), is worth having because we
-    believe it may strengthen the propagation. In these cases, it happens
-    that the constraint is added during the search (i.e., with state() ==
-    IN_SEARCH or state() == IN_ROOT_NODE). When a constraint is
-    added during a search, it applies only to the subtree of the search tree
-    rooted at the current node, and will be automatically removed by
-    backtracking.
-
-    This method does not take ownership of the constraint. If the constraint
-    has been created by any factory method (Solver::MakeXXX), it will
-    automatically be deleted. However, power users who implement their own
-    constraints should do: solver.AddConstraint(solver.RevAlloc(new
-    MyConstraint(...));
-    """
-    return _pywrapcp.Solver_AddConstraint(self, c)
-
-
-
-def AllDifferent(self, *args) ‑> operations_research::Constraint * -
-
-

Overload 1: -All variables are pairwise different. This corresponds to the -stronger version of the propagation algorithm.

|

+

Overload 2: -All variables are pairwise different. -If 'stronger_propagation' -is true, stronger, and potentially slower propagation will -occur. This API will be deprecated in the future.

-
- -Expand source code - -
def AllDifferent(self, *args) -> "operations_research::Constraint *":
-    r"""
-    *Overload 1:*
-    All variables are pairwise different. This corresponds to the
-    stronger version of the propagation algorithm.
+MakeIntVar will create a variable with the given sparse domain.

- | - - *Overload 2:* - All variables are pairwise different. If 'stronger_propagation' - is true, stronger, and potentially slower propagation will - occur. This API will be deprecated in the future. - """ - return _pywrapcp.Solver_AllDifferent(self, *args)
-
-
-
-def AllDifferentExcept(self, vars: std::vector< operations_research::IntVar * > const &, escape_value: int64_t) ‑> operations_research::Constraint * -
-
-

All variables are pairwise different, unless they are assigned to -the escape value.

-
- -Expand source code - -
def AllDifferentExcept(self, vars: "std::vector< operations_research::IntVar * > const &", escape_value: "int64_t") -> "operations_research::Constraint *":
-    r"""
-    All variables are pairwise different, unless they are assigned to
-    the escape value.
-    """
-    return _pywrapcp.Solver_AllDifferentExcept(self, vars, escape_value)
-
-
-
-def AllSolutionCollector(self, *args) ‑> operations_research::SolutionCollector * -
-
-

Overload 1: -Collect all solutions of the search.

|

-

Overload 2: -Collect all solutions of the search. The variables will need to -be added later.

-
- -Expand source code - -
def AllSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
-    r"""
-    *Overload 1:*
-    Collect all solutions of the search.
 
-    |
+

Overload 3: +MakeIntVar will create a variable with the given sparse domain.

- *Overload 2:* - Collect all solutions of the search. The variables will need to - be added later. - """ - return _pywrapcp.Solver_AllSolutionCollector(self, *args)
-
-
-
-def AllowedAssignments(self, *args) ‑> operations_research::Constraint * -
-
-

Overload 1: -This method creates a constraint where the graph of the relation -between the variables is given in extension. There are 'arity' -variables involved in the relation and the graph is given by a -integer tuple set.

|

-

Overload 2: -Compatibility layer for Python API.

-
- -Expand source code - -
def AllowedAssignments(self, *args) -> "operations_research::Constraint *":
-    r"""
-    *Overload 1:*
-    This method creates a constraint where the graph of the relation
-    between the variables is given in extension. There are 'arity'
-    variables involved in the relation and the graph is given by a
-    integer tuple set.
 
-    |
+

Overload 4: +MakeIntVar will create the best range based int var for the bounds given.

- *Overload 2:* - Compatibility layer for Python API. - """ - return _pywrapcp.Solver_AllowedAssignments(self, *args)
-
-
-
-def AssignVariableValue(self, var: IntVar, val: int64_t) ‑> operations_research::Decision * -
-
-

Decisions.

-
- -Expand source code - -
def AssignVariableValue(self, var: "IntVar", val: "int64_t") -> "operations_research::Decision *":
-    r""" Decisions."""
-    return _pywrapcp.Solver_AssignVariableValue(self, var, val)
-
-
-
-def AssignVariableValueOrFail(self, var: IntVar, value: int64_t) ‑> operations_research::Decision * -
-
-
-
- -Expand source code - -
def AssignVariableValueOrFail(self, var: "IntVar", value: "int64_t") -> "operations_research::Decision *":
-    return _pywrapcp.Solver_AssignVariableValueOrFail(self, var, value)
-
-
-
-def AssignVariablesValues(self, vars: std::vector< operations_research::IntVar * > const &, values: std::vector< int64_t > const &) ‑> operations_research::Decision * -
-
-
-
- -Expand source code - -
def AssignVariablesValues(self, vars: "std::vector< operations_research::IntVar * > const &", values: "std::vector< int64_t > const &") -> "operations_research::Decision *":
-    return _pywrapcp.Solver_AssignVariablesValues(self, vars, values)
-
-
-
-def Assignment(self, *args) ‑> operations_research::Assignment * -
-
-

Overload 1: -This method creates an empty assignment.

|

-

Overload 2: -This method creates an assignment which is a copy of 'a'.

-
- -Expand source code - -
def Assignment(self, *args) -> "operations_research::Assignment *":
-    r"""
-    *Overload 1:*
-    This method creates an empty assignment.
 
-    |
+

Overload 5: +MakeIntVar will create a variable with the given sparse domain.

- *Overload 2:* - This method creates an assignment which is a copy of 'a'. - """ - return _pywrapcp.Solver_Assignment(self, *args)
-
-
-
-def BestValueSolutionCollector(self, *args) ‑> operations_research::SolutionCollector * -
-
-

Overload 1: -Collect the solution corresponding to the optimal value of the objective -of 'assignment'; if 'assignment' does not have an objective no solution is -collected. This collector only collects one solution corresponding to the -best objective value (the first one found).

|

-

Overload 2: -Collect the solution corresponding to the optimal value of the -objective of 'assignment'; if 'assignment' does not have an objective no -solution is collected. This collector only collects one solution -corresponding to the best objective value (the first one -found). The variables will need to be added later.

-
- -Expand source code - -
def BestValueSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
-    r"""
-    *Overload 1:*
-    Collect the solution corresponding to the optimal value of the objective
-    of 'assignment'; if 'assignment' does not have an objective no solution is
-    collected. This collector only collects one solution corresponding to the
-    best objective value (the first one found).
 
-    |
+

Overload 6: +MakeIntVar will create a variable with the given sparse domain.

+
- *Overload 2:* - Collect the solution corresponding to the optimal value of the - objective of 'assignment'; if 'assignment' does not have an objective no - solution is collected. This collector only collects one solution - corresponding to the best objective value (the first one - found). The variables will need to be added later. - """ - return _pywrapcp.Solver_BestValueSolutionCollector(self, *args) - - -
-def BetweenCt(self, expr: IntExpr, l: int64_t, u: int64_t) ‑> operations_research::Constraint * -
-
-

(l <= expr <= u)

-
- -Expand source code - -
def BetweenCt(self, expr: "IntExpr", l: "int64_t", u: "int64_t") -> "operations_research::Constraint *":
-    r""" (l <= expr <= u)"""
-    return _pywrapcp.Solver_BetweenCt(self, expr, l, u)
-
-
-
-def BoolVar(self, *args) ‑> operations_research::IntVar * -
-
-

Overload 1: + +

+
+
#   + + + def + BoolVar(self, *args) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def BoolVar(self, *args) -> "operations_research::IntVar *":
+        r"""
+        *Overload 1:*
+        MakeBoolVar will create a variable with a {0, 1} domain.
+
+        |
+
+        *Overload 2:*
+        MakeBoolVar will create a variable with a {0, 1} domain.
+        """
+        return _pywrapcp.Solver_BoolVar(self, *args)
+
+ +
+ +

Overload 1: MakeBoolVar will create a variable with a {0, 1} domain.

+

|

+

Overload 2: -MakeBoolVar will create a variable with a {0, 1} domain.

-
- -Expand source code - -
def BoolVar(self, *args) -> "operations_research::IntVar *":
-    r"""
-    *Overload 1:*
-    MakeBoolVar will create a variable with a {0, 1} domain.
+MakeBoolVar will create a variable with a {0, 1} domain.

+
- | - *Overload 2:* - MakeBoolVar will create a variable with a {0, 1} domain. - """ - return _pywrapcp.Solver_BoolVar(self, *args) - -
-
-def Branches(self) ‑> int64_t -
-
-

The number of branches explored since the creation of the solver.

-
- -Expand source code - -
def Branches(self) -> "int64_t":
-    r""" The number of branches explored since the creation of the solver."""
-    return _pywrapcp.Solver_Branches(self)
-
-
-
-def BranchesLimit(self, branches: int64_t) ‑> operations_research::RegularLimit * -
-
-

Creates a search limit that constrains the number of branches -explored in the search tree.

-
- -Expand source code - -
def BranchesLimit(self, branches: "int64_t") -> "operations_research::RegularLimit *":
-    r"""
-    Creates a search limit that constrains the number of branches
-    explored in the search tree.
-    """
-    return _pywrapcp.Solver_BranchesLimit(self, branches)
-
-
-
-def CheckAssignment(self, solution: Assignment) ‑> bool -
-
-

Checks whether the given assignment satisfies all relevant constraints.

-
- -Expand source code - -
def CheckAssignment(self, solution: "Assignment") -> "bool":
-    r""" Checks whether the given assignment satisfies all relevant constraints."""
-    return _pywrapcp.Solver_CheckAssignment(self, solution)
-
-
-
-def CheckConstraint(self, ct: Constraint) ‑> bool -
-
-

Checks whether adding this constraint will lead to an immediate -failure. It will return false if the model is already inconsistent, or if -adding the constraint makes it inconsistent.

-
- -Expand source code - -
def CheckConstraint(self, ct: "Constraint") -> "bool":
-    r"""
-    Checks whether adding this constraint will lead to an immediate
-    failure. It will return false if the model is already inconsistent, or if
-    adding the constraint makes it inconsistent.
-    """
-    return _pywrapcp.Solver_CheckConstraint(self, ct)
-
-
-
-def Circuit(self, nexts: std::vector< operations_research::IntVar * > const &) ‑> operations_research::Constraint * -
-
-

Force the "nexts" variable to create a complete Hamiltonian path.

-
- -Expand source code - -
def Circuit(self, nexts: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-    r""" Force the "nexts" variable to create a complete Hamiltonian path."""
-    return _pywrapcp.Solver_Circuit(self, nexts)
-
-
-
-def ClosureDemon(self, closure: operations_research::Solver::Closure) ‑> operations_research::Demon * -
-
-

Creates a demon from a closure.

-
- -Expand source code - -
def ClosureDemon(self, closure: "operations_research::Solver::Closure") -> "operations_research::Demon *":
-    r""" Creates a demon from a closure."""
-    return _pywrapcp.Solver_ClosureDemon(self, closure)
-
-
-
-def Compose(self, dbs: std::vector< operations_research::DecisionBuilder * > const &) ‑> operations_research::DecisionBuilder * -
-
-
-
- -Expand source code - -
def Compose(self, dbs: "std::vector< operations_research::DecisionBuilder * > const &") -> "operations_research::DecisionBuilder *":
-    return _pywrapcp.Solver_Compose(self, dbs)
-
-
-
-def ConcatenateOperators(self, *args) ‑> operations_research::LocalSearchOperator * -
-
-
-
- -Expand source code - -
def ConcatenateOperators(self, *args) -> "operations_research::LocalSearchOperator *":
-    return _pywrapcp.Solver_ConcatenateOperators(self, *args)
-
-
-
-def ConditionalExpression(self, condition: IntVar, expr: IntExpr, unperformed_value: int64_t) ‑> operations_research::IntExpr * -
-
-

Conditional Expr condition ? expr : unperformed_value

-
- -Expand source code - -
def ConditionalExpression(self, condition: "IntVar", expr: "IntExpr", unperformed_value: "int64_t") -> "operations_research::IntExpr *":
-    r""" Conditional Expr condition ? expr : unperformed_value"""
-    return _pywrapcp.Solver_ConditionalExpression(self, condition, expr, unperformed_value)
-
-
-
-def ConstantRestart(self, frequency: int) ‑> operations_research::SearchMonitor * -
-
-

This search monitor will restart the search periodically after 'frequency' -failures.

-
- -Expand source code - -
def ConstantRestart(self, frequency: "int") -> "operations_research::SearchMonitor *":
-    r"""
-    This search monitor will restart the search periodically after 'frequency'
-    failures.
-    """
-    return _pywrapcp.Solver_ConstantRestart(self, frequency)
-
-
-
-def ConstraintAdder(self, ct: Constraint) ‑> operations_research::DecisionBuilder * -
-
-

Returns a decision builder that will add the given constraint to -the model.

-
- -Expand source code - -
def ConstraintAdder(self, ct: "Constraint") -> "operations_research::DecisionBuilder *":
-    r"""
-    Returns a decision builder that will add the given constraint to
-    the model.
-    """
-    return _pywrapcp.Solver_ConstraintAdder(self, ct)
-
-
-
-def ConstraintInitialPropagateCallback(self, ct: Constraint) ‑> operations_research::Demon * -
-
-

This method is a specialized case of the MakeConstraintDemon -method to call the InitiatePropagate of the constraint 'ct'.

-
- -Expand source code - -
def ConstraintInitialPropagateCallback(self, ct: "Constraint") -> "operations_research::Demon *":
-    r"""
-    This method is a specialized case of the MakeConstraintDemon
-    method to call the InitiatePropagate of the constraint 'ct'.
-    """
-    return _pywrapcp.Solver_ConstraintInitialPropagateCallback(self, ct)
-
-
-
-def Constraints(self) ‑> int -
-
-

Counts the number of constraints that have been added -to the solver before the search.

-
- -Expand source code - -
def Constraints(self) -> "int":
-    r"""
-    Counts the number of constraints that have been added
-    to the solver before the search.
-    """
-    return _pywrapcp.Solver_Constraints(self)
-
-
-
-def ConvexPiecewiseExpr(self, expr: IntExpr, early_cost: int64_t, early_date: int64_t, late_date: int64_t, late_cost: int64_t) ‑> operations_research::IntExpr * -
-
-

Convex piecewise function.

-
- -Expand source code - -
def ConvexPiecewiseExpr(self, expr: "IntExpr", early_cost: "int64_t", early_date: "int64_t", late_date: "int64_t", late_cost: "int64_t") -> "operations_research::IntExpr *":
-    r""" Convex piecewise function."""
-    return _pywrapcp.Solver_ConvexPiecewiseExpr(self, expr, early_cost, early_date, late_date, late_cost)
-
-
-
-def Count(self, *args) ‑> operations_research::Constraint * -
-
-

Overload 1: -|{i | vars[i] == value}| == max_count

+
+
+
#   + + + def + IntConst(self, *args) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def IntConst(self, *args) -> "operations_research::IntVar *":
+        r"""
+        *Overload 1:*
+        IntConst will create a constant expression.
+
+        |
+
+        *Overload 2:*
+        IntConst will create a constant expression.
+        """
+        return _pywrapcp.Solver_IntConst(self, *args)
+
+ +
+ +

Overload 1: +IntConst will create a constant expression.

+

|

+

Overload 2: -|{i | vars[i] == value}| == max_count

-
- -Expand source code - -
def Count(self, *args) -> "operations_research::Constraint *":
-    r"""
-    *Overload 1:*
-    |{i | vars[i] == value}| == max_count
+IntConst will create a constant expression.

+
- | - *Overload 2:* - |{i | vars[i] == value}| == max_count - """ - return _pywrapcp.Solver_Count(self, *args) - -
-
-def Cover(self, vars: std::vector< operations_research::IntervalVar * > const &, target_var: IntervalVar) ‑> operations_research::Constraint * -
-
-

This constraint states that the target_var is the convex hull of -the intervals. If none of the interval variables is performed, -then the target var is unperformed too. Also, if the target -variable is unperformed, then all the intervals variables are -unperformed too.

-
- -Expand source code - -
def Cover(self, vars: "std::vector< operations_research::IntervalVar * > const &", target_var: "IntervalVar") -> "operations_research::Constraint *":
-    r"""
-    This constraint states that the target_var is the convex hull of
-    the intervals. If none of the interval variables is performed,
-    then the target var is unperformed too. Also, if the target
-    variable is unperformed, then all the intervals variables are
-    unperformed too.
-    """
-    return _pywrapcp.Solver_Cover(self, vars, target_var)
-
-
-
-def Cumulative(self, *args) ‑> operations_research::Constraint * -
-
-

Overload 1: -This constraint forces that, for any integer t, the sum of the demands -corresponding to an interval containing t does not exceed the given -capacity.

-

Intervals and demands should be vectors of equal size.

-

Demands should only contain non-negative values. Zero values are -supported, and the corresponding intervals are filtered out, as they -neither impact nor are impacted by this constraint.

+
+
+
#   + + + def + Sum( + self, + vars: 'std::vector< operations_research::IntVar * > const &' +) -> 'operations_research::IntExpr *': +
+ +
+ View Source +
    def Sum(self, vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::IntExpr *":
+        r""" sum of all vars."""
+        return _pywrapcp.Solver_Sum(self, vars)
+
+ +
+ +

sum of all vars.

+
+ + +
+
+
#   + + + def + ScalProd(self, *args) -> 'operations_research::IntExpr *': +
+ +
+ View Source +
    def ScalProd(self, *args) -> "operations_research::IntExpr *":
+        r"""
+        *Overload 1:*
+        scalar product
+
+        |
+
+        *Overload 2:*
+        scalar product
+        """
+        return _pywrapcp.Solver_ScalProd(self, *args)
+
+ +
+ +

Overload 1: +scalar product

+

|

+

Overload 2: -This constraint forces that, for any integer t, the sum of the demands -corresponding to an interval containing t does not exceed the given -capacity.

-

Intervals and demands should be vectors of equal size.

-

Demands should only contain non-negative values. Zero values are -supported, and the corresponding intervals are filtered out, as they -neither impact nor are impacted by this constraint.

-

|

-

Overload 3: -This constraint forces that, for any integer t, the sum of the demands -corresponding to an interval containing t does not exceed the given -capacity.

-

Intervals and demands should be vectors of equal size.

-

Demands should only contain non-negative values. Zero values are -supported, and the corresponding intervals are filtered out, as they -neither impact nor are impacted by this constraint.

-

|

-

Overload 4: -This constraint enforces that, for any integer t, the sum of the demands -corresponding to an interval containing t does not exceed the given -capacity.

-

Intervals and demands should be vectors of equal size.

-

Demands should only contain non-negative values. Zero values are -supported, and the corresponding intervals are filtered out, as they -neither impact nor are impacted by this constraint.

-

|

-

Overload 5: -This constraint enforces that, for any integer t, the sum of demands -corresponding to an interval containing t does not exceed the given -capacity.

-

Intervals and demands should be vectors of equal size.

-

Demands should be positive.

-

|

-

Overload 6: -This constraint enforces that, for any integer t, the sum of demands -corresponding to an interval containing t does not exceed the given -capacity.

-

Intervals and demands should be vectors of equal size.

-

Demands should be positive.

-
- -Expand source code - -
def Cumulative(self, *args) -> "operations_research::Constraint *":
-    r"""
-    *Overload 1:*
-    This constraint forces that, for any integer t, the sum of the demands
-    corresponding to an interval containing t does not exceed the given
-    capacity.
+scalar product

+
- Intervals and demands should be vectors of equal size. - Demands should only contain non-negative values. Zero values are - supported, and the corresponding intervals are filtered out, as they - neither impact nor are impacted by this constraint. +
+
+
#   - | + + def + MonotonicElement( + self, + values: 'operations_research::Solver::IndexEvaluator1', + increasing: bool, + index: pywrapcp.IntVar +) -> 'operations_research::IntExpr *': +
- *Overload 2:* - This constraint forces that, for any integer t, the sum of the demands - corresponding to an interval containing t does not exceed the given - capacity. +
+ View Source +
    def MonotonicElement(self, values: "operations_research::Solver::IndexEvaluator1", increasing: "bool", index: "IntVar") -> "operations_research::IntExpr *":
+        r""" Function based element. The constraint takes ownership of the callback.  The callback must be monotonic. It must be able to cope with any possible value in the domain of 'index' (potentially negative ones too). Furtermore, monotonicity is not checked. Thus giving a non-monotonic function, or specifying an incorrect increasing parameter will result in undefined behavior."""
+        return _pywrapcp.Solver_MonotonicElement(self, values, increasing, index)
+
- Intervals and demands should be vectors of equal size. +
- Demands should only contain non-negative values. Zero values are - supported, and the corresponding intervals are filtered out, as they - neither impact nor are impacted by this constraint. +

Function based element. The constraint takes ownership of the callback. The callback must be monotonic. It must be able to cope with any possible value in the domain of 'index' (potentially negative ones too). Furtermore, monotonicity is not checked. Thus giving a non-monotonic function, or specifying an incorrect increasing parameter will result in undefined behavior.

+
- | - *Overload 3:* - This constraint forces that, for any integer t, the sum of the demands - corresponding to an interval containing t does not exceed the given - capacity. +
+
+
#   - Intervals and demands should be vectors of equal size. + + def + Element(self, *args) -> 'operations_research::IntExpr *': +
- Demands should only contain non-negative values. Zero values are - supported, and the corresponding intervals are filtered out, as they - neither impact nor are impacted by this constraint. +
+ View Source +
    def Element(self, *args) -> "operations_research::IntExpr *":
+        r"""
+        *Overload 1:*
+        values[index]
 
-    |
+        |
 
-    *Overload 4:*
-    This constraint enforces that, for any integer t, the sum of the demands
-    corresponding to an interval containing t does not exceed the given
-    capacity.
+        *Overload 2:*
+        values[index]
 
-    Intervals and demands should be vectors of equal size.
+        |
 
-    Demands should only contain non-negative values. Zero values are
-    supported, and the corresponding intervals are filtered out, as they
-    neither impact nor are impacted by this constraint.
+        *Overload 3:*
+        Function-based element. The constraint takes ownership of the callback. The callback must be able to cope with any possible value in the domain of 'index' (potentially negative ones too).
 
-    |
+        |
 
-    *Overload 5:*
-    This constraint enforces that, for any integer t, the sum of demands
-    corresponding to an interval containing t does not exceed the given
-    capacity.
+        *Overload 4:*
+        2D version of function-based element expression, values(expr1, expr2).
 
-    Intervals and demands should be vectors of equal size.
+        |
 
-    Demands should be positive.
+        *Overload 5:*
+        vars[expr]
+        """
+        return _pywrapcp.Solver_Element(self, *args)
+
- | +
- *Overload 6:* - This constraint enforces that, for any integer t, the sum of demands - corresponding to an interval containing t does not exceed the given - capacity. - - Intervals and demands should be vectors of equal size. - - Demands should be positive. - """ - return _pywrapcp.Solver_Cumulative(self, *args)
- - -
-def CustomLimit(self, limiter: std::function< bool () >) ‑> operations_research::SearchLimit * -
-
-

Callback-based search limit. Search stops when limiter returns true; if -this happens at a leaf the corresponding solution will be rejected.

-
- -Expand source code - -
def CustomLimit(self, limiter: "std::function< bool () >") -> "operations_research::SearchLimit *":
-    r"""
-    Callback-based search limit. Search stops when limiter returns true; if
-    this happens at a leaf the corresponding solution will be rejected.
-    """
-    return _pywrapcp.Solver_CustomLimit(self, limiter)
-
-
-
-def Decision(self, apply: operations_research::Solver::Action, refute: operations_research::Solver::Action) ‑> operations_research::Decision * -
-
-
-
- -Expand source code - -
def Decision(self, apply: "operations_research::Solver::Action", refute: "operations_research::Solver::Action") -> "operations_research::Decision *":
-    return _pywrapcp.Solver_Decision(self, apply, refute)
-
-
-
-def DecisionBuilderFromAssignment(self, assignment: Assignment, db: DecisionBuilder, vars: std::vector< operations_research::IntVar * > const &) ‑> operations_research::DecisionBuilder * -
-
-

Returns a decision builder for which the left-most leaf corresponds -to assignment, the rest of the tree being explored using 'db'.

-
- -Expand source code - -
def DecisionBuilderFromAssignment(self, assignment: "Assignment", db: "DecisionBuilder", vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::DecisionBuilder *":
-    r"""
-    Returns a decision builder for which the left-most leaf corresponds
-    to assignment, the rest of the tree being explored using 'db'.
-    """
-    return _pywrapcp.Solver_DecisionBuilderFromAssignment(self, assignment, db, vars)
-
-
-
-def DefaultPhase(self, *args) ‑> operations_research::DecisionBuilder * -
-
-
-
- -Expand source code - -
def DefaultPhase(self, *args) -> "operations_research::DecisionBuilder *":
-    return _pywrapcp.Solver_DefaultPhase(self, *args)
-
-
-
-def DelayedConstraintInitialPropagateCallback(self, ct: Constraint) ‑> operations_research::Demon * -
-
-

This method is a specialized case of the MakeConstraintDemon -method to call the InitiatePropagate of the constraint 'ct' with -low priority.

-
- -Expand source code - -
def DelayedConstraintInitialPropagateCallback(self, ct: "Constraint") -> "operations_research::Demon *":
-    r"""
-    This method is a specialized case of the MakeConstraintDemon
-    method to call the InitiatePropagate of the constraint 'ct' with
-    low priority.
-    """
-    return _pywrapcp.Solver_DelayedConstraintInitialPropagateCallback(self, ct)
-
-
-
-def DelayedPathCumul(self, nexts: std::vector< operations_research::IntVar * > const &, active: std::vector< operations_research::IntVar * > const &, cumuls: std::vector< operations_research::IntVar * > const &, transits: std::vector< operations_research::IntVar * > const &) ‑> operations_research::Constraint * -
-
-

Delayed version of the same constraint: propagation on the nexts variables -is delayed until all constraints have propagated.

-
- -Expand source code - -
def DelayedPathCumul(self, nexts: "std::vector< operations_research::IntVar * > const &", active: "std::vector< operations_research::IntVar * > const &", cumuls: "std::vector< operations_research::IntVar * > const &", transits: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-    r"""
-    Delayed version of the same constraint: propagation on the nexts variables
-    is delayed until all constraints have propagated.
-    """
-    return _pywrapcp.Solver_DelayedPathCumul(self, nexts, active, cumuls, transits)
-
-
-
-def Deviation(self, vars: std::vector< operations_research::IntVar * > const &, deviation_var: IntVar, total_sum: int64_t) ‑> operations_research::Constraint * -
-
-

Deviation constraint: -sum_i |n * vars[i] - total_sum| <= deviation_var and -sum_i vars[i] == total_sum -n = #vars

-
- -Expand source code - -
def Deviation(self, vars: "std::vector< operations_research::IntVar * > const &", deviation_var: "IntVar", total_sum: "int64_t") -> "operations_research::Constraint *":
-    r"""
-    Deviation constraint:
-    sum_i |n * vars[i] - total_sum| <= deviation_var and
-    sum_i vars[i] == total_sum
-    n = #vars
-    """
-    return _pywrapcp.Solver_Deviation(self, vars, deviation_var, total_sum)
-
-
-
-def DisjunctiveConstraint(self, intervals: std::vector< operations_research::IntervalVar * > const &, name: std::string const &) ‑> operations_research::DisjunctiveConstraint * -
-
-

This constraint forces all interval vars into an non-overlapping -sequence. Intervals with zero duration can be scheduled anywhere.

-
- -Expand source code - -
def DisjunctiveConstraint(self, intervals: "std::vector< operations_research::IntervalVar * > const &", name: "std::string const &") -> "operations_research::DisjunctiveConstraint *":
-    r"""
-    This constraint forces all interval vars into an non-overlapping
-    sequence. Intervals with zero duration can be scheduled anywhere.
-    """
-    return _pywrapcp.Solver_DisjunctiveConstraint(self, intervals, name)
-
-
-
-def Distribute(self, *args) ‑> operations_research::Constraint * -
-
-

Overload 1: -Aggregated version of count: -|{i | v[i] == values[j]}| == cards[j]

-

|

-

Overload 2: -Aggregated version of count: -|{i | v[i] == values[j]}| == cards[j]

-

|

-

Overload 3: -Aggregated version of count: -|{i | v[i] == j}| == cards[j]

-

|

-

Overload 4: -Aggregated version of count with bounded cardinalities: -forall j in 0 .. card_size - 1: card_min <= |{i | v[i] == j}| <= card_max

-

|

-

Overload 5: -Aggregated version of count with bounded cardinalities: -forall j in 0 .. card_size - 1: -card_min[j] <= |{i | v[i] == j}| <= card_max[j]

-

|

-

Overload 6: -Aggregated version of count with bounded cardinalities: -forall j in 0 .. card_size - 1: -card_min[j] <= |{i | v[i] == j}| <= card_max[j]

-

|

-

Overload 7: -Aggregated version of count with bounded cardinalities: -forall j in 0 .. card_size - 1: -card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j]

-

|

-

Overload 8: -Aggregated version of count with bounded cardinalities: -forall j in 0 .. card_size - 1: -card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j]

-
- -Expand source code - -
def Distribute(self, *args) -> "operations_research::Constraint *":
-    r"""
-    *Overload 1:*
-    Aggregated version of count:  |{i | v[i] == values[j]}| == cards[j]
-
-    |
-
-    *Overload 2:*
-    Aggregated version of count:  |{i | v[i] == values[j]}| == cards[j]
-
-    |
-
-    *Overload 3:*
-    Aggregated version of count:  |{i | v[i] == j}| == cards[j]
-
-    |
-
-    *Overload 4:*
-    Aggregated version of count with bounded cardinalities:
-    forall j in 0 .. card_size - 1: card_min <= |{i | v[i] == j}| <= card_max
-
-    |
-
-    *Overload 5:*
-    Aggregated version of count with bounded cardinalities:
-    forall j in 0 .. card_size - 1:
-       card_min[j] <= |{i | v[i] == j}| <= card_max[j]
-
-    |
-
-    *Overload 6:*
-    Aggregated version of count with bounded cardinalities:
-    forall j in 0 .. card_size - 1:
-       card_min[j] <= |{i | v[i] == j}| <= card_max[j]
-
-    |
-
-    *Overload 7:*
-    Aggregated version of count with bounded cardinalities:
-    forall j in 0 .. card_size - 1:
-       card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j]
-
-    |
-
-    *Overload 8:*
-    Aggregated version of count with bounded cardinalities:
-    forall j in 0 .. card_size - 1:
-       card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j]
-    """
-    return _pywrapcp.Solver_Distribute(self, *args)
-
-
-
-def Element(self, *args) ‑> operations_research::IntExpr * -
-
-

Overload 1: +

Overload 1: values[index]

+

|

+

Overload 2: values[index]

+

|

+

Overload 3: -Function-based element. The constraint takes ownership of the -callback. The callback must be able to cope with any possible -value in the domain of 'index' (potentially negative ones too).

+Function-based element. The constraint takes ownership of the callback. The callback must be able to cope with any possible value in the domain of 'index' (potentially negative ones too).

+

|

+

Overload 4: 2D version of function-based element expression, values(expr1, expr2).

+

|

+

Overload 5: -vars[expr]

-
- -Expand source code - -
def Element(self, *args) -> "operations_research::IntExpr *":
-    r"""
-    *Overload 1:*
-    values[index]
+vars[expr]

+
- | - *Overload 2:* - values[index] +
+
+
#   - | + + def + IndexExpression( + self, + vars: 'std::vector< operations_research::IntVar * > const &', + value: 'int64_t' +) -> 'operations_research::IntExpr *': +
- *Overload 3:* - Function-based element. The constraint takes ownership of the - callback. The callback must be able to cope with any possible - value in the domain of 'index' (potentially negative ones too). +
+ View Source +
    def IndexExpression(self, vars: "std::vector< operations_research::IntVar * > const &", value: "int64_t") -> "operations_research::IntExpr *":
+        r""" Returns the expression expr such that vars[expr] == value. It assumes that vars are all different."""
+        return _pywrapcp.Solver_IndexExpression(self, vars, value)
+
- | +
- *Overload 4:* - 2D version of function-based element expression, values(expr1, expr2). +

Returns the expression expr such that vars[expr] == value. It assumes that vars are all different.

+
- | - *Overload 5:* - vars[expr] - """ - return _pywrapcp.Solver_Element(self, *args)
- - -
-def ElementEquality(self, *args) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def ElementEquality(self, *args) -> "operations_research::Constraint *":
-    return _pywrapcp.Solver_ElementEquality(self, *args)
-
-
-
-def ElementFunction(self, values: std::function< int64_t (int64_t) >, index: IntVar) ‑> operations_research::IntExpr * -
-
-
-
- -Expand source code - -
def ElementFunction(self, values: "std::function< int64_t (int64_t) >", index: "IntVar") -> "operations_research::IntExpr *":
-    return _pywrapcp.Solver_ElementFunction(self, values, index)
-
-
-
-def EndSearch(self) ‑> void -
-
-
-
- -Expand source code - -
def EndSearch(self) -> "void":
-    return _pywrapcp.Solver_EndSearch(self)
-
-
-
-def EvalEvalStrPhase(self, vars: std::vector< operations_research::IntVar * > const &, evaluator: operations_research::Solver::IndexEvaluator2, str: operations_research::Solver::EvaluatorStrategy) ‑> operations_research::DecisionBuilder * -
-
-
-
- -Expand source code - -
def EvalEvalStrPhase(self, vars: "std::vector< operations_research::IntVar * > const &", evaluator: "operations_research::Solver::IndexEvaluator2", str: "operations_research::Solver::EvaluatorStrategy") -> "operations_research::DecisionBuilder *":
-    return _pywrapcp.Solver_EvalEvalStrPhase(self, vars, evaluator, str)
-
-
-
-def EvalEvalStrTieBreakPhase(self, vars: std::vector< operations_research::IntVar * > const &, evaluator: operations_research::Solver::IndexEvaluator2, tie_breaker: operations_research::Solver::IndexEvaluator1, str: operations_research::Solver::EvaluatorStrategy) ‑> operations_research::DecisionBuilder * -
-
-
-
- -Expand source code - -
def EvalEvalStrTieBreakPhase(self, vars: "std::vector< operations_research::IntVar * > const &", evaluator: "operations_research::Solver::IndexEvaluator2", tie_breaker: "operations_research::Solver::IndexEvaluator1", str: "operations_research::Solver::EvaluatorStrategy") -> "operations_research::DecisionBuilder *":
-    return _pywrapcp.Solver_EvalEvalStrTieBreakPhase(self, vars, evaluator, tie_breaker, str)
-
-
-
-def Fail(self) ‑> void -
-
-

Abandon the current branch in the search tree. A backtrack will follow.

-
- -Expand source code - -
def Fail(self) -> "void":
-    r""" Abandon the current branch in the search tree. A backtrack will follow."""
-    return _pywrapcp.Solver_Fail(self)
-
-
-
-def FailDecision(self) ‑> operations_research::Decision * -
-
-
-
- -Expand source code - -
def FailDecision(self) -> "operations_research::Decision *":
-    return _pywrapcp.Solver_FailDecision(self)
-
-
-
-def FailStamp(self) ‑> uint64_t -
-
-

The fail_stamp() is incremented after each backtrack.

-
- -Expand source code - -
def FailStamp(self) -> "uint64_t":
-    r""" The fail_stamp() is incremented after each backtrack."""
-    return _pywrapcp.Solver_FailStamp(self)
-
-
-
-def Failures(self) ‑> int64_t -
-
-

The number of failures encountered since the creation of the solver.

-
- -Expand source code - -
def Failures(self) -> "int64_t":
-    r""" The number of failures encountered since the creation of the solver."""
-    return _pywrapcp.Solver_Failures(self)
-
-
-
-def FailuresLimit(self, failures: int64_t) ‑> operations_research::RegularLimit * -
-
-

Creates a search limit that constrains the number of failures -that can happen when exploring the search tree.

-
- -Expand source code - -
def FailuresLimit(self, failures: "int64_t") -> "operations_research::RegularLimit *":
-    r"""
-    Creates a search limit that constrains the number of failures
-    that can happen when exploring the search tree.
-    """
-    return _pywrapcp.Solver_FailuresLimit(self, failures)
-
-
-
-def FalseConstraint(self, *args) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def FalseConstraint(self, *args) -> "operations_research::Constraint *":
-    return _pywrapcp.Solver_FalseConstraint(self, *args)
-
-
-
-def FinishCurrentSearch(self) ‑> void -
-
-

Tells the solver to kill or restart the current search.

-
- -Expand source code - -
def FinishCurrentSearch(self) -> "void":
-    r""" Tells the solver to kill or restart the current search."""
-    return _pywrapcp.Solver_FinishCurrentSearch(self)
-
-
-
-def FirstSolutionCollector(self, *args) ‑> operations_research::SolutionCollector * -
-
-

Overload 1: -Collect the first solution of the search.

-

|

-

Overload 2: -Collect the first solution of the search. The variables will need to -be added later.

-
- -Expand source code - -
def FirstSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
-    r"""
-    *Overload 1:*
-    Collect the first solution of the search.
+                            
+
+
#   - | + + def + Min(self, *args) -> 'operations_research::IntExpr *': +
- *Overload 2:* - Collect the first solution of the search. The variables will need to - be added later. - """ - return _pywrapcp.Solver_FirstSolutionCollector(self, *args)
- - -
-def FixedDurationEndSyncedOnEndIntervalVar(self, interval_var: IntervalVar, duration: int64_t, offset: int64_t) ‑> operations_research::IntervalVar * -
-
-

Creates an interval var with a fixed duration whose end is -synchronized with the end of another interval, with a given -offset. The performed status is also in sync with the performed -status of the given interval variable.

-
- -Expand source code - -
def FixedDurationEndSyncedOnEndIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
-    r"""
-    Creates an interval var with a fixed duration whose end is
-    synchronized with the end of another interval, with a given
-    offset. The performed status is also in sync with the performed
-    status of the given interval variable.
-    """
-    return _pywrapcp.Solver_FixedDurationEndSyncedOnEndIntervalVar(self, interval_var, duration, offset)
-
-
-
-def FixedDurationEndSyncedOnStartIntervalVar(self, interval_var: IntervalVar, duration: int64_t, offset: int64_t) ‑> operations_research::IntervalVar * -
-
-

Creates an interval var with a fixed duration whose end is -synchronized with the start of another interval, with a given -offset. The performed status is also in sync with the performed -status of the given interval variable.

-
- -Expand source code - -
def FixedDurationEndSyncedOnStartIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
-    r"""
-    Creates an interval var with a fixed duration whose end is
-    synchronized with the start of another interval, with a given
-    offset. The performed status is also in sync with the performed
-    status of the given interval variable.
-    """
-    return _pywrapcp.Solver_FixedDurationEndSyncedOnStartIntervalVar(self, interval_var, duration, offset)
-
-
-
-def FixedDurationIntervalVar(self, *args) ‑> operations_research::IntervalVar * -
-
-

Overload 1: -Creates an interval var with a fixed duration. The duration must -be greater than 0. If optional is true, then the interval can be -performed or unperformed. If optional is false, then the interval -is always performed.

-

|

-

Overload 2: -Creates a performed interval var with a fixed duration. The duration must -be greater than 0.

-

|

-

Overload 3: -Creates an interval var with a fixed duration, and performed_variable. -The duration must be greater than 0.

-
- -Expand source code - -
def FixedDurationIntervalVar(self, *args) -> "operations_research::IntervalVar *":
-    r"""
-    *Overload 1:*
-    Creates an interval var with a fixed duration. The duration must
-    be greater than 0. If optional is true, then the interval can be
-    performed or unperformed. If optional is false, then the interval
-    is always performed.
+                
+ View Source +
    def Min(self, *args) -> "operations_research::IntExpr *":
+        r"""
+        *Overload 1:*
+        std::min(vars)
 
-    |
+        |
 
-    *Overload 2:*
-    Creates a performed interval var with a fixed duration. The duration must
-    be greater than 0.
+        *Overload 2:*
+        std::min (left, right)
 
-    |
+        |
 
-    *Overload 3:*
-    Creates an interval var with a fixed duration, and performed_variable.
-    The duration must be greater than 0.
-    """
-    return _pywrapcp.Solver_FixedDurationIntervalVar(self, *args)
-
-
-
-def FixedDurationStartSyncedOnEndIntervalVar(self, interval_var: IntervalVar, duration: int64_t, offset: int64_t) ‑> operations_research::IntervalVar * -
-
-

Creates an interval var with a fixed duration whose start is -synchronized with the end of another interval, with a given -offset. The performed status is also in sync with the performed -status of the given interval variable.

-
- -Expand source code - -
def FixedDurationStartSyncedOnEndIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
-    r"""
-    Creates an interval var with a fixed duration whose start is
-    synchronized with the end of another interval, with a given
-    offset. The performed status is also in sync with the performed
-    status of the given interval variable.
-    """
-    return _pywrapcp.Solver_FixedDurationStartSyncedOnEndIntervalVar(self, interval_var, duration, offset)
-
-
-
-def FixedDurationStartSyncedOnStartIntervalVar(self, interval_var: IntervalVar, duration: int64_t, offset: int64_t) ‑> operations_research::IntervalVar * -
-
-

Creates an interval var with a fixed duration whose start is -synchronized with the start of another interval, with a given -offset. The performed status is also in sync with the performed -status of the given interval variable.

-
- -Expand source code - -
def FixedDurationStartSyncedOnStartIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
-    r"""
-    Creates an interval var with a fixed duration whose start is
-    synchronized with the start of another interval, with a given
-    offset. The performed status is also in sync with the performed
-    status of the given interval variable.
-    """
-    return _pywrapcp.Solver_FixedDurationStartSyncedOnStartIntervalVar(self, interval_var, duration, offset)
-
-
-
-def FixedInterval(self, start: int64_t, duration: int64_t, name: std::string const &) ‑> operations_research::IntervalVar * -
-
-

Creates a fixed and performed interval.

-
- -Expand source code - -
def FixedInterval(self, start: "int64_t", duration: "int64_t", name: "std::string const &") -> "operations_research::IntervalVar *":
-    r""" Creates a fixed and performed interval."""
-    return _pywrapcp.Solver_FixedInterval(self, start, duration, name)
-
-
-
-def GuidedLocalSearch(self, *args) ‑> operations_research::SearchMonitor * -
-
-
-
- -Expand source code - -
def GuidedLocalSearch(self, *args) -> "operations_research::SearchMonitor *":
-    return _pywrapcp.Solver_GuidedLocalSearch(self, *args)
-
-
-
-def IndexExpression(self, vars: std::vector< operations_research::IntVar * > const &, value: int64_t) ‑> operations_research::IntExpr * -
-
-

Returns the expression expr such that vars[expr] == value. -It assumes that vars are all different.

-
- -Expand source code - -
def IndexExpression(self, vars: "std::vector< operations_research::IntVar * > const &", value: "int64_t") -> "operations_research::IntExpr *":
-    r"""
-    Returns the expression expr such that vars[expr] == value.
-    It assumes that vars are all different.
-    """
-    return _pywrapcp.Solver_IndexExpression(self, vars, value)
-
-
-
-def IndexOfConstraint(self, vars: std::vector< operations_research::IntVar * > const &, index: IntVar, target: int64_t) ‑> operations_research::Constraint * -
-
-

This constraint is a special case of the element constraint with -an array of integer variables, where the variables are all -different and the index variable is constrained such that -vars[index] == target.

-
- -Expand source code - -
def IndexOfConstraint(self, vars: "std::vector< operations_research::IntVar * > const &", index: "IntVar", target: "int64_t") -> "operations_research::Constraint *":
-    r"""
-    This constraint is a special case of the element constraint with
-    an array of integer variables, where the variables are all
-    different and the index variable is constrained such that
-    vars[index] == target.
-    """
-    return _pywrapcp.Solver_IndexOfConstraint(self, vars, index, target)
-
-
-
-def IntConst(self, *args) ‑> operations_research::IntVar * -
-
-

Overload 1: -IntConst will create a constant expression.

-

|

-

Overload 2: -IntConst will create a constant expression.

-
- -Expand source code - -
def IntConst(self, *args) -> "operations_research::IntVar *":
-    r"""
-    *Overload 1:*
-    IntConst will create a constant expression.
+        *Overload 3:*
+        std::min(expr, value)
 
-    |
+        |
 
-    *Overload 2:*
-    IntConst will create a constant expression.
-    """
-    return _pywrapcp.Solver_IntConst(self, *args)
-
-
-
-def IntVar(self, *args) ‑> operations_research::IntVar * -
-
-

Overload 1: -MakeIntVar will create the best range based int var for the bounds given.

-

|

-

Overload 2: -MakeIntVar will create a variable with the given sparse domain.

-

|

-

Overload 3: -MakeIntVar will create a variable with the given sparse domain.

-

|

-

Overload 4: -MakeIntVar will create the best range based int var for the bounds given.

-

|

-

Overload 5: -MakeIntVar will create a variable with the given sparse domain.

-

|

-

Overload 6: -MakeIntVar will create a variable with the given sparse domain.

-
- -Expand source code - -
def IntVar(self, *args) -> "operations_research::IntVar *":
-    r"""
-    *Overload 1:*
-    MakeIntVar will create the best range based int var for the bounds given.
+        *Overload 4:*
+        std::min(expr, value)
+        """
+        return _pywrapcp.Solver_Min(self, *args)
+
- | + - *Overload 2:* - MakeIntVar will create a variable with the given sparse domain. - - | - - *Overload 3:* - MakeIntVar will create a variable with the given sparse domain. - - | - - *Overload 4:* - MakeIntVar will create the best range based int var for the bounds given. - - | - - *Overload 5:* - MakeIntVar will create a variable with the given sparse domain. - - | - - *Overload 6:* - MakeIntVar will create a variable with the given sparse domain. - """ - return _pywrapcp.Solver_IntVar(self, *args) - - -
-def IntervalRelaxedMax(self, interval_var: IntervalVar) ‑> operations_research::IntervalVar * -
-
-

Creates and returns an interval variable that wraps around the given one, -relaxing the max start and end. Relaxing means making unbounded when -optional. If the variable is non optional, this method returns -interval_var.

-

More precisely, such an interval variable behaves as follows: -When the underlying must be performed, the returned interval variable -behaves exactly as the underlying; -When the underlying may or may not be performed, the returned interval -variable behaves like the underlying, except that it is unbounded on -the max side; -When the underlying cannot be performed, the returned interval variable -is of duration 0 and must be performed in an interval unbounded on -both sides.

-

This is very useful for implementing propagators that may only modify -the start min or end min.

-
- -Expand source code - -
def IntervalRelaxedMax(self, interval_var: "IntervalVar") -> "operations_research::IntervalVar *":
-    r"""
-     Creates and returns an interval variable that wraps around the given one,
-     relaxing the max start and end. Relaxing means making unbounded when
-     optional. If the variable is non optional, this method returns
-     interval_var.
-
-     More precisely, such an interval variable behaves as follows:
-    When the underlying must be performed, the returned interval variable
-         behaves exactly as the underlying;
-    When the underlying may or may not be performed, the returned interval
-         variable behaves like the underlying, except that it is unbounded on
-         the max side;
-    When the underlying cannot be performed, the returned interval variable
-         is of duration 0 and must be performed in an interval unbounded on
-         both sides.
-
-     This is very useful for implementing propagators that may only modify
-     the start min or end min.
-    """
-    return _pywrapcp.Solver_IntervalRelaxedMax(self, interval_var)
-
-
-
-def IntervalRelaxedMin(self, interval_var: IntervalVar) ‑> operations_research::IntervalVar * -
-
-

Creates and returns an interval variable that wraps around the given one, -relaxing the min start and end. Relaxing means making unbounded when -optional. If the variable is non-optional, this method returns -interval_var.

-

More precisely, such an interval variable behaves as follows: -When the underlying must be performed, the returned interval variable -behaves exactly as the underlying; -When the underlying may or may not be performed, the returned interval -variable behaves like the underlying, except that it is unbounded on -the min side; -When the underlying cannot be performed, the returned interval variable -is of duration 0 and must be performed in an interval unbounded on -both sides.

-

This is very useful to implement propagators that may only modify -the start max or end max.

-
- -Expand source code - -
def IntervalRelaxedMin(self, interval_var: "IntervalVar") -> "operations_research::IntervalVar *":
-    r"""
-     Creates and returns an interval variable that wraps around the given one,
-     relaxing the min start and end. Relaxing means making unbounded when
-     optional. If the variable is non-optional, this method returns
-     interval_var.
-
-     More precisely, such an interval variable behaves as follows:
-    When the underlying must be performed, the returned interval variable
-         behaves exactly as the underlying;
-    When the underlying may or may not be performed, the returned interval
-         variable behaves like the underlying, except that it is unbounded on
-         the min side;
-    When the underlying cannot be performed, the returned interval variable
-         is of duration 0 and must be performed in an interval unbounded on
-         both sides.
-
-     This is very useful to implement propagators that may only modify
-     the start max or end max.
-    """
-    return _pywrapcp.Solver_IntervalRelaxedMin(self, interval_var)
-
-
-
-def IntervalVar(self, start_min: int64_t, start_max: int64_t, duration_min: int64_t, duration_max: int64_t, end_min: int64_t, end_max: int64_t, optional: bool, name: std::string const &) ‑> operations_research::IntervalVar * -
-
-

Creates an interval var by specifying the bounds on start, -duration, and end.

-
- -Expand source code - -
def IntervalVar(self, start_min: "int64_t", start_max: "int64_t", duration_min: "int64_t", duration_max: "int64_t", end_min: "int64_t", end_max: "int64_t", optional: "bool", name: "std::string const &") -> "operations_research::IntervalVar *":
-    r"""
-    Creates an interval var by specifying the bounds on start,
-    duration, and end.
-    """
-    return _pywrapcp.Solver_IntervalVar(self, start_min, start_max, duration_min, duration_max, end_min, end_max, optional, name)
-
-
-
-def InversePermutationConstraint(self, left: std::vector< operations_research::IntVar * > const &, right: std::vector< operations_research::IntVar * > const &) ‑> operations_research::Constraint * -
-
-

Creates a constraint that enforces that 'left' and 'right' both -represent permutations of [0..left.size()-1], and that 'right' is -the inverse permutation of 'left', i.e. for all i in -[0..left.size()-1], right[left[i]] = i.

-
- -Expand source code - -
def InversePermutationConstraint(self, left: "std::vector< operations_research::IntVar * > const &", right: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-    r"""
-    Creates a constraint that enforces that 'left' and 'right' both
-    represent permutations of [0..left.size()-1], and that 'right' is
-    the inverse permutation of 'left', i.e. for all i in
-    [0..left.size()-1], right[left[i]] = i.
-    """
-    return _pywrapcp.Solver_InversePermutationConstraint(self, left, right)
-
-
-
-def IsBetweenCt(self, expr: IntExpr, l: int64_t, u: int64_t, b: IntVar) ‑> operations_research::Constraint * -
-
-

b == (l <= expr <= u)

-
- -Expand source code - -
def IsBetweenCt(self, expr: "IntExpr", l: "int64_t", u: "int64_t", b: "IntVar") -> "operations_research::Constraint *":
-    r""" b == (l <= expr <= u)"""
-    return _pywrapcp.Solver_IsBetweenCt(self, expr, l, u, b)
-
-
-
-def IsBetweenVar(self, v: IntExpr, l: int64_t, u: int64_t) ‑> operations_research::IntVar * -
-
-
-
- -Expand source code - -
def IsBetweenVar(self, v: "IntExpr", l: "int64_t", u: "int64_t") -> "operations_research::IntVar *":
-    return _pywrapcp.Solver_IsBetweenVar(self, v, l, u)
-
-
-
-def IsDifferentCstCt(self, var: IntExpr, value: int64_t, boolvar: IntVar) ‑> operations_research::Constraint * -
-
-

boolvar == (var != value)

-
- -Expand source code - -
def IsDifferentCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
-    r""" boolvar == (var != value)"""
-    return _pywrapcp.Solver_IsDifferentCstCt(self, var, value, boolvar)
-
-
-
-def IsDifferentCstVar(self, var: IntExpr, value: int64_t) ‑> operations_research::IntVar * -
-
-

status var of (var != value)

-
- -Expand source code - -
def IsDifferentCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
-    r""" status var of (var != value)"""
-    return _pywrapcp.Solver_IsDifferentCstVar(self, var, value)
-
-
-
-def IsDifferentCt(self, v1: IntExpr, v2: IntExpr, b: IntVar) ‑> operations_research::Constraint * -
-
-

b == (v1 != v2)

-
- -Expand source code - -
def IsDifferentCt(self, v1: "IntExpr", v2: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
-    r""" b == (v1 != v2)"""
-    return _pywrapcp.Solver_IsDifferentCt(self, v1, v2, b)
-
-
-
-def IsDifferentVar(self, v1: IntExpr, v2: IntExpr) ‑> operations_research::IntVar * -
-
-

status var of (v1 != v2)

-
- -Expand source code - -
def IsDifferentVar(self, v1: "IntExpr", v2: "IntExpr") -> "operations_research::IntVar *":
-    r""" status var of (v1 != v2)"""
-    return _pywrapcp.Solver_IsDifferentVar(self, v1, v2)
-
-
-
-def IsEqualCstCt(self, var: IntExpr, value: int64_t, boolvar: IntVar) ‑> operations_research::Constraint * -
-
-

boolvar == (var == value)

-
- -Expand source code - -
def IsEqualCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
-    r""" boolvar == (var == value)"""
-    return _pywrapcp.Solver_IsEqualCstCt(self, var, value, boolvar)
-
-
-
-def IsEqualCstVar(self, var: IntExpr, value: int64_t) ‑> operations_research::IntVar * -
-
-

status var of (var == value)

-
- -Expand source code - -
def IsEqualCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
-    r""" status var of (var == value)"""
-    return _pywrapcp.Solver_IsEqualCstVar(self, var, value)
-
-
-
-def IsEqualCt(self, v1: IntExpr, v2: IntExpr, b: IntVar) ‑> operations_research::Constraint * -
-
-

b == (v1 == v2)

-
- -Expand source code - -
def IsEqualCt(self, v1: "IntExpr", v2: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
-    r""" b == (v1 == v2)"""
-    return _pywrapcp.Solver_IsEqualCt(self, v1, v2, b)
-
-
-
-def IsEqualVar(self, v1: IntExpr, v2: IntExpr) ‑> operations_research::IntVar * -
-
-

status var of (v1 == v2)

-
- -Expand source code - -
def IsEqualVar(self, v1: "IntExpr", v2: "IntExpr") -> "operations_research::IntVar *":
-    r""" status var of (v1 == v2)"""
-    return _pywrapcp.Solver_IsEqualVar(self, v1, v2)
-
-
-
-def IsGreaterCstCt(self, v: IntExpr, c: int64_t, b: IntVar) ‑> operations_research::Constraint * -
-
-

b == (v > c)

-
- -Expand source code - -
def IsGreaterCstCt(self, v: "IntExpr", c: "int64_t", b: "IntVar") -> "operations_research::Constraint *":
-    r""" b == (v > c)"""
-    return _pywrapcp.Solver_IsGreaterCstCt(self, v, c, b)
-
-
-
-def IsGreaterCstVar(self, var: IntExpr, value: int64_t) ‑> operations_research::IntVar * -
-
-

status var of (var > value)

-
- -Expand source code - -
def IsGreaterCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
-    r""" status var of (var > value)"""
-    return _pywrapcp.Solver_IsGreaterCstVar(self, var, value)
-
-
-
-def IsGreaterCt(self, left: IntExpr, right: IntExpr, b: IntVar) ‑> operations_research::Constraint * -
-
-

b == (left > right)

-
- -Expand source code - -
def IsGreaterCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
-    r""" b == (left > right)"""
-    return _pywrapcp.Solver_IsGreaterCt(self, left, right, b)
-
-
-
-def IsGreaterOrEqualCstCt(self, var: IntExpr, value: int64_t, boolvar: IntVar) ‑> operations_research::Constraint * -
-
-

boolvar == (var >= value)

-
- -Expand source code - -
def IsGreaterOrEqualCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
-    r""" boolvar == (var >= value)"""
-    return _pywrapcp.Solver_IsGreaterOrEqualCstCt(self, var, value, boolvar)
-
-
-
-def IsGreaterOrEqualCstVar(self, var: IntExpr, value: int64_t) ‑> operations_research::IntVar * -
-
-

status var of (var >= value)

-
- -Expand source code - -
def IsGreaterOrEqualCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
-    r""" status var of (var >= value)"""
-    return _pywrapcp.Solver_IsGreaterOrEqualCstVar(self, var, value)
-
-
-
-def IsGreaterOrEqualCt(self, left: IntExpr, right: IntExpr, b: IntVar) ‑> operations_research::Constraint * -
-
-

b == (left >= right)

-
- -Expand source code - -
def IsGreaterOrEqualCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
-    r""" b == (left >= right)"""
-    return _pywrapcp.Solver_IsGreaterOrEqualCt(self, left, right, b)
-
-
-
-def IsGreaterOrEqualVar(self, left: IntExpr, right: IntExpr) ‑> operations_research::IntVar * -
-
-

status var of (left >= right)

-
- -Expand source code - -
def IsGreaterOrEqualVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
-    r""" status var of (left >= right)"""
-    return _pywrapcp.Solver_IsGreaterOrEqualVar(self, left, right)
-
-
-
-def IsGreaterVar(self, left: IntExpr, right: IntExpr) ‑> operations_research::IntVar * -
-
-

status var of (left > right)

-
- -Expand source code - -
def IsGreaterVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
-    r""" status var of (left > right)"""
-    return _pywrapcp.Solver_IsGreaterVar(self, left, right)
-
-
-
-def IsLessCstCt(self, v: IntExpr, c: int64_t, b: IntVar) ‑> operations_research::Constraint * -
-
-

b == (v < c)

-
- -Expand source code - -
def IsLessCstCt(self, v: "IntExpr", c: "int64_t", b: "IntVar") -> "operations_research::Constraint *":
-    r""" b == (v < c)"""
-    return _pywrapcp.Solver_IsLessCstCt(self, v, c, b)
-
-
-
-def IsLessCstVar(self, var: IntExpr, value: int64_t) ‑> operations_research::IntVar * -
-
-

status var of (var < value)

-
- -Expand source code - -
def IsLessCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
-    r""" status var of (var < value)"""
-    return _pywrapcp.Solver_IsLessCstVar(self, var, value)
-
-
-
-def IsLessCt(self, left: IntExpr, right: IntExpr, b: IntVar) ‑> operations_research::Constraint * -
-
-

b == (left < right)

-
- -Expand source code - -
def IsLessCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
-    r""" b == (left < right)"""
-    return _pywrapcp.Solver_IsLessCt(self, left, right, b)
-
-
-
-def IsLessOrEqualCstCt(self, var: IntExpr, value: int64_t, boolvar: IntVar) ‑> operations_research::Constraint * -
-
-

boolvar == (var <= value)

-
- -Expand source code - -
def IsLessOrEqualCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
-    r""" boolvar == (var <= value)"""
-    return _pywrapcp.Solver_IsLessOrEqualCstCt(self, var, value, boolvar)
-
-
-
-def IsLessOrEqualCstVar(self, var: IntExpr, value: int64_t) ‑> operations_research::IntVar * -
-
-

status var of (var <= value)

-
- -Expand source code - -
def IsLessOrEqualCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
-    r""" status var of (var <= value)"""
-    return _pywrapcp.Solver_IsLessOrEqualCstVar(self, var, value)
-
-
-
-def IsLessOrEqualCt(self, left: IntExpr, right: IntExpr, b: IntVar) ‑> operations_research::Constraint * -
-
-

b == (left <= right)

-
- -Expand source code - -
def IsLessOrEqualCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
-    r""" b == (left <= right)"""
-    return _pywrapcp.Solver_IsLessOrEqualCt(self, left, right, b)
-
-
-
-def IsLessOrEqualVar(self, left: IntExpr, right: IntExpr) ‑> operations_research::IntVar * -
-
-

status var of (left <= right)

-
- -Expand source code - -
def IsLessOrEqualVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
-    r""" status var of (left <= right)"""
-    return _pywrapcp.Solver_IsLessOrEqualVar(self, left, right)
-
-
-
-def IsLessVar(self, left: IntExpr, right: IntExpr) ‑> operations_research::IntVar * -
-
-

status var of (left < right)

-
- -Expand source code - -
def IsLessVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
-    r""" status var of (left < right)"""
-    return _pywrapcp.Solver_IsLessVar(self, left, right)
-
-
-
-def IsMemberCt(self, *args) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def IsMemberCt(self, *args) -> "operations_research::Constraint *":
-    return _pywrapcp.Solver_IsMemberCt(self, *args)
-
-
-
-def IsMemberVar(self, *args) ‑> operations_research::IntVar * -
-
-
-
- -Expand source code - -
def IsMemberVar(self, *args) -> "operations_research::IntVar *":
-    return _pywrapcp.Solver_IsMemberVar(self, *args)
-
-
-
-def LastSolutionCollector(self, *args) ‑> operations_research::SolutionCollector * -
-
-

Overload 1: -Collect the last solution of the search.

-

|

-

Overload 2: -Collect the last solution of the search. The variables will need to -be added later.

-
- -Expand source code - -
def LastSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
-    r"""
-    *Overload 1:*
-    Collect the last solution of the search.
-
-    |
-
-    *Overload 2:*
-    Collect the last solution of the search. The variables will need to
-    be added later.
-    """
-    return _pywrapcp.Solver_LastSolutionCollector(self, *args)
-
-
-
-def LexicalLess(self, left: std::vector< operations_research::IntVar * > const &, right: std::vector< operations_research::IntVar * > const &) ‑> operations_research::Constraint * -
-
-

Creates a constraint that enforces that left is lexicographically less -than right.

-
- -Expand source code - -
def LexicalLess(self, left: "std::vector< operations_research::IntVar * > const &", right: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-    r"""
-    Creates a constraint that enforces that left is lexicographically less
-    than right.
-    """
-    return _pywrapcp.Solver_LexicalLess(self, left, right)
-
-
-
-def LexicalLessOrEqual(self, left: std::vector< operations_research::IntVar * > const &, right: std::vector< operations_research::IntVar * > const &) ‑> operations_research::Constraint * -
-
-

Creates a constraint that enforces that left is lexicographically less -than or equal to right.

-
- -Expand source code - -
def LexicalLessOrEqual(self, left: "std::vector< operations_research::IntVar * > const &", right: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-    r"""
-    Creates a constraint that enforces that left is lexicographically less
-    than or equal to right.
-    """
-    return _pywrapcp.Solver_LexicalLessOrEqual(self, left, right)
-
-
-
-def Limit(self, *args) ‑> operations_research::SearchLimit * -
-
-

Overload 1: -Limits the search with the 'time', 'branches', 'failures' and -'solutions' limits. 'smart_time_check' reduces the calls to the wall

-

|

-

Overload 2: -Creates a search limit from its protobuf description

-

|

-

Overload 3: -Creates a search limit that is reached when either of the underlying limit -is reached. That is, the returned limit is more stringent than both -argument limits.

-
- -Expand source code - -
def Limit(self, *args) -> "operations_research::SearchLimit *":
-    r"""
-    *Overload 1:*
-    Limits the search with the 'time', 'branches', 'failures' and
-    'solutions' limits. 'smart_time_check' reduces the calls to the wall
-
-    |
-
-    *Overload 2:*
-    Creates a search limit from its protobuf description
-
-    |
-
-    *Overload 3:*
-    Creates a search limit that is reached when either of the underlying limit
-    is reached. That is, the returned limit is more stringent than both
-    argument limits.
-    """
-    return _pywrapcp.Solver_Limit(self, *args)
-
-
-
-def LocalSearchPhase(self, *args) ‑> operations_research::DecisionBuilder * -
-
-
-
- -Expand source code - -
def LocalSearchPhase(self, *args) -> "operations_research::DecisionBuilder *":
-    return _pywrapcp.Solver_LocalSearchPhase(self, *args)
-
-
-
-def LocalSearchPhaseParameters(self, *args) ‑> operations_research::LocalSearchPhaseParameters * -
-
-
-
- -Expand source code - -
def LocalSearchPhaseParameters(self, *args) -> "operations_research::LocalSearchPhaseParameters *":
-    return _pywrapcp.Solver_LocalSearchPhaseParameters(self, *args)
-
-
-
-def LocalSearchProfile(self) ‑> std::string -
-
-

Returns local search profiling information in a human readable format.

-
- -Expand source code - -
def LocalSearchProfile(self) -> "std::string":
-    r""" Returns local search profiling information in a human readable format."""
-    return _pywrapcp.Solver_LocalSearchProfile(self)
-
-
-
-def LubyRestart(self, scale_factor: int) ‑> operations_research::SearchMonitor * -
-
-

This search monitor will restart the search periodically. -At the iteration n, it will restart after scale_factor * Luby(n) failures -where Luby is the Luby Strategy (i.e. 1 1 2 1 1 2 4 1 1 2 1 1 2 4 8…).

-
- -Expand source code - -
def LubyRestart(self, scale_factor: "int") -> "operations_research::SearchMonitor *":
-    r"""
-    This search monitor will restart the search periodically.
-    At the iteration n, it will restart after scale_factor * Luby(n) failures
-    where Luby is the Luby Strategy (i.e. 1 1 2 1 1 2 4 1 1 2 1 1 2 4 8...).
-    """
-    return _pywrapcp.Solver_LubyRestart(self, scale_factor)
-
-
-
-def Max(self, *args) ‑> operations_research::IntExpr * -
-
-

Overload 1: -std::max(vars)

-

|

-

Overload 2: -std::max(left, right)

-

|

-

Overload 3: -std::max(expr, value)

-

|

-

Overload 4: -std::max(expr, value)

-
- -Expand source code - -
def Max(self, *args) -> "operations_research::IntExpr *":
-    r"""
-    *Overload 1:*
-    std::max(vars)
-
-    |
-
-    *Overload 2:*
-    std::max(left, right)
-
-    |
-
-    *Overload 3:*
-    std::max(expr, value)
-
-    |
-
-    *Overload 4:*
-    std::max(expr, value)
-    """
-    return _pywrapcp.Solver_Max(self, *args)
-
-
-
-def MaxEquality(self, vars: std::vector< operations_research::IntVar * > const &, max_var: IntVar) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def MaxEquality(self, vars: "std::vector< operations_research::IntVar * > const &", max_var: "IntVar") -> "operations_research::Constraint *":
-    return _pywrapcp.Solver_MaxEquality(self, vars, max_var)
-
-
-
-def Maximize(self, v: IntVar, step: int64_t) ‑> operations_research::OptimizeVar * -
-
-

Creates a maximization objective.

-
- -Expand source code - -
def Maximize(self, v: "IntVar", step: "int64_t") -> "operations_research::OptimizeVar *":
-    r""" Creates a maximization objective."""
-    return _pywrapcp.Solver_Maximize(self, v, step)
-
-
-
-def MemberCt(self, *args) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def MemberCt(self, *args) -> "operations_research::Constraint *":
-    return _pywrapcp.Solver_MemberCt(self, *args)
-
-
-
-def Min(self, *args) ‑> operations_research::IntExpr * -
-
-

Overload 1: +

Overload 1: std::min(vars)

+

|

+

Overload 2: std::min (left, right)

+

|

+

Overload 3: std::min(expr, value)

+

|

+

Overload 4: -std::min(expr, value)

-
- -Expand source code - -
def Min(self, *args) -> "operations_research::IntExpr *":
-    r"""
-    *Overload 1:*
-    std::min(vars)
+std::min(expr, value)

+
- | - *Overload 2:* - std::min (left, right) + +
+
#   - | + + def + Max(self, *args) -> 'operations_research::IntExpr *': +
- *Overload 3:* - std::min(expr, value) +
+ View Source +
    def Max(self, *args) -> "operations_research::IntExpr *":
+        r"""
+        *Overload 1:*
+        std::max(vars)
 
-    |
+        |
+
+        *Overload 2:*
+        std::max(left, right)
+
+        |
+
+        *Overload 3:*
+        std::max(expr, value)
+
+        |
+
+        *Overload 4:*
+        std::max(expr, value)
+        """
+        return _pywrapcp.Solver_Max(self, *args)
+
+ +
+ +

Overload 1: +std::max(vars)

- *Overload 4:* - std::min(expr, value) - """ - return _pywrapcp.Solver_Min(self, *args)
- -
-
-def MinEquality(self, vars: std::vector< operations_research::IntVar * > const &, min_var: IntVar) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def MinEquality(self, vars: "std::vector< operations_research::IntVar * > const &", min_var: "IntVar") -> "operations_research::Constraint *":
-    return _pywrapcp.Solver_MinEquality(self, vars, min_var)
-
-
-
-def Minimize(self, v: IntVar, step: int64_t) ‑> operations_research::OptimizeVar * -
-
-

Creates a minimization objective.

-
- -Expand source code - -
def Minimize(self, v: "IntVar", step: "int64_t") -> "operations_research::OptimizeVar *":
-    r""" Creates a minimization objective."""
-    return _pywrapcp.Solver_Minimize(self, v, step)
-
-
-
-def MirrorInterval(self, interval_var: IntervalVar) ‑> operations_research::IntervalVar * -
-
-

Creates an interval var that is the mirror image of the given one, that -is, the interval var obtained by reversing the axis.

-
- -Expand source code - -
def MirrorInterval(self, interval_var: "IntervalVar") -> "operations_research::IntervalVar *":
-    r"""
-    Creates an interval var that is the mirror image of the given one, that
-    is, the interval var obtained by reversing the axis.
-    """
-    return _pywrapcp.Solver_MirrorInterval(self, interval_var)
-
-
-
-def MonotonicElement(self, values: operations_research::Solver::IndexEvaluator1, increasing: bool, index: IntVar) ‑> operations_research::IntExpr * -
-
-

Function based element. The constraint takes ownership of the -callback. -The callback must be monotonic. It must be able to -cope with any possible value in the domain of 'index' -(potentially negative ones too). Furtermore, monotonicity is not -checked. Thus giving a non-monotonic function, or specifying an -incorrect increasing parameter will result in undefined behavior.

-
- -Expand source code - -
def MonotonicElement(self, values: "operations_research::Solver::IndexEvaluator1", increasing: "bool", index: "IntVar") -> "operations_research::IntExpr *":
-    r"""
-    Function based element. The constraint takes ownership of the
-    callback.  The callback must be monotonic. It must be able to
-    cope with any possible value in the domain of 'index'
-    (potentially negative ones too). Furtermore, monotonicity is not
-    checked. Thus giving a non-monotonic function, or specifying an
-    incorrect increasing parameter will result in undefined behavior.
-    """
-    return _pywrapcp.Solver_MonotonicElement(self, values, increasing, index)
-
-
-
-def MoveTowardTargetOperator(self, *args) ‑> operations_research::LocalSearchOperator * -
-
-

Overload 1: -Creates a local search operator that tries to move the assignment of some -variables toward a target. The target is given as an Assignment. This -operator generates neighbors in which the only difference compared to the -current state is that one variable that belongs to the target assignment -is set to its target value.

|

+

Overload 2: -Creates a local search operator that tries to move the assignment of some -variables toward a target. The target is given either as two vectors: a -vector of variables and a vector of associated target values. The two -vectors should be of the same length. This operator generates neighbors in -which the only difference compared to the current state is that one -variable that belongs to the given vector is set to its target value.

-
- -Expand source code - -
def MoveTowardTargetOperator(self, *args) -> "operations_research::LocalSearchOperator *":
-    r"""
-    *Overload 1:*
-    Creates a local search operator that tries to move the assignment of some
-    variables toward a target. The target is given as an Assignment. This
-    operator generates neighbors in which the only difference compared to the
-    current state is that one variable that belongs to the target assignment
-    is set to its target value.
+std::max(left, right)

- | - - *Overload 2:* - Creates a local search operator that tries to move the assignment of some - variables toward a target. The target is given either as two vectors: a - vector of variables and a vector of associated target values. The two - vectors should be of the same length. This operator generates neighbors in - which the only difference compared to the current state is that one - variable that belongs to the given vector is set to its target value. - """ - return _pywrapcp.Solver_MoveTowardTargetOperator(self, *args)
-
-
-
-def NeighborhoodLimit(self, op: LocalSearchOperator, limit: int64_t) ‑> operations_research::LocalSearchOperator * -
-
-

Creates a local search operator that wraps another local search -operator and limits the number of neighbors explored (i.e., calls -to MakeNextNeighbor from the current solution (between two calls -to Start()). When this limit is reached, MakeNextNeighbor() -returns false. The counter is cleared when Start() is called.

-
- -Expand source code - -
def NeighborhoodLimit(self, op: "LocalSearchOperator", limit: "int64_t") -> "operations_research::LocalSearchOperator *":
-    r"""
-    Creates a local search operator that wraps another local search
-    operator and limits the number of neighbors explored (i.e., calls
-    to MakeNextNeighbor from the current solution (between two calls
-    to Start()). When this limit is reached, MakeNextNeighbor()
-    returns false. The counter is cleared when Start() is called.
-    """
-    return _pywrapcp.Solver_NeighborhoodLimit(self, op, limit)
-
-
-
-def NestedOptimize(self, *args) ‑> operations_research::DecisionBuilder * -
-
-
-
- -Expand source code - -
def NestedOptimize(self, *args) -> "operations_research::DecisionBuilder *":
-    return _pywrapcp.Solver_NestedOptimize(self, *args)
-
-
-
-def NewSearch(self, *args) ‑> void -
-
-
-
- -Expand source code - -
def NewSearch(self, *args) -> "void":
-    return _pywrapcp.Solver_NewSearch(self, *args)
-
-
-
-def NextSolution(self) ‑> bool -
-
-
-
- -Expand source code - -
def NextSolution(self) -> "bool":
-    return _pywrapcp.Solver_NextSolution(self)
-
-
-
-def NonOverlappingBoxesConstraint(self, *args) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def NonOverlappingBoxesConstraint(self, *args) -> "operations_research::Constraint *":
-    return _pywrapcp.Solver_NonOverlappingBoxesConstraint(self, *args)
-
-
-
-def NotMemberCt(self, *args) ‑> operations_research::Constraint * -
-
-

Overload 1: -expr not in set.

|

+ +

Overload 3: +std::max(expr, value)

+ +

|

+ +

Overload 4: +std::max(expr, value)

+
+ + + +
+
#   + + + def + ConvexPiecewiseExpr( + self, + expr: pywrapcp.IntExpr, + early_cost: 'int64_t', + early_date: 'int64_t', + late_date: 'int64_t', + late_cost: 'int64_t' +) -> 'operations_research::IntExpr *': +
+ +
+ View Source +
    def ConvexPiecewiseExpr(self, expr: "IntExpr", early_cost: "int64_t", early_date: "int64_t", late_date: "int64_t", late_cost: "int64_t") -> "operations_research::IntExpr *":
+        r""" Convex piecewise function."""
+        return _pywrapcp.Solver_ConvexPiecewiseExpr(self, expr, early_cost, early_date, late_date, late_cost)
+
+ +
+ +

Convex piecewise function.

+
+ + +
+
+
#   + + + def + SemiContinuousExpr( + self, + expr: pywrapcp.IntExpr, + fixed_charge: 'int64_t', + step: 'int64_t' +) -> 'operations_research::IntExpr *': +
+ +
+ View Source +
    def SemiContinuousExpr(self, expr: "IntExpr", fixed_charge: "int64_t", step: "int64_t") -> "operations_research::IntExpr *":
+        r""" Semi continuous Expression (x <= 0 -> f(x) = 0; x > 0 -> f(x) = ax + b) a >= 0 and b >= 0"""
+        return _pywrapcp.Solver_SemiContinuousExpr(self, expr, fixed_charge, step)
+
+ +
+ +

Semi continuous Expression (x <= 0 -> f(x) = 0; x > 0 -> f(x) = ax + b) a >= 0 and b >= 0

+
+ + +
+
+
#   + + + def + ConditionalExpression( + self, + condition: pywrapcp.IntVar, + expr: pywrapcp.IntExpr, + unperformed_value: 'int64_t' +) -> 'operations_research::IntExpr *': +
+ +
+ View Source +
    def ConditionalExpression(self, condition: "IntVar", expr: "IntExpr", unperformed_value: "int64_t") -> "operations_research::IntExpr *":
+        r""" Conditional Expr condition ? expr : unperformed_value"""
+        return _pywrapcp.Solver_ConditionalExpression(self, condition, expr, unperformed_value)
+
+ +
+ +

Conditional Expr condition ? expr : unperformed_value

+
+ + +
+
+
#   + + + def + TrueConstraint(self) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def TrueConstraint(self) -> "operations_research::Constraint *":
+        r""" This constraint always succeeds."""
+        return _pywrapcp.Solver_TrueConstraint(self)
+
+ +
+ +

This constraint always succeeds.

+
+ + +
+
+
#   + + + def + FalseConstraint(self, *args) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def FalseConstraint(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_FalseConstraint(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + IsEqualCstCt( + self, + var: pywrapcp.IntExpr, + value: 'int64_t', + boolvar: pywrapcp.IntVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def IsEqualCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
+        r""" boolvar == (var == value)"""
+        return _pywrapcp.Solver_IsEqualCstCt(self, var, value, boolvar)
+
+ +
+ +

boolvar == (var == value)

+
+ + +
+
+
#   + + + def + IsEqualCstVar( + self, + var: pywrapcp.IntExpr, + value: 'int64_t' +) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def IsEqualCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
+        r""" status var of (var == value)"""
+        return _pywrapcp.Solver_IsEqualCstVar(self, var, value)
+
+ +
+ +

status var of (var == value)

+
+ + +
+
+
#   + + + def + IsEqualCt( + self, + v1: pywrapcp.IntExpr, + v2: pywrapcp.IntExpr, + b: pywrapcp.IntVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def IsEqualCt(self, v1: "IntExpr", v2: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (v1 == v2)"""
+        return _pywrapcp.Solver_IsEqualCt(self, v1, v2, b)
+
+ +
+ +

b == (v1 == v2)

+
+ + +
+
+
#   + + + def + IsEqualVar( + self, + v1: pywrapcp.IntExpr, + v2: pywrapcp.IntExpr +) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def IsEqualVar(self, v1: "IntExpr", v2: "IntExpr") -> "operations_research::IntVar *":
+        r""" status var of (v1 == v2)"""
+        return _pywrapcp.Solver_IsEqualVar(self, v1, v2)
+
+ +
+ +

status var of (v1 == v2)

+
+ + +
+
+
#   + + + def + IsDifferentCstCt( + self, + var: pywrapcp.IntExpr, + value: 'int64_t', + boolvar: pywrapcp.IntVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def IsDifferentCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
+        r""" boolvar == (var != value)"""
+        return _pywrapcp.Solver_IsDifferentCstCt(self, var, value, boolvar)
+
+ +
+ +

boolvar == (var != value)

+
+ + +
+
+
#   + + + def + IsDifferentCstVar( + self, + var: pywrapcp.IntExpr, + value: 'int64_t' +) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def IsDifferentCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
+        r""" status var of (var != value)"""
+        return _pywrapcp.Solver_IsDifferentCstVar(self, var, value)
+
+ +
+ +

status var of (var != value)

+
+ + +
+
+
#   + + + def + IsDifferentVar( + self, + v1: pywrapcp.IntExpr, + v2: pywrapcp.IntExpr +) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def IsDifferentVar(self, v1: "IntExpr", v2: "IntExpr") -> "operations_research::IntVar *":
+        r""" status var of (v1 != v2)"""
+        return _pywrapcp.Solver_IsDifferentVar(self, v1, v2)
+
+ +
+ +

status var of (v1 != v2)

+
+ + +
+
+
#   + + + def + IsDifferentCt( + self, + v1: pywrapcp.IntExpr, + v2: pywrapcp.IntExpr, + b: pywrapcp.IntVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def IsDifferentCt(self, v1: "IntExpr", v2: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (v1 != v2)"""
+        return _pywrapcp.Solver_IsDifferentCt(self, v1, v2, b)
+
+ +
+ +

b == (v1 != v2)

+
+ + +
+
+
#   + + + def + IsLessOrEqualCstCt( + self, + var: pywrapcp.IntExpr, + value: 'int64_t', + boolvar: pywrapcp.IntVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def IsLessOrEqualCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
+        r""" boolvar == (var <= value)"""
+        return _pywrapcp.Solver_IsLessOrEqualCstCt(self, var, value, boolvar)
+
+ +
+ +

boolvar == (var <= value)

+
+ + +
+
+
#   + + + def + IsLessOrEqualCstVar( + self, + var: pywrapcp.IntExpr, + value: 'int64_t' +) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def IsLessOrEqualCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
+        r""" status var of (var <= value)"""
+        return _pywrapcp.Solver_IsLessOrEqualCstVar(self, var, value)
+
+ +
+ +

status var of (var <= value)

+
+ + +
+
+
#   + + + def + IsLessOrEqualVar( + self, + left: pywrapcp.IntExpr, + right: pywrapcp.IntExpr +) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def IsLessOrEqualVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
+        r""" status var of (left <= right)"""
+        return _pywrapcp.Solver_IsLessOrEqualVar(self, left, right)
+
+ +
+ +

status var of (left <= right)

+
+ + +
+
+
#   + + + def + IsLessOrEqualCt( + self, + left: pywrapcp.IntExpr, + right: pywrapcp.IntExpr, + b: pywrapcp.IntVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def IsLessOrEqualCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (left <= right)"""
+        return _pywrapcp.Solver_IsLessOrEqualCt(self, left, right, b)
+
+ +
+ +

b == (left <= right)

+
+ + +
+
+
#   + + + def + IsGreaterOrEqualCstCt( + self, + var: pywrapcp.IntExpr, + value: 'int64_t', + boolvar: pywrapcp.IntVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def IsGreaterOrEqualCstCt(self, var: "IntExpr", value: "int64_t", boolvar: "IntVar") -> "operations_research::Constraint *":
+        r""" boolvar == (var >= value)"""
+        return _pywrapcp.Solver_IsGreaterOrEqualCstCt(self, var, value, boolvar)
+
+ +
+ +

boolvar == (var >= value)

+
+ + +
+
+
#   + + + def + IsGreaterOrEqualCstVar( + self, + var: pywrapcp.IntExpr, + value: 'int64_t' +) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def IsGreaterOrEqualCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
+        r""" status var of (var >= value)"""
+        return _pywrapcp.Solver_IsGreaterOrEqualCstVar(self, var, value)
+
+ +
+ +

status var of (var >= value)

+
+ + +
+
+
#   + + + def + IsGreaterOrEqualVar( + self, + left: pywrapcp.IntExpr, + right: pywrapcp.IntExpr +) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def IsGreaterOrEqualVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
+        r""" status var of (left >= right)"""
+        return _pywrapcp.Solver_IsGreaterOrEqualVar(self, left, right)
+
+ +
+ +

status var of (left >= right)

+
+ + +
+
+
#   + + + def + IsGreaterOrEqualCt( + self, + left: pywrapcp.IntExpr, + right: pywrapcp.IntExpr, + b: pywrapcp.IntVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def IsGreaterOrEqualCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (left >= right)"""
+        return _pywrapcp.Solver_IsGreaterOrEqualCt(self, left, right, b)
+
+ +
+ +

b == (left >= right)

+
+ + +
+
+
#   + + + def + IsGreaterCstCt( + self, + v: pywrapcp.IntExpr, + c: 'int64_t', + b: pywrapcp.IntVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def IsGreaterCstCt(self, v: "IntExpr", c: "int64_t", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (v > c)"""
+        return _pywrapcp.Solver_IsGreaterCstCt(self, v, c, b)
+
+ +
+ +

b == (v > c)

+
+ + +
+
+
#   + + + def + IsGreaterCstVar( + self, + var: pywrapcp.IntExpr, + value: 'int64_t' +) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def IsGreaterCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
+        r""" status var of (var > value)"""
+        return _pywrapcp.Solver_IsGreaterCstVar(self, var, value)
+
+ +
+ +

status var of (var > value)

+
+ + +
+
+
#   + + + def + IsGreaterVar( + self, + left: pywrapcp.IntExpr, + right: pywrapcp.IntExpr +) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def IsGreaterVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
+        r""" status var of (left > right)"""
+        return _pywrapcp.Solver_IsGreaterVar(self, left, right)
+
+ +
+ +

status var of (left > right)

+
+ + +
+
+
#   + + + def + IsGreaterCt( + self, + left: pywrapcp.IntExpr, + right: pywrapcp.IntExpr, + b: pywrapcp.IntVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def IsGreaterCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (left > right)"""
+        return _pywrapcp.Solver_IsGreaterCt(self, left, right, b)
+
+ +
+ +

b == (left > right)

+
+ + +
+
+
#   + + + def + IsLessCstCt( + self, + v: pywrapcp.IntExpr, + c: 'int64_t', + b: pywrapcp.IntVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def IsLessCstCt(self, v: "IntExpr", c: "int64_t", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (v < c)"""
+        return _pywrapcp.Solver_IsLessCstCt(self, v, c, b)
+
+ +
+ +

b == (v < c)

+
+ + +
+
+
#   + + + def + IsLessCstVar( + self, + var: pywrapcp.IntExpr, + value: 'int64_t' +) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def IsLessCstVar(self, var: "IntExpr", value: "int64_t") -> "operations_research::IntVar *":
+        r""" status var of (var < value)"""
+        return _pywrapcp.Solver_IsLessCstVar(self, var, value)
+
+ +
+ +

status var of (var < value)

+
+ + +
+
+
#   + + + def + IsLessVar( + self, + left: pywrapcp.IntExpr, + right: pywrapcp.IntExpr +) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def IsLessVar(self, left: "IntExpr", right: "IntExpr") -> "operations_research::IntVar *":
+        r""" status var of (left < right)"""
+        return _pywrapcp.Solver_IsLessVar(self, left, right)
+
+ +
+ +

status var of (left < right)

+
+ + +
+
+
#   + + + def + IsLessCt( + self, + left: pywrapcp.IntExpr, + right: pywrapcp.IntExpr, + b: pywrapcp.IntVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def IsLessCt(self, left: "IntExpr", right: "IntExpr", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (left < right)"""
+        return _pywrapcp.Solver_IsLessCt(self, left, right, b)
+
+ +
+ +

b == (left < right)

+
+ + +
+
+
#   + + + def + SumLessOrEqual( + self, + vars: 'std::vector< operations_research::IntVar * > const &', + cst: 'int64_t' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def SumLessOrEqual(self, vars: "std::vector< operations_research::IntVar * > const &", cst: "int64_t") -> "operations_research::Constraint *":
+        r""" Variation on arrays."""
+        return _pywrapcp.Solver_SumLessOrEqual(self, vars, cst)
+
+ +
+ +

Variation on arrays.

+
+ + +
+
+
#   + + + def + SumGreaterOrEqual( + self, + vars: 'std::vector< operations_research::IntVar * > const &', + cst: 'int64_t' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def SumGreaterOrEqual(self, vars: "std::vector< operations_research::IntVar * > const &", cst: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_SumGreaterOrEqual(self, vars, cst)
+
+ +
+ + + +
+
+
#   + + + def + SumEquality(self, *args) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def SumEquality(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_SumEquality(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + ScalProdEquality(self, *args) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def ScalProdEquality(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_ScalProdEquality(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + ScalProdGreaterOrEqual(self, *args) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def ScalProdGreaterOrEqual(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_ScalProdGreaterOrEqual(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + ScalProdLessOrEqual(self, *args) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def ScalProdLessOrEqual(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_ScalProdLessOrEqual(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + MinEquality( + self, + vars: 'std::vector< operations_research::IntVar * > const &', + min_var: pywrapcp.IntVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def MinEquality(self, vars: "std::vector< operations_research::IntVar * > const &", min_var: "IntVar") -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_MinEquality(self, vars, min_var)
+
+ +
+ + + +
+
+
#   + + + def + MaxEquality( + self, + vars: 'std::vector< operations_research::IntVar * > const &', + max_var: pywrapcp.IntVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def MaxEquality(self, vars: "std::vector< operations_research::IntVar * > const &", max_var: "IntVar") -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_MaxEquality(self, vars, max_var)
+
+ +
+ + + +
+
+
#   + + + def + ElementEquality(self, *args) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def ElementEquality(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_ElementEquality(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + AbsEquality( + self, + var: pywrapcp.IntVar, + abs_var: pywrapcp.IntVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def AbsEquality(self, var: "IntVar", abs_var: "IntVar") -> "operations_research::Constraint *":
+        r""" Creates the constraint abs(var) == abs_var."""
+        return _pywrapcp.Solver_AbsEquality(self, var, abs_var)
+
+ +
+ +

Creates the constraint abs(var) == abs_var.

+
+ + +
+
+
#   + + + def + IndexOfConstraint( + self, + vars: 'std::vector< operations_research::IntVar * > const &', + index: pywrapcp.IntVar, + target: 'int64_t' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def IndexOfConstraint(self, vars: "std::vector< operations_research::IntVar * > const &", index: "IntVar", target: "int64_t") -> "operations_research::Constraint *":
+        r""" This constraint is a special case of the element constraint with an array of integer variables, where the variables are all different and the index variable is constrained such that vars[index] == target."""
+        return _pywrapcp.Solver_IndexOfConstraint(self, vars, index, target)
+
+ +
+ +

This constraint is a special case of the element constraint with an array of integer variables, where the variables are all different and the index variable is constrained such that vars[index] == target.

+
+ + +
+
+
#   + + + def + ConstraintInitialPropagateCallback(self, ct: pywrapcp.Constraint) -> 'operations_research::Demon *': +
+ +
+ View Source +
    def ConstraintInitialPropagateCallback(self, ct: "Constraint") -> "operations_research::Demon *":
+        r""" This method is a specialized case of the MakeConstraintDemon method to call the InitiatePropagate of the constraint 'ct'."""
+        return _pywrapcp.Solver_ConstraintInitialPropagateCallback(self, ct)
+
+ +
+ +

This method is a specialized case of the MakeConstraintDemon method to call the InitiatePropagate of the constraint 'ct'.

+
+ + +
+
+
#   + + + def + DelayedConstraintInitialPropagateCallback(self, ct: pywrapcp.Constraint) -> 'operations_research::Demon *': +
+ +
+ View Source +
    def DelayedConstraintInitialPropagateCallback(self, ct: "Constraint") -> "operations_research::Demon *":
+        r""" This method is a specialized case of the MakeConstraintDemon method to call the InitiatePropagate of the constraint 'ct' with low priority."""
+        return _pywrapcp.Solver_DelayedConstraintInitialPropagateCallback(self, ct)
+
+ +
+ +

This method is a specialized case of the MakeConstraintDemon method to call the InitiatePropagate of the constraint 'ct' with low priority.

+
+ + +
+
+
#   + + + def + ClosureDemon( + self, + closure: 'operations_research::Solver::Closure' +) -> 'operations_research::Demon *': +
+ +
+ View Source +
    def ClosureDemon(self, closure: "operations_research::Solver::Closure") -> "operations_research::Demon *":
+        r""" Creates a demon from a closure."""
+        return _pywrapcp.Solver_ClosureDemon(self, closure)
+
+ +
+ +

Creates a demon from a closure.

+
+ + +
+
+
#   + + + def + BetweenCt( + self, + expr: pywrapcp.IntExpr, + l: 'int64_t', + u: 'int64_t' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def BetweenCt(self, expr: "IntExpr", l: "int64_t", u: "int64_t") -> "operations_research::Constraint *":
+        r""" (l <= expr <= u)"""
+        return _pywrapcp.Solver_BetweenCt(self, expr, l, u)
+
+ +
+ +

(l <= expr <= u)

+
+ + +
+
+
#   + + + def + IsBetweenCt( + self, + expr: pywrapcp.IntExpr, + l: 'int64_t', + u: 'int64_t', + b: pywrapcp.IntVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def IsBetweenCt(self, expr: "IntExpr", l: "int64_t", u: "int64_t", b: "IntVar") -> "operations_research::Constraint *":
+        r""" b == (l <= expr <= u)"""
+        return _pywrapcp.Solver_IsBetweenCt(self, expr, l, u, b)
+
+ +
+ +

b == (l <= expr <= u)

+
+ + +
+
+
#   + + + def + IsBetweenVar( + self, + v: pywrapcp.IntExpr, + l: 'int64_t', + u: 'int64_t' +) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def IsBetweenVar(self, v: "IntExpr", l: "int64_t", u: "int64_t") -> "operations_research::IntVar *":
+        return _pywrapcp.Solver_IsBetweenVar(self, v, l, u)
+
+ +
+ + + +
+
+
#   + + + def + MemberCt(self, *args) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def MemberCt(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_MemberCt(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + NotMemberCt(self, *args) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def NotMemberCt(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        expr not in set.
+
+        |
+
+        *Overload 2:*
+        expr should not be in the list of forbidden intervals [start[i]..end[i]].
+
+        |
+
+        *Overload 3:*
+        expr should not be in the list of forbidden intervals [start[i]..end[i]].
+        """
+        return _pywrapcp.Solver_NotMemberCt(self, *args)
+
+ +
+ +

Overload 1: +expr not in set.

+ +

|

+

Overload 2: expr should not be in the list of forbidden intervals [start[i]..end[i]].

+

|

+

Overload 3: -expr should not be in the list of forbidden intervals [start[i]..end[i]].

-
- -Expand source code - -
def NotMemberCt(self, *args) -> "operations_research::Constraint *":
-    r"""
-    *Overload 1:*
-    expr not in set.
-
-    |
-
-    *Overload 2:*
-    expr should not be in the list of forbidden intervals [start[i]..end[i]].
-
-    |
-
-    *Overload 3:*
-    expr should not be in the list of forbidden intervals [start[i]..end[i]].
-    """
-    return _pywrapcp.Solver_NotMemberCt(self, *args)
-
-
-
-def NullIntersect(self, first_vars: std::vector< operations_research::IntVar * > const &, second_vars: std::vector< operations_research::IntVar * > const &) ‑> operations_research::Constraint * -
-
-

Creates a constraint that states that all variables in the first -vector are different from all variables in the second -group. Thus the set of values in the first vector does not -intersect with the set of values in the second vector.

-
- -Expand source code - -
def NullIntersect(self, first_vars: "std::vector< operations_research::IntVar * > const &", second_vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-    r"""
-    Creates a constraint that states that all variables in the first
-    vector are different from all variables in the second
-    group. Thus the set of values in the first vector does not
-    intersect with the set of values in the second vector.
-    """
-    return _pywrapcp.Solver_NullIntersect(self, first_vars, second_vars)
-
-
-
-def NullIntersectExcept(self, first_vars: std::vector< operations_research::IntVar * > const &, second_vars: std::vector< operations_research::IntVar * > const &, escape_value: int64_t) ‑> operations_research::Constraint * -
-
-

Creates a constraint that states that all variables in the first -vector are different from all variables from the second group, -unless they are assigned to the escape value. Thus the set of -values in the first vector minus the escape value does not -intersect with the set of values in the second vector.

-
- -Expand source code - -
def NullIntersectExcept(self, first_vars: "std::vector< operations_research::IntVar * > const &", second_vars: "std::vector< operations_research::IntVar * > const &", escape_value: "int64_t") -> "operations_research::Constraint *":
-    r"""
-    Creates a constraint that states that all variables in the first
-    vector are different from all variables from the second group,
-    unless they are assigned to the escape value. Thus the set of
-    values in the first vector minus the escape value does not
-    intersect with the set of values in the second vector.
-    """
-    return _pywrapcp.Solver_NullIntersectExcept(self, first_vars, second_vars, escape_value)
-
-
-
-def Operator(self, *args) ‑> operations_research::LocalSearchOperator * -
-
-
-
- -Expand source code - -
def Operator(self, *args) -> "operations_research::LocalSearchOperator *":
-    return _pywrapcp.Solver_Operator(self, *args)
-
-
-
-def Optimize(self, maximize: bool, v: IntVar, step: int64_t) ‑> operations_research::OptimizeVar * -
-
-

Creates a objective with a given sense (true = maximization).

-
- -Expand source code - -
def Optimize(self, maximize: "bool", v: "IntVar", step: "int64_t") -> "operations_research::OptimizeVar *":
-    r""" Creates a objective with a given sense (true = maximization)."""
-    return _pywrapcp.Solver_Optimize(self, maximize, v, step)
-
-
-
-def Pack(self, vars: std::vector< operations_research::IntVar * > const &, number_of_bins: int) ‑> operations_research::Pack * -
-
-

This constraint packs all variables onto 'number_of_bins' -variables. -For any given variable, a value of 'number_of_bins' -indicates that the variable is not assigned to any bin. -Dimensions, i.e., cumulative constraints on this packing, can be -added directly from the pack class.

-
- -Expand source code - -
def Pack(self, vars: "std::vector< operations_research::IntVar * > const &", number_of_bins: "int") -> "operations_research::Pack *":
-    r"""
-    This constraint packs all variables onto 'number_of_bins'
-    variables.  For any given variable, a value of 'number_of_bins'
-    indicates that the variable is not assigned to any bin.
-    Dimensions, i.e., cumulative constraints on this packing, can be
-    added directly from the pack class.
-    """
-    return _pywrapcp.Solver_Pack(self, vars, number_of_bins)
-
-
-
-def Parameters(self) ‑> operations_research::ConstraintSolverParameters -
-
-

Stored Parameters.

-
- -Expand source code - -
def Parameters(self) -> "operations_research::ConstraintSolverParameters":
-    r""" Stored Parameters."""
-    return _pywrapcp.Solver_Parameters(self)
-
-
-
-def PathCumul(self, *args) ‑> operations_research::Constraint * -
-
-

Overload 1: -Creates a constraint which accumulates values along a path such that: -cumuls[next[i]] = cumuls[i] + transits[i]. -Active variables indicate if the corresponding next variable is active; -this could be useful to model unperformed nodes in a routing problem.

-

|

-

Overload 2: -Creates a constraint which accumulates values along a path such that: -cumuls[next[i]] = cumuls[i] + transit_evaluator(i, next[i]). -Active variables indicate if the corresponding next variable is active; -this could be useful to model unperformed nodes in a routing problem. -Ownership of transit_evaluator is taken and it must be a repeatable -callback.

-

|

-

Overload 3: -Creates a constraint which accumulates values along a path such that: -cumuls[next[i]] = cumuls[i] + transit_evaluator(i, next[i]) + slacks[i]. -Active variables indicate if the corresponding next variable is active; -this could be useful to model unperformed nodes in a routing problem. -Ownership of transit_evaluator is taken and it must be a repeatable -callback.

-
- -Expand source code - -
def PathCumul(self, *args) -> "operations_research::Constraint *":
-    r"""
-    *Overload 1:*
-    Creates a constraint which accumulates values along a path such that:
-    cumuls[next[i]] = cumuls[i] + transits[i].
-    Active variables indicate if the corresponding next variable is active;
-    this could be useful to model unperformed nodes in a routing problem.
-
-    |
-
-    *Overload 2:*
-    Creates a constraint which accumulates values along a path such that:
-    cumuls[next[i]] = cumuls[i] + transit_evaluator(i, next[i]).
-    Active variables indicate if the corresponding next variable is active;
-    this could be useful to model unperformed nodes in a routing problem.
-    Ownership of transit_evaluator is taken and it must be a repeatable
-    callback.
-
-    |
-
-    *Overload 3:*
-    Creates a constraint which accumulates values along a path such that:
-    cumuls[next[i]] = cumuls[i] + transit_evaluator(i, next[i]) + slacks[i].
-    Active variables indicate if the corresponding next variable is active;
-    this could be useful to model unperformed nodes in a routing problem.
-    Ownership of transit_evaluator is taken and it must be a repeatable
-    callback.
-    """
-    return _pywrapcp.Solver_PathCumul(self, *args)
-
-
-
-def Phase(self, *args) ‑> operations_research::DecisionBuilder * -
-
-
-
- -Expand source code - -
def Phase(self, *args) -> "operations_research::DecisionBuilder *":
-    return _pywrapcp.Solver_Phase(self, *args)
-
-
-
-def PrintModelVisitor(self) ‑> operations_research::ModelVisitor * -
-
-

Prints the model.

-
- -Expand source code - -
def PrintModelVisitor(self) -> "operations_research::ModelVisitor *":
-    r""" Prints the model."""
-    return _pywrapcp.Solver_PrintModelVisitor(self)
-
-
-
-def Rand32(self, size: int32_t) ‑> int32_t -
-
-

Returns a random value between 0 and 'size' - 1;

-
- -Expand source code - -
def Rand32(self, size: "int32_t") -> "int32_t":
-    r""" Returns a random value between 0 and 'size' - 1;"""
-    return _pywrapcp.Solver_Rand32(self, size)
-
-
-
-def Rand64(self, size: int64_t) ‑> int64_t -
-
-

Returns a random value between 0 and 'size' - 1;

-
- -Expand source code - -
def Rand64(self, size: "int64_t") -> "int64_t":
-    r""" Returns a random value between 0 and 'size' - 1;"""
-    return _pywrapcp.Solver_Rand64(self, size)
-
-
-
-def RandomConcatenateOperators(self, *args) ‑> operations_research::LocalSearchOperator * -
-
-

Overload 1: -Randomized version of local search concatenator; calls a random operator -at each call to MakeNextNeighbor().

-

|

-

Overload 2: -Randomized version of local search concatenator; calls a random operator -at each call to MakeNextNeighbor(). The provided seed is used to -initialize the random number generator.

-
- -Expand source code - -
def RandomConcatenateOperators(self, *args) -> "operations_research::LocalSearchOperator *":
-    r"""
-    *Overload 1:*
-    Randomized version of local search concatenator; calls a random operator
-    at each call to MakeNextNeighbor().
-
-    |
-
-    *Overload 2:*
-    Randomized version of local search concatenator; calls a random operator
-    at each call to MakeNextNeighbor(). The provided seed is used to
-    initialize the random number generator.
-    """
-    return _pywrapcp.Solver_RandomConcatenateOperators(self, *args)
-
-
-
-def RandomLnsOperator(self, *args) ‑> operations_research::LocalSearchOperator * -
-
-
-
- -Expand source code - -
def RandomLnsOperator(self, *args) -> "operations_research::LocalSearchOperator *":
-    return _pywrapcp.Solver_RandomLnsOperator(self, *args)
-
-
-
-def RankFirstInterval(self, sequence: SequenceVar, index: int) ‑> operations_research::Decision * -
-
-

Returns a decision that tries to rank first the ith interval var -in the sequence variable.

-
- -Expand source code - -
def RankFirstInterval(self, sequence: "SequenceVar", index: "int") -> "operations_research::Decision *":
-    r"""
-    Returns a decision that tries to rank first the ith interval var
-    in the sequence variable.
-    """
-    return _pywrapcp.Solver_RankFirstInterval(self, sequence, index)
-
-
-
-def RankLastInterval(self, sequence: SequenceVar, index: int) ‑> operations_research::Decision * -
-
-

Returns a decision that tries to rank last the ith interval var -in the sequence variable.

-
- -Expand source code - -
def RankLastInterval(self, sequence: "SequenceVar", index: "int") -> "operations_research::Decision *":
-    r"""
-    Returns a decision that tries to rank last the ith interval var
-    in the sequence variable.
-    """
-    return _pywrapcp.Solver_RankLastInterval(self, sequence, index)
-
-
-
-def ReSeed(self, seed: int32_t) ‑> void -
-
-

Reseed the solver random generator.

-
- -Expand source code - -
def ReSeed(self, seed: "int32_t") -> "void":
-    r""" Reseed the solver random generator."""
-    return _pywrapcp.Solver_ReSeed(self, seed)
-
-
-
-def RestartCurrentSearch(self) ‑> void -
-
-
-
- -Expand source code - -
def RestartCurrentSearch(self) -> "void":
-    return _pywrapcp.Solver_RestartCurrentSearch(self)
-
-
-
-def RestartSearch(self) ‑> void -
-
-
-
- -Expand source code - -
def RestartSearch(self) -> "void":
-    return _pywrapcp.Solver_RestartSearch(self)
-
-
-
-def RestoreAssignment(self, assignment: Assignment) ‑> operations_research::DecisionBuilder * -
-
-

Returns a DecisionBuilder which restores an Assignment -(calls void Assignment::Restore())

-
- -Expand source code - -
def RestoreAssignment(self, assignment: "Assignment") -> "operations_research::DecisionBuilder *":
-    r"""
-    Returns a DecisionBuilder which restores an Assignment
-    (calls void Assignment::Restore())
-    """
-    return _pywrapcp.Solver_RestoreAssignment(self, assignment)
-
-
-
-def ScalProd(self, *args) ‑> operations_research::IntExpr * -
-
-

Overload 1: -scalar product

-

|

-

Overload 2: -scalar product

-
- -Expand source code - -
def ScalProd(self, *args) -> "operations_research::IntExpr *":
-    r"""
-    *Overload 1:*
-    scalar product
-
-    |
-
-    *Overload 2:*
-    scalar product
-    """
-    return _pywrapcp.Solver_ScalProd(self, *args)
-
-
-
-def ScalProdEquality(self, *args) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def ScalProdEquality(self, *args) -> "operations_research::Constraint *":
-    return _pywrapcp.Solver_ScalProdEquality(self, *args)
-
-
-
-def ScalProdGreaterOrEqual(self, *args) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def ScalProdGreaterOrEqual(self, *args) -> "operations_research::Constraint *":
-    return _pywrapcp.Solver_ScalProdGreaterOrEqual(self, *args)
-
-
-
-def ScalProdLessOrEqual(self, *args) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def ScalProdLessOrEqual(self, *args) -> "operations_research::Constraint *":
-    return _pywrapcp.Solver_ScalProdLessOrEqual(self, *args)
-
-
-
-def ScheduleOrExpedite(self, var: IntervalVar, est: int64_t, marker: int64_t *const) ‑> operations_research::Decision * -
-
-

Returns a decision that tries to schedule a task at a given time. -On the Apply branch, it will set that interval var as performed and set -its end to 'est'. On the Refute branch, it will just update the -'marker' to 'est' - 1. This decision is used in the -INTERVAL_SET_TIMES_BACKWARD strategy.

-
- -Expand source code - -
def ScheduleOrExpedite(self, var: "IntervalVar", est: "int64_t", marker: "int64_t *const") -> "operations_research::Decision *":
-    r"""
-    Returns a decision that tries to schedule a task at a given time.
-    On the Apply branch, it will set that interval var as performed and set
-    its end to 'est'. On the Refute branch, it will just update the
-    'marker' to 'est' - 1. This decision is used in the
-    INTERVAL_SET_TIMES_BACKWARD strategy.
-    """
-    return _pywrapcp.Solver_ScheduleOrExpedite(self, var, est, marker)
-
-
-
-def ScheduleOrPostpone(self, var: IntervalVar, est: int64_t, marker: int64_t *const) ‑> operations_research::Decision * -
-
-

Returns a decision that tries to schedule a task at a given time. -On the Apply branch, it will set that interval var as performed and set -its start to 'est'. On the Refute branch, it will just update the -'marker' to 'est' + 1. This decision is used in the -INTERVAL_SET_TIMES_FORWARD strategy.

-
- -Expand source code - -
def ScheduleOrPostpone(self, var: "IntervalVar", est: "int64_t", marker: "int64_t *const") -> "operations_research::Decision *":
-    r"""
-    Returns a decision that tries to schedule a task at a given time.
-    On the Apply branch, it will set that interval var as performed and set
-    its start to 'est'. On the Refute branch, it will just update the
-    'marker' to 'est' + 1. This decision is used in the
-    INTERVAL_SET_TIMES_FORWARD strategy.
-    """
-    return _pywrapcp.Solver_ScheduleOrPostpone(self, var, est, marker)
-
-
-
-def SearchDepth(self) ‑> int -
-
-

Gets the search depth of the current active search. Returns -1 if -there is no active search opened.

-
- -Expand source code - -
def SearchDepth(self) -> "int":
-    r"""
-    Gets the search depth of the current active search. Returns -1 if
-    there is no active search opened.
-    """
-    return _pywrapcp.Solver_SearchDepth(self)
-
-
-
-def SearchLeftDepth(self) ‑> int -
-
-

Gets the search left depth of the current active search. Returns -1 if -there is no active search opened.

-
- -Expand source code - -
def SearchLeftDepth(self) -> "int":
-    r"""
-    Gets the search left depth of the current active search. Returns -1 if
-    there is no active search opened.
-    """
-    return _pywrapcp.Solver_SearchLeftDepth(self)
-
-
-
-def SearchLog(self, *args) ‑> operations_research::SearchMonitor * -
-
-
-
- -Expand source code - -
def SearchLog(self, *args) -> "operations_research::SearchMonitor *":
-    return _pywrapcp.Solver_SearchLog(self, *args)
-
-
-
-def SearchLogWithCallback(self, period: int, callback: std::function< std::string () >) ‑> operations_research::SearchMonitor * -
-
-
-
- -Expand source code - -
def SearchLogWithCallback(self, period: "int", callback: "std::function< std::string () >") -> "operations_research::SearchMonitor *":
-    return _pywrapcp.Solver_SearchLogWithCallback(self, period, callback)
-
-
-
-def SearchTrace(self, prefix: std::string const &) ‑> operations_research::SearchMonitor * -
-
-

Creates a search monitor that will trace precisely the behavior of the -search. Use this only for low level debugging.

-
- -Expand source code - -
def SearchTrace(self, prefix: "std::string const &") -> "operations_research::SearchMonitor *":
-    r"""
-    Creates a search monitor that will trace precisely the behavior of the
-    search. Use this only for low level debugging.
-    """
-    return _pywrapcp.Solver_SearchTrace(self, prefix)
-
-
-
-def SemiContinuousExpr(self, expr: IntExpr, fixed_charge: int64_t, step: int64_t) ‑> operations_research::IntExpr * -
-
-

Semi continuous Expression (x <= 0 -> f(x) = 0; x > 0 -> f(x) = ax + b) -a >= 0 and b >= 0

-
- -Expand source code - -
def SemiContinuousExpr(self, expr: "IntExpr", fixed_charge: "int64_t", step: "int64_t") -> "operations_research::IntExpr *":
-    r"""
-    Semi continuous Expression (x <= 0 -> f(x) = 0; x > 0 -> f(x) = ax + b)
-    a >= 0 and b >= 0
-    """
-    return _pywrapcp.Solver_SemiContinuousExpr(self, expr, fixed_charge, step)
-
-
-
-def ShouldFail(self) ‑> void -
-
-

These methods are only useful for the SWIG wrappers, which need a way -to externally cause the Solver to fail.

-
- -Expand source code - -
def ShouldFail(self) -> "void":
-    r"""
-    These methods are only useful for the SWIG wrappers, which need a way
-    to externally cause the Solver to fail.
-    """
-    return _pywrapcp.Solver_ShouldFail(self)
-
-
-
-def SimulatedAnnealing(self, maximize: bool, v: IntVar, step: int64_t, initial_temperature: int64_t) ‑> operations_research::SearchMonitor * -
-
-

Creates a Simulated Annealing monitor.

-
- -Expand source code - -
def SimulatedAnnealing(self, maximize: "bool", v: "IntVar", step: "int64_t", initial_temperature: "int64_t") -> "operations_research::SearchMonitor *":
-    r""" Creates a Simulated Annealing monitor."""
-    return _pywrapcp.Solver_SimulatedAnnealing(self, maximize, v, step, initial_temperature)
-
-
-
-def Solutions(self) ‑> int64_t -
-
-

The number of solutions found since the start of the search.

-
- -Expand source code - -
def Solutions(self) -> "int64_t":
-    r""" The number of solutions found since the start of the search."""
-    return _pywrapcp.Solver_Solutions(self)
-
-
-
-def SolutionsLimit(self, solutions: int64_t) ‑> operations_research::RegularLimit * -
-
-

Creates a search limit that constrains the number of solutions found -during the search.

-
- -Expand source code - -
def SolutionsLimit(self, solutions: "int64_t") -> "operations_research::RegularLimit *":
-    r"""
-    Creates a search limit that constrains the number of solutions found
-    during the search.
-    """
-    return _pywrapcp.Solver_SolutionsLimit(self, solutions)
-
-
-
-def Solve(self, *args) ‑> bool -
-
-
-
- -Expand source code - -
def Solve(self, *args) -> "bool":
-    return _pywrapcp.Solver_Solve(self, *args)
-
-
-
-def SolveAndCommit(self, *args) ‑> bool -
-
-
-
- -Expand source code - -
def SolveAndCommit(self, *args) -> "bool":
-    return _pywrapcp.Solver_SolveAndCommit(self, *args)
-
-
-
-def SolveDepth(self) ‑> int -
-
-

Gets the number of nested searches. It returns 0 outside search, -1 during the top level search, 2 or more in case of nested searches.

-
- -Expand source code - -
def SolveDepth(self) -> "int":
-    r"""
-    Gets the number of nested searches. It returns 0 outside search,
-    1 during the top level search, 2 or more in case of nested searches.
-    """
-    return _pywrapcp.Solver_SolveDepth(self)
-
-
-
-def SolveOnce(self, db: DecisionBuilder, monitors: std::vector< operations_research::SearchMonitor * > const &) ‑> operations_research::DecisionBuilder * -
-
-
-
- -Expand source code - -
def SolveOnce(self, db: "DecisionBuilder", monitors: "std::vector< operations_research::SearchMonitor * > const &") -> "operations_research::DecisionBuilder *":
-    return _pywrapcp.Solver_SolveOnce(self, db, monitors)
-
-
-
-def SortingConstraint(self, vars: std::vector< operations_research::IntVar * > const &, sorted: std::vector< operations_research::IntVar * > const &) ‑> operations_research::Constraint * -
-
-

Creates a constraint binding the arrays of variables "vars" and -"sorted_vars": sorted_vars[0] must be equal to the minimum of all -variables in vars, and so on: the value of sorted_vars[i] must be -equal to the i-th value of variables invars.

-

This constraint propagates in both directions: from "vars" to -"sorted_vars" and vice-versa.

-

Behind the scenes, this constraint maintains that: -- sorted is always increasing. -- whatever the values of vars, there exists a permutation that -injects its values into the sorted variables.

-

For more info, please have a look at: -https://mpi-inf.mpg.de/~mehlhorn/ftp/Mehlhorn-Thiel.pdf

-
- -Expand source code - -
def SortingConstraint(self, vars: "std::vector< operations_research::IntVar * > const &", sorted: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-    r"""
-    Creates a constraint binding the arrays of variables "vars" and
-    "sorted_vars": sorted_vars[0] must be equal to the minimum of all
-    variables in vars, and so on: the value of sorted_vars[i] must be
-    equal to the i-th value of variables invars.
-
-    This constraint propagates in both directions: from "vars" to
-    "sorted_vars" and vice-versa.
-
-    Behind the scenes, this constraint maintains that:
-      - sorted is always increasing.
-      - whatever the values of vars, there exists a permutation that
-        injects its values into the sorted variables.
-
-    For more info, please have a look at:
-      https://mpi-inf.mpg.de/~mehlhorn/ftp/Mehlhorn-Thiel.pdf
-    """
-    return _pywrapcp.Solver_SortingConstraint(self, vars, sorted)
-
-
-
-def SplitVariableDomain(self, var: IntVar, val: int64_t, start_with_lower_half: bool) ‑> operations_research::Decision * -
-
-
-
- -Expand source code - -
def SplitVariableDomain(self, var: "IntVar", val: "int64_t", start_with_lower_half: "bool") -> "operations_research::Decision *":
-    return _pywrapcp.Solver_SplitVariableDomain(self, var, val, start_with_lower_half)
-
-
-
-def Stamp(self) ‑> uint64_t -
-
-

The stamp indicates how many moves in the search tree we have performed. -It is useful to detect if we need to update same lazy structures.

-
- -Expand source code - -
def Stamp(self) -> "uint64_t":
-    r"""
-    The stamp indicates how many moves in the search tree we have performed.
-    It is useful to detect if we need to update same lazy structures.
-    """
-    return _pywrapcp.Solver_Stamp(self)
-
-
-
-def StatisticsModelVisitor(self) ‑> operations_research::ModelVisitor * -
-
-

Displays some nice statistics on the model.

-
- -Expand source code - -
def StatisticsModelVisitor(self) -> "operations_research::ModelVisitor *":
-    r""" Displays some nice statistics on the model."""
-    return _pywrapcp.Solver_StatisticsModelVisitor(self)
-
-
-
-def StoreAssignment(self, assignment: Assignment) ‑> operations_research::DecisionBuilder * -
-
-

Returns a DecisionBuilder which stores an Assignment -(calls void Assignment::Store())

-
- -Expand source code - -
def StoreAssignment(self, assignment: "Assignment") -> "operations_research::DecisionBuilder *":
-    r"""
-    Returns a DecisionBuilder which stores an Assignment
-    (calls void Assignment::Store())
-    """
-    return _pywrapcp.Solver_StoreAssignment(self, assignment)
-
-
-
-def SubCircuit(self, nexts: std::vector< operations_research::IntVar * > const &) ‑> operations_research::Constraint * -
-
-

Force the "nexts" variable to create a complete Hamiltonian path -for those that do not loop upon themselves.

-
- -Expand source code - -
def SubCircuit(self, nexts: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
-    r"""
-    Force the "nexts" variable to create a complete Hamiltonian path
-    for those that do not loop upon themselves.
-    """
-    return _pywrapcp.Solver_SubCircuit(self, nexts)
-
-
-
-def Sum(self, vars: std::vector< operations_research::IntVar * > const &) ‑> operations_research::IntExpr * -
-
-

sum of all vars.

-
- -Expand source code - -
def Sum(self, vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::IntExpr *":
-    r""" sum of all vars."""
-    return _pywrapcp.Solver_Sum(self, vars)
-
-
-
-def SumEquality(self, *args) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def SumEquality(self, *args) -> "operations_research::Constraint *":
-    return _pywrapcp.Solver_SumEquality(self, *args)
-
-
-
-def SumGreaterOrEqual(self, vars: std::vector< operations_research::IntVar * > const &, cst: int64_t) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def SumGreaterOrEqual(self, vars: "std::vector< operations_research::IntVar * > const &", cst: "int64_t") -> "operations_research::Constraint *":
-    return _pywrapcp.Solver_SumGreaterOrEqual(self, vars, cst)
-
-
-
-def SumLessOrEqual(self, vars: std::vector< operations_research::IntVar * > const &, cst: int64_t) ‑> operations_research::Constraint * -
-
-

Variation on arrays.

-
- -Expand source code - -
def SumLessOrEqual(self, vars: "std::vector< operations_research::IntVar * > const &", cst: "int64_t") -> "operations_research::Constraint *":
-    r""" Variation on arrays."""
-    return _pywrapcp.Solver_SumLessOrEqual(self, vars, cst)
-
-
-
-def SumObjectiveFilter(self, vars: std::vector< operations_research::IntVar * > const &, values: operations_research::Solver::IndexEvaluator2, filter_enum: operations_research::Solver::LocalSearchFilterBound) ‑> operations_research::LocalSearchFilter * -
-
-
-
- -Expand source code - -
def SumObjectiveFilter(self, vars: "std::vector< operations_research::IntVar * > const &", values: "operations_research::Solver::IndexEvaluator2", filter_enum: "operations_research::Solver::LocalSearchFilterBound") -> "operations_research::LocalSearchFilter *":
-    return _pywrapcp.Solver_SumObjectiveFilter(self, vars, values, filter_enum)
-
-
-
-def TabuSearch(self, maximize: bool, v: IntVar, step: int64_t, vars: std::vector< operations_research::IntVar * > const &, keep_tenure: int64_t, forbid_tenure: int64_t, tabu_factor: double) ‑> operations_research::SearchMonitor * -
-
-

MetaHeuristics which try to get the search out of local optima. -Creates a Tabu Search monitor. -In the context of local search the behavior is similar to MakeOptimize(), -creating an objective in a given sense. The behavior differs once a local -optimum is reached: thereafter solutions which degrade the value of the -objective are allowed if they are not "tabu". A solution is "tabu" if it -doesn't respect the following rules: -- improving the best solution found so far -- variables in the "keep" list must keep their value, variables in the -"forbid" list must not take the value they have in the list. -Variables with new values enter the tabu lists after each new solution -found and leave the lists after a given number of iterations (called -tenure). Only the variables passed to the method can enter the lists. -The tabu criterion is softened by the tabu factor which gives the number -of "tabu" violations which is tolerated; a factor of 1 means no violations -allowed; a factor of 0 means all violations are allowed.

-
- -Expand source code - -
def TabuSearch(self, maximize: "bool", v: "IntVar", step: "int64_t", vars: "std::vector< operations_research::IntVar * > const &", keep_tenure: "int64_t", forbid_tenure: "int64_t", tabu_factor: "double") -> "operations_research::SearchMonitor *":
-    r"""
-    MetaHeuristics which try to get the search out of local optima.
-    Creates a Tabu Search monitor.
-    In the context of local search the behavior is similar to MakeOptimize(),
-    creating an objective in a given sense. The behavior differs once a local
-    optimum is reached: thereafter solutions which degrade the value of the
-    objective are allowed if they are not "tabu". A solution is "tabu" if it
-    doesn't respect the following rules:
-    - improving the best solution found so far
-    - variables in the "keep" list must keep their value, variables in the
-    "forbid" list must not take the value they have in the list.
-    Variables with new values enter the tabu lists after each new solution
-    found and leave the lists after a given number of iterations (called
-    tenure). Only the variables passed to the method can enter the lists.
-    The tabu criterion is softened by the tabu factor which gives the number
-    of "tabu" violations which is tolerated; a factor of 1 means no violations
-    allowed; a factor of 0 means all violations are allowed.
-    """
-    return _pywrapcp.Solver_TabuSearch(self, maximize, v, step, vars, keep_tenure, forbid_tenure, tabu_factor)
-
-
-
-def TemporalDisjunction(self, *args) ‑> operations_research::Constraint * -
-
-

Overload 1: -This constraint implements a temporal disjunction between two -interval vars t1 and t2. 'alt' indicates which alternative was -chosen (alt == 0 is equivalent to t1 before t2).

-

|

-

Overload 2: -This constraint implements a temporal disjunction between two -interval vars.

-
- -Expand source code - -
def TemporalDisjunction(self, *args) -> "operations_research::Constraint *":
-    r"""
-    *Overload 1:*
-    This constraint implements a temporal disjunction between two
-    interval vars t1 and t2. 'alt' indicates which alternative was
-    chosen (alt == 0 is equivalent to t1 before t2).
-
-    |
-
-    *Overload 2:*
-    This constraint implements a temporal disjunction between two
-    interval vars.
-    """
-    return _pywrapcp.Solver_TemporalDisjunction(self, *args)
-
-
-
-def TimeLimit(self, *args) ‑> operations_research::RegularLimit * -
-
-
-
- -Expand source code - -
def TimeLimit(self, *args) -> "operations_research::RegularLimit *":
-    return _pywrapcp.Solver_TimeLimit(self, *args)
-
-
-
-def TransitionConstraint(self, *args) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def TransitionConstraint(self, *args) -> "operations_research::Constraint *":
-    return _pywrapcp.Solver_TransitionConstraint(self, *args)
-
-
-
-def TreeNoCycle(self, nexts: std::vector< operations_research::IntVar * > const &, active: std::vector< operations_research::IntVar * > const &, callback: operations_research::Solver::IndexFilter1 = 0) ‑> operations_research::Constraint * -
-
-
-
- -Expand source code - -
def TreeNoCycle(self, nexts: "std::vector< operations_research::IntVar * > const &", active: "std::vector< operations_research::IntVar * > const &", callback: "operations_research::Solver::IndexFilter1"=0) -> "operations_research::Constraint *":
-    return _pywrapcp.Solver_TreeNoCycle(self, nexts, active, callback)
-
-
-
-def TrueConstraint(self) ‑> operations_research::Constraint * -
-
-

This constraint always succeeds.

-
- -Expand source code - -
def TrueConstraint(self) -> "operations_research::Constraint *":
-    r""" This constraint always succeeds."""
-    return _pywrapcp.Solver_TrueConstraint(self)
-
-
-
-def Try(self, dbs: std::vector< operations_research::DecisionBuilder * > const &) ‑> operations_research::DecisionBuilder * -
-
-
-
- -Expand source code - -
def Try(self, dbs: "std::vector< operations_research::DecisionBuilder * > const &") -> "operations_research::DecisionBuilder *":
-    return _pywrapcp.Solver_Try(self, dbs)
-
-
-
-def VarEvalValEvalPhase(self, vars: std::vector< operations_research::IntVar * > const &, var_eval: std::function< int64_t (int64_t) >, val_eval: operations_research::Solver::IndexEvaluator2) ‑> operations_research::DecisionBuilder * -
-
-
-
- -Expand source code - -
def VarEvalValEvalPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_eval: "std::function< int64_t (int64_t) >", val_eval: "operations_research::Solver::IndexEvaluator2") -> "operations_research::DecisionBuilder *":
-    return _pywrapcp.Solver_VarEvalValEvalPhase(self, vars, var_eval, val_eval)
-
-
-
-def VarEvalValEvalTieBreakPhase(self, vars: std::vector< operations_research::IntVar * > const &, var_eval: std::function< int64_t (int64_t) >, val_eval: operations_research::Solver::IndexEvaluator2, tie_breaker: std::function< int64_t (int64_t) >) ‑> operations_research::DecisionBuilder * -
-
-
-
- -Expand source code - -
def VarEvalValEvalTieBreakPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_eval: "std::function< int64_t (int64_t) >", val_eval: "operations_research::Solver::IndexEvaluator2", tie_breaker: "std::function< int64_t (int64_t) >") -> "operations_research::DecisionBuilder *":
-    return _pywrapcp.Solver_VarEvalValEvalTieBreakPhase(self, vars, var_eval, val_eval, tie_breaker)
-
-
-
-def VarEvalValStrPhase(self, vars: std::vector< operations_research::IntVar * > const &, var_evaluator: std::function< int64_t (int64_t) >, val_str: operations_research::Solver::IntValueStrategy) ‑> operations_research::DecisionBuilder * -
-
-
-
- -Expand source code - -
def VarEvalValStrPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_evaluator: "std::function< int64_t (int64_t) >", val_str: "operations_research::Solver::IntValueStrategy") -> "operations_research::DecisionBuilder *":
-    return _pywrapcp.Solver_VarEvalValStrPhase(self, vars, var_evaluator, val_str)
-
-
-
-def VarStrValEvalPhase(self, vars: std::vector< operations_research::IntVar * > const &, var_str: operations_research::Solver::IntVarStrategy, val_eval: operations_research::Solver::IndexEvaluator2) ‑> operations_research::DecisionBuilder * -
-
-
-
- -Expand source code - -
def VarStrValEvalPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_str: "operations_research::Solver::IntVarStrategy", val_eval: "operations_research::Solver::IndexEvaluator2") -> "operations_research::DecisionBuilder *":
-    return _pywrapcp.Solver_VarStrValEvalPhase(self, vars, var_str, val_eval)
-
-
-
-def VarStrValEvalTieBreakPhase(self, vars: std::vector< operations_research::IntVar * > const &, var_str: operations_research::Solver::IntVarStrategy, val_eval: operations_research::Solver::IndexEvaluator2, tie_breaker: std::function< int64_t (int64_t) >) ‑> operations_research::DecisionBuilder * -
-
-
-
- -Expand source code - -
def VarStrValEvalTieBreakPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_str: "operations_research::Solver::IntVarStrategy", val_eval: "operations_research::Solver::IndexEvaluator2", tie_breaker: "std::function< int64_t (int64_t) >") -> "operations_research::DecisionBuilder *":
-    return _pywrapcp.Solver_VarStrValEvalTieBreakPhase(self, vars, var_str, val_eval, tie_breaker)
-
-
-
-def VariableGreaterOrEqualValue(self, var: IntVar, value: int64_t) ‑> operations_research::Decision * -
-
-
-
- -Expand source code - -
def VariableGreaterOrEqualValue(self, var: "IntVar", value: "int64_t") -> "operations_research::Decision *":
-    return _pywrapcp.Solver_VariableGreaterOrEqualValue(self, var, value)
-
-
-
-def VariableLessOrEqualValue(self, var: IntVar, value: int64_t) ‑> operations_research::Decision * -
-
-
-
- -Expand source code - -
def VariableLessOrEqualValue(self, var: "IntVar", value: "int64_t") -> "operations_research::Decision *":
-    return _pywrapcp.Solver_VariableLessOrEqualValue(self, var, value)
-
-
-
-def WallTime(self) ‑> int64_t -
-
-

DEPRECATED: Use Now() instead. -Time elapsed, in ms since the creation of the solver.

-
- -Expand source code - -
def WallTime(self) -> "int64_t":
-    r"""
-    DEPRECATED: Use Now() instead.
-    Time elapsed, in ms since the creation of the solver.
-    """
-    return _pywrapcp.Solver_WallTime(self)
-
-
-
-def WeightedMaximize(self, *args) ‑> operations_research::OptimizeVar * -
-
-

Overload 1: -Creates a maximization weigthed objective.

-

|

-

Overload 2: -Creates a maximization weigthed objective.

-
- -Expand source code - -
def WeightedMaximize(self, *args) -> "operations_research::OptimizeVar *":
-    r"""
-    *Overload 1:*
-    Creates a maximization weigthed objective.
-
-    |
-
-    *Overload 2:*
-    Creates a maximization weigthed objective.
-    """
-    return _pywrapcp.Solver_WeightedMaximize(self, *args)
-
-
-
-def WeightedMinimize(self, *args) ‑> operations_research::OptimizeVar * -
-
-

Overload 1: -Creates a minimization weighted objective. The actual objective is -scalar_prod(sub_objectives, weights).

-

|

-

Overload 2: -Creates a minimization weighted objective. The actual objective is -scalar_prod(sub_objectives, weights).

-
- -Expand source code - -
def WeightedMinimize(self, *args) -> "operations_research::OptimizeVar *":
-    r"""
-    *Overload 1:*
-    Creates a minimization weighted objective. The actual objective is
-    scalar_prod(sub_objectives, weights).
-
-    |
-
-    *Overload 2:*
-    Creates a minimization weighted objective. The actual objective is
-    scalar_prod(sub_objectives, weights).
-    """
-    return _pywrapcp.Solver_WeightedMinimize(self, *args)
-
-
-
-def WeightedOptimize(self, *args) ‑> operations_research::OptimizeVar * -
-
-

Overload 1: -Creates a weighted objective with a given sense (true = maximization).

-

|

-

Overload 2: -Creates a weighted objective with a given sense (true = maximization).

-
- -Expand source code - -
def WeightedOptimize(self, *args) -> "operations_research::OptimizeVar *":
-    r"""
-    *Overload 1:*
-    Creates a weighted objective with a given sense (true = maximization).
-
-    |
-
-    *Overload 2:*
-    Creates a weighted objective with a given sense (true = maximization).
-    """
-    return _pywrapcp.Solver_WeightedOptimize(self, *args)
-
-
- - -
-class TypeIncompatibilityChecker -(model: RoutingModel, check_hard_incompatibilities: bool) -
-
-

Checker for type incompatibilities.

-
- -Expand source code - -
class TypeIncompatibilityChecker(TypeRegulationsChecker):
-    r""" Checker for type incompatibilities."""
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self, model: "RoutingModel", check_hard_incompatibilities: "bool"):
-        _pywrapcp.TypeIncompatibilityChecker_swiginit(self, _pywrapcp.new_TypeIncompatibilityChecker(model, check_hard_incompatibilities))
-    __swig_destroy__ = _pywrapcp.delete_TypeIncompatibilityChecker
-
-

Ancestors

- -

Inherited members

- -
-
-class TypeRegulationsChecker -(*args, **kwargs) -
-
-
-
- -Expand source code - -
class TypeRegulationsChecker(object):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
-    __repr__ = _swig_repr
-    __swig_destroy__ = _pywrapcp.delete_TypeRegulationsChecker
-
-    def CheckVehicle(self, vehicle: "int", next_accessor: "std::function< int64_t (int64_t) > const &") -> "bool":
-        return _pywrapcp.TypeRegulationsChecker_CheckVehicle(self, vehicle, next_accessor)
-
-

Subclasses

- -

Instance variables

-
-
var thisown
-
-

The membership flag

-
- -Expand source code - -
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-
-
-

Methods

-
-
-def CheckVehicle(self, vehicle: int, next_accessor: std::function< int64_t (int64_t) > const &) ‑> bool -
-
-
-
- -Expand source code - -
def CheckVehicle(self, vehicle: "int", next_accessor: "std::function< int64_t (int64_t) > const &") -> "bool":
-    return _pywrapcp.TypeRegulationsChecker_CheckVehicle(self, vehicle, next_accessor)
-
-
-
-
-
-class TypeRegulationsConstraint -(model: RoutingModel) -
-
-

The following constraint ensures that incompatibilities and requirements -between types are respected.

-

It verifies both "hard" and "temporal" incompatibilities. -Two nodes with hard incompatible types cannot be served by the same vehicle -at all, while with a temporal incompatibility they can't be on the same -route at the same time. -The VisitTypePolicy of a node determines how visiting it impacts the type -count on the route.

-

For example, for -- three temporally incompatible types T1 T2 and T3 -- 2 pairs of nodes a1/r1 and a2/r2 of type T1 and T2 respectively, with -- a1 and a2 of VisitTypePolicy TYPE_ADDED_TO_VEHICLE -- r1 and r2 of policy ADDED_TYPE_REMOVED_FROM_VEHICLE -- 3 nodes A, UV and AR of type T3, respectively with type policies -TYPE_ADDED_TO_VEHICLE, TYPE_ON_VEHICLE_UP_TO_VISIT and -TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED -the configurations -UV –> a1 –> r1 –> a2 –> r2, -a1 –> r1 –> a2 –> r2 –> A and -a1 –> r1 –> AR –> a2 –> r2 are acceptable, whereas the configurations -a1 –> a2 –> r1 –> …, or A –> a1 –> r1 –> …, or -a1 –> r1 –> UV –> … are not feasible.

-

It also verifies same-vehicle and temporal type requirements. -A node of type T_d with a same-vehicle requirement for type T_r needs to be -served by the same vehicle as a node of type T_r. -Temporal requirements, on the other hand, can take effect either when the -dependent type is being added to the route or when it's removed from it, -which is determined by the dependent node's VisitTypePolicy. -In the above example: -- If T3 is required on the same vehicle as T1, A, AR or UV must be on the -same vehicle as a1. -- If T2 is required when adding T1, a2 must be visited before a1, and if -r2 is also visited on the route, it must be after a1, i.e. T2 must be on -the vehicle when a1 is visited: -… –> a2 –> … –> a1 –> … –> r2 –> … -- If T3 is required when removing T1, T3 needs to be on the vehicle when -r1 is visited: -… –> A –> … –> r1 –> … -OR -… –> r1 –> … –> UV –> …

-
- -Expand source code - -
class TypeRegulationsConstraint(Constraint):
-    r"""
-    The following constraint ensures that incompatibilities and requirements
-    between types are respected.
-
-    It verifies both "hard" and "temporal" incompatibilities.
-    Two nodes with hard incompatible types cannot be served by the same vehicle
-    at all, while with a temporal incompatibility they can't be on the same
-    route at the same time.
-    The VisitTypePolicy of a node determines how visiting it impacts the type
-    count on the route.
-
-    For example, for
-    - three temporally incompatible types T1 T2 and T3
-    - 2 pairs of nodes a1/r1 and a2/r2 of type T1 and T2 respectively, with
-        - a1 and a2 of VisitTypePolicy TYPE_ADDED_TO_VEHICLE
-        - r1 and r2 of policy ADDED_TYPE_REMOVED_FROM_VEHICLE
-    - 3 nodes A, UV and AR of type T3, respectively with type policies
-      TYPE_ADDED_TO_VEHICLE, TYPE_ON_VEHICLE_UP_TO_VISIT and
-      TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED
-    the configurations
-    UV --> a1 --> r1 --> a2 --> r2,   a1 --> r1 --> a2 --> r2 --> A and
-    a1 --> r1 --> AR --> a2 --> r2 are acceptable, whereas the configurations
-    a1 --> a2 --> r1 --> ..., or A --> a1 --> r1 --> ..., or
-    a1 --> r1 --> UV --> ... are not feasible.
-
-    It also verifies same-vehicle and temporal type requirements.
-    A node of type T_d with a same-vehicle requirement for type T_r needs to be
-    served by the same vehicle as a node of type T_r.
-    Temporal requirements, on the other hand, can take effect either when the
-    dependent type is being added to the route or when it's removed from it,
-    which is determined by the dependent node's VisitTypePolicy.
-    In the above example:
-    - If T3 is required on the same vehicle as T1, A, AR or UV must be on the
-      same vehicle as a1.
-    - If T2 is required when adding T1, a2 must be visited *before* a1, and if
-      r2 is also visited on the route, it must be *after* a1, i.e. T2 must be on
-      the vehicle when a1 is visited:
-      ... --> a2 --> ... --> a1 --> ... --> r2 --> ...
-    - If T3 is required when removing T1, T3 needs to be on the vehicle when
-      r1 is visited:
-      ... --> A --> ... --> r1 --> ...   OR   ... --> r1 --> ... --> UV --> ...
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self, model: "RoutingModel"):
-        _pywrapcp.TypeRegulationsConstraint_swiginit(self, _pywrapcp.new_TypeRegulationsConstraint(model))
-
-    def Post(self) -> "void":
-        return _pywrapcp.TypeRegulationsConstraint_Post(self)
-
-    def InitialPropagateWrapper(self) -> "void":
-        return _pywrapcp.TypeRegulationsConstraint_InitialPropagateWrapper(self)
-    __swig_destroy__ = _pywrapcp.delete_TypeRegulationsConstraint
-
-

Ancestors

- -

Inherited members

- -
-
-class TypeRequirementChecker -(model: RoutingModel) -
-
-

Checker for type requirements.

-
- -Expand source code - -
class TypeRequirementChecker(TypeRegulationsChecker):
-    r""" Checker for type requirements."""
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self, model: "RoutingModel"):
-        _pywrapcp.TypeRequirementChecker_swiginit(self, _pywrapcp.new_TypeRequirementChecker(model))
-    __swig_destroy__ = _pywrapcp.delete_TypeRequirementChecker
-
-

Ancestors

- -

Inherited members

- -
- -
-
- -
- + + + +
+
#   + + + def + IsMemberCt(self, *args) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def IsMemberCt(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_IsMemberCt(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + IsMemberVar(self, *args) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def IsMemberVar(self, *args) -> "operations_research::IntVar *":
+        return _pywrapcp.Solver_IsMemberVar(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + Count(self, *args) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def Count(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        |{i | vars[i] == value}| == max_count
+
+        |
+
+        *Overload 2:*
+        |{i | vars[i] == value}| == max_count
+        """
+        return _pywrapcp.Solver_Count(self, *args)
+
+ +
+ +

Overload 1: +|{i | vars[i] == value}| == max_count

+ +

|

+ +

Overload 2: +|{i | vars[i] == value}| == max_count

+
+ + +
+
+
#   + + + def + Distribute(self, *args) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def Distribute(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        Aggregated version of count:  |{i | v[i] == values[j]}| == cards[j]
+
+        |
+
+        *Overload 2:*
+        Aggregated version of count:  |{i | v[i] == values[j]}| == cards[j]
+
+        |
+
+        *Overload 3:*
+        Aggregated version of count:  |{i | v[i] == j}| == cards[j]
+
+        |
+
+        *Overload 4:*
+        Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1: card_min <= |{i | v[i] == j}| <= card_max
+
+        |
+
+        *Overload 5:*
+        Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1:    card_min[j] <= |{i | v[i] == j}| <= card_max[j]
+
+        |
+
+        *Overload 6:*
+        Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1:    card_min[j] <= |{i | v[i] == j}| <= card_max[j]
+
+        |
+
+        *Overload 7:*
+        Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1:    card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j]
+
+        |
+
+        *Overload 8:*
+        Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1:    card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j]
+        """
+        return _pywrapcp.Solver_Distribute(self, *args)
+
+ +
+ +

Overload 1: +Aggregated version of count: |{i | v[i] == values[j]}| == cards[j]

+ +

|

+ +

Overload 2: +Aggregated version of count: |{i | v[i] == values[j]}| == cards[j]

+ +

|

+ +

Overload 3: +Aggregated version of count: |{i | v[i] == j}| == cards[j]

+ +

|

+ +

Overload 4: +Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1: card_min <= |{i | v[i] == j}| <= card_max

+ +

|

+ +

Overload 5: +Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1: card_min[j] <= |{i | v[i] == j}| <= card_max[j]

+ +

|

+ +

Overload 6: +Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1: card_min[j] <= |{i | v[i] == j}| <= card_max[j]

+ +

|

+ +

Overload 7: +Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1: card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j]

+ +

|

+ +

Overload 8: +Aggregated version of count with bounded cardinalities: forall j in 0 .. card_size - 1: card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j]

+
+ + +
+
+
#   + + + def + Deviation( + self, + vars: 'std::vector< operations_research::IntVar * > const &', + deviation_var: pywrapcp.IntVar, + total_sum: 'int64_t' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def Deviation(self, vars: "std::vector< operations_research::IntVar * > const &", deviation_var: "IntVar", total_sum: "int64_t") -> "operations_research::Constraint *":
+        r""" Deviation constraint: sum_i |n * vars[i] - total_sum| <= deviation_var and sum_i vars[i] == total_sum n = #vars"""
+        return _pywrapcp.Solver_Deviation(self, vars, deviation_var, total_sum)
+
+ +
+ +

Deviation constraint: sum_i |n * vars[i] - total_sum| <= deviation_var and sum_i vars[i] == total_sum n = #vars

+
+ + +
+
+
#   + + + def + AllDifferent(self, *args) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def AllDifferent(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        All variables are pairwise different. This corresponds to the stronger version of the propagation algorithm.
+
+        |
+
+        *Overload 2:*
+        All variables are pairwise different.  If 'stronger_propagation' is true, stronger, and potentially slower propagation will occur. This API will be deprecated in the future.
+        """
+        return _pywrapcp.Solver_AllDifferent(self, *args)
+
+ +
+ +

Overload 1: +All variables are pairwise different. This corresponds to the stronger version of the propagation algorithm.

+ +

|

+ +

Overload 2: +All variables are pairwise different. If 'stronger_propagation' is true, stronger, and potentially slower propagation will occur. This API will be deprecated in the future.

+
+ + +
+
+
#   + + + def + AllDifferentExcept( + self, + vars: 'std::vector< operations_research::IntVar * > const &', + escape_value: 'int64_t' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def AllDifferentExcept(self, vars: "std::vector< operations_research::IntVar * > const &", escape_value: "int64_t") -> "operations_research::Constraint *":
+        r""" All variables are pairwise different, unless they are assigned to the escape value."""
+        return _pywrapcp.Solver_AllDifferentExcept(self, vars, escape_value)
+
+ +
+ +

All variables are pairwise different, unless they are assigned to the escape value.

+
+ + +
+
+
#   + + + def + SortingConstraint( + self, + vars: 'std::vector< operations_research::IntVar * > const &', + sorted: 'std::vector< operations_research::IntVar * > const &' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def SortingConstraint(self, vars: "std::vector< operations_research::IntVar * > const &", sorted: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Creates a constraint binding the arrays of variables "vars" and "sorted_vars": sorted_vars[0] must be equal to the minimum of all variables in vars, and so on: the value of sorted_vars[i] must be equal to the i-th value of variables invars. This constraint propagates in both directions: from "vars" to "sorted_vars" and vice-versa. Behind the scenes, this constraint maintains that:   - sorted is always increasing.   - whatever the values of vars, there exists a permutation that     injects its values into the sorted variables. For more info, please have a look at:   https://mpi-inf.mpg.de/~mehlhorn/ftp/Mehlhorn-Thiel.pdf"""
+        return _pywrapcp.Solver_SortingConstraint(self, vars, sorted)
+
+ +
+ +

Creates a constraint binding the arrays of variables "vars" and "sorted_vars": sorted_vars[0] must be equal to the minimum of all variables in vars, and so on: the value of sorted_vars[i] must be equal to the i-th value of variables invars. This constraint propagates in both directions: from "vars" to "sorted_vars" and vice-versa. Behind the scenes, this constraint maintains that: - sorted is always increasing. - whatever the values of vars, there exists a permutation that injects its values into the sorted variables. For more info, please have a look at: https://mpi-inf.mpg.de/~mehlhorn/ftp/Mehlhorn-Thiel.pdf

+
+ + +
+
+
#   + + + def + LexicalLess( + self, + left: 'std::vector< operations_research::IntVar * > const &', + right: 'std::vector< operations_research::IntVar * > const &' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def LexicalLess(self, left: "std::vector< operations_research::IntVar * > const &", right: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Creates a constraint that enforces that left is lexicographically less than right."""
+        return _pywrapcp.Solver_LexicalLess(self, left, right)
+
+ +
+ +

Creates a constraint that enforces that left is lexicographically less than right.

+
+ + +
+
+
#   + + + def + LexicalLessOrEqual( + self, + left: 'std::vector< operations_research::IntVar * > const &', + right: 'std::vector< operations_research::IntVar * > const &' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def LexicalLessOrEqual(self, left: "std::vector< operations_research::IntVar * > const &", right: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Creates a constraint that enforces that left is lexicographically less than or equal to right."""
+        return _pywrapcp.Solver_LexicalLessOrEqual(self, left, right)
+
+ +
+ +

Creates a constraint that enforces that left is lexicographically less than or equal to right.

+
+ + +
+
+
#   + + + def + InversePermutationConstraint( + self, + left: 'std::vector< operations_research::IntVar * > const &', + right: 'std::vector< operations_research::IntVar * > const &' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def InversePermutationConstraint(self, left: "std::vector< operations_research::IntVar * > const &", right: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Creates a constraint that enforces that 'left' and 'right' both represent permutations of [0..left.size()-1], and that 'right' is the inverse permutation of 'left', i.e. for all i in [0..left.size()-1], right[left[i]] = i."""
+        return _pywrapcp.Solver_InversePermutationConstraint(self, left, right)
+
+ +
+ +

Creates a constraint that enforces that 'left' and 'right' both represent permutations of [0..left.size()-1], and that 'right' is the inverse permutation of 'left', i.e. for all i in [0..left.size()-1], right[left[i]] = i.

+
+ + +
+
+
#   + + + def + NullIntersect( + self, + first_vars: 'std::vector< operations_research::IntVar * > const &', + second_vars: 'std::vector< operations_research::IntVar * > const &' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def NullIntersect(self, first_vars: "std::vector< operations_research::IntVar * > const &", second_vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Creates a constraint that states that all variables in the first vector are different from all variables in the second group. Thus the set of values in the first vector does not intersect with the set of values in the second vector."""
+        return _pywrapcp.Solver_NullIntersect(self, first_vars, second_vars)
+
+ +
+ +

Creates a constraint that states that all variables in the first vector are different from all variables in the second group. Thus the set of values in the first vector does not intersect with the set of values in the second vector.

+
+ + +
+
+
#   + + + def + NullIntersectExcept( + self, + first_vars: 'std::vector< operations_research::IntVar * > const &', + second_vars: 'std::vector< operations_research::IntVar * > const &', + escape_value: 'int64_t' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def NullIntersectExcept(self, first_vars: "std::vector< operations_research::IntVar * > const &", second_vars: "std::vector< operations_research::IntVar * > const &", escape_value: "int64_t") -> "operations_research::Constraint *":
+        r""" Creates a constraint that states that all variables in the first vector are different from all variables from the second group, unless they are assigned to the escape value. Thus the set of values in the first vector minus the escape value does not intersect with the set of values in the second vector."""
+        return _pywrapcp.Solver_NullIntersectExcept(self, first_vars, second_vars, escape_value)
+
+ +
+ +

Creates a constraint that states that all variables in the first vector are different from all variables from the second group, unless they are assigned to the escape value. Thus the set of values in the first vector minus the escape value does not intersect with the set of values in the second vector.

+
+ + +
+
+
#   + + + def + Circuit( + self, + nexts: 'std::vector< operations_research::IntVar * > const &' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def Circuit(self, nexts: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Force the "nexts" variable to create a complete Hamiltonian path."""
+        return _pywrapcp.Solver_Circuit(self, nexts)
+
+ +
+ +

Force the "nexts" variable to create a complete Hamiltonian path.

+
+ + +
+
+
#   + + + def + SubCircuit( + self, + nexts: 'std::vector< operations_research::IntVar * > const &' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def SubCircuit(self, nexts: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Force the "nexts" variable to create a complete Hamiltonian path for those that do not loop upon themselves."""
+        return _pywrapcp.Solver_SubCircuit(self, nexts)
+
+ +
+ +

Force the "nexts" variable to create a complete Hamiltonian path for those that do not loop upon themselves.

+
+ + +
+
+
#   + + + def + DelayedPathCumul( + self, + nexts: 'std::vector< operations_research::IntVar * > const &', + active: 'std::vector< operations_research::IntVar * > const &', + cumuls: 'std::vector< operations_research::IntVar * > const &', + transits: 'std::vector< operations_research::IntVar * > const &' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def DelayedPathCumul(self, nexts: "std::vector< operations_research::IntVar * > const &", active: "std::vector< operations_research::IntVar * > const &", cumuls: "std::vector< operations_research::IntVar * > const &", transits: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        r""" Delayed version of the same constraint: propagation on the nexts variables is delayed until all constraints have propagated."""
+        return _pywrapcp.Solver_DelayedPathCumul(self, nexts, active, cumuls, transits)
+
+ +
+ +

Delayed version of the same constraint: propagation on the nexts variables is delayed until all constraints have propagated.

+
+ + +
+
+
#   + + + def + PathCumul(self, *args) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def PathCumul(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        Creates a constraint which accumulates values along a path such that: cumuls[next[i]] = cumuls[i] + transits[i]. Active variables indicate if the corresponding next variable is active; this could be useful to model unperformed nodes in a routing problem.
+
+        |
+
+        *Overload 2:*
+        Creates a constraint which accumulates values along a path such that: cumuls[next[i]] = cumuls[i] + transit_evaluator(i, next[i]). Active variables indicate if the corresponding next variable is active; this could be useful to model unperformed nodes in a routing problem. Ownership of transit_evaluator is taken and it must be a repeatable callback.
+
+        |
+
+        *Overload 3:*
+        Creates a constraint which accumulates values along a path such that: cumuls[next[i]] = cumuls[i] + transit_evaluator(i, next[i]) + slacks[i]. Active variables indicate if the corresponding next variable is active; this could be useful to model unperformed nodes in a routing problem. Ownership of transit_evaluator is taken and it must be a repeatable callback.
+        """
+        return _pywrapcp.Solver_PathCumul(self, *args)
+
+ +
+ +

Overload 1: +Creates a constraint which accumulates values along a path such that: cumuls[next[i]] = cumuls[i] + transits[i]. Active variables indicate if the corresponding next variable is active; this could be useful to model unperformed nodes in a routing problem.

+ +

|

+ +

Overload 2: +Creates a constraint which accumulates values along a path such that: cumuls[next[i]] = cumuls[i] + transit_evaluator(i, next[i]). Active variables indicate if the corresponding next variable is active; this could be useful to model unperformed nodes in a routing problem. Ownership of transit_evaluator is taken and it must be a repeatable callback.

+ +

|

+ +

Overload 3: +Creates a constraint which accumulates values along a path such that: cumuls[next[i]] = cumuls[i] + transit_evaluator(i, next[i]) + slacks[i]. Active variables indicate if the corresponding next variable is active; this could be useful to model unperformed nodes in a routing problem. Ownership of transit_evaluator is taken and it must be a repeatable callback.

+
+ + +
+
+
#   + + + def + AllowedAssignments(self, *args) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def AllowedAssignments(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        This method creates a constraint where the graph of the relation between the variables is given in extension. There are 'arity' variables involved in the relation and the graph is given by a integer tuple set.
+
+        |
+
+        *Overload 2:*
+        Compatibility layer for Python API.
+        """
+        return _pywrapcp.Solver_AllowedAssignments(self, *args)
+
+ +
+ +

Overload 1: +This method creates a constraint where the graph of the relation between the variables is given in extension. There are 'arity' variables involved in the relation and the graph is given by a integer tuple set.

+ +

|

+ +

Overload 2: +Compatibility layer for Python API.

+
+ + +
+
+
#   + + + def + TransitionConstraint(self, *args) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def TransitionConstraint(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_TransitionConstraint(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + NonOverlappingBoxesConstraint(self, *args) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def NonOverlappingBoxesConstraint(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_NonOverlappingBoxesConstraint(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + Pack( + self, + vars: 'std::vector< operations_research::IntVar * > const &', + number_of_bins: int +) -> 'operations_research::Pack *': +
+ +
+ View Source +
    def Pack(self, vars: "std::vector< operations_research::IntVar * > const &", number_of_bins: "int") -> "operations_research::Pack *":
+        r""" This constraint packs all variables onto 'number_of_bins' variables.  For any given variable, a value of 'number_of_bins' indicates that the variable is not assigned to any bin. Dimensions, i.e., cumulative constraints on this packing, can be added directly from the pack class."""
+        return _pywrapcp.Solver_Pack(self, vars, number_of_bins)
+
+ +
+ +

This constraint packs all variables onto 'number_of_bins' variables. For any given variable, a value of 'number_of_bins' indicates that the variable is not assigned to any bin. Dimensions, i.e., cumulative constraints on this packing, can be added directly from the pack class.

+
+ + +
+
+
#   + + + def + FixedDurationIntervalVar(self, *args) -> 'operations_research::IntervalVar *': +
+ +
+ View Source +
    def FixedDurationIntervalVar(self, *args) -> "operations_research::IntervalVar *":
+        r"""
+        *Overload 1:*
+        Creates an interval var with a fixed duration. The duration must be greater than 0. If optional is true, then the interval can be performed or unperformed. If optional is false, then the interval is always performed.
+
+        |
+
+        *Overload 2:*
+        Creates a performed interval var with a fixed duration. The duration must be greater than 0.
+
+        |
+
+        *Overload 3:*
+        Creates an interval var with a fixed duration, and performed_variable. The duration must be greater than 0.
+        """
+        return _pywrapcp.Solver_FixedDurationIntervalVar(self, *args)
+
+ +
+ +

Overload 1: +Creates an interval var with a fixed duration. The duration must be greater than 0. If optional is true, then the interval can be performed or unperformed. If optional is false, then the interval is always performed.

+ +

|

+ +

Overload 2: +Creates a performed interval var with a fixed duration. The duration must be greater than 0.

+ +

|

+ +

Overload 3: +Creates an interval var with a fixed duration, and performed_variable. The duration must be greater than 0.

+
+ + +
+
+
#   + + + def + FixedInterval( + self, + start: 'int64_t', + duration: 'int64_t', + name: 'std::string const &' +) -> 'operations_research::IntervalVar *': +
+ +
+ View Source +
    def FixedInterval(self, start: "int64_t", duration: "int64_t", name: "std::string const &") -> "operations_research::IntervalVar *":
+        r""" Creates a fixed and performed interval."""
+        return _pywrapcp.Solver_FixedInterval(self, start, duration, name)
+
+ +
+ +

Creates a fixed and performed interval.

+
+ + +
+
+
#   + + + def + IntervalVar( + self, + start_min: 'int64_t', + start_max: 'int64_t', + duration_min: 'int64_t', + duration_max: 'int64_t', + end_min: 'int64_t', + end_max: 'int64_t', + optional: bool, + name: 'std::string const &' +) -> 'operations_research::IntervalVar *': +
+ +
+ View Source +
    def IntervalVar(self, start_min: "int64_t", start_max: "int64_t", duration_min: "int64_t", duration_max: "int64_t", end_min: "int64_t", end_max: "int64_t", optional: "bool", name: "std::string const &") -> "operations_research::IntervalVar *":
+        r""" Creates an interval var by specifying the bounds on start, duration, and end."""
+        return _pywrapcp.Solver_IntervalVar(self, start_min, start_max, duration_min, duration_max, end_min, end_max, optional, name)
+
+ +
+ +

Creates an interval var by specifying the bounds on start, duration, and end.

+
+ + +
+
+
#   + + + def + MirrorInterval( + self, + interval_var: pywrapcp.IntervalVar +) -> 'operations_research::IntervalVar *': +
+ +
+ View Source +
    def MirrorInterval(self, interval_var: "IntervalVar") -> "operations_research::IntervalVar *":
+        r""" Creates an interval var that is the mirror image of the given one, that is, the interval var obtained by reversing the axis."""
+        return _pywrapcp.Solver_MirrorInterval(self, interval_var)
+
+ +
+ +

Creates an interval var that is the mirror image of the given one, that is, the interval var obtained by reversing the axis.

+
+ + +
+
+
#   + + + def + FixedDurationStartSyncedOnStartIntervalVar( + self, + interval_var: pywrapcp.IntervalVar, + duration: 'int64_t', + offset: 'int64_t' +) -> 'operations_research::IntervalVar *': +
+ +
+ View Source +
    def FixedDurationStartSyncedOnStartIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
+        r""" Creates an interval var with a fixed duration whose start is synchronized with the start of another interval, with a given offset. The performed status is also in sync with the performed status of the given interval variable."""
+        return _pywrapcp.Solver_FixedDurationStartSyncedOnStartIntervalVar(self, interval_var, duration, offset)
+
+ +
+ +

Creates an interval var with a fixed duration whose start is synchronized with the start of another interval, with a given offset. The performed status is also in sync with the performed status of the given interval variable.

+
+ + +
+
+
#   + + + def + FixedDurationStartSyncedOnEndIntervalVar( + self, + interval_var: pywrapcp.IntervalVar, + duration: 'int64_t', + offset: 'int64_t' +) -> 'operations_research::IntervalVar *': +
+ +
+ View Source +
    def FixedDurationStartSyncedOnEndIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
+        r""" Creates an interval var with a fixed duration whose start is synchronized with the end of another interval, with a given offset. The performed status is also in sync with the performed status of the given interval variable."""
+        return _pywrapcp.Solver_FixedDurationStartSyncedOnEndIntervalVar(self, interval_var, duration, offset)
+
+ +
+ +

Creates an interval var with a fixed duration whose start is synchronized with the end of another interval, with a given offset. The performed status is also in sync with the performed status of the given interval variable.

+
+ + +
+
+
#   + + + def + FixedDurationEndSyncedOnStartIntervalVar( + self, + interval_var: pywrapcp.IntervalVar, + duration: 'int64_t', + offset: 'int64_t' +) -> 'operations_research::IntervalVar *': +
+ +
+ View Source +
    def FixedDurationEndSyncedOnStartIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
+        r""" Creates an interval var with a fixed duration whose end is synchronized with the start of another interval, with a given offset. The performed status is also in sync with the performed status of the given interval variable."""
+        return _pywrapcp.Solver_FixedDurationEndSyncedOnStartIntervalVar(self, interval_var, duration, offset)
+
+ +
+ +

Creates an interval var with a fixed duration whose end is synchronized with the start of another interval, with a given offset. The performed status is also in sync with the performed status of the given interval variable.

+
+ + +
+
+
#   + + + def + FixedDurationEndSyncedOnEndIntervalVar( + self, + interval_var: pywrapcp.IntervalVar, + duration: 'int64_t', + offset: 'int64_t' +) -> 'operations_research::IntervalVar *': +
+ +
+ View Source +
    def FixedDurationEndSyncedOnEndIntervalVar(self, interval_var: "IntervalVar", duration: "int64_t", offset: "int64_t") -> "operations_research::IntervalVar *":
+        r""" Creates an interval var with a fixed duration whose end is synchronized with the end of another interval, with a given offset. The performed status is also in sync with the performed status of the given interval variable."""
+        return _pywrapcp.Solver_FixedDurationEndSyncedOnEndIntervalVar(self, interval_var, duration, offset)
+
+ +
+ +

Creates an interval var with a fixed duration whose end is synchronized with the end of another interval, with a given offset. The performed status is also in sync with the performed status of the given interval variable.

+
+ + +
+
+
#   + + + def + IntervalRelaxedMin( + self, + interval_var: pywrapcp.IntervalVar +) -> 'operations_research::IntervalVar *': +
+ +
+ View Source +
    def IntervalRelaxedMin(self, interval_var: "IntervalVar") -> "operations_research::IntervalVar *":
+        r""" Creates and returns an interval variable that wraps around the given one, relaxing the min start and end. Relaxing means making unbounded when optional. If the variable is non-optional, this method returns interval_var. More precisely, such an interval variable behaves as follows: * When the underlying must be performed, the returned interval variable     behaves exactly as the underlying; * When the underlying may or may not be performed, the returned interval     variable behaves like the underlying, except that it is unbounded on     the min side; * When the underlying cannot be performed, the returned interval variable     is of duration 0 and must be performed in an interval unbounded on     both sides. This is very useful to implement propagators that may only modify the start max or end max."""
+        return _pywrapcp.Solver_IntervalRelaxedMin(self, interval_var)
+
+ +
+ +

Creates and returns an interval variable that wraps around the given one, relaxing the min start and end. Relaxing means making unbounded when optional. If the variable is non-optional, this method returns interval_var. More precisely, such an interval variable behaves as follows: * When the underlying must be performed, the returned interval variable behaves exactly as the underlying; * When the underlying may or may not be performed, the returned interval variable behaves like the underlying, except that it is unbounded on the min side; * When the underlying cannot be performed, the returned interval variable is of duration 0 and must be performed in an interval unbounded on both sides. This is very useful to implement propagators that may only modify the start max or end max.

+
+ + +
+
+
#   + + + def + IntervalRelaxedMax( + self, + interval_var: pywrapcp.IntervalVar +) -> 'operations_research::IntervalVar *': +
+ +
+ View Source +
    def IntervalRelaxedMax(self, interval_var: "IntervalVar") -> "operations_research::IntervalVar *":
+        r""" Creates and returns an interval variable that wraps around the given one, relaxing the max start and end. Relaxing means making unbounded when optional. If the variable is non optional, this method returns interval_var. More precisely, such an interval variable behaves as follows: * When the underlying must be performed, the returned interval variable     behaves exactly as the underlying; * When the underlying may or may not be performed, the returned interval     variable behaves like the underlying, except that it is unbounded on     the max side; * When the underlying cannot be performed, the returned interval variable     is of duration 0 and must be performed in an interval unbounded on     both sides. This is very useful for implementing propagators that may only modify the start min or end min."""
+        return _pywrapcp.Solver_IntervalRelaxedMax(self, interval_var)
+
+ +
+ +

Creates and returns an interval variable that wraps around the given one, relaxing the max start and end. Relaxing means making unbounded when optional. If the variable is non optional, this method returns interval_var. More precisely, such an interval variable behaves as follows: * When the underlying must be performed, the returned interval variable behaves exactly as the underlying; * When the underlying may or may not be performed, the returned interval variable behaves like the underlying, except that it is unbounded on the max side; * When the underlying cannot be performed, the returned interval variable is of duration 0 and must be performed in an interval unbounded on both sides. This is very useful for implementing propagators that may only modify the start min or end min.

+
+ + +
+
+
#   + + + def + TemporalDisjunction(self, *args) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def TemporalDisjunction(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        This constraint implements a temporal disjunction between two interval vars t1 and t2. 'alt' indicates which alternative was chosen (alt == 0 is equivalent to t1 before t2).
+
+        |
+
+        *Overload 2:*
+        This constraint implements a temporal disjunction between two interval vars.
+        """
+        return _pywrapcp.Solver_TemporalDisjunction(self, *args)
+
+ +
+ +

Overload 1: +This constraint implements a temporal disjunction between two interval vars t1 and t2. 'alt' indicates which alternative was chosen (alt == 0 is equivalent to t1 before t2).

+ +

|

+ +

Overload 2: +This constraint implements a temporal disjunction between two interval vars.

+
+ + +
+
+
#   + + + def + DisjunctiveConstraint( + self, + intervals: 'std::vector< operations_research::IntervalVar * > const &', + name: 'std::string const &' +) -> 'operations_research::DisjunctiveConstraint *': +
+ +
+ View Source +
    def DisjunctiveConstraint(self, intervals: "std::vector< operations_research::IntervalVar * > const &", name: "std::string const &") -> "operations_research::DisjunctiveConstraint *":
+        r""" This constraint forces all interval vars into an non-overlapping sequence. Intervals with zero duration can be scheduled anywhere."""
+        return _pywrapcp.Solver_DisjunctiveConstraint(self, intervals, name)
+
+ +
+ +

This constraint forces all interval vars into an non-overlapping sequence. Intervals with zero duration can be scheduled anywhere.

+
+ + +
+
+
#   + + + def + Cumulative(self, *args) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def Cumulative(self, *args) -> "operations_research::Constraint *":
+        r"""
+        *Overload 1:*
+        This constraint forces that, for any integer t, the sum of the demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should only contain non-negative values. Zero values are supported, and the corresponding intervals are filtered out, as they neither impact nor are impacted by this constraint.
+
+        |
+
+        *Overload 2:*
+        This constraint forces that, for any integer t, the sum of the demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should only contain non-negative values. Zero values are supported, and the corresponding intervals are filtered out, as they neither impact nor are impacted by this constraint.
+
+        |
+
+        *Overload 3:*
+        This constraint forces that, for any integer t, the sum of the demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should only contain non-negative values. Zero values are supported, and the corresponding intervals are filtered out, as they neither impact nor are impacted by this constraint.
+
+        |
+
+        *Overload 4:*
+        This constraint enforces that, for any integer t, the sum of the demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should only contain non-negative values. Zero values are supported, and the corresponding intervals are filtered out, as they neither impact nor are impacted by this constraint.
+
+        |
+
+        *Overload 5:*
+        This constraint enforces that, for any integer t, the sum of demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should be positive.
+
+        |
+
+        *Overload 6:*
+        This constraint enforces that, for any integer t, the sum of demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should be positive.
+        """
+        return _pywrapcp.Solver_Cumulative(self, *args)
+
+ +
+ +

Overload 1: +This constraint forces that, for any integer t, the sum of the demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should only contain non-negative values. Zero values are supported, and the corresponding intervals are filtered out, as they neither impact nor are impacted by this constraint.

+ +

|

+ +

Overload 2: +This constraint forces that, for any integer t, the sum of the demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should only contain non-negative values. Zero values are supported, and the corresponding intervals are filtered out, as they neither impact nor are impacted by this constraint.

+ +

|

+ +

Overload 3: +This constraint forces that, for any integer t, the sum of the demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should only contain non-negative values. Zero values are supported, and the corresponding intervals are filtered out, as they neither impact nor are impacted by this constraint.

+ +

|

+ +

Overload 4: +This constraint enforces that, for any integer t, the sum of the demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should only contain non-negative values. Zero values are supported, and the corresponding intervals are filtered out, as they neither impact nor are impacted by this constraint.

+ +

|

+ +

Overload 5: +This constraint enforces that, for any integer t, the sum of demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should be positive.

+ +

|

+ +

Overload 6: +This constraint enforces that, for any integer t, the sum of demands corresponding to an interval containing t does not exceed the given capacity. Intervals and demands should be vectors of equal size. Demands should be positive.

+
+ + +
+
+
#   + + + def + Cover( + self, + vars: 'std::vector< operations_research::IntervalVar * > const &', + target_var: pywrapcp.IntervalVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def Cover(self, vars: "std::vector< operations_research::IntervalVar * > const &", target_var: "IntervalVar") -> "operations_research::Constraint *":
+        r""" This constraint states that the target_var is the convex hull of the intervals. If none of the interval variables is performed, then the target var is unperformed too. Also, if the target variable is unperformed, then all the intervals variables are unperformed too."""
+        return _pywrapcp.Solver_Cover(self, vars, target_var)
+
+ +
+ +

This constraint states that the target_var is the convex hull of the intervals. If none of the interval variables is performed, then the target var is unperformed too. Also, if the target variable is unperformed, then all the intervals variables are unperformed too.

+
+ + +
+
+
#   + + + def + Assignment(self, *args) -> 'operations_research::Assignment *': +
+ +
+ View Source +
    def Assignment(self, *args) -> "operations_research::Assignment *":
+        r"""
+        *Overload 1:*
+        This method creates an empty assignment.
+
+        |
+
+        *Overload 2:*
+        This method creates an assignment which is a copy of 'a'.
+        """
+        return _pywrapcp.Solver_Assignment(self, *args)
+
+ +
+ +

Overload 1: +This method creates an empty assignment.

+ +

|

+ +

Overload 2: +This method creates an assignment which is a copy of 'a'.

+
+ + +
+
+
#   + + + def + FirstSolutionCollector(self, *args) -> 'operations_research::SolutionCollector *': +
+ +
+ View Source +
    def FirstSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
+        r"""
+        *Overload 1:*
+        Collect the first solution of the search.
+
+        |
+
+        *Overload 2:*
+        Collect the first solution of the search. The variables will need to be added later.
+        """
+        return _pywrapcp.Solver_FirstSolutionCollector(self, *args)
+
+ +
+ +

Overload 1: +Collect the first solution of the search.

+ +

|

+ +

Overload 2: +Collect the first solution of the search. The variables will need to be added later.

+
+ + +
+
+
#   + + + def + LastSolutionCollector(self, *args) -> 'operations_research::SolutionCollector *': +
+ +
+ View Source +
    def LastSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
+        r"""
+        *Overload 1:*
+        Collect the last solution of the search.
+
+        |
+
+        *Overload 2:*
+        Collect the last solution of the search. The variables will need to be added later.
+        """
+        return _pywrapcp.Solver_LastSolutionCollector(self, *args)
+
+ +
+ +

Overload 1: +Collect the last solution of the search.

+ +

|

+ +

Overload 2: +Collect the last solution of the search. The variables will need to be added later.

+
+ + +
+
+
#   + + + def + BestValueSolutionCollector(self, *args) -> 'operations_research::SolutionCollector *': +
+ +
+ View Source +
    def BestValueSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
+        r"""
+        *Overload 1:*
+        Collect the solution corresponding to the optimal value of the objective of 'assignment'; if 'assignment' does not have an objective no solution is collected. This collector only collects one solution corresponding to the best objective value (the first one found).
+
+        |
+
+        *Overload 2:*
+        Collect the solution corresponding to the optimal value of the objective of 'assignment'; if 'assignment' does not have an objective no solution is collected. This collector only collects one solution corresponding to the best objective value (the first one found). The variables will need to be added later.
+        """
+        return _pywrapcp.Solver_BestValueSolutionCollector(self, *args)
+
+ +
+ +

Overload 1: +Collect the solution corresponding to the optimal value of the objective of 'assignment'; if 'assignment' does not have an objective no solution is collected. This collector only collects one solution corresponding to the best objective value (the first one found).

+ +

|

+ +

Overload 2: +Collect the solution corresponding to the optimal value of the objective of 'assignment'; if 'assignment' does not have an objective no solution is collected. This collector only collects one solution corresponding to the best objective value (the first one found). The variables will need to be added later.

+
+ + +
+
+
#   + + + def + AllSolutionCollector(self, *args) -> 'operations_research::SolutionCollector *': +
+ +
+ View Source +
    def AllSolutionCollector(self, *args) -> "operations_research::SolutionCollector *":
+        r"""
+        *Overload 1:*
+        Collect all solutions of the search.
+
+        |
+
+        *Overload 2:*
+        Collect all solutions of the search. The variables will need to be added later.
+        """
+        return _pywrapcp.Solver_AllSolutionCollector(self, *args)
+
+ +
+ +

Overload 1: +Collect all solutions of the search.

+ +

|

+ +

Overload 2: +Collect all solutions of the search. The variables will need to be added later.

+
+ + +
+
+
#   + + + def + Minimize( + self, + v: pywrapcp.IntVar, + step: 'int64_t' +) -> 'operations_research::OptimizeVar *': +
+ +
+ View Source +
    def Minimize(self, v: "IntVar", step: "int64_t") -> "operations_research::OptimizeVar *":
+        r""" Creates a minimization objective."""
+        return _pywrapcp.Solver_Minimize(self, v, step)
+
+ +
+ +

Creates a minimization objective.

+
+ + +
+
+
#   + + + def + Maximize( + self, + v: pywrapcp.IntVar, + step: 'int64_t' +) -> 'operations_research::OptimizeVar *': +
+ +
+ View Source +
    def Maximize(self, v: "IntVar", step: "int64_t") -> "operations_research::OptimizeVar *":
+        r""" Creates a maximization objective."""
+        return _pywrapcp.Solver_Maximize(self, v, step)
+
+ +
+ +

Creates a maximization objective.

+
+ + +
+
+
#   + + + def + Optimize( + self, + maximize: bool, + v: pywrapcp.IntVar, + step: 'int64_t' +) -> 'operations_research::OptimizeVar *': +
+ +
+ View Source +
    def Optimize(self, maximize: "bool", v: "IntVar", step: "int64_t") -> "operations_research::OptimizeVar *":
+        r""" Creates a objective with a given sense (true = maximization)."""
+        return _pywrapcp.Solver_Optimize(self, maximize, v, step)
+
+ +
+ +

Creates a objective with a given sense (true = maximization).

+
+ + +
+
+
#   + + + def + WeightedMinimize(self, *args) -> 'operations_research::OptimizeVar *': +
+ +
+ View Source +
    def WeightedMinimize(self, *args) -> "operations_research::OptimizeVar *":
+        r"""
+        *Overload 1:*
+        Creates a minimization weighted objective. The actual objective is scalar_prod(sub_objectives, weights).
+
+        |
+
+        *Overload 2:*
+        Creates a minimization weighted objective. The actual objective is scalar_prod(sub_objectives, weights).
+        """
+        return _pywrapcp.Solver_WeightedMinimize(self, *args)
+
+ +
+ +

Overload 1: +Creates a minimization weighted objective. The actual objective is scalar_prod(sub_objectives, weights).

+ +

|

+ +

Overload 2: +Creates a minimization weighted objective. The actual objective is scalar_prod(sub_objectives, weights).

+
+ + +
+
+
#   + + + def + WeightedMaximize(self, *args) -> 'operations_research::OptimizeVar *': +
+ +
+ View Source +
    def WeightedMaximize(self, *args) -> "operations_research::OptimizeVar *":
+        r"""
+        *Overload 1:*
+        Creates a maximization weigthed objective.
+
+        |
+
+        *Overload 2:*
+        Creates a maximization weigthed objective.
+        """
+        return _pywrapcp.Solver_WeightedMaximize(self, *args)
+
+ +
+ +

Overload 1: +Creates a maximization weigthed objective.

+ +

|

+ +

Overload 2: +Creates a maximization weigthed objective.

+
+ + +
+
+
#   + + + def + WeightedOptimize(self, *args) -> 'operations_research::OptimizeVar *': +
+ +
+ View Source +
    def WeightedOptimize(self, *args) -> "operations_research::OptimizeVar *":
+        r"""
+        *Overload 1:*
+        Creates a weighted objective with a given sense (true = maximization).
+
+        |
+
+        *Overload 2:*
+        Creates a weighted objective with a given sense (true = maximization).
+        """
+        return _pywrapcp.Solver_WeightedOptimize(self, *args)
+
+ +
+ +

Overload 1: +Creates a weighted objective with a given sense (true = maximization).

+ +

|

+ +

Overload 2: +Creates a weighted objective with a given sense (true = maximization).

+
+ + +
+
+
#   + + + def + TabuSearch( + self, + maximize: bool, + v: pywrapcp.IntVar, + step: 'int64_t', + vars: 'std::vector< operations_research::IntVar * > const &', + keep_tenure: 'int64_t', + forbid_tenure: 'int64_t', + tabu_factor: 'double' +) -> 'operations_research::SearchMonitor *': +
+ +
+ View Source +
    def TabuSearch(self, maximize: "bool", v: "IntVar", step: "int64_t", vars: "std::vector< operations_research::IntVar * > const &", keep_tenure: "int64_t", forbid_tenure: "int64_t", tabu_factor: "double") -> "operations_research::SearchMonitor *":
+        r""" MetaHeuristics which try to get the search out of local optima. Creates a Tabu Search monitor. In the context of local search the behavior is similar to MakeOptimize(), creating an objective in a given sense. The behavior differs once a local optimum is reached: thereafter solutions which degrade the value of the objective are allowed if they are not "tabu". A solution is "tabu" if it doesn't respect the following rules: - improving the best solution found so far - variables in the "keep" list must keep their value, variables in the "forbid" list must not take the value they have in the list. Variables with new values enter the tabu lists after each new solution found and leave the lists after a given number of iterations (called tenure). Only the variables passed to the method can enter the lists. The tabu criterion is softened by the tabu factor which gives the number of "tabu" violations which is tolerated; a factor of 1 means no violations allowed; a factor of 0 means all violations are allowed."""
+        return _pywrapcp.Solver_TabuSearch(self, maximize, v, step, vars, keep_tenure, forbid_tenure, tabu_factor)
+
+ +
+ +

MetaHeuristics which try to get the search out of local optima. Creates a Tabu Search monitor. In the context of local search the behavior is similar to MakeOptimize(), creating an objective in a given sense. The behavior differs once a local optimum is reached: thereafter solutions which degrade the value of the objective are allowed if they are not "tabu". A solution is "tabu" if it doesn't respect the following rules: - improving the best solution found so far - variables in the "keep" list must keep their value, variables in the "forbid" list must not take the value they have in the list. Variables with new values enter the tabu lists after each new solution found and leave the lists after a given number of iterations (called tenure). Only the variables passed to the method can enter the lists. The tabu criterion is softened by the tabu factor which gives the number of "tabu" violations which is tolerated; a factor of 1 means no violations allowed; a factor of 0 means all violations are allowed.

+
+ + +
+
+
#   + + + def + SimulatedAnnealing( + self, + maximize: bool, + v: pywrapcp.IntVar, + step: 'int64_t', + initial_temperature: 'int64_t' +) -> 'operations_research::SearchMonitor *': +
+ +
+ View Source +
    def SimulatedAnnealing(self, maximize: "bool", v: "IntVar", step: "int64_t", initial_temperature: "int64_t") -> "operations_research::SearchMonitor *":
+        r""" Creates a Simulated Annealing monitor."""
+        return _pywrapcp.Solver_SimulatedAnnealing(self, maximize, v, step, initial_temperature)
+
+ +
+ +

Creates a Simulated Annealing monitor.

+
+ + +
+
+
#   + + + def + LubyRestart(self, scale_factor: int) -> 'operations_research::SearchMonitor *': +
+ +
+ View Source +
    def LubyRestart(self, scale_factor: "int") -> "operations_research::SearchMonitor *":
+        r""" This search monitor will restart the search periodically. At the iteration n, it will restart after scale_factor * Luby(n) failures where Luby is the Luby Strategy (i.e. 1 1 2 1 1 2 4 1 1 2 1 1 2 4 8...)."""
+        return _pywrapcp.Solver_LubyRestart(self, scale_factor)
+
+ +
+ +

This search monitor will restart the search periodically. At the iteration n, it will restart after scale_factor * Luby(n) failures where Luby is the Luby Strategy (i.e. 1 1 2 1 1 2 4 1 1 2 1 1 2 4 8...).

+
+ + +
+
+
#   + + + def + ConstantRestart(self, frequency: int) -> 'operations_research::SearchMonitor *': +
+ +
+ View Source +
    def ConstantRestart(self, frequency: "int") -> "operations_research::SearchMonitor *":
+        r""" This search monitor will restart the search periodically after 'frequency' failures."""
+        return _pywrapcp.Solver_ConstantRestart(self, frequency)
+
+ +
+ +

This search monitor will restart the search periodically after 'frequency' failures.

+
+ + +
+
+
#   + + + def + TimeLimit(self, *args) -> 'operations_research::RegularLimit *': +
+ +
+ View Source +
    def TimeLimit(self, *args) -> "operations_research::RegularLimit *":
+        return _pywrapcp.Solver_TimeLimit(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + BranchesLimit(self, branches: 'int64_t') -> 'operations_research::RegularLimit *': +
+ +
+ View Source +
    def BranchesLimit(self, branches: "int64_t") -> "operations_research::RegularLimit *":
+        r""" Creates a search limit that constrains the number of branches explored in the search tree."""
+        return _pywrapcp.Solver_BranchesLimit(self, branches)
+
+ +
+ +

Creates a search limit that constrains the number of branches explored in the search tree.

+
+ + +
+
+
#   + + + def + FailuresLimit(self, failures: 'int64_t') -> 'operations_research::RegularLimit *': +
+ +
+ View Source +
    def FailuresLimit(self, failures: "int64_t") -> "operations_research::RegularLimit *":
+        r""" Creates a search limit that constrains the number of failures that can happen when exploring the search tree."""
+        return _pywrapcp.Solver_FailuresLimit(self, failures)
+
+ +
+ +

Creates a search limit that constrains the number of failures that can happen when exploring the search tree.

+
+ + +
+
+
#   + + + def + SolutionsLimit(self, solutions: 'int64_t') -> 'operations_research::RegularLimit *': +
+ +
+ View Source +
    def SolutionsLimit(self, solutions: "int64_t") -> "operations_research::RegularLimit *":
+        r""" Creates a search limit that constrains the number of solutions found during the search."""
+        return _pywrapcp.Solver_SolutionsLimit(self, solutions)
+
+ +
+ +

Creates a search limit that constrains the number of solutions found during the search.

+
+ + +
+
+
#   + + + def + Limit(self, *args) -> 'operations_research::SearchLimit *': +
+ +
+ View Source +
    def Limit(self, *args) -> "operations_research::SearchLimit *":
+        r"""
+        *Overload 1:*
+        Limits the search with the 'time', 'branches', 'failures' and 'solutions' limits. 'smart_time_check' reduces the calls to the wall
+
+        |
+
+        *Overload 2:*
+        Creates a search limit from its protobuf description
+
+        |
+
+        *Overload 3:*
+        Creates a search limit that is reached when either of the underlying limit is reached. That is, the returned limit is more stringent than both argument limits.
+        """
+        return _pywrapcp.Solver_Limit(self, *args)
+
+ +
+ +

Overload 1: +Limits the search with the 'time', 'branches', 'failures' and 'solutions' limits. 'smart_time_check' reduces the calls to the wall

+ +

|

+ +

Overload 2: +Creates a search limit from its protobuf description

+ +

|

+ +

Overload 3: +Creates a search limit that is reached when either of the underlying limit is reached. That is, the returned limit is more stringent than both argument limits.

+
+ + +
+
+
#   + + + def + CustomLimit( + self, + limiter: 'std::function< bool () >' +) -> 'operations_research::SearchLimit *': +
+ +
+ View Source +
    def CustomLimit(self, limiter: "std::function< bool () >") -> "operations_research::SearchLimit *":
+        r""" Callback-based search limit. Search stops when limiter returns true; if this happens at a leaf the corresponding solution will be rejected."""
+        return _pywrapcp.Solver_CustomLimit(self, limiter)
+
+ +
+ +

Callback-based search limit. Search stops when limiter returns true; if this happens at a leaf the corresponding solution will be rejected.

+
+ + +
+
+
#   + + + def + SearchLog(self, *args) -> 'operations_research::SearchMonitor *': +
+ +
+ View Source +
    def SearchLog(self, *args) -> "operations_research::SearchMonitor *":
+        return _pywrapcp.Solver_SearchLog(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + SearchTrace( + self, + prefix: 'std::string const &' +) -> 'operations_research::SearchMonitor *': +
+ +
+ View Source +
    def SearchTrace(self, prefix: "std::string const &") -> "operations_research::SearchMonitor *":
+        r""" Creates a search monitor that will trace precisely the behavior of the search. Use this only for low level debugging."""
+        return _pywrapcp.Solver_SearchTrace(self, prefix)
+
+ +
+ +

Creates a search monitor that will trace precisely the behavior of the search. Use this only for low level debugging.

+
+ + +
+
+
#   + + + def + PrintModelVisitor(self) -> 'operations_research::ModelVisitor *': +
+ +
+ View Source +
    def PrintModelVisitor(self) -> "operations_research::ModelVisitor *":
+        r""" Prints the model."""
+        return _pywrapcp.Solver_PrintModelVisitor(self)
+
+ +
+ +

Prints the model.

+
+ + +
+
+
#   + + + def + StatisticsModelVisitor(self) -> 'operations_research::ModelVisitor *': +
+ +
+ View Source +
    def StatisticsModelVisitor(self) -> "operations_research::ModelVisitor *":
+        r""" Displays some nice statistics on the model."""
+        return _pywrapcp.Solver_StatisticsModelVisitor(self)
+
+ +
+ +

Displays some nice statistics on the model.

+
+ + +
+
+
#   + + + def + AssignVariableValue( + self, + var: pywrapcp.IntVar, + val: 'int64_t' +) -> 'operations_research::Decision *': +
+ +
+ View Source +
    def AssignVariableValue(self, var: "IntVar", val: "int64_t") -> "operations_research::Decision *":
+        r""" Decisions."""
+        return _pywrapcp.Solver_AssignVariableValue(self, var, val)
+
+ +
+ +

Decisions.

+
+ + +
+
+
#   + + + def + VariableLessOrEqualValue( + self, + var: pywrapcp.IntVar, + value: 'int64_t' +) -> 'operations_research::Decision *': +
+ +
+ View Source +
    def VariableLessOrEqualValue(self, var: "IntVar", value: "int64_t") -> "operations_research::Decision *":
+        return _pywrapcp.Solver_VariableLessOrEqualValue(self, var, value)
+
+ +
+ + + +
+
+
#   + + + def + VariableGreaterOrEqualValue( + self, + var: pywrapcp.IntVar, + value: 'int64_t' +) -> 'operations_research::Decision *': +
+ +
+ View Source +
    def VariableGreaterOrEqualValue(self, var: "IntVar", value: "int64_t") -> "operations_research::Decision *":
+        return _pywrapcp.Solver_VariableGreaterOrEqualValue(self, var, value)
+
+ +
+ + + +
+
+
#   + + + def + SplitVariableDomain( + self, + var: pywrapcp.IntVar, + val: 'int64_t', + start_with_lower_half: bool +) -> 'operations_research::Decision *': +
+ +
+ View Source +
    def SplitVariableDomain(self, var: "IntVar", val: "int64_t", start_with_lower_half: "bool") -> "operations_research::Decision *":
+        return _pywrapcp.Solver_SplitVariableDomain(self, var, val, start_with_lower_half)
+
+ +
+ + + +
+
+
#   + + + def + AssignVariableValueOrFail( + self, + var: pywrapcp.IntVar, + value: 'int64_t' +) -> 'operations_research::Decision *': +
+ +
+ View Source +
    def AssignVariableValueOrFail(self, var: "IntVar", value: "int64_t") -> "operations_research::Decision *":
+        return _pywrapcp.Solver_AssignVariableValueOrFail(self, var, value)
+
+ +
+ + + +
+
+
#   + + + def + AssignVariablesValues( + self, + vars: 'std::vector< operations_research::IntVar * > const &', + values: 'std::vector< int64_t > const &' +) -> 'operations_research::Decision *': +
+ +
+ View Source +
    def AssignVariablesValues(self, vars: "std::vector< operations_research::IntVar * > const &", values: "std::vector< int64_t > const &") -> "operations_research::Decision *":
+        return _pywrapcp.Solver_AssignVariablesValues(self, vars, values)
+
+ +
+ + + +
+
+
#   + + + def + FailDecision(self) -> 'operations_research::Decision *': +
+ +
+ View Source +
    def FailDecision(self) -> "operations_research::Decision *":
+        return _pywrapcp.Solver_FailDecision(self)
+
+ +
+ + + +
+
+
#   + + + def + Decision( + self, + apply: 'operations_research::Solver::Action', + refute: 'operations_research::Solver::Action' +) -> 'operations_research::Decision *': +
+ +
+ View Source +
    def Decision(self, apply: "operations_research::Solver::Action", refute: "operations_research::Solver::Action") -> "operations_research::Decision *":
+        return _pywrapcp.Solver_Decision(self, apply, refute)
+
+ +
+ + + +
+
+
#   + + + def + Compose( + self, + dbs: 'std::vector< operations_research::DecisionBuilder * > const &' +) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def Compose(self, dbs: "std::vector< operations_research::DecisionBuilder * > const &") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_Compose(self, dbs)
+
+ +
+ + + +
+
+
#   + + + def + Try( + self, + dbs: 'std::vector< operations_research::DecisionBuilder * > const &' +) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def Try(self, dbs: "std::vector< operations_research::DecisionBuilder * > const &") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_Try(self, dbs)
+
+ +
+ + + +
+
+
#   + + + def + DefaultPhase(self, *args) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def DefaultPhase(self, *args) -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_DefaultPhase(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + ScheduleOrPostpone( + self, + var: pywrapcp.IntervalVar, + est: 'int64_t', + marker: 'int64_t *const' +) -> 'operations_research::Decision *': +
+ +
+ View Source +
    def ScheduleOrPostpone(self, var: "IntervalVar", est: "int64_t", marker: "int64_t *const") -> "operations_research::Decision *":
+        r""" Returns a decision that tries to schedule a task at a given time. On the Apply branch, it will set that interval var as performed and set its start to 'est'. On the Refute branch, it will just update the 'marker' to 'est' + 1. This decision is used in the INTERVAL_SET_TIMES_FORWARD strategy."""
+        return _pywrapcp.Solver_ScheduleOrPostpone(self, var, est, marker)
+
+ +
+ +

Returns a decision that tries to schedule a task at a given time. On the Apply branch, it will set that interval var as performed and set its start to 'est'. On the Refute branch, it will just update the 'marker' to 'est' + 1. This decision is used in the INTERVAL_SET_TIMES_FORWARD strategy.

+
+ + +
+
+
#   + + + def + ScheduleOrExpedite( + self, + var: pywrapcp.IntervalVar, + est: 'int64_t', + marker: 'int64_t *const' +) -> 'operations_research::Decision *': +
+ +
+ View Source +
    def ScheduleOrExpedite(self, var: "IntervalVar", est: "int64_t", marker: "int64_t *const") -> "operations_research::Decision *":
+        r""" Returns a decision that tries to schedule a task at a given time. On the Apply branch, it will set that interval var as performed and set its end to 'est'. On the Refute branch, it will just update the 'marker' to 'est' - 1. This decision is used in the INTERVAL_SET_TIMES_BACKWARD strategy."""
+        return _pywrapcp.Solver_ScheduleOrExpedite(self, var, est, marker)
+
+ +
+ +

Returns a decision that tries to schedule a task at a given time. On the Apply branch, it will set that interval var as performed and set its end to 'est'. On the Refute branch, it will just update the 'marker' to 'est' - 1. This decision is used in the INTERVAL_SET_TIMES_BACKWARD strategy.

+
+ + +
+
+
#   + + + def + RankFirstInterval( + self, + sequence: pywrapcp.SequenceVar, + index: int +) -> 'operations_research::Decision *': +
+ +
+ View Source +
    def RankFirstInterval(self, sequence: "SequenceVar", index: "int") -> "operations_research::Decision *":
+        r""" Returns a decision that tries to rank first the ith interval var in the sequence variable."""
+        return _pywrapcp.Solver_RankFirstInterval(self, sequence, index)
+
+ +
+ +

Returns a decision that tries to rank first the ith interval var in the sequence variable.

+
+ + +
+
+
#   + + + def + RankLastInterval( + self, + sequence: pywrapcp.SequenceVar, + index: int +) -> 'operations_research::Decision *': +
+ +
+ View Source +
    def RankLastInterval(self, sequence: "SequenceVar", index: "int") -> "operations_research::Decision *":
+        r""" Returns a decision that tries to rank last the ith interval var in the sequence variable."""
+        return _pywrapcp.Solver_RankLastInterval(self, sequence, index)
+
+ +
+ +

Returns a decision that tries to rank last the ith interval var in the sequence variable.

+
+ + +
+
+
#   + + + def + Phase(self, *args) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def Phase(self, *args) -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_Phase(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + DecisionBuilderFromAssignment( + self, + assignment: pywrapcp.Assignment, + db: pywrapcp.DecisionBuilder, + vars: 'std::vector< operations_research::IntVar * > const &' +) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def DecisionBuilderFromAssignment(self, assignment: "Assignment", db: "DecisionBuilder", vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::DecisionBuilder *":
+        r""" Returns a decision builder for which the left-most leaf corresponds to assignment, the rest of the tree being explored using 'db'."""
+        return _pywrapcp.Solver_DecisionBuilderFromAssignment(self, assignment, db, vars)
+
+ +
+ +

Returns a decision builder for which the left-most leaf corresponds to assignment, the rest of the tree being explored using 'db'.

+
+ + +
+
+
#   + + + def + ConstraintAdder( + self, + ct: pywrapcp.Constraint +) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def ConstraintAdder(self, ct: "Constraint") -> "operations_research::DecisionBuilder *":
+        r""" Returns a decision builder that will add the given constraint to the model."""
+        return _pywrapcp.Solver_ConstraintAdder(self, ct)
+
+ +
+ +

Returns a decision builder that will add the given constraint to the model.

+
+ + +
+
+
#   + + + def + SolveOnce( + self, + db: pywrapcp.DecisionBuilder, + monitors: 'std::vector< operations_research::SearchMonitor * > const &' +) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def SolveOnce(self, db: "DecisionBuilder", monitors: "std::vector< operations_research::SearchMonitor * > const &") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_SolveOnce(self, db, monitors)
+
+ +
+ + + +
+
+
#   + + + def + NestedOptimize(self, *args) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def NestedOptimize(self, *args) -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_NestedOptimize(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + RestoreAssignment( + self, + assignment: pywrapcp.Assignment +) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def RestoreAssignment(self, assignment: "Assignment") -> "operations_research::DecisionBuilder *":
+        r""" Returns a DecisionBuilder which restores an Assignment (calls void Assignment::Restore())"""
+        return _pywrapcp.Solver_RestoreAssignment(self, assignment)
+
+ +
+ +

Returns a DecisionBuilder which restores an Assignment (calls void Assignment::Restore())

+
+ + +
+
+
#   + + + def + StoreAssignment( + self, + assignment: pywrapcp.Assignment +) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def StoreAssignment(self, assignment: "Assignment") -> "operations_research::DecisionBuilder *":
+        r""" Returns a DecisionBuilder which stores an Assignment (calls void Assignment::Store())"""
+        return _pywrapcp.Solver_StoreAssignment(self, assignment)
+
+ +
+ +

Returns a DecisionBuilder which stores an Assignment (calls void Assignment::Store())

+
+ + +
+
+
#   + + + def + Operator(self, *args) -> 'operations_research::LocalSearchOperator *': +
+ +
+ View Source +
    def Operator(self, *args) -> "operations_research::LocalSearchOperator *":
+        return _pywrapcp.Solver_Operator(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + RandomLnsOperator(self, *args) -> 'operations_research::LocalSearchOperator *': +
+ +
+ View Source +
    def RandomLnsOperator(self, *args) -> "operations_research::LocalSearchOperator *":
+        return _pywrapcp.Solver_RandomLnsOperator(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + MoveTowardTargetOperator(self, *args) -> 'operations_research::LocalSearchOperator *': +
+ +
+ View Source +
    def MoveTowardTargetOperator(self, *args) -> "operations_research::LocalSearchOperator *":
+        r"""
+        *Overload 1:*
+        Creates a local search operator that tries to move the assignment of some variables toward a target. The target is given as an Assignment. This operator generates neighbors in which the only difference compared to the current state is that one variable that belongs to the target assignment is set to its target value.
+
+        |
+
+        *Overload 2:*
+        Creates a local search operator that tries to move the assignment of some variables toward a target. The target is given either as two vectors: a vector of variables and a vector of associated target values. The two vectors should be of the same length. This operator generates neighbors in which the only difference compared to the current state is that one variable that belongs to the given vector is set to its target value.
+        """
+        return _pywrapcp.Solver_MoveTowardTargetOperator(self, *args)
+
+ +
+ +

Overload 1: +Creates a local search operator that tries to move the assignment of some variables toward a target. The target is given as an Assignment. This operator generates neighbors in which the only difference compared to the current state is that one variable that belongs to the target assignment is set to its target value.

+ +

|

+ +

Overload 2: +Creates a local search operator that tries to move the assignment of some variables toward a target. The target is given either as two vectors: a vector of variables and a vector of associated target values. The two vectors should be of the same length. This operator generates neighbors in which the only difference compared to the current state is that one variable that belongs to the given vector is set to its target value.

+
+ + +
+
+
#   + + + def + ConcatenateOperators(self, *args) -> 'operations_research::LocalSearchOperator *': +
+ +
+ View Source +
    def ConcatenateOperators(self, *args) -> "operations_research::LocalSearchOperator *":
+        return _pywrapcp.Solver_ConcatenateOperators(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + RandomConcatenateOperators(self, *args) -> 'operations_research::LocalSearchOperator *': +
+ +
+ View Source +
    def RandomConcatenateOperators(self, *args) -> "operations_research::LocalSearchOperator *":
+        r"""
+        *Overload 1:*
+        Randomized version of local search concatenator; calls a random operator at each call to MakeNextNeighbor().
+
+        |
+
+        *Overload 2:*
+        Randomized version of local search concatenator; calls a random operator at each call to MakeNextNeighbor(). The provided seed is used to initialize the random number generator.
+        """
+        return _pywrapcp.Solver_RandomConcatenateOperators(self, *args)
+
+ +
+ +

Overload 1: +Randomized version of local search concatenator; calls a random operator at each call to MakeNextNeighbor().

+ +

|

+ +

Overload 2: +Randomized version of local search concatenator; calls a random operator at each call to MakeNextNeighbor(). The provided seed is used to initialize the random number generator.

+
+ + +
+
+
#   + + + def + NeighborhoodLimit( + self, + op: pywrapcp.LocalSearchOperator, + limit: 'int64_t' +) -> 'operations_research::LocalSearchOperator *': +
+ +
+ View Source +
    def NeighborhoodLimit(self, op: "LocalSearchOperator", limit: "int64_t") -> "operations_research::LocalSearchOperator *":
+        r""" Creates a local search operator that wraps another local search operator and limits the number of neighbors explored (i.e., calls to MakeNextNeighbor from the current solution (between two calls to Start()). When this limit is reached, MakeNextNeighbor() returns false. The counter is cleared when Start() is called."""
+        return _pywrapcp.Solver_NeighborhoodLimit(self, op, limit)
+
+ +
+ +

Creates a local search operator that wraps another local search operator and limits the number of neighbors explored (i.e., calls to MakeNextNeighbor from the current solution (between two calls to Start()). When this limit is reached, MakeNextNeighbor() returns false. The counter is cleared when Start() is called.

+
+ + +
+
+
#   + + + def + LocalSearchPhase(self, *args) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def LocalSearchPhase(self, *args) -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_LocalSearchPhase(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + LocalSearchPhaseParameters(self, *args) -> 'operations_research::LocalSearchPhaseParameters *': +
+ +
+ View Source +
    def LocalSearchPhaseParameters(self, *args) -> "operations_research::LocalSearchPhaseParameters *":
+        return _pywrapcp.Solver_LocalSearchPhaseParameters(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + SearchDepth(self) -> int: +
+ +
+ View Source +
    def SearchDepth(self) -> "int":
+        r""" Gets the search depth of the current active search. Returns -1 if there is no active search opened."""
+        return _pywrapcp.Solver_SearchDepth(self)
+
+ +
+ +

Gets the search depth of the current active search. Returns -1 if there is no active search opened.

+
+ + +
+
+
#   + + + def + SearchLeftDepth(self) -> int: +
+ +
+ View Source +
    def SearchLeftDepth(self) -> "int":
+        r""" Gets the search left depth of the current active search. Returns -1 if there is no active search opened."""
+        return _pywrapcp.Solver_SearchLeftDepth(self)
+
+ +
+ +

Gets the search left depth of the current active search. Returns -1 if there is no active search opened.

+
+ + +
+
+
#   + + + def + SolveDepth(self) -> int: +
+ +
+ View Source +
    def SolveDepth(self) -> "int":
+        r""" Gets the number of nested searches. It returns 0 outside search, 1 during the top level search, 2 or more in case of nested searches."""
+        return _pywrapcp.Solver_SolveDepth(self)
+
+ +
+ +

Gets the number of nested searches. It returns 0 outside search, 1 during the top level search, 2 or more in case of nested searches.

+
+ + +
+
+
#   + + + def + Rand64(self, size: 'int64_t') -> 'int64_t': +
+ +
+ View Source +
    def Rand64(self, size: "int64_t") -> "int64_t":
+        r""" Returns a random value between 0 and 'size' - 1;"""
+        return _pywrapcp.Solver_Rand64(self, size)
+
+ +
+ +

Returns a random value between 0 and 'size' - 1;

+
+ + +
+
+
#   + + + def + Rand32(self, size: 'int32_t') -> 'int32_t': +
+ +
+ View Source +
    def Rand32(self, size: "int32_t") -> "int32_t":
+        r""" Returns a random value between 0 and 'size' - 1;"""
+        return _pywrapcp.Solver_Rand32(self, size)
+
+ +
+ +

Returns a random value between 0 and 'size' - 1;

+
+ + +
+
+
#   + + + def + ReSeed(self, seed: 'int32_t') -> 'void': +
+ +
+ View Source +
    def ReSeed(self, seed: "int32_t") -> "void":
+        r""" Reseed the solver random generator."""
+        return _pywrapcp.Solver_ReSeed(self, seed)
+
+ +
+ +

Reseed the solver random generator.

+
+ + +
+
+
#   + + + def + LocalSearchProfile(self) -> 'std::string': +
+ +
+ View Source +
    def LocalSearchProfile(self) -> "std::string":
+        r""" Returns local search profiling information in a human readable format."""
+        return _pywrapcp.Solver_LocalSearchProfile(self)
+
+ +
+ +

Returns local search profiling information in a human readable format.

+
+ + +
+
+
#   + + + def + Constraints(self) -> int: +
+ +
+ View Source +
    def Constraints(self) -> "int":
+        r""" Counts the number of constraints that have been added to the solver before the search."""
+        return _pywrapcp.Solver_Constraints(self)
+
+ +
+ +

Counts the number of constraints that have been added to the solver before the search.

+
+ + +
+
+
#   + + + def + Accept(self, visitor: 'operations_research::ModelVisitor *const') -> 'void': +
+ +
+ View Source +
    def Accept(self, visitor: "operations_research::ModelVisitor *const") -> "void":
+        r""" Accepts the given model visitor."""
+        return _pywrapcp.Solver_Accept(self, visitor)
+
+ +
+ +

Accepts the given model visitor.

+
+ + +
+
+
#   + + + def + FinishCurrentSearch(self) -> 'void': +
+ +
+ View Source +
    def FinishCurrentSearch(self) -> "void":
+        r""" Tells the solver to kill or restart the current search."""
+        return _pywrapcp.Solver_FinishCurrentSearch(self)
+
+ +
+ +

Tells the solver to kill or restart the current search.

+
+ + +
+
+
#   + + + def + RestartCurrentSearch(self) -> 'void': +
+ +
+ View Source +
    def RestartCurrentSearch(self) -> "void":
+        return _pywrapcp.Solver_RestartCurrentSearch(self)
+
+ +
+ + + +
+
+
#   + + + def + ShouldFail(self) -> 'void': +
+ +
+ View Source +
    def ShouldFail(self) -> "void":
+        r""" These methods are only useful for the SWIG wrappers, which need a way to externally cause the Solver to fail."""
+        return _pywrapcp.Solver_ShouldFail(self)
+
+ +
+ +

These methods are only useful for the SWIG wrappers, which need a way to externally cause the Solver to fail.

+
+ + +
+
+
#   + + + def + Add(self, ct): +
+ +
+ View Source +
    def Add(self, ct):
+      if isinstance(ct, PyConstraint):
+        self.__python_constraints.append(ct)
+      self.AddConstraint(ct)
+
+ +
+ + + +
+
+
#   + + + def + TreeNoCycle( + self, + nexts: 'std::vector< operations_research::IntVar * > const &', + active: 'std::vector< operations_research::IntVar * > const &', + callback: 'operations_research::Solver::IndexFilter1' = 0 +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def TreeNoCycle(self, nexts: "std::vector< operations_research::IntVar * > const &", active: "std::vector< operations_research::IntVar * > const &", callback: "operations_research::Solver::IndexFilter1"=0) -> "operations_research::Constraint *":
+        return _pywrapcp.Solver_TreeNoCycle(self, nexts, active, callback)
+
+ +
+ + + +
+
+
#   + + + def + SearchLogWithCallback( + self, + period: int, + callback: 'std::function< std::string () >' +) -> 'operations_research::SearchMonitor *': +
+ +
+ View Source +
    def SearchLogWithCallback(self, period: "int", callback: "std::function< std::string () >") -> "operations_research::SearchMonitor *":
+        return _pywrapcp.Solver_SearchLogWithCallback(self, period, callback)
+
+ +
+ + + +
+
+
#   + + + def + ElementFunction( + self, + values: 'std::function< int64_t (int64_t) >', + index: pywrapcp.IntVar +) -> 'operations_research::IntExpr *': +
+ +
+ View Source +
    def ElementFunction(self, values: "std::function< int64_t (int64_t) >", index: "IntVar") -> "operations_research::IntExpr *":
+        return _pywrapcp.Solver_ElementFunction(self, values, index)
+
+ +
+ + + +
+
+
#   + + + def + VarEvalValStrPhase( + self, + vars: 'std::vector< operations_research::IntVar * > const &', + var_evaluator: 'std::function< int64_t (int64_t) >', + val_str: 'operations_research::Solver::IntValueStrategy' +) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def VarEvalValStrPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_evaluator: "std::function< int64_t (int64_t) >", val_str: "operations_research::Solver::IntValueStrategy") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_VarEvalValStrPhase(self, vars, var_evaluator, val_str)
+
+ +
+ + + +
+
+
#   + + + def + VarStrValEvalPhase( + self, + vars: 'std::vector< operations_research::IntVar * > const &', + var_str: 'operations_research::Solver::IntVarStrategy', + val_eval: 'operations_research::Solver::IndexEvaluator2' +) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def VarStrValEvalPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_str: "operations_research::Solver::IntVarStrategy", val_eval: "operations_research::Solver::IndexEvaluator2") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_VarStrValEvalPhase(self, vars, var_str, val_eval)
+
+ +
+ + + +
+
+
#   + + + def + VarEvalValEvalPhase( + self, + vars: 'std::vector< operations_research::IntVar * > const &', + var_eval: 'std::function< int64_t (int64_t) >', + val_eval: 'operations_research::Solver::IndexEvaluator2' +) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def VarEvalValEvalPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_eval: "std::function< int64_t (int64_t) >", val_eval: "operations_research::Solver::IndexEvaluator2") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_VarEvalValEvalPhase(self, vars, var_eval, val_eval)
+
+ +
+ + + +
+
+
#   + + + def + VarStrValEvalTieBreakPhase( + self, + vars: 'std::vector< operations_research::IntVar * > const &', + var_str: 'operations_research::Solver::IntVarStrategy', + val_eval: 'operations_research::Solver::IndexEvaluator2', + tie_breaker: 'std::function< int64_t (int64_t) >' +) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def VarStrValEvalTieBreakPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_str: "operations_research::Solver::IntVarStrategy", val_eval: "operations_research::Solver::IndexEvaluator2", tie_breaker: "std::function< int64_t (int64_t) >") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_VarStrValEvalTieBreakPhase(self, vars, var_str, val_eval, tie_breaker)
+
+ +
+ + + +
+
+
#   + + + def + VarEvalValEvalTieBreakPhase( + self, + vars: 'std::vector< operations_research::IntVar * > const &', + var_eval: 'std::function< int64_t (int64_t) >', + val_eval: 'operations_research::Solver::IndexEvaluator2', + tie_breaker: 'std::function< int64_t (int64_t) >' +) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def VarEvalValEvalTieBreakPhase(self, vars: "std::vector< operations_research::IntVar * > const &", var_eval: "std::function< int64_t (int64_t) >", val_eval: "operations_research::Solver::IndexEvaluator2", tie_breaker: "std::function< int64_t (int64_t) >") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_VarEvalValEvalTieBreakPhase(self, vars, var_eval, val_eval, tie_breaker)
+
+ +
+ + + +
+
+
#   + + + def + EvalEvalStrPhase( + self, + vars: 'std::vector< operations_research::IntVar * > const &', + evaluator: 'operations_research::Solver::IndexEvaluator2', + str: 'operations_research::Solver::EvaluatorStrategy' +) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def EvalEvalStrPhase(self, vars: "std::vector< operations_research::IntVar * > const &", evaluator: "operations_research::Solver::IndexEvaluator2", str: "operations_research::Solver::EvaluatorStrategy") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_EvalEvalStrPhase(self, vars, evaluator, str)
+
+ +
+ + + +
+
+
#   + + + def + EvalEvalStrTieBreakPhase( + self, + vars: 'std::vector< operations_research::IntVar * > const &', + evaluator: 'operations_research::Solver::IndexEvaluator2', + tie_breaker: 'operations_research::Solver::IndexEvaluator1', + str: 'operations_research::Solver::EvaluatorStrategy' +) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def EvalEvalStrTieBreakPhase(self, vars: "std::vector< operations_research::IntVar * > const &", evaluator: "operations_research::Solver::IndexEvaluator2", tie_breaker: "operations_research::Solver::IndexEvaluator1", str: "operations_research::Solver::EvaluatorStrategy") -> "operations_research::DecisionBuilder *":
+        return _pywrapcp.Solver_EvalEvalStrTieBreakPhase(self, vars, evaluator, tie_breaker, str)
+
+ +
+ + + +
+
+
#   + + + def + GuidedLocalSearch(self, *args) -> 'operations_research::SearchMonitor *': +
+ +
+ View Source +
    def GuidedLocalSearch(self, *args) -> "operations_research::SearchMonitor *":
+        return _pywrapcp.Solver_GuidedLocalSearch(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + SumObjectiveFilter( + self, + vars: 'std::vector< operations_research::IntVar * > const &', + values: 'operations_research::Solver::IndexEvaluator2', + filter_enum: 'operations_research::Solver::LocalSearchFilterBound' +) -> 'operations_research::LocalSearchFilter *': +
+ +
+ View Source +
    def SumObjectiveFilter(self, vars: "std::vector< operations_research::IntVar * > const &", values: "operations_research::Solver::IndexEvaluator2", filter_enum: "operations_research::Solver::LocalSearchFilterBound") -> "operations_research::LocalSearchFilter *":
+        return _pywrapcp.Solver_SumObjectiveFilter(self, vars, values, filter_enum)
+
+ +
+ + + +
+ +
+
#   + + + def + Solver_DefaultSolverParameters() -> 'operations_research::ConstraintSolverParameters': +
+ +
+ View Source +
def Solver_DefaultSolverParameters() -> "operations_research::ConstraintSolverParameters":
+    r""" Create a ConstraintSolverParameters proto with all the default values."""
+    return _pywrapcp.Solver_DefaultSolverParameters()
+
+ +
+ +

Create a ConstraintSolverParameters proto with all the default values.

+
+ + +
+
+
#   + + + def + Solver_MemoryUsage() -> 'int64_t': +
+ +
+ View Source +
def Solver_MemoryUsage() -> "int64_t":
+    r""" Current memory usage in bytes"""
+    return _pywrapcp.Solver_MemoryUsage()
+
+ +
+ +

Current memory usage in bytes

+
+ + +
+
+
+ #   + + + class + BaseObject: +
+ +
+ View Source +
class BaseObject(object):
+    r""" A BaseObject is the root of all reversibly allocated objects. A DebugString method and the associated << operator are implemented as a convenience."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self):
+        if self.__class__ == BaseObject:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.BaseObject_swiginit(self, _pywrapcp.new_BaseObject(_self, ))
+    __swig_destroy__ = _pywrapcp.delete_BaseObject
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.BaseObject_DebugString(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.BaseObject___str__(self)
+
+    def __repr__(self) -> "std::string":
+        return _pywrapcp.BaseObject___repr__(self)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_BaseObject(self)
+        return weakref.proxy(self)
+
+ +
+ +

A BaseObject is the root of all reversibly allocated objects. A DebugString method and the associated << operator are implemented as a convenience.

+
+ + +
+
#   + + + BaseObject() +
+ +
+ View Source +
    def __init__(self):
+        if self.__class__ == BaseObject:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.BaseObject_swiginit(self, _pywrapcp.new_BaseObject(_self, ))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + DebugString(self) -> 'std::string': +
+ +
+ View Source +
    def DebugString(self) -> "std::string":
+        return _pywrapcp.BaseObject_DebugString(self)
+
+ +
+ + + +
+
+
+
+ #   + + + class + PropagationBaseObject(BaseObject): +
+ +
+ View Source +
class PropagationBaseObject(BaseObject):
+    r""" NOLINT The PropagationBaseObject is a subclass of BaseObject that is also friend to the Solver class. It allows accessing methods useful when writing new constraints or new expressions."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, s: "Solver"):
+        if self.__class__ == PropagationBaseObject:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.PropagationBaseObject_swiginit(self, _pywrapcp.new_PropagationBaseObject(_self, s))
+    __swig_destroy__ = _pywrapcp.delete_PropagationBaseObject
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.PropagationBaseObject_DebugString(self)
+
+    def solver(self) -> "operations_research::Solver *":
+        return _pywrapcp.PropagationBaseObject_solver(self)
+
+    def Name(self) -> "std::string":
+        r""" Object naming."""
+        return _pywrapcp.PropagationBaseObject_Name(self)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_PropagationBaseObject(self)
+        return weakref.proxy(self)
+
+ +
+ +

NOLINT The PropagationBaseObject is a subclass of BaseObject that is also friend to the Solver class. It allows accessing methods useful when writing new constraints or new expressions.

+
+ + +
+
#   + + + PropagationBaseObject(s: pywrapcp.Solver) +
+ +
+ View Source +
    def __init__(self, s: "Solver"):
+        if self.__class__ == PropagationBaseObject:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.PropagationBaseObject_swiginit(self, _pywrapcp.new_PropagationBaseObject(_self, s))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + DebugString(self) -> 'std::string': +
+ +
+ View Source +
    def DebugString(self) -> "std::string":
+        return _pywrapcp.PropagationBaseObject_DebugString(self)
+
+ +
+ + + +
+
+
#   + + + def + solver(self) -> 'operations_research::Solver *': +
+ +
+ View Source +
    def solver(self) -> "operations_research::Solver *":
+        return _pywrapcp.PropagationBaseObject_solver(self)
+
+ +
+ + + +
+
+
#   + + + def + Name(self) -> 'std::string': +
+ +
+ View Source +
    def Name(self) -> "std::string":
+        r""" Object naming."""
+        return _pywrapcp.PropagationBaseObject_Name(self)
+
+ +
+ +

Object naming.

+
+ + +
+
+
+
+ #   + + + class + Decision(BaseObject): +
+ +
+ View Source +
class Decision(BaseObject):
+    r""" A Decision represents a choice point in the search tree. The two main methods are Apply() to go left, or Refute() to go right."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self):
+        if self.__class__ == Decision:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.Decision_swiginit(self, _pywrapcp.new_Decision(_self, ))
+    __swig_destroy__ = _pywrapcp.delete_Decision
+
+    def ApplyWrapper(self, s: "Solver") -> "void":
+        r""" Apply will be called first when the decision is executed."""
+        return _pywrapcp.Decision_ApplyWrapper(self, s)
+
+    def RefuteWrapper(self, s: "Solver") -> "void":
+        r""" Refute will be called after a backtrack."""
+        return _pywrapcp.Decision_RefuteWrapper(self, s)
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.Decision_DebugString(self)
+
+    def __repr__(self) -> "std::string":
+        return _pywrapcp.Decision___repr__(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.Decision___str__(self)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_Decision(self)
+        return weakref.proxy(self)
+
+ +
+ +

A Decision represents a choice point in the search tree. The two main methods are Apply() to go left, or Refute() to go right.

+
+ + +
+
#   + + + Decision() +
+ +
+ View Source +
    def __init__(self):
+        if self.__class__ == Decision:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.Decision_swiginit(self, _pywrapcp.new_Decision(_self, ))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + ApplyWrapper(self, s: pywrapcp.Solver) -> 'void': +
+ +
+ View Source +
    def ApplyWrapper(self, s: "Solver") -> "void":
+        r""" Apply will be called first when the decision is executed."""
+        return _pywrapcp.Decision_ApplyWrapper(self, s)
+
+ +
+ +

Apply will be called first when the decision is executed.

+
+ + +
+
+
#   + + + def + RefuteWrapper(self, s: pywrapcp.Solver) -> 'void': +
+ +
+ View Source +
    def RefuteWrapper(self, s: "Solver") -> "void":
+        r""" Refute will be called after a backtrack."""
+        return _pywrapcp.Decision_RefuteWrapper(self, s)
+
+ +
+ +

Refute will be called after a backtrack.

+
+ + +
+
+
#   + + + def + DebugString(self) -> 'std::string': +
+ +
+ View Source +
    def DebugString(self) -> "std::string":
+        return _pywrapcp.Decision_DebugString(self)
+
+ +
+ + + +
+
+
+
+ #   + + + class + DecisionBuilder(BaseObject): +
+ +
+ View Source +
class DecisionBuilder(BaseObject):
+    r""" A DecisionBuilder is responsible for creating the search tree. The important method is Next(), which returns the next decision to execute."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self):
+        if self.__class__ == DecisionBuilder:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.DecisionBuilder_swiginit(self, _pywrapcp.new_DecisionBuilder(_self, ))
+    __swig_destroy__ = _pywrapcp.delete_DecisionBuilder
+
+    def NextWrapper(self, s: "Solver") -> "operations_research::Decision *":
+        r""" This is the main method of the decision builder class. It must return a decision (an instance of the class Decision). If it returns nullptr, this means that the decision builder has finished its work."""
+        return _pywrapcp.DecisionBuilder_NextWrapper(self, s)
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.DecisionBuilder_DebugString(self)
+
+    def __repr__(self) -> "std::string":
+        return _pywrapcp.DecisionBuilder___repr__(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.DecisionBuilder___str__(self)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_DecisionBuilder(self)
+        return weakref.proxy(self)
+
+ +
+ +

A DecisionBuilder is responsible for creating the search tree. The important method is Next(), which returns the next decision to execute.

+
+ + +
+
#   + + + DecisionBuilder() +
+ +
+ View Source +
    def __init__(self):
+        if self.__class__ == DecisionBuilder:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.DecisionBuilder_swiginit(self, _pywrapcp.new_DecisionBuilder(_self, ))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + NextWrapper(self, s: pywrapcp.Solver) -> 'operations_research::Decision *': +
+ +
+ View Source +
    def NextWrapper(self, s: "Solver") -> "operations_research::Decision *":
+        r""" This is the main method of the decision builder class. It must return a decision (an instance of the class Decision). If it returns nullptr, this means that the decision builder has finished its work."""
+        return _pywrapcp.DecisionBuilder_NextWrapper(self, s)
+
+ +
+ +

This is the main method of the decision builder class. It must return a decision (an instance of the class Decision). If it returns nullptr, this means that the decision builder has finished its work.

+
+ + +
+
+
#   + + + def + DebugString(self) -> 'std::string': +
+ +
+ View Source +
    def DebugString(self) -> "std::string":
+        return _pywrapcp.DecisionBuilder_DebugString(self)
+
+ +
+ + + +
+
+
+
+ #   + + + class + Demon(BaseObject): +
+ +
+ View Source +
class Demon(BaseObject):
+    r""" A Demon is the base element of a propagation queue. It is the main   object responsible for implementing the actual propagation   of the constraint and pruning the inconsistent values in the domains   of the variables. The main concept is that demons are listeners that are   attached to the variables and listen to their modifications. There are two methods:  - Run() is the actual method called when the demon is processed.  - priority() returns its priority. Standard priorities are slow, normal    or fast. "immediate" is reserved for variables and is treated separately."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self):
+        r""" This indicates the priority of a demon. Immediate demons are treated separately and corresponds to variables."""
+        if self.__class__ == Demon:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.Demon_swiginit(self, _pywrapcp.new_Demon(_self, ))
+    __swig_destroy__ = _pywrapcp.delete_Demon
+
+    def RunWrapper(self, s: "Solver") -> "void":
+        r""" This is the main callback of the demon."""
+        return _pywrapcp.Demon_RunWrapper(self, s)
+
+    def Priority(self) -> "operations_research::Solver::DemonPriority":
+        r""" This method returns the priority of the demon. Usually a demon is fast, slow or normal. Immediate demons are reserved for internal use to maintain variables."""
+        return _pywrapcp.Demon_Priority(self)
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.Demon_DebugString(self)
+
+    def Inhibit(self, s: "Solver") -> "void":
+        r""" This method inhibits the demon in the search tree below the current position."""
+        return _pywrapcp.Demon_Inhibit(self, s)
+
+    def Desinhibit(self, s: "Solver") -> "void":
+        r""" This method un-inhibits the demon that was previously inhibited."""
+        return _pywrapcp.Demon_Desinhibit(self, s)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_Demon(self)
+        return weakref.proxy(self)
+
+ +
+ +

A Demon is the base element of a propagation queue. It is the main object responsible for implementing the actual propagation of the constraint and pruning the inconsistent values in the domains of the variables. The main concept is that demons are listeners that are attached to the variables and listen to their modifications. There are two methods: - Run() is the actual method called when the demon is processed. - priority() returns its priority. Standard priorities are slow, normal or fast. "immediate" is reserved for variables and is treated separately.

+
+ + +
+
#   + + + Demon() +
+ +
+ View Source +
    def __init__(self):
+        r""" This indicates the priority of a demon. Immediate demons are treated separately and corresponds to variables."""
+        if self.__class__ == Demon:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.Demon_swiginit(self, _pywrapcp.new_Demon(_self, ))
+
+ +
+ +

This indicates the priority of a demon. Immediate demons are treated separately and corresponds to variables.

+
+ + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + RunWrapper(self, s: pywrapcp.Solver) -> 'void': +
+ +
+ View Source +
    def RunWrapper(self, s: "Solver") -> "void":
+        r""" This is the main callback of the demon."""
+        return _pywrapcp.Demon_RunWrapper(self, s)
+
+ +
+ +

This is the main callback of the demon.

+
+ + +
+
+
#   + + + def + Priority(self) -> 'operations_research::Solver::DemonPriority': +
+ +
+ View Source +
    def Priority(self) -> "operations_research::Solver::DemonPriority":
+        r""" This method returns the priority of the demon. Usually a demon is fast, slow or normal. Immediate demons are reserved for internal use to maintain variables."""
+        return _pywrapcp.Demon_Priority(self)
+
+ +
+ +

This method returns the priority of the demon. Usually a demon is fast, slow or normal. Immediate demons are reserved for internal use to maintain variables.

+
+ + +
+
+
#   + + + def + DebugString(self) -> 'std::string': +
+ +
+ View Source +
    def DebugString(self) -> "std::string":
+        return _pywrapcp.Demon_DebugString(self)
+
+ +
+ + + +
+
+
#   + + + def + Inhibit(self, s: pywrapcp.Solver) -> 'void': +
+ +
+ View Source +
    def Inhibit(self, s: "Solver") -> "void":
+        r""" This method inhibits the demon in the search tree below the current position."""
+        return _pywrapcp.Demon_Inhibit(self, s)
+
+ +
+ +

This method inhibits the demon in the search tree below the current position.

+
+ + +
+
+
#   + + + def + Desinhibit(self, s: pywrapcp.Solver) -> 'void': +
+ +
+ View Source +
    def Desinhibit(self, s: "Solver") -> "void":
+        r""" This method un-inhibits the demon that was previously inhibited."""
+        return _pywrapcp.Demon_Desinhibit(self, s)
+
+ +
+ +

This method un-inhibits the demon that was previously inhibited.

+
+ + +
+
+
+
+ #   + + + class + Constraint(PropagationBaseObject): +
+ +
+ View Source +
class Constraint(PropagationBaseObject):
+    r""" A constraint is the main modeling object. It provides two methods:   - Post() is responsible for creating the demons and attaching them to     immediate demons().   - InitialPropagate() is called once just after Post and performs     the initial propagation. The subsequent propagations will be performed     by the demons Posted during the post() method."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, solver: "Solver"):
+        if self.__class__ == Constraint:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.Constraint_swiginit(self, _pywrapcp.new_Constraint(_self, solver))
+    __swig_destroy__ = _pywrapcp.delete_Constraint
+
+    def Post(self) -> "void":
+        r""" This method is called when the constraint is processed by the solver. Its main usage is to attach demons to variables."""
+        return _pywrapcp.Constraint_Post(self)
+
+    def InitialPropagateWrapper(self) -> "void":
+        r""" This method performs the initial propagation of the constraint. It is called just after the post."""
+        return _pywrapcp.Constraint_InitialPropagateWrapper(self)
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.Constraint_DebugString(self)
+
+    def Var(self) -> "operations_research::IntVar *":
+        r""" Creates a Boolean variable representing the status of the constraint (false = constraint is violated, true = constraint is satisfied). It returns nullptr if the constraint does not support this API."""
+        return _pywrapcp.Constraint_Var(self)
+
+    def __repr__(self) -> "std::string":
+        return _pywrapcp.Constraint___repr__(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.Constraint___str__(self)
+
+    def __add__(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint___add__(self, *args)
+
+    def __radd__(self, v: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint___radd__(self, v)
+
+    def __sub__(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint___sub__(self, *args)
+
+    def __rsub__(self, v: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint___rsub__(self, v)
+
+    def __mul__(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint___mul__(self, *args)
+
+    def __rmul__(self, v: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint___rmul__(self, v)
+
+    def __floordiv__(self, v: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint___floordiv__(self, v)
+
+    def __neg__(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint___neg__(self)
+
+    def __abs__(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint___abs__(self)
+
+    def Square(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint_Square(self)
+
+    def __eq__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Constraint___eq__(self, *args)
+
+    def __ne__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Constraint___ne__(self, *args)
+
+    def __ge__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Constraint___ge__(self, *args)
+
+    def __gt__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Constraint___gt__(self, *args)
+
+    def __le__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Constraint___le__(self, *args)
+
+    def __lt__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.Constraint___lt__(self, *args)
+
+    def MapTo(self, vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        return _pywrapcp.Constraint_MapTo(self, vars)
+
+    def IndexOf(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint_IndexOf(self, *args)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_Constraint(self)
+        return weakref.proxy(self)
+
+ +
+ +

A constraint is the main modeling object. It provides two methods: - Post() is responsible for creating the demons and attaching them to immediate demons(). - InitialPropagate() is called once just after Post and performs the initial propagation. The subsequent propagations will be performed by the demons Posted during the post() method.

+
+ + +
+
#   + + + Constraint(solver: pywrapcp.Solver) +
+ +
+ View Source +
    def __init__(self, solver: "Solver"):
+        if self.__class__ == Constraint:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.Constraint_swiginit(self, _pywrapcp.new_Constraint(_self, solver))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Post(self) -> 'void': +
+ +
+ View Source +
    def Post(self) -> "void":
+        r""" This method is called when the constraint is processed by the solver. Its main usage is to attach demons to variables."""
+        return _pywrapcp.Constraint_Post(self)
+
+ +
+ +

This method is called when the constraint is processed by the solver. Its main usage is to attach demons to variables.

+
+ + +
+
+
#   + + + def + InitialPropagateWrapper(self) -> 'void': +
+ +
+ View Source +
    def InitialPropagateWrapper(self) -> "void":
+        r""" This method performs the initial propagation of the constraint. It is called just after the post."""
+        return _pywrapcp.Constraint_InitialPropagateWrapper(self)
+
+ +
+ +

This method performs the initial propagation of the constraint. It is called just after the post.

+
+ + +
+
+
#   + + + def + DebugString(self) -> 'std::string': +
+ +
+ View Source +
    def DebugString(self) -> "std::string":
+        return _pywrapcp.Constraint_DebugString(self)
+
+ +
+ + + +
+
+
#   + + + def + Var(self) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def Var(self) -> "operations_research::IntVar *":
+        r""" Creates a Boolean variable representing the status of the constraint (false = constraint is violated, true = constraint is satisfied). It returns nullptr if the constraint does not support this API."""
+        return _pywrapcp.Constraint_Var(self)
+
+ +
+ +

Creates a Boolean variable representing the status of the constraint (false = constraint is violated, true = constraint is satisfied). It returns nullptr if the constraint does not support this API.

+
+ + +
+
+
#   + + + def + Square(self) -> 'operations_research::IntExpr *': +
+ +
+ View Source +
    def Square(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint_Square(self)
+
+ +
+ + + +
+
+
#   + + + def + MapTo( + self, + vars: 'std::vector< operations_research::IntVar * > const &' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def MapTo(self, vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        return _pywrapcp.Constraint_MapTo(self, vars)
+
+ +
+ + + +
+
+
#   + + + def + IndexOf(self, *args) -> 'operations_research::IntExpr *': +
+ +
+ View Source +
    def IndexOf(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.Constraint_IndexOf(self, *args)
+
+ +
+ + + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ #   + + + class + SearchMonitor(BaseObject): +
+ +
+ View Source +
class SearchMonitor(BaseObject):
+    r""" A search monitor is a simple set of callbacks to monitor all search events"""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, s: "Solver"):
+        if self.__class__ == SearchMonitor:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.SearchMonitor_swiginit(self, _pywrapcp.new_SearchMonitor(_self, s))
+    __swig_destroy__ = _pywrapcp.delete_SearchMonitor
+
+    def EnterSearch(self) -> "void":
+        r""" Beginning of the search."""
+        return _pywrapcp.SearchMonitor_EnterSearch(self)
+
+    def RestartSearch(self) -> "void":
+        r""" Restart the search."""
+        return _pywrapcp.SearchMonitor_RestartSearch(self)
+
+    def ExitSearch(self) -> "void":
+        r""" End of the search."""
+        return _pywrapcp.SearchMonitor_ExitSearch(self)
+
+    def BeginNextDecision(self, b: "DecisionBuilder") -> "void":
+        r""" Before calling DecisionBuilder::Next."""
+        return _pywrapcp.SearchMonitor_BeginNextDecision(self, b)
+
+    def EndNextDecision(self, b: "DecisionBuilder", d: "Decision") -> "void":
+        r""" After calling DecisionBuilder::Next, along with the returned decision."""
+        return _pywrapcp.SearchMonitor_EndNextDecision(self, b, d)
+
+    def ApplyDecision(self, d: "Decision") -> "void":
+        r""" Before applying the decision."""
+        return _pywrapcp.SearchMonitor_ApplyDecision(self, d)
+
+    def RefuteDecision(self, d: "Decision") -> "void":
+        r""" Before refuting the decision."""
+        return _pywrapcp.SearchMonitor_RefuteDecision(self, d)
+
+    def AfterDecision(self, d: "Decision", apply: "bool") -> "void":
+        r""" Just after refuting or applying the decision, apply is true after Apply. This is called only if the Apply() or Refute() methods have not failed."""
+        return _pywrapcp.SearchMonitor_AfterDecision(self, d, apply)
+
+    def BeginFail(self) -> "void":
+        r""" Just when the failure occurs."""
+        return _pywrapcp.SearchMonitor_BeginFail(self)
+
+    def EndFail(self) -> "void":
+        r""" After completing the backtrack."""
+        return _pywrapcp.SearchMonitor_EndFail(self)
+
+    def BeginInitialPropagation(self) -> "void":
+        r""" Before the initial propagation."""
+        return _pywrapcp.SearchMonitor_BeginInitialPropagation(self)
+
+    def EndInitialPropagation(self) -> "void":
+        r""" After the initial propagation."""
+        return _pywrapcp.SearchMonitor_EndInitialPropagation(self)
+
+    def AcceptSolution(self) -> "bool":
+        r""" This method is called when a solution is found. It asserts whether the solution is valid. A value of false indicates that the solution should be discarded."""
+        return _pywrapcp.SearchMonitor_AcceptSolution(self)
+
+    def AtSolution(self) -> "bool":
+        r""" This method is called when a valid solution is found. If the return value is true, then search will resume after. If the result is false, then search will stop there."""
+        return _pywrapcp.SearchMonitor_AtSolution(self)
+
+    def NoMoreSolutions(self) -> "void":
+        r""" When the search tree is finished."""
+        return _pywrapcp.SearchMonitor_NoMoreSolutions(self)
+
+    def LocalOptimum(self) -> "bool":
+        r""" When a local optimum is reached. If 'true' is returned, the last solution is discarded and the search proceeds with the next one."""
+        return _pywrapcp.SearchMonitor_LocalOptimum(self)
+
+    def AcceptDelta(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
+        return _pywrapcp.SearchMonitor_AcceptDelta(self, delta, deltadelta)
+
+    def AcceptNeighbor(self) -> "void":
+        r""" After accepting a neighbor during local search."""
+        return _pywrapcp.SearchMonitor_AcceptNeighbor(self)
+
+    def solver(self) -> "operations_research::Solver *":
+        return _pywrapcp.SearchMonitor_solver(self)
+
+    def __repr__(self) -> "std::string":
+        return _pywrapcp.SearchMonitor___repr__(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.SearchMonitor___str__(self)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_SearchMonitor(self)
+        return weakref.proxy(self)
+
+ +
+ +

A search monitor is a simple set of callbacks to monitor all search events

+
+ + +
+
#   + + + SearchMonitor(s: pywrapcp.Solver) +
+ +
+ View Source +
    def __init__(self, s: "Solver"):
+        if self.__class__ == SearchMonitor:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.SearchMonitor_swiginit(self, _pywrapcp.new_SearchMonitor(_self, s))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + EnterSearch(self) -> 'void': +
+ +
+ View Source +
    def EnterSearch(self) -> "void":
+        r""" Beginning of the search."""
+        return _pywrapcp.SearchMonitor_EnterSearch(self)
+
+ +
+ +

Beginning of the search.

+
+ + +
+
+
#   + + + def + RestartSearch(self) -> 'void': +
+ +
+ View Source +
    def RestartSearch(self) -> "void":
+        r""" Restart the search."""
+        return _pywrapcp.SearchMonitor_RestartSearch(self)
+
+ +
+ +

Restart the search.

+
+ + +
+
+
#   + + + def + ExitSearch(self) -> 'void': +
+ +
+ View Source +
    def ExitSearch(self) -> "void":
+        r""" End of the search."""
+        return _pywrapcp.SearchMonitor_ExitSearch(self)
+
+ +
+ +

End of the search.

+
+ + +
+
+
#   + + + def + BeginNextDecision(self, b: pywrapcp.DecisionBuilder) -> 'void': +
+ +
+ View Source +
    def BeginNextDecision(self, b: "DecisionBuilder") -> "void":
+        r""" Before calling DecisionBuilder::Next."""
+        return _pywrapcp.SearchMonitor_BeginNextDecision(self, b)
+
+ +
+ +

Before calling DecisionBuilder::Next.

+
+ + +
+
+
#   + + + def + EndNextDecision(self, b: pywrapcp.DecisionBuilder, d: pywrapcp.Decision) -> 'void': +
+ +
+ View Source +
    def EndNextDecision(self, b: "DecisionBuilder", d: "Decision") -> "void":
+        r""" After calling DecisionBuilder::Next, along with the returned decision."""
+        return _pywrapcp.SearchMonitor_EndNextDecision(self, b, d)
+
+ +
+ +

After calling DecisionBuilder::Next, along with the returned decision.

+
+ + +
+
+
#   + + + def + ApplyDecision(self, d: pywrapcp.Decision) -> 'void': +
+ +
+ View Source +
    def ApplyDecision(self, d: "Decision") -> "void":
+        r""" Before applying the decision."""
+        return _pywrapcp.SearchMonitor_ApplyDecision(self, d)
+
+ +
+ +

Before applying the decision.

+
+ + +
+
+
#   + + + def + RefuteDecision(self, d: pywrapcp.Decision) -> 'void': +
+ +
+ View Source +
    def RefuteDecision(self, d: "Decision") -> "void":
+        r""" Before refuting the decision."""
+        return _pywrapcp.SearchMonitor_RefuteDecision(self, d)
+
+ +
+ +

Before refuting the decision.

+
+ + +
+
+
#   + + + def + AfterDecision(self, d: pywrapcp.Decision, apply: bool) -> 'void': +
+ +
+ View Source +
    def AfterDecision(self, d: "Decision", apply: "bool") -> "void":
+        r""" Just after refuting or applying the decision, apply is true after Apply. This is called only if the Apply() or Refute() methods have not failed."""
+        return _pywrapcp.SearchMonitor_AfterDecision(self, d, apply)
+
+ +
+ +

Just after refuting or applying the decision, apply is true after Apply. This is called only if the Apply() or Refute() methods have not failed.

+
+ + +
+
+
#   + + + def + BeginFail(self) -> 'void': +
+ +
+ View Source +
    def BeginFail(self) -> "void":
+        r""" Just when the failure occurs."""
+        return _pywrapcp.SearchMonitor_BeginFail(self)
+
+ +
+ +

Just when the failure occurs.

+
+ + +
+
+
#   + + + def + EndFail(self) -> 'void': +
+ +
+ View Source +
    def EndFail(self) -> "void":
+        r""" After completing the backtrack."""
+        return _pywrapcp.SearchMonitor_EndFail(self)
+
+ +
+ +

After completing the backtrack.

+
+ + +
+
+
#   + + + def + BeginInitialPropagation(self) -> 'void': +
+ +
+ View Source +
    def BeginInitialPropagation(self) -> "void":
+        r""" Before the initial propagation."""
+        return _pywrapcp.SearchMonitor_BeginInitialPropagation(self)
+
+ +
+ +

Before the initial propagation.

+
+ + +
+
+
#   + + + def + EndInitialPropagation(self) -> 'void': +
+ +
+ View Source +
    def EndInitialPropagation(self) -> "void":
+        r""" After the initial propagation."""
+        return _pywrapcp.SearchMonitor_EndInitialPropagation(self)
+
+ +
+ +

After the initial propagation.

+
+ + +
+
+
#   + + + def + AcceptSolution(self) -> bool: +
+ +
+ View Source +
    def AcceptSolution(self) -> "bool":
+        r""" This method is called when a solution is found. It asserts whether the solution is valid. A value of false indicates that the solution should be discarded."""
+        return _pywrapcp.SearchMonitor_AcceptSolution(self)
+
+ +
+ +

This method is called when a solution is found. It asserts whether the solution is valid. A value of false indicates that the solution should be discarded.

+
+ + +
+
+
#   + + + def + AtSolution(self) -> bool: +
+ +
+ View Source +
    def AtSolution(self) -> "bool":
+        r""" This method is called when a valid solution is found. If the return value is true, then search will resume after. If the result is false, then search will stop there."""
+        return _pywrapcp.SearchMonitor_AtSolution(self)
+
+ +
+ +

This method is called when a valid solution is found. If the return value is true, then search will resume after. If the result is false, then search will stop there.

+
+ + +
+
+
#   + + + def + NoMoreSolutions(self) -> 'void': +
+ +
+ View Source +
    def NoMoreSolutions(self) -> "void":
+        r""" When the search tree is finished."""
+        return _pywrapcp.SearchMonitor_NoMoreSolutions(self)
+
+ +
+ +

When the search tree is finished.

+
+ + +
+
+
#   + + + def + LocalOptimum(self) -> bool: +
+ +
+ View Source +
    def LocalOptimum(self) -> "bool":
+        r""" When a local optimum is reached. If 'true' is returned, the last solution is discarded and the search proceeds with the next one."""
+        return _pywrapcp.SearchMonitor_LocalOptimum(self)
+
+ +
+ +

When a local optimum is reached. If 'true' is returned, the last solution is discarded and the search proceeds with the next one.

+
+ + +
+
+
#   + + + def + AcceptDelta( + self, + delta: pywrapcp.Assignment, + deltadelta: pywrapcp.Assignment +) -> bool: +
+ +
+ View Source +
    def AcceptDelta(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
+        return _pywrapcp.SearchMonitor_AcceptDelta(self, delta, deltadelta)
+
+ +
+ + + +
+
+
#   + + + def + AcceptNeighbor(self) -> 'void': +
+ +
+ View Source +
    def AcceptNeighbor(self) -> "void":
+        r""" After accepting a neighbor during local search."""
+        return _pywrapcp.SearchMonitor_AcceptNeighbor(self)
+
+ +
+ +

After accepting a neighbor during local search.

+
+ + +
+
+
#   + + + def + solver(self) -> 'operations_research::Solver *': +
+ +
+ View Source +
    def solver(self) -> "operations_research::Solver *":
+        return _pywrapcp.SearchMonitor_solver(self)
+
+ +
+ + + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ #   + + + class + IntExpr(PropagationBaseObject): +
+ +
+ View Source +
class IntExpr(PropagationBaseObject):
+    r""" The class IntExpr is the base of all integer expressions in constraint programming. It contains the basic protocol for an expression:   - setting and modifying its bound   - querying if it is bound   - listening to events modifying its bounds   - casting it into a variable (instance of IntVar)"""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+    def Min(self) -> "int64_t":
+        return _pywrapcp.IntExpr_Min(self)
+
+    def SetMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntExpr_SetMin(self, m)
+
+    def Max(self) -> "int64_t":
+        return _pywrapcp.IntExpr_Max(self)
+
+    def SetMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntExpr_SetMax(self, m)
+
+    def SetRange(self, l: "int64_t", u: "int64_t") -> "void":
+        r""" This method sets both the min and the max of the expression."""
+        return _pywrapcp.IntExpr_SetRange(self, l, u)
+
+    def SetValue(self, v: "int64_t") -> "void":
+        r""" This method sets the value of the expression."""
+        return _pywrapcp.IntExpr_SetValue(self, v)
+
+    def Bound(self) -> "bool":
+        r""" Returns true if the min and the max of the expression are equal."""
+        return _pywrapcp.IntExpr_Bound(self)
+
+    def IsVar(self) -> "bool":
+        r""" Returns true if the expression is indeed a variable."""
+        return _pywrapcp.IntExpr_IsVar(self)
+
+    def Var(self) -> "operations_research::IntVar *":
+        r""" Creates a variable from the expression."""
+        return _pywrapcp.IntExpr_Var(self)
+
+    def VarWithName(self, name: "std::string const &") -> "operations_research::IntVar *":
+        r""" Creates a variable from the expression and set the name of the resulting var. If the expression is already a variable, then it will set the name of the expression, possibly overwriting it. This is just a shortcut to Var() followed by set_name()."""
+        return _pywrapcp.IntExpr_VarWithName(self, name)
+
+    def WhenRange(self, *args) -> "void":
+        r"""
+        *Overload 1:*
+        Attach a demon that will watch the min or the max of the expression.
+
+        |
+
+        *Overload 2:*
+        Attach a demon that will watch the min or the max of the expression.
+        """
+        return _pywrapcp.IntExpr_WhenRange(self, *args)
+
+    def __repr__(self) -> "std::string":
+        return _pywrapcp.IntExpr___repr__(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.IntExpr___str__(self)
+
+    def __add__(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___add__(self, *args)
+
+    def __radd__(self, v: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___radd__(self, v)
+
+    def __sub__(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___sub__(self, *args)
+
+    def __rsub__(self, v: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___rsub__(self, v)
+
+    def __mul__(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___mul__(self, *args)
+
+    def __rmul__(self, v: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___rmul__(self, v)
+
+    def __floordiv__(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___floordiv__(self, *args)
+
+    def __mod__(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___mod__(self, *args)
+
+    def __neg__(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___neg__(self)
+
+    def __abs__(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr___abs__(self)
+
+    def Square(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr_Square(self)
+
+    def __eq__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr___eq__(self, *args)
+
+    def __ne__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr___ne__(self, *args)
+
+    def __ge__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr___ge__(self, *args)
+
+    def __gt__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr___gt__(self, *args)
+
+    def __le__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr___le__(self, *args)
+
+    def __lt__(self, *args) -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr___lt__(self, *args)
+
+    def MapTo(self, vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr_MapTo(self, vars)
+
+    def IndexOf(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr_IndexOf(self, *args)
+
+    def IsMember(self, values: "std::vector< int64_t > const &") -> "operations_research::IntVar *":
+        return _pywrapcp.IntExpr_IsMember(self, values)
+
+    def Member(self, values: "std::vector< int64_t > const &") -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr_Member(self, values)
+
+    def NotMember(self, starts: "std::vector< int64_t > const &", ends: "std::vector< int64_t > const &") -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr_NotMember(self, starts, ends)
+
+ +
+ +

The class IntExpr is the base of all integer expressions in constraint programming. It contains the basic protocol for an expression: - setting and modifying its bound - querying if it is bound - listening to events modifying its bounds - casting it into a variable (instance of IntVar)

+
+ + +
+
#   + + + IntExpr(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Min(self) -> 'int64_t': +
+ +
+ View Source +
    def Min(self) -> "int64_t":
+        return _pywrapcp.IntExpr_Min(self)
+
+ +
+ + + +
+
+
#   + + + def + SetMin(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntExpr_SetMin(self, m)
+
+ +
+ + + +
+
+
#   + + + def + Max(self) -> 'int64_t': +
+ +
+ View Source +
    def Max(self) -> "int64_t":
+        return _pywrapcp.IntExpr_Max(self)
+
+ +
+ + + +
+
+
#   + + + def + SetMax(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntExpr_SetMax(self, m)
+
+ +
+ + + +
+
+
#   + + + def + SetRange(self, l: 'int64_t', u: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetRange(self, l: "int64_t", u: "int64_t") -> "void":
+        r""" This method sets both the min and the max of the expression."""
+        return _pywrapcp.IntExpr_SetRange(self, l, u)
+
+ +
+ +

This method sets both the min and the max of the expression.

+
+ + +
+
+
#   + + + def + SetValue(self, v: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetValue(self, v: "int64_t") -> "void":
+        r""" This method sets the value of the expression."""
+        return _pywrapcp.IntExpr_SetValue(self, v)
+
+ +
+ +

This method sets the value of the expression.

+
+ + +
+
+
#   + + + def + Bound(self) -> bool: +
+ +
+ View Source +
    def Bound(self) -> "bool":
+        r""" Returns true if the min and the max of the expression are equal."""
+        return _pywrapcp.IntExpr_Bound(self)
+
+ +
+ +

Returns true if the min and the max of the expression are equal.

+
+ + +
+
+
#   + + + def + IsVar(self) -> bool: +
+ +
+ View Source +
    def IsVar(self) -> "bool":
+        r""" Returns true if the expression is indeed a variable."""
+        return _pywrapcp.IntExpr_IsVar(self)
+
+ +
+ +

Returns true if the expression is indeed a variable.

+
+ + +
+
+
#   + + + def + Var(self) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def Var(self) -> "operations_research::IntVar *":
+        r""" Creates a variable from the expression."""
+        return _pywrapcp.IntExpr_Var(self)
+
+ +
+ +

Creates a variable from the expression.

+
+ + +
+
+
#   + + + def + VarWithName(self, name: 'std::string const &') -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def VarWithName(self, name: "std::string const &") -> "operations_research::IntVar *":
+        r""" Creates a variable from the expression and set the name of the resulting var. If the expression is already a variable, then it will set the name of the expression, possibly overwriting it. This is just a shortcut to Var() followed by set_name()."""
+        return _pywrapcp.IntExpr_VarWithName(self, name)
+
+ +
+ +

Creates a variable from the expression and set the name of the resulting var. If the expression is already a variable, then it will set the name of the expression, possibly overwriting it. This is just a shortcut to Var() followed by set_name().

+
+ + +
+
+
#   + + + def + WhenRange(self, *args) -> 'void': +
+ +
+ View Source +
    def WhenRange(self, *args) -> "void":
+        r"""
+        *Overload 1:*
+        Attach a demon that will watch the min or the max of the expression.
+
+        |
+
+        *Overload 2:*
+        Attach a demon that will watch the min or the max of the expression.
+        """
+        return _pywrapcp.IntExpr_WhenRange(self, *args)
+
+ +
+ +

Overload 1: +Attach a demon that will watch the min or the max of the expression.

+ +

|

+ +

Overload 2: +Attach a demon that will watch the min or the max of the expression.

+
+ + +
+
+
#   + + + def + Square(self) -> 'operations_research::IntExpr *': +
+ +
+ View Source +
    def Square(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr_Square(self)
+
+ +
+ + + +
+
+
#   + + + def + MapTo( + self, + vars: 'std::vector< operations_research::IntVar * > const &' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def MapTo(self, vars: "std::vector< operations_research::IntVar * > const &") -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr_MapTo(self, vars)
+
+ +
+ + + +
+
+
#   + + + def + IndexOf(self, *args) -> 'operations_research::IntExpr *': +
+ +
+ View Source +
    def IndexOf(self, *args) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntExpr_IndexOf(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + IsMember( + self, + values: 'std::vector< int64_t > const &' +) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def IsMember(self, values: "std::vector< int64_t > const &") -> "operations_research::IntVar *":
+        return _pywrapcp.IntExpr_IsMember(self, values)
+
+ +
+ + + +
+
+
#   + + + def + Member( + self, + values: 'std::vector< int64_t > const &' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def Member(self, values: "std::vector< int64_t > const &") -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr_Member(self, values)
+
+ +
+ + + +
+
+
#   + + + def + NotMember( + self, + starts: 'std::vector< int64_t > const &', + ends: 'std::vector< int64_t > const &' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def NotMember(self, starts: "std::vector< int64_t > const &", ends: "std::vector< int64_t > const &") -> "operations_research::Constraint *":
+        return _pywrapcp.IntExpr_NotMember(self, starts, ends)
+
+ +
+ + + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ #   + + + class + IntVarIterator(BaseObject): +
+ +
+ View Source +
class IntVarIterator(BaseObject):
+    r""" The class Iterator has two direct subclasses. HoleIterators iterates over all holes, that is value removed between the current min and max of the variable since the last time the variable was processed in the queue. DomainIterators iterates over all elements of the variable domain. Both iterators are not robust to domain changes. Hole iterators can also report values outside the current min and max of the variable. HoleIterators should only be called from a demon attached to the variable that has created this iterator. IntVar* current_var; std::unique_ptr<IntVarIterator> it(current_var->MakeHoleIterator(false)); for (const int64_t hole : InitAndGetValues(it)) {   /// use the hole }"""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+
+    def Init(self) -> "void":
+        r""" This method must be called before each loop."""
+        return _pywrapcp.IntVarIterator_Init(self)
+
+    def Ok(self) -> "bool":
+        r""" This method indicates if we can call Value() or not."""
+        return _pywrapcp.IntVarIterator_Ok(self)
+
+    def Value(self) -> "int64_t":
+        r""" This method returns the current value of the iterator."""
+        return _pywrapcp.IntVarIterator_Value(self)
+
+    def Next(self) -> "void":
+        r""" This method moves the iterator to the next value."""
+        return _pywrapcp.IntVarIterator_Next(self)
+
+    def DebugString(self) -> "std::string":
+        r""" Pretty Print."""
+        return _pywrapcp.IntVarIterator_DebugString(self)
+
+    def __iter__(self):
+      self.Init()
+      return self
+
+    def next(self):
+      if self.Ok():
+        result = self.Value()
+        self.Next()
+        return result
+      else:
+        raise StopIteration()
+
+    def __next__(self):
+      return self.next()
+
+ +
+ +

The class Iterator has two direct subclasses. HoleIterators iterates over all holes, that is value removed between the current min and max of the variable since the last time the variable was processed in the queue. DomainIterators iterates over all elements of the variable domain. Both iterators are not robust to domain changes. Hole iterators can also report values outside the current min and max of the variable. HoleIterators should only be called from a demon attached to the variable that has created this iterator. IntVar* current_var; std::unique_ptr it(current_var->MakeHoleIterator(false)); for (const int64_t hole : InitAndGetValues(it)) { /// use the hole }

+
+ + +
+
#   + + + IntVarIterator(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Init(self) -> 'void': +
+ +
+ View Source +
    def Init(self) -> "void":
+        r""" This method must be called before each loop."""
+        return _pywrapcp.IntVarIterator_Init(self)
+
+ +
+ +

This method must be called before each loop.

+
+ + +
+
+
#   + + + def + Ok(self) -> bool: +
+ +
+ View Source +
    def Ok(self) -> "bool":
+        r""" This method indicates if we can call Value() or not."""
+        return _pywrapcp.IntVarIterator_Ok(self)
+
+ +
+ +

This method indicates if we can call Value() or not.

+
+ + +
+
+
#   + + + def + Value(self) -> 'int64_t': +
+ +
+ View Source +
    def Value(self) -> "int64_t":
+        r""" This method returns the current value of the iterator."""
+        return _pywrapcp.IntVarIterator_Value(self)
+
+ +
+ +

This method returns the current value of the iterator.

+
+ + +
+
+
#   + + + def + Next(self) -> 'void': +
+ +
+ View Source +
    def Next(self) -> "void":
+        r""" This method moves the iterator to the next value."""
+        return _pywrapcp.IntVarIterator_Next(self)
+
+ +
+ +

This method moves the iterator to the next value.

+
+ + +
+
+
#   + + + def + DebugString(self) -> 'std::string': +
+ +
+ View Source +
    def DebugString(self) -> "std::string":
+        r""" Pretty Print."""
+        return _pywrapcp.IntVarIterator_DebugString(self)
+
+ +
+ +

Pretty Print.

+
+ + +
+
+
#   + + + def + next(self): +
+ +
+ View Source +
    def next(self):
+      if self.Ok():
+        result = self.Value()
+        self.Next()
+        return result
+      else:
+        raise StopIteration()
+
+ +
+ + + +
+
+
+
+ #   + + + class + IntVar(IntExpr): +
+ +
+ View Source +
class IntVar(IntExpr):
+    r""" The class IntVar is a subset of IntExpr. In addition to the IntExpr protocol, it offers persistence, removing values from the domains, and a finer model for events."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+    def IsVar(self) -> "bool":
+        return _pywrapcp.IntVar_IsVar(self)
+
+    def Var(self) -> "operations_research::IntVar *":
+        return _pywrapcp.IntVar_Var(self)
+
+    def Value(self) -> "int64_t":
+        r""" This method returns the value of the variable. This method checks before that the variable is bound."""
+        return _pywrapcp.IntVar_Value(self)
+
+    def RemoveValue(self, v: "int64_t") -> "void":
+        r""" This method removes the value 'v' from the domain of the variable."""
+        return _pywrapcp.IntVar_RemoveValue(self, v)
+
+    def RemoveInterval(self, l: "int64_t", u: "int64_t") -> "void":
+        r""" This method removes the interval 'l' .. 'u' from the domain of the variable. It assumes that 'l' <= 'u'."""
+        return _pywrapcp.IntVar_RemoveInterval(self, l, u)
+
+    def RemoveValues(self, values: "std::vector< int64_t > const &") -> "void":
+        r""" This method remove the values from the domain of the variable."""
+        return _pywrapcp.IntVar_RemoveValues(self, values)
+
+    def SetValues(self, values: "std::vector< int64_t > const &") -> "void":
+        r""" This method intersects the current domain with the values in the array."""
+        return _pywrapcp.IntVar_SetValues(self, values)
+
+    def WhenBound(self, *args) -> "void":
+        r"""
+        *Overload 1:*
+        This method attaches a demon that will be awakened when the variable is bound.
+
+        |
+
+        *Overload 2:*
+        This method attaches a closure that will be awakened when the variable is bound.
+        """
+        return _pywrapcp.IntVar_WhenBound(self, *args)
+
+    def WhenDomain(self, *args) -> "void":
+        r"""
+        *Overload 1:*
+        This method attaches a demon that will watch any domain modification of the domain of the variable.
+
+        |
+
+        *Overload 2:*
+        This method attaches a closure that will watch any domain modification of the domain of the variable.
+        """
+        return _pywrapcp.IntVar_WhenDomain(self, *args)
+
+    def Size(self) -> "uint64_t":
+        r""" This method returns the number of values in the domain of the variable."""
+        return _pywrapcp.IntVar_Size(self)
+
+    def Contains(self, v: "int64_t") -> "bool":
+        r""" This method returns whether the value 'v' is in the domain of the variable."""
+        return _pywrapcp.IntVar_Contains(self, v)
+
+    def HoleIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *":
+        r""" Creates a hole iterator. When 'reversible' is false, the returned object is created on the normal C++ heap and the solver does NOT take ownership of the object."""
+        return _pywrapcp.IntVar_HoleIteratorAux(self, reversible)
+
+    def DomainIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *":
+        r""" Creates a domain iterator. When 'reversible' is false, the returned object is created on the normal C++ heap and the solver does NOT take ownership of the object."""
+        return _pywrapcp.IntVar_DomainIteratorAux(self, reversible)
+
+    def OldMin(self) -> "int64_t":
+        r""" Returns the previous min."""
+        return _pywrapcp.IntVar_OldMin(self)
+
+    def OldMax(self) -> "int64_t":
+        r""" Returns the previous max."""
+        return _pywrapcp.IntVar_OldMax(self)
+
+    def __repr__(self) -> "std::string":
+        return _pywrapcp.IntVar___repr__(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.IntVar___str__(self)
+
+    def DomainIterator(self):
+      return iter(self.DomainIteratorAux(False))
+
+    def HoleIterator(self):
+      return iter(self.HoleIteratorAux(False))
+
+ +
+ +

The class IntVar is a subset of IntExpr. In addition to the IntExpr protocol, it offers persistence, removing values from the domains, and a finer model for events.

+
+ + +
+
#   + + + IntVar(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + IsVar(self) -> bool: +
+ +
+ View Source +
    def IsVar(self) -> "bool":
+        return _pywrapcp.IntVar_IsVar(self)
+
+ +
+ +

Returns true if the expression is indeed a variable.

+
+ + +
+
+
#   + + + def + Var(self) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def Var(self) -> "operations_research::IntVar *":
+        return _pywrapcp.IntVar_Var(self)
+
+ +
+ +

Creates a variable from the expression.

+
+ + +
+
+
#   + + + def + Value(self) -> 'int64_t': +
+ +
+ View Source +
    def Value(self) -> "int64_t":
+        r""" This method returns the value of the variable. This method checks before that the variable is bound."""
+        return _pywrapcp.IntVar_Value(self)
+
+ +
+ +

This method returns the value of the variable. This method checks before that the variable is bound.

+
+ + +
+
+
#   + + + def + RemoveValue(self, v: 'int64_t') -> 'void': +
+ +
+ View Source +
    def RemoveValue(self, v: "int64_t") -> "void":
+        r""" This method removes the value 'v' from the domain of the variable."""
+        return _pywrapcp.IntVar_RemoveValue(self, v)
+
+ +
+ +

This method removes the value 'v' from the domain of the variable.

+
+ + +
+
+
#   + + + def + RemoveInterval(self, l: 'int64_t', u: 'int64_t') -> 'void': +
+ +
+ View Source +
    def RemoveInterval(self, l: "int64_t", u: "int64_t") -> "void":
+        r""" This method removes the interval 'l' .. 'u' from the domain of the variable. It assumes that 'l' <= 'u'."""
+        return _pywrapcp.IntVar_RemoveInterval(self, l, u)
+
+ +
+ +

This method removes the interval 'l' .. 'u' from the domain of the variable. It assumes that 'l' <= 'u'.

+
+ + +
+
+
#   + + + def + RemoveValues(self, values: 'std::vector< int64_t > const &') -> 'void': +
+ +
+ View Source +
    def RemoveValues(self, values: "std::vector< int64_t > const &") -> "void":
+        r""" This method remove the values from the domain of the variable."""
+        return _pywrapcp.IntVar_RemoveValues(self, values)
+
+ +
+ +

This method remove the values from the domain of the variable.

+
+ + +
+
+
#   + + + def + SetValues(self, values: 'std::vector< int64_t > const &') -> 'void': +
+ +
+ View Source +
    def SetValues(self, values: "std::vector< int64_t > const &") -> "void":
+        r""" This method intersects the current domain with the values in the array."""
+        return _pywrapcp.IntVar_SetValues(self, values)
+
+ +
+ +

This method intersects the current domain with the values in the array.

+
+ + +
+
+
#   + + + def + WhenBound(self, *args) -> 'void': +
+ +
+ View Source +
    def WhenBound(self, *args) -> "void":
+        r"""
+        *Overload 1:*
+        This method attaches a demon that will be awakened when the variable is bound.
+
+        |
+
+        *Overload 2:*
+        This method attaches a closure that will be awakened when the variable is bound.
+        """
+        return _pywrapcp.IntVar_WhenBound(self, *args)
+
+ +
+ +

Overload 1: +This method attaches a demon that will be awakened when the variable is bound.

+ +

|

+ +

Overload 2: +This method attaches a closure that will be awakened when the variable is bound.

+
+ + +
+
+
#   + + + def + WhenDomain(self, *args) -> 'void': +
+ +
+ View Source +
    def WhenDomain(self, *args) -> "void":
+        r"""
+        *Overload 1:*
+        This method attaches a demon that will watch any domain modification of the domain of the variable.
+
+        |
+
+        *Overload 2:*
+        This method attaches a closure that will watch any domain modification of the domain of the variable.
+        """
+        return _pywrapcp.IntVar_WhenDomain(self, *args)
+
+ +
+ +

Overload 1: +This method attaches a demon that will watch any domain modification of the domain of the variable.

+ +

|

+ +

Overload 2: +This method attaches a closure that will watch any domain modification of the domain of the variable.

+
+ + +
+
+
#   + + + def + Size(self) -> 'uint64_t': +
+ +
+ View Source +
    def Size(self) -> "uint64_t":
+        r""" This method returns the number of values in the domain of the variable."""
+        return _pywrapcp.IntVar_Size(self)
+
+ +
+ +

This method returns the number of values in the domain of the variable.

+
+ + +
+
+
#   + + + def + Contains(self, v: 'int64_t') -> bool: +
+ +
+ View Source +
    def Contains(self, v: "int64_t") -> "bool":
+        r""" This method returns whether the value 'v' is in the domain of the variable."""
+        return _pywrapcp.IntVar_Contains(self, v)
+
+ +
+ +

This method returns whether the value 'v' is in the domain of the variable.

+
+ + +
+
+
#   + + + def + HoleIteratorAux(self, reversible: bool) -> 'operations_research::IntVarIterator *': +
+ +
+ View Source +
    def HoleIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *":
+        r""" Creates a hole iterator. When 'reversible' is false, the returned object is created on the normal C++ heap and the solver does NOT take ownership of the object."""
+        return _pywrapcp.IntVar_HoleIteratorAux(self, reversible)
+
+ +
+ +

Creates a hole iterator. When 'reversible' is false, the returned object is created on the normal C++ heap and the solver does NOT take ownership of the object.

+
+ + +
+
+
#   + + + def + DomainIteratorAux(self, reversible: bool) -> 'operations_research::IntVarIterator *': +
+ +
+ View Source +
    def DomainIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *":
+        r""" Creates a domain iterator. When 'reversible' is false, the returned object is created on the normal C++ heap and the solver does NOT take ownership of the object."""
+        return _pywrapcp.IntVar_DomainIteratorAux(self, reversible)
+
+ +
+ +

Creates a domain iterator. When 'reversible' is false, the returned object is created on the normal C++ heap and the solver does NOT take ownership of the object.

+
+ + +
+
+
#   + + + def + OldMin(self) -> 'int64_t': +
+ +
+ View Source +
    def OldMin(self) -> "int64_t":
+        r""" Returns the previous min."""
+        return _pywrapcp.IntVar_OldMin(self)
+
+ +
+ +

Returns the previous min.

+
+ + +
+
+
#   + + + def + OldMax(self) -> 'int64_t': +
+ +
+ View Source +
    def OldMax(self) -> "int64_t":
+        r""" Returns the previous max."""
+        return _pywrapcp.IntVar_OldMax(self)
+
+ +
+ +

Returns the previous max.

+
+ + +
+
+
#   + + + def + DomainIterator(self): +
+ +
+ View Source +
    def DomainIterator(self):
+      return iter(self.DomainIteratorAux(False))
+
+ +
+ + + +
+
+
#   + + + def + HoleIterator(self): +
+ +
+ View Source +
    def HoleIterator(self):
+      return iter(self.HoleIteratorAux(False))
+
+ +
+ + + +
+ +
+
+
+ #   + + + class + SolutionCollector(SearchMonitor): +
+ +
+ View Source +
class SolutionCollector(SearchMonitor):
+    r""" This class is the root class of all solution collectors. It implements a basic query API to be used independently of the collector used."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.SolutionCollector_DebugString(self)
+
+    def Add(self, *args) -> "void":
+        return _pywrapcp.SolutionCollector_Add(self, *args)
+
+    def AddObjective(self, objective: "IntVar") -> "void":
+        return _pywrapcp.SolutionCollector_AddObjective(self, objective)
+
+    def EnterSearch(self) -> "void":
+        r""" Beginning of the search."""
+        return _pywrapcp.SolutionCollector_EnterSearch(self)
+
+    def SolutionCount(self) -> "int":
+        r""" Returns how many solutions were stored during the search."""
+        return _pywrapcp.SolutionCollector_SolutionCount(self)
+
+    def Solution(self, n: "int") -> "operations_research::Assignment *":
+        r""" Returns the nth solution."""
+        return _pywrapcp.SolutionCollector_Solution(self, n)
+
+    def WallTime(self, n: "int") -> "int64_t":
+        r""" Returns the wall time in ms for the nth solution."""
+        return _pywrapcp.SolutionCollector_WallTime(self, n)
+
+    def Branches(self, n: "int") -> "int64_t":
+        r""" Returns the number of branches when the nth solution was found."""
+        return _pywrapcp.SolutionCollector_Branches(self, n)
+
+    def Failures(self, n: "int") -> "int64_t":
+        r""" Returns the number of failures encountered at the time of the nth solution."""
+        return _pywrapcp.SolutionCollector_Failures(self, n)
+
+    def ObjectiveValue(self, n: "int") -> "int64_t":
+        r""" Returns the objective value of the nth solution."""
+        return _pywrapcp.SolutionCollector_ObjectiveValue(self, n)
+
+    def Value(self, n: "int", var: "IntVar") -> "int64_t":
+        r""" This is a shortcut to get the Value of 'var' in the nth solution."""
+        return _pywrapcp.SolutionCollector_Value(self, n, var)
+
+    def StartValue(self, n: "int", var: "IntervalVar") -> "int64_t":
+        r""" This is a shortcut to get the StartValue of 'var' in the nth solution."""
+        return _pywrapcp.SolutionCollector_StartValue(self, n, var)
+
+    def EndValue(self, n: "int", var: "IntervalVar") -> "int64_t":
+        r""" This is a shortcut to get the EndValue of 'var' in the nth solution."""
+        return _pywrapcp.SolutionCollector_EndValue(self, n, var)
+
+    def DurationValue(self, n: "int", var: "IntervalVar") -> "int64_t":
+        r""" This is a shortcut to get the DurationValue of 'var' in the nth solution."""
+        return _pywrapcp.SolutionCollector_DurationValue(self, n, var)
+
+    def PerformedValue(self, n: "int", var: "IntervalVar") -> "int64_t":
+        r""" This is a shortcut to get the PerformedValue of 'var' in the nth solution."""
+        return _pywrapcp.SolutionCollector_PerformedValue(self, n, var)
+
+    def ForwardSequence(self, n: "int", var: "SequenceVar") -> "std::vector< int > const &":
+        r""" This is a shortcut to get the ForwardSequence of 'var' in the nth solution. The forward sequence is the list of ranked interval variables starting from the start of the sequence."""
+        return _pywrapcp.SolutionCollector_ForwardSequence(self, n, var)
+
+    def BackwardSequence(self, n: "int", var: "SequenceVar") -> "std::vector< int > const &":
+        r""" This is a shortcut to get the BackwardSequence of 'var' in the nth solution. The backward sequence is the list of ranked interval variables starting from the end of the sequence."""
+        return _pywrapcp.SolutionCollector_BackwardSequence(self, n, var)
+
+    def Unperformed(self, n: "int", var: "SequenceVar") -> "std::vector< int > const &":
+        r""" This is a shortcut to get the list of unperformed of 'var' in the nth solution."""
+        return _pywrapcp.SolutionCollector_Unperformed(self, n, var)
+
+ +
+ +

This class is the root class of all solution collectors. It implements a basic query API to be used independently of the collector used.

+
+ + +
+
#   + + + SolutionCollector(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + DebugString(self) -> 'std::string': +
+ +
+ View Source +
    def DebugString(self) -> "std::string":
+        return _pywrapcp.SolutionCollector_DebugString(self)
+
+ +
+ + + +
+
+
#   + + + def + Add(self, *args) -> 'void': +
+ +
+ View Source +
    def Add(self, *args) -> "void":
+        return _pywrapcp.SolutionCollector_Add(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + AddObjective(self, objective: pywrapcp.IntVar) -> 'void': +
+ +
+ View Source +
    def AddObjective(self, objective: "IntVar") -> "void":
+        return _pywrapcp.SolutionCollector_AddObjective(self, objective)
+
+ +
+ + + +
+
+
#   + + + def + EnterSearch(self) -> 'void': +
+ +
+ View Source +
    def EnterSearch(self) -> "void":
+        r""" Beginning of the search."""
+        return _pywrapcp.SolutionCollector_EnterSearch(self)
+
+ +
+ +

Beginning of the search.

+
+ + +
+
+
#   + + + def + SolutionCount(self) -> int: +
+ +
+ View Source +
    def SolutionCount(self) -> "int":
+        r""" Returns how many solutions were stored during the search."""
+        return _pywrapcp.SolutionCollector_SolutionCount(self)
+
+ +
+ +

Returns how many solutions were stored during the search.

+
+ + +
+
+
#   + + + def + Solution(self, n: int) -> 'operations_research::Assignment *': +
+ +
+ View Source +
    def Solution(self, n: "int") -> "operations_research::Assignment *":
+        r""" Returns the nth solution."""
+        return _pywrapcp.SolutionCollector_Solution(self, n)
+
+ +
+ +

Returns the nth solution.

+
+ + +
+
+
#   + + + def + WallTime(self, n: int) -> 'int64_t': +
+ +
+ View Source +
    def WallTime(self, n: "int") -> "int64_t":
+        r""" Returns the wall time in ms for the nth solution."""
+        return _pywrapcp.SolutionCollector_WallTime(self, n)
+
+ +
+ +

Returns the wall time in ms for the nth solution.

+
+ + +
+
+
#   + + + def + Branches(self, n: int) -> 'int64_t': +
+ +
+ View Source +
    def Branches(self, n: "int") -> "int64_t":
+        r""" Returns the number of branches when the nth solution was found."""
+        return _pywrapcp.SolutionCollector_Branches(self, n)
+
+ +
+ +

Returns the number of branches when the nth solution was found.

+
+ + +
+
+
#   + + + def + Failures(self, n: int) -> 'int64_t': +
+ +
+ View Source +
    def Failures(self, n: "int") -> "int64_t":
+        r""" Returns the number of failures encountered at the time of the nth solution."""
+        return _pywrapcp.SolutionCollector_Failures(self, n)
+
+ +
+ +

Returns the number of failures encountered at the time of the nth solution.

+
+ + +
+
+
#   + + + def + ObjectiveValue(self, n: int) -> 'int64_t': +
+ +
+ View Source +
    def ObjectiveValue(self, n: "int") -> "int64_t":
+        r""" Returns the objective value of the nth solution."""
+        return _pywrapcp.SolutionCollector_ObjectiveValue(self, n)
+
+ +
+ +

Returns the objective value of the nth solution.

+
+ + +
+
+
#   + + + def + Value(self, n: int, var: pywrapcp.IntVar) -> 'int64_t': +
+ +
+ View Source +
    def Value(self, n: "int", var: "IntVar") -> "int64_t":
+        r""" This is a shortcut to get the Value of 'var' in the nth solution."""
+        return _pywrapcp.SolutionCollector_Value(self, n, var)
+
+ +
+ +

This is a shortcut to get the Value of 'var' in the nth solution.

+
+ + +
+
+
#   + + + def + StartValue(self, n: int, var: pywrapcp.IntervalVar) -> 'int64_t': +
+ +
+ View Source +
    def StartValue(self, n: "int", var: "IntervalVar") -> "int64_t":
+        r""" This is a shortcut to get the StartValue of 'var' in the nth solution."""
+        return _pywrapcp.SolutionCollector_StartValue(self, n, var)
+
+ +
+ +

This is a shortcut to get the StartValue of 'var' in the nth solution.

+
+ + +
+
+
#   + + + def + EndValue(self, n: int, var: pywrapcp.IntervalVar) -> 'int64_t': +
+ +
+ View Source +
    def EndValue(self, n: "int", var: "IntervalVar") -> "int64_t":
+        r""" This is a shortcut to get the EndValue of 'var' in the nth solution."""
+        return _pywrapcp.SolutionCollector_EndValue(self, n, var)
+
+ +
+ +

This is a shortcut to get the EndValue of 'var' in the nth solution.

+
+ + +
+
+
#   + + + def + DurationValue(self, n: int, var: pywrapcp.IntervalVar) -> 'int64_t': +
+ +
+ View Source +
    def DurationValue(self, n: "int", var: "IntervalVar") -> "int64_t":
+        r""" This is a shortcut to get the DurationValue of 'var' in the nth solution."""
+        return _pywrapcp.SolutionCollector_DurationValue(self, n, var)
+
+ +
+ +

This is a shortcut to get the DurationValue of 'var' in the nth solution.

+
+ + +
+
+
#   + + + def + PerformedValue(self, n: int, var: pywrapcp.IntervalVar) -> 'int64_t': +
+ +
+ View Source +
    def PerformedValue(self, n: "int", var: "IntervalVar") -> "int64_t":
+        r""" This is a shortcut to get the PerformedValue of 'var' in the nth solution."""
+        return _pywrapcp.SolutionCollector_PerformedValue(self, n, var)
+
+ +
+ +

This is a shortcut to get the PerformedValue of 'var' in the nth solution.

+
+ + +
+
+
#   + + + def + ForwardSequence( + self, + n: int, + var: pywrapcp.SequenceVar +) -> 'std::vector< int > const &': +
+ +
+ View Source +
    def ForwardSequence(self, n: "int", var: "SequenceVar") -> "std::vector< int > const &":
+        r""" This is a shortcut to get the ForwardSequence of 'var' in the nth solution. The forward sequence is the list of ranked interval variables starting from the start of the sequence."""
+        return _pywrapcp.SolutionCollector_ForwardSequence(self, n, var)
+
+ +
+ +

This is a shortcut to get the ForwardSequence of 'var' in the nth solution. The forward sequence is the list of ranked interval variables starting from the start of the sequence.

+
+ + +
+
+
#   + + + def + BackwardSequence( + self, + n: int, + var: pywrapcp.SequenceVar +) -> 'std::vector< int > const &': +
+ +
+ View Source +
    def BackwardSequence(self, n: "int", var: "SequenceVar") -> "std::vector< int > const &":
+        r""" This is a shortcut to get the BackwardSequence of 'var' in the nth solution. The backward sequence is the list of ranked interval variables starting from the end of the sequence."""
+        return _pywrapcp.SolutionCollector_BackwardSequence(self, n, var)
+
+ +
+ +

This is a shortcut to get the BackwardSequence of 'var' in the nth solution. The backward sequence is the list of ranked interval variables starting from the end of the sequence.

+
+ + +
+
+
#   + + + def + Unperformed( + self, + n: int, + var: pywrapcp.SequenceVar +) -> 'std::vector< int > const &': +
+ +
+ View Source +
    def Unperformed(self, n: "int", var: "SequenceVar") -> "std::vector< int > const &":
+        r""" This is a shortcut to get the list of unperformed of 'var' in the nth solution."""
+        return _pywrapcp.SolutionCollector_Unperformed(self, n, var)
+
+ +
+ +

This is a shortcut to get the list of unperformed of 'var' in the nth solution.

+
+ + +
+ +
+
+
+ #   + + + class + OptimizeVar(SearchMonitor): +
+ +
+ View Source +
class OptimizeVar(SearchMonitor):
+    r""" This class encapsulates an objective. It requires the direction (minimize or maximize), the variable to optimize, and the improvement step."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Best(self) -> "int64_t":
+        r""" Returns the best value found during search."""
+        return _pywrapcp.OptimizeVar_Best(self)
+
+    def Var(self) -> "operations_research::IntVar *":
+        r""" Returns the variable that is optimized."""
+        return _pywrapcp.OptimizeVar_Var(self)
+
+    def AcceptDelta(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
+        r""" Internal methods."""
+        return _pywrapcp.OptimizeVar_AcceptDelta(self, delta, deltadelta)
+
+    def EnterSearch(self) -> "void":
+        return _pywrapcp.OptimizeVar_EnterSearch(self)
+
+    def BeginNextDecision(self, db: "DecisionBuilder") -> "void":
+        return _pywrapcp.OptimizeVar_BeginNextDecision(self, db)
+
+    def RefuteDecision(self, d: "Decision") -> "void":
+        return _pywrapcp.OptimizeVar_RefuteDecision(self, d)
+
+    def AtSolution(self) -> "bool":
+        return _pywrapcp.OptimizeVar_AtSolution(self)
+
+    def AcceptSolution(self) -> "bool":
+        return _pywrapcp.OptimizeVar_AcceptSolution(self)
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.OptimizeVar_DebugString(self)
+
+ +
+ +

This class encapsulates an objective. It requires the direction (minimize or maximize), the variable to optimize, and the improvement step.

+
+ + +
+
#   + + + OptimizeVar(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Best(self) -> 'int64_t': +
+ +
+ View Source +
    def Best(self) -> "int64_t":
+        r""" Returns the best value found during search."""
+        return _pywrapcp.OptimizeVar_Best(self)
+
+ +
+ +

Returns the best value found during search.

+
+ + +
+
+
#   + + + def + Var(self) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def Var(self) -> "operations_research::IntVar *":
+        r""" Returns the variable that is optimized."""
+        return _pywrapcp.OptimizeVar_Var(self)
+
+ +
+ +

Returns the variable that is optimized.

+
+ + +
+
+
#   + + + def + AcceptDelta( + self, + delta: pywrapcp.Assignment, + deltadelta: pywrapcp.Assignment +) -> bool: +
+ +
+ View Source +
    def AcceptDelta(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
+        r""" Internal methods."""
+        return _pywrapcp.OptimizeVar_AcceptDelta(self, delta, deltadelta)
+
+ +
+ +

Internal methods.

+
+ + +
+
+
#   + + + def + EnterSearch(self) -> 'void': +
+ +
+ View Source +
    def EnterSearch(self) -> "void":
+        return _pywrapcp.OptimizeVar_EnterSearch(self)
+
+ +
+ +

Beginning of the search.

+
+ + +
+
+
#   + + + def + BeginNextDecision(self, db: pywrapcp.DecisionBuilder) -> 'void': +
+ +
+ View Source +
    def BeginNextDecision(self, db: "DecisionBuilder") -> "void":
+        return _pywrapcp.OptimizeVar_BeginNextDecision(self, db)
+
+ +
+ +

Before calling DecisionBuilder::Next.

+
+ + +
+
+
#   + + + def + RefuteDecision(self, d: pywrapcp.Decision) -> 'void': +
+ +
+ View Source +
    def RefuteDecision(self, d: "Decision") -> "void":
+        return _pywrapcp.OptimizeVar_RefuteDecision(self, d)
+
+ +
+ +

Before refuting the decision.

+
+ + +
+
+
#   + + + def + AtSolution(self) -> bool: +
+ +
+ View Source +
    def AtSolution(self) -> "bool":
+        return _pywrapcp.OptimizeVar_AtSolution(self)
+
+ +
+ +

This method is called when a valid solution is found. If the return value is true, then search will resume after. If the result is false, then search will stop there.

+
+ + +
+
+
#   + + + def + AcceptSolution(self) -> bool: +
+ +
+ View Source +
    def AcceptSolution(self) -> "bool":
+        return _pywrapcp.OptimizeVar_AcceptSolution(self)
+
+ +
+ +

This method is called when a solution is found. It asserts whether the solution is valid. A value of false indicates that the solution should be discarded.

+
+ + +
+
+
#   + + + def + DebugString(self) -> 'std::string': +
+ +
+ View Source +
    def DebugString(self) -> "std::string":
+        return _pywrapcp.OptimizeVar_DebugString(self)
+
+ +
+ + + +
+ +
+
+
+ #   + + + class + SearchLimit(SearchMonitor): +
+ +
+ View Source +
class SearchLimit(SearchMonitor):
+    r""" Base class of all search limits."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+    __swig_destroy__ = _pywrapcp.delete_SearchLimit
+
+    def Crossed(self) -> "bool":
+        r""" Returns true if the limit has been crossed."""
+        return _pywrapcp.SearchLimit_Crossed(self)
+
+    def Check(self) -> "bool":
+        r""" This method is called to check the status of the limit. A return value of true indicates that we have indeed crossed the limit. In that case, this method will not be called again and the remaining search will be discarded."""
+        return _pywrapcp.SearchLimit_Check(self)
+
+    def Init(self) -> "void":
+        r""" This method is called when the search limit is initialized."""
+        return _pywrapcp.SearchLimit_Init(self)
+
+    def EnterSearch(self) -> "void":
+        r""" Internal methods."""
+        return _pywrapcp.SearchLimit_EnterSearch(self)
+
+    def BeginNextDecision(self, b: "DecisionBuilder") -> "void":
+        return _pywrapcp.SearchLimit_BeginNextDecision(self, b)
+
+    def RefuteDecision(self, d: "Decision") -> "void":
+        return _pywrapcp.SearchLimit_RefuteDecision(self, d)
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.SearchLimit_DebugString(self)
+
+ +
+ +

Base class of all search limits.

+
+ + +
+
#   + + + SearchLimit(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Crossed(self) -> bool: +
+ +
+ View Source +
    def Crossed(self) -> "bool":
+        r""" Returns true if the limit has been crossed."""
+        return _pywrapcp.SearchLimit_Crossed(self)
+
+ +
+ +

Returns true if the limit has been crossed.

+
+ + +
+
+
#   + + + def + Check(self) -> bool: +
+ +
+ View Source +
    def Check(self) -> "bool":
+        r""" This method is called to check the status of the limit. A return value of true indicates that we have indeed crossed the limit. In that case, this method will not be called again and the remaining search will be discarded."""
+        return _pywrapcp.SearchLimit_Check(self)
+
+ +
+ +

This method is called to check the status of the limit. A return value of true indicates that we have indeed crossed the limit. In that case, this method will not be called again and the remaining search will be discarded.

+
+ + +
+
+
#   + + + def + Init(self) -> 'void': +
+ +
+ View Source +
    def Init(self) -> "void":
+        r""" This method is called when the search limit is initialized."""
+        return _pywrapcp.SearchLimit_Init(self)
+
+ +
+ +

This method is called when the search limit is initialized.

+
+ + +
+
+
#   + + + def + EnterSearch(self) -> 'void': +
+ +
+ View Source +
    def EnterSearch(self) -> "void":
+        r""" Internal methods."""
+        return _pywrapcp.SearchLimit_EnterSearch(self)
+
+ +
+ +

Internal methods.

+
+ + +
+
+
#   + + + def + BeginNextDecision(self, b: pywrapcp.DecisionBuilder) -> 'void': +
+ +
+ View Source +
    def BeginNextDecision(self, b: "DecisionBuilder") -> "void":
+        return _pywrapcp.SearchLimit_BeginNextDecision(self, b)
+
+ +
+ +

Before calling DecisionBuilder::Next.

+
+ + +
+
+
#   + + + def + RefuteDecision(self, d: pywrapcp.Decision) -> 'void': +
+ +
+ View Source +
    def RefuteDecision(self, d: "Decision") -> "void":
+        return _pywrapcp.SearchLimit_RefuteDecision(self, d)
+
+ +
+ +

Before refuting the decision.

+
+ + +
+
+
#   + + + def + DebugString(self) -> 'std::string': +
+ +
+ View Source +
    def DebugString(self) -> "std::string":
+        return _pywrapcp.SearchLimit_DebugString(self)
+
+ +
+ + + +
+ +
+
+
+ #   + + + class + IntervalVar(PropagationBaseObject): +
+ +
+ View Source +
class IntervalVar(PropagationBaseObject):
+    r""" Interval variables are often used in scheduling. The main characteristics of an IntervalVar are the start position, duration, and end date. All these characteristics can be queried and set, and demons can be posted on their modifications. An important aspect is optionality: an IntervalVar can be performed or not. If unperformed, then it simply does not exist, and its characteristics cannot be accessed any more. An interval var is automatically marked as unperformed when it is not consistent anymore (start greater than end, duration < 0...)"""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+    def StartMin(self) -> "int64_t":
+        r""" These methods query, set, and watch the start position of the interval var."""
+        return _pywrapcp.IntervalVar_StartMin(self)
+
+    def StartMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_StartMax(self)
+
+    def SetStartMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetStartMin(self, m)
+
+    def SetStartMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetStartMax(self, m)
+
+    def SetStartRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetStartRange(self, mi, ma)
+
+    def OldStartMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_OldStartMin(self)
+
+    def OldStartMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_OldStartMax(self)
+
+    def WhenStartRange(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenStartRange(self, *args)
+
+    def WhenStartBound(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenStartBound(self, *args)
+
+    def DurationMin(self) -> "int64_t":
+        r""" These methods query, set, and watch the duration of the interval var."""
+        return _pywrapcp.IntervalVar_DurationMin(self)
+
+    def DurationMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_DurationMax(self)
+
+    def SetDurationMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetDurationMin(self, m)
+
+    def SetDurationMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetDurationMax(self, m)
+
+    def SetDurationRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetDurationRange(self, mi, ma)
+
+    def OldDurationMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_OldDurationMin(self)
+
+    def OldDurationMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_OldDurationMax(self)
+
+    def WhenDurationRange(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenDurationRange(self, *args)
+
+    def WhenDurationBound(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenDurationBound(self, *args)
+
+    def EndMin(self) -> "int64_t":
+        r""" These methods query, set, and watch the end position of the interval var."""
+        return _pywrapcp.IntervalVar_EndMin(self)
+
+    def EndMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_EndMax(self)
+
+    def SetEndMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetEndMin(self, m)
+
+    def SetEndMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetEndMax(self, m)
+
+    def SetEndRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetEndRange(self, mi, ma)
+
+    def OldEndMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_OldEndMin(self)
+
+    def OldEndMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_OldEndMax(self)
+
+    def WhenEndRange(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenEndRange(self, *args)
+
+    def WhenEndBound(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenEndBound(self, *args)
+
+    def MustBePerformed(self) -> "bool":
+        r""" These methods query, set, and watch the performed status of the interval var."""
+        return _pywrapcp.IntervalVar_MustBePerformed(self)
+
+    def MayBePerformed(self) -> "bool":
+        return _pywrapcp.IntervalVar_MayBePerformed(self)
+
+    def CannotBePerformed(self) -> "bool":
+        return _pywrapcp.IntervalVar_CannotBePerformed(self)
+
+    def IsPerformedBound(self) -> "bool":
+        return _pywrapcp.IntervalVar_IsPerformedBound(self)
+
+    def SetPerformed(self, val: "bool") -> "void":
+        return _pywrapcp.IntervalVar_SetPerformed(self, val)
+
+    def WasPerformedBound(self) -> "bool":
+        return _pywrapcp.IntervalVar_WasPerformedBound(self)
+
+    def WhenPerformedBound(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenPerformedBound(self, *args)
+
+    def WhenAnything(self, *args) -> "void":
+        r"""
+        *Overload 1:*
+        Attaches a demon awakened when anything about this interval changes.
+
+        |
+
+        *Overload 2:*
+        Attaches a closure awakened when anything about this interval changes.
+        """
+        return _pywrapcp.IntervalVar_WhenAnything(self, *args)
+
+    def StartExpr(self) -> "operations_research::IntExpr *":
+        r""" These methods create expressions encapsulating the start, end and duration of the interval var. Please note that these must not be used if the interval var is unperformed."""
+        return _pywrapcp.IntervalVar_StartExpr(self)
+
+    def DurationExpr(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntervalVar_DurationExpr(self)
+
+    def EndExpr(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntervalVar_EndExpr(self)
+
+    def PerformedExpr(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntervalVar_PerformedExpr(self)
+
+    def SafeStartExpr(self, unperformed_value: "int64_t") -> "operations_research::IntExpr *":
+        r""" These methods create expressions encapsulating the start, end and duration of the interval var. If the interval var is unperformed, they will return the unperformed_value."""
+        return _pywrapcp.IntervalVar_SafeStartExpr(self, unperformed_value)
+
+    def SafeDurationExpr(self, unperformed_value: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.IntervalVar_SafeDurationExpr(self, unperformed_value)
+
+    def SafeEndExpr(self, unperformed_value: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.IntervalVar_SafeEndExpr(self, unperformed_value)
+
+    def EndsAfterEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAfterEnd(self, other)
+
+    def EndsAfterEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAfterEndWithDelay(self, other, delay)
+
+    def EndsAfterStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAfterStart(self, other)
+
+    def EndsAfterStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAfterStartWithDelay(self, other, delay)
+
+    def EndsAtEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAtEnd(self, other)
+
+    def EndsAtEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAtEndWithDelay(self, other, delay)
+
+    def EndsAtStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAtStart(self, other)
+
+    def EndsAtStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAtStartWithDelay(self, other, delay)
+
+    def StartsAfterEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAfterEnd(self, other)
+
+    def StartsAfterEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAfterEndWithDelay(self, other, delay)
+
+    def StartsAfterStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAfterStart(self, other)
+
+    def StartsAfterStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAfterStartWithDelay(self, other, delay)
+
+    def StartsAtEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAtEnd(self, other)
+
+    def StartsAtEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAtEndWithDelay(self, other, delay)
+
+    def StartsAtStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAtStart(self, other)
+
+    def StartsAtStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAtStartWithDelay(self, other, delay)
+
+    def StaysInSync(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StaysInSync(self, other)
+
+    def StaysInSyncWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StaysInSyncWithDelay(self, other, delay)
+
+    def EndsAfter(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAfter(self, date)
+
+    def EndsAt(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAt(self, date)
+
+    def EndsBefore(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsBefore(self, date)
+
+    def StartsAfter(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAfter(self, date)
+
+    def StartsAt(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAt(self, date)
+
+    def StartsBefore(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsBefore(self, date)
+
+    def CrossesDate(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_CrossesDate(self, date)
+
+    def AvoidsDate(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_AvoidsDate(self, date)
+
+    def __repr__(self) -> "std::string":
+        return _pywrapcp.IntervalVar___repr__(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.IntervalVar___str__(self)
+
+ +
+ +

Interval variables are often used in scheduling. The main characteristics of an IntervalVar are the start position, duration, and end date. All these characteristics can be queried and set, and demons can be posted on their modifications. An important aspect is optionality: an IntervalVar can be performed or not. If unperformed, then it simply does not exist, and its characteristics cannot be accessed any more. An interval var is automatically marked as unperformed when it is not consistent anymore (start greater than end, duration < 0...)

+
+ + +
+
#   + + + IntervalVar(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + StartMin(self) -> 'int64_t': +
+ +
+ View Source +
    def StartMin(self) -> "int64_t":
+        r""" These methods query, set, and watch the start position of the interval var."""
+        return _pywrapcp.IntervalVar_StartMin(self)
+
+ +
+ +

These methods query, set, and watch the start position of the interval var.

+
+ + +
+
+
#   + + + def + StartMax(self) -> 'int64_t': +
+ +
+ View Source +
    def StartMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_StartMax(self)
+
+ +
+ + + +
+
+
#   + + + def + SetStartMin(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetStartMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetStartMin(self, m)
+
+ +
+ + + +
+
+
#   + + + def + SetStartMax(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetStartMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetStartMax(self, m)
+
+ +
+ + + +
+
+
#   + + + def + SetStartRange(self, mi: 'int64_t', ma: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetStartRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetStartRange(self, mi, ma)
+
+ +
+ + + +
+
+
#   + + + def + OldStartMin(self) -> 'int64_t': +
+ +
+ View Source +
    def OldStartMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_OldStartMin(self)
+
+ +
+ + + +
+
+
#   + + + def + OldStartMax(self) -> 'int64_t': +
+ +
+ View Source +
    def OldStartMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_OldStartMax(self)
+
+ +
+ + + +
+
+
#   + + + def + WhenStartRange(self, *args) -> 'void': +
+ +
+ View Source +
    def WhenStartRange(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenStartRange(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + WhenStartBound(self, *args) -> 'void': +
+ +
+ View Source +
    def WhenStartBound(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenStartBound(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + DurationMin(self) -> 'int64_t': +
+ +
+ View Source +
    def DurationMin(self) -> "int64_t":
+        r""" These methods query, set, and watch the duration of the interval var."""
+        return _pywrapcp.IntervalVar_DurationMin(self)
+
+ +
+ +

These methods query, set, and watch the duration of the interval var.

+
+ + +
+
+
#   + + + def + DurationMax(self) -> 'int64_t': +
+ +
+ View Source +
    def DurationMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_DurationMax(self)
+
+ +
+ + + +
+
+
#   + + + def + SetDurationMin(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetDurationMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetDurationMin(self, m)
+
+ +
+ + + +
+
+
#   + + + def + SetDurationMax(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetDurationMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetDurationMax(self, m)
+
+ +
+ + + +
+
+
#   + + + def + SetDurationRange(self, mi: 'int64_t', ma: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetDurationRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetDurationRange(self, mi, ma)
+
+ +
+ + + +
+
+
#   + + + def + OldDurationMin(self) -> 'int64_t': +
+ +
+ View Source +
    def OldDurationMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_OldDurationMin(self)
+
+ +
+ + + +
+
+
#   + + + def + OldDurationMax(self) -> 'int64_t': +
+ +
+ View Source +
    def OldDurationMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_OldDurationMax(self)
+
+ +
+ + + +
+
+
#   + + + def + WhenDurationRange(self, *args) -> 'void': +
+ +
+ View Source +
    def WhenDurationRange(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenDurationRange(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + WhenDurationBound(self, *args) -> 'void': +
+ +
+ View Source +
    def WhenDurationBound(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenDurationBound(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + EndMin(self) -> 'int64_t': +
+ +
+ View Source +
    def EndMin(self) -> "int64_t":
+        r""" These methods query, set, and watch the end position of the interval var."""
+        return _pywrapcp.IntervalVar_EndMin(self)
+
+ +
+ +

These methods query, set, and watch the end position of the interval var.

+
+ + +
+
+
#   + + + def + EndMax(self) -> 'int64_t': +
+ +
+ View Source +
    def EndMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_EndMax(self)
+
+ +
+ + + +
+
+
#   + + + def + SetEndMin(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetEndMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetEndMin(self, m)
+
+ +
+ + + +
+
+
#   + + + def + SetEndMax(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetEndMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetEndMax(self, m)
+
+ +
+ + + +
+
+
#   + + + def + SetEndRange(self, mi: 'int64_t', ma: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetEndRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVar_SetEndRange(self, mi, ma)
+
+ +
+ + + +
+
+
#   + + + def + OldEndMin(self) -> 'int64_t': +
+ +
+ View Source +
    def OldEndMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_OldEndMin(self)
+
+ +
+ + + +
+
+
#   + + + def + OldEndMax(self) -> 'int64_t': +
+ +
+ View Source +
    def OldEndMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVar_OldEndMax(self)
+
+ +
+ + + +
+
+
#   + + + def + WhenEndRange(self, *args) -> 'void': +
+ +
+ View Source +
    def WhenEndRange(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenEndRange(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + WhenEndBound(self, *args) -> 'void': +
+ +
+ View Source +
    def WhenEndBound(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenEndBound(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + MustBePerformed(self) -> bool: +
+ +
+ View Source +
    def MustBePerformed(self) -> "bool":
+        r""" These methods query, set, and watch the performed status of the interval var."""
+        return _pywrapcp.IntervalVar_MustBePerformed(self)
+
+ +
+ +

These methods query, set, and watch the performed status of the interval var.

+
+ + +
+
+
#   + + + def + MayBePerformed(self) -> bool: +
+ +
+ View Source +
    def MayBePerformed(self) -> "bool":
+        return _pywrapcp.IntervalVar_MayBePerformed(self)
+
+ +
+ + + +
+
+
#   + + + def + CannotBePerformed(self) -> bool: +
+ +
+ View Source +
    def CannotBePerformed(self) -> "bool":
+        return _pywrapcp.IntervalVar_CannotBePerformed(self)
+
+ +
+ + + +
+
+
#   + + + def + IsPerformedBound(self) -> bool: +
+ +
+ View Source +
    def IsPerformedBound(self) -> "bool":
+        return _pywrapcp.IntervalVar_IsPerformedBound(self)
+
+ +
+ + + +
+
+
#   + + + def + SetPerformed(self, val: bool) -> 'void': +
+ +
+ View Source +
    def SetPerformed(self, val: "bool") -> "void":
+        return _pywrapcp.IntervalVar_SetPerformed(self, val)
+
+ +
+ + + +
+
+
#   + + + def + WasPerformedBound(self) -> bool: +
+ +
+ View Source +
    def WasPerformedBound(self) -> "bool":
+        return _pywrapcp.IntervalVar_WasPerformedBound(self)
+
+ +
+ + + +
+
+
#   + + + def + WhenPerformedBound(self, *args) -> 'void': +
+ +
+ View Source +
    def WhenPerformedBound(self, *args) -> "void":
+        return _pywrapcp.IntervalVar_WhenPerformedBound(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + WhenAnything(self, *args) -> 'void': +
+ +
+ View Source +
    def WhenAnything(self, *args) -> "void":
+        r"""
+        *Overload 1:*
+        Attaches a demon awakened when anything about this interval changes.
+
+        |
+
+        *Overload 2:*
+        Attaches a closure awakened when anything about this interval changes.
+        """
+        return _pywrapcp.IntervalVar_WhenAnything(self, *args)
+
+ +
+ +

Overload 1: +Attaches a demon awakened when anything about this interval changes.

+ +

|

+ +

Overload 2: +Attaches a closure awakened when anything about this interval changes.

+
+ + +
+
+
#   + + + def + StartExpr(self) -> 'operations_research::IntExpr *': +
+ +
+ View Source +
    def StartExpr(self) -> "operations_research::IntExpr *":
+        r""" These methods create expressions encapsulating the start, end and duration of the interval var. Please note that these must not be used if the interval var is unperformed."""
+        return _pywrapcp.IntervalVar_StartExpr(self)
+
+ +
+ +

These methods create expressions encapsulating the start, end and duration of the interval var. Please note that these must not be used if the interval var is unperformed.

+
+ + +
+
+
#   + + + def + DurationExpr(self) -> 'operations_research::IntExpr *': +
+ +
+ View Source +
    def DurationExpr(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntervalVar_DurationExpr(self)
+
+ +
+ + + +
+
+
#   + + + def + EndExpr(self) -> 'operations_research::IntExpr *': +
+ +
+ View Source +
    def EndExpr(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntervalVar_EndExpr(self)
+
+ +
+ + + +
+
+
#   + + + def + PerformedExpr(self) -> 'operations_research::IntExpr *': +
+ +
+ View Source +
    def PerformedExpr(self) -> "operations_research::IntExpr *":
+        return _pywrapcp.IntervalVar_PerformedExpr(self)
+
+ +
+ + + +
+
+
#   + + + def + SafeStartExpr( + self, + unperformed_value: 'int64_t' +) -> 'operations_research::IntExpr *': +
+ +
+ View Source +
    def SafeStartExpr(self, unperformed_value: "int64_t") -> "operations_research::IntExpr *":
+        r""" These methods create expressions encapsulating the start, end and duration of the interval var. If the interval var is unperformed, they will return the unperformed_value."""
+        return _pywrapcp.IntervalVar_SafeStartExpr(self, unperformed_value)
+
+ +
+ +

These methods create expressions encapsulating the start, end and duration of the interval var. If the interval var is unperformed, they will return the unperformed_value.

+
+ + +
+
+
#   + + + def + SafeDurationExpr( + self, + unperformed_value: 'int64_t' +) -> 'operations_research::IntExpr *': +
+ +
+ View Source +
    def SafeDurationExpr(self, unperformed_value: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.IntervalVar_SafeDurationExpr(self, unperformed_value)
+
+ +
+ + + +
+
+
#   + + + def + SafeEndExpr( + self, + unperformed_value: 'int64_t' +) -> 'operations_research::IntExpr *': +
+ +
+ View Source +
    def SafeEndExpr(self, unperformed_value: "int64_t") -> "operations_research::IntExpr *":
+        return _pywrapcp.IntervalVar_SafeEndExpr(self, unperformed_value)
+
+ +
+ + + +
+
+
#   + + + def + EndsAfterEnd( + self, + other: pywrapcp.IntervalVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def EndsAfterEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAfterEnd(self, other)
+
+ +
+ + + +
+
+
#   + + + def + EndsAfterEndWithDelay( + self, + other: pywrapcp.IntervalVar, + delay: 'int64_t' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def EndsAfterEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAfterEndWithDelay(self, other, delay)
+
+ +
+ + + +
+
+
#   + + + def + EndsAfterStart( + self, + other: pywrapcp.IntervalVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def EndsAfterStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAfterStart(self, other)
+
+ +
+ + + +
+
+
#   + + + def + EndsAfterStartWithDelay( + self, + other: pywrapcp.IntervalVar, + delay: 'int64_t' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def EndsAfterStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAfterStartWithDelay(self, other, delay)
+
+ +
+ + + +
+
+
#   + + + def + EndsAtEnd( + self, + other: pywrapcp.IntervalVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def EndsAtEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAtEnd(self, other)
+
+ +
+ + + +
+
+
#   + + + def + EndsAtEndWithDelay( + self, + other: pywrapcp.IntervalVar, + delay: 'int64_t' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def EndsAtEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAtEndWithDelay(self, other, delay)
+
+ +
+ + + +
+
+
#   + + + def + EndsAtStart( + self, + other: pywrapcp.IntervalVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def EndsAtStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAtStart(self, other)
+
+ +
+ + + +
+
+
#   + + + def + EndsAtStartWithDelay( + self, + other: pywrapcp.IntervalVar, + delay: 'int64_t' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def EndsAtStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAtStartWithDelay(self, other, delay)
+
+ +
+ + + +
+
+
#   + + + def + StartsAfterEnd( + self, + other: pywrapcp.IntervalVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def StartsAfterEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAfterEnd(self, other)
+
+ +
+ + + +
+
+
#   + + + def + StartsAfterEndWithDelay( + self, + other: pywrapcp.IntervalVar, + delay: 'int64_t' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def StartsAfterEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAfterEndWithDelay(self, other, delay)
+
+ +
+ + + +
+
+
#   + + + def + StartsAfterStart( + self, + other: pywrapcp.IntervalVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def StartsAfterStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAfterStart(self, other)
+
+ +
+ + + +
+
+
#   + + + def + StartsAfterStartWithDelay( + self, + other: pywrapcp.IntervalVar, + delay: 'int64_t' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def StartsAfterStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAfterStartWithDelay(self, other, delay)
+
+ +
+ + + +
+
+
#   + + + def + StartsAtEnd( + self, + other: pywrapcp.IntervalVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def StartsAtEnd(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAtEnd(self, other)
+
+ +
+ + + +
+
+
#   + + + def + StartsAtEndWithDelay( + self, + other: pywrapcp.IntervalVar, + delay: 'int64_t' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def StartsAtEndWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAtEndWithDelay(self, other, delay)
+
+ +
+ + + +
+
+
#   + + + def + StartsAtStart( + self, + other: pywrapcp.IntervalVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def StartsAtStart(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAtStart(self, other)
+
+ +
+ + + +
+
+
#   + + + def + StartsAtStartWithDelay( + self, + other: pywrapcp.IntervalVar, + delay: 'int64_t' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def StartsAtStartWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAtStartWithDelay(self, other, delay)
+
+ +
+ + + +
+
+
#   + + + def + StaysInSync( + self, + other: pywrapcp.IntervalVar +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def StaysInSync(self, other: "IntervalVar") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StaysInSync(self, other)
+
+ +
+ + + +
+
+
#   + + + def + StaysInSyncWithDelay( + self, + other: pywrapcp.IntervalVar, + delay: 'int64_t' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def StaysInSyncWithDelay(self, other: "IntervalVar", delay: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StaysInSyncWithDelay(self, other, delay)
+
+ +
+ + + +
+
+
#   + + + def + EndsAfter(self, date: 'int64_t') -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def EndsAfter(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAfter(self, date)
+
+ +
+ + + +
+
+
#   + + + def + EndsAt(self, date: 'int64_t') -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def EndsAt(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsAt(self, date)
+
+ +
+ + + +
+
+
#   + + + def + EndsBefore(self, date: 'int64_t') -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def EndsBefore(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_EndsBefore(self, date)
+
+ +
+ + + +
+
+
#   + + + def + StartsAfter(self, date: 'int64_t') -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def StartsAfter(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAfter(self, date)
+
+ +
+ + + +
+
+
#   + + + def + StartsAt(self, date: 'int64_t') -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def StartsAt(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsAt(self, date)
+
+ +
+ + + +
+
+
#   + + + def + StartsBefore(self, date: 'int64_t') -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def StartsBefore(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_StartsBefore(self, date)
+
+ +
+ + + +
+
+
#   + + + def + CrossesDate(self, date: 'int64_t') -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def CrossesDate(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_CrossesDate(self, date)
+
+ +
+ + + +
+
+
#   + + + def + AvoidsDate(self, date: 'int64_t') -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def AvoidsDate(self, date: "int64_t") -> "operations_research::Constraint *":
+        return _pywrapcp.IntervalVar_AvoidsDate(self, date)
+
+ +
+ + + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ #   + + + class + SequenceVar(PropagationBaseObject): +
+ +
+ View Source +
class SequenceVar(PropagationBaseObject):
+    r""" A sequence variable is a variable whose domain is a set of possible orderings of the interval variables. It allows ordering of tasks. It has two sets of methods: ComputePossibleFirstsAndLasts(), which returns the list of interval variables that can be ranked first or last; and RankFirst/RankNotFirst/RankLast/RankNotLast, which can be used to create the search decision."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.SequenceVar_DebugString(self)
+
+    def RankFirst(self, index: "int") -> "void":
+        r""" Ranks the index_th interval var first of all unranked interval vars. After that, it will no longer be considered ranked."""
+        return _pywrapcp.SequenceVar_RankFirst(self, index)
+
+    def RankNotFirst(self, index: "int") -> "void":
+        r""" Indicates that the index_th interval var will not be ranked first of all currently unranked interval vars."""
+        return _pywrapcp.SequenceVar_RankNotFirst(self, index)
+
+    def RankLast(self, index: "int") -> "void":
+        r""" Ranks the index_th interval var first of all unranked interval vars. After that, it will no longer be considered ranked."""
+        return _pywrapcp.SequenceVar_RankLast(self, index)
+
+    def RankNotLast(self, index: "int") -> "void":
+        r""" Indicates that the index_th interval var will not be ranked first of all currently unranked interval vars."""
+        return _pywrapcp.SequenceVar_RankNotLast(self, index)
+
+    def Interval(self, index: "int") -> "operations_research::IntervalVar *":
+        r""" Returns the index_th interval of the sequence."""
+        return _pywrapcp.SequenceVar_Interval(self, index)
+
+    def Next(self, index: "int") -> "operations_research::IntVar *":
+        r""" Returns the next of the index_th interval of the sequence."""
+        return _pywrapcp.SequenceVar_Next(self, index)
+
+    def Size(self) -> "int64_t":
+        r""" Returns the number of interval vars in the sequence."""
+        return _pywrapcp.SequenceVar_Size(self)
+
+    def __repr__(self) -> "std::string":
+        return _pywrapcp.SequenceVar___repr__(self)
+
+    def __str__(self) -> "std::string":
+        return _pywrapcp.SequenceVar___str__(self)
+
+ +
+ +

A sequence variable is a variable whose domain is a set of possible orderings of the interval variables. It allows ordering of tasks. It has two sets of methods: ComputePossibleFirstsAndLasts(), which returns the list of interval variables that can be ranked first or last; and RankFirst/RankNotFirst/RankLast/RankNotLast, which can be used to create the search decision.

+
+ + +
+
#   + + + SequenceVar(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + DebugString(self) -> 'std::string': +
+ +
+ View Source +
    def DebugString(self) -> "std::string":
+        return _pywrapcp.SequenceVar_DebugString(self)
+
+ +
+ + + +
+
+
#   + + + def + RankFirst(self, index: int) -> 'void': +
+ +
+ View Source +
    def RankFirst(self, index: "int") -> "void":
+        r""" Ranks the index_th interval var first of all unranked interval vars. After that, it will no longer be considered ranked."""
+        return _pywrapcp.SequenceVar_RankFirst(self, index)
+
+ +
+ +

Ranks the index_th interval var first of all unranked interval vars. After that, it will no longer be considered ranked.

+
+ + +
+
+
#   + + + def + RankNotFirst(self, index: int) -> 'void': +
+ +
+ View Source +
    def RankNotFirst(self, index: "int") -> "void":
+        r""" Indicates that the index_th interval var will not be ranked first of all currently unranked interval vars."""
+        return _pywrapcp.SequenceVar_RankNotFirst(self, index)
+
+ +
+ +

Indicates that the index_th interval var will not be ranked first of all currently unranked interval vars.

+
+ + +
+
+
#   + + + def + RankLast(self, index: int) -> 'void': +
+ +
+ View Source +
    def RankLast(self, index: "int") -> "void":
+        r""" Ranks the index_th interval var first of all unranked interval vars. After that, it will no longer be considered ranked."""
+        return _pywrapcp.SequenceVar_RankLast(self, index)
+
+ +
+ +

Ranks the index_th interval var first of all unranked interval vars. After that, it will no longer be considered ranked.

+
+ + +
+
+
#   + + + def + RankNotLast(self, index: int) -> 'void': +
+ +
+ View Source +
    def RankNotLast(self, index: "int") -> "void":
+        r""" Indicates that the index_th interval var will not be ranked first of all currently unranked interval vars."""
+        return _pywrapcp.SequenceVar_RankNotLast(self, index)
+
+ +
+ +

Indicates that the index_th interval var will not be ranked first of all currently unranked interval vars.

+
+ + +
+
+
#   + + + def + Interval(self, index: int) -> 'operations_research::IntervalVar *': +
+ +
+ View Source +
    def Interval(self, index: "int") -> "operations_research::IntervalVar *":
+        r""" Returns the index_th interval of the sequence."""
+        return _pywrapcp.SequenceVar_Interval(self, index)
+
+ +
+ +

Returns the index_th interval of the sequence.

+
+ + +
+
+
#   + + + def + Next(self, index: int) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def Next(self, index: "int") -> "operations_research::IntVar *":
+        r""" Returns the next of the index_th interval of the sequence."""
+        return _pywrapcp.SequenceVar_Next(self, index)
+
+ +
+ +

Returns the next of the index_th interval of the sequence.

+
+ + +
+
+
#   + + + def + Size(self) -> 'int64_t': +
+ +
+ View Source +
    def Size(self) -> "int64_t":
+        r""" Returns the number of interval vars in the sequence."""
+        return _pywrapcp.SequenceVar_Size(self)
+
+ +
+ +

Returns the number of interval vars in the sequence.

+
+ + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ #   + + + class + AssignmentElement: +
+ +
+ View Source +
class AssignmentElement(object):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Activate(self) -> "void":
+        return _pywrapcp.AssignmentElement_Activate(self)
+
+    def Deactivate(self) -> "void":
+        return _pywrapcp.AssignmentElement_Deactivate(self)
+
+    def Activated(self) -> "bool":
+        return _pywrapcp.AssignmentElement_Activated(self)
+    __swig_destroy__ = _pywrapcp.delete_AssignmentElement
+
+ +
+ + + +
+
#   + + + AssignmentElement(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Activate(self) -> 'void': +
+ +
+ View Source +
    def Activate(self) -> "void":
+        return _pywrapcp.AssignmentElement_Activate(self)
+
+ +
+ + + +
+
+
#   + + + def + Deactivate(self) -> 'void': +
+ +
+ View Source +
    def Deactivate(self) -> "void":
+        return _pywrapcp.AssignmentElement_Deactivate(self)
+
+ +
+ + + +
+
+
#   + + + def + Activated(self) -> bool: +
+ +
+ View Source +
    def Activated(self) -> "bool":
+        return _pywrapcp.AssignmentElement_Activated(self)
+
+ +
+ + + +
+
+
+
+ #   + + + class + IntVarElement(AssignmentElement): +
+ +
+ View Source +
class IntVarElement(AssignmentElement):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Var(self) -> "operations_research::IntVar *":
+        return _pywrapcp.IntVarElement_Var(self)
+
+    def Min(self) -> "int64_t":
+        return _pywrapcp.IntVarElement_Min(self)
+
+    def SetMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntVarElement_SetMin(self, m)
+
+    def Max(self) -> "int64_t":
+        return _pywrapcp.IntVarElement_Max(self)
+
+    def SetMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntVarElement_SetMax(self, m)
+
+    def Value(self) -> "int64_t":
+        return _pywrapcp.IntVarElement_Value(self)
+
+    def Bound(self) -> "bool":
+        return _pywrapcp.IntVarElement_Bound(self)
+
+    def SetRange(self, l: "int64_t", u: "int64_t") -> "void":
+        return _pywrapcp.IntVarElement_SetRange(self, l, u)
+
+    def SetValue(self, v: "int64_t") -> "void":
+        return _pywrapcp.IntVarElement_SetValue(self, v)
+
+    def __eq__(self, element: "IntVarElement") -> "bool":
+        return _pywrapcp.IntVarElement___eq__(self, element)
+
+    def __ne__(self, element: "IntVarElement") -> "bool":
+        return _pywrapcp.IntVarElement___ne__(self, element)
+    __swig_destroy__ = _pywrapcp.delete_IntVarElement
+
+ +
+ + + +
+
#   + + + IntVarElement(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Var(self) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def Var(self) -> "operations_research::IntVar *":
+        return _pywrapcp.IntVarElement_Var(self)
+
+ +
+ + + +
+
+
#   + + + def + Min(self) -> 'int64_t': +
+ +
+ View Source +
    def Min(self) -> "int64_t":
+        return _pywrapcp.IntVarElement_Min(self)
+
+ +
+ + + +
+
+
#   + + + def + SetMin(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntVarElement_SetMin(self, m)
+
+ +
+ + + +
+
+
#   + + + def + Max(self) -> 'int64_t': +
+ +
+ View Source +
    def Max(self) -> "int64_t":
+        return _pywrapcp.IntVarElement_Max(self)
+
+ +
+ + + +
+
+
#   + + + def + SetMax(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntVarElement_SetMax(self, m)
+
+ +
+ + + +
+
+
#   + + + def + Value(self) -> 'int64_t': +
+ +
+ View Source +
    def Value(self) -> "int64_t":
+        return _pywrapcp.IntVarElement_Value(self)
+
+ +
+ + + +
+
+
#   + + + def + Bound(self) -> bool: +
+ +
+ View Source +
    def Bound(self) -> "bool":
+        return _pywrapcp.IntVarElement_Bound(self)
+
+ +
+ + + +
+
+
#   + + + def + SetRange(self, l: 'int64_t', u: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetRange(self, l: "int64_t", u: "int64_t") -> "void":
+        return _pywrapcp.IntVarElement_SetRange(self, l, u)
+
+ +
+ + + +
+
+
#   + + + def + SetValue(self, v: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetValue(self, v: "int64_t") -> "void":
+        return _pywrapcp.IntVarElement_SetValue(self, v)
+
+ +
+ + + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ #   + + + class + IntervalVarElement(AssignmentElement): +
+ +
+ View Source +
class IntervalVarElement(AssignmentElement):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Var(self) -> "operations_research::IntervalVar *":
+        return _pywrapcp.IntervalVarElement_Var(self)
+
+    def StartMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_StartMin(self)
+
+    def StartMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_StartMax(self)
+
+    def StartValue(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_StartValue(self)
+
+    def DurationMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_DurationMin(self)
+
+    def DurationMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_DurationMax(self)
+
+    def DurationValue(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_DurationValue(self)
+
+    def EndMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_EndMin(self)
+
+    def EndMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_EndMax(self)
+
+    def EndValue(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_EndValue(self)
+
+    def PerformedMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_PerformedMin(self)
+
+    def PerformedMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_PerformedMax(self)
+
+    def PerformedValue(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_PerformedValue(self)
+
+    def SetStartMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetStartMin(self, m)
+
+    def SetStartMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetStartMax(self, m)
+
+    def SetStartRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetStartRange(self, mi, ma)
+
+    def SetStartValue(self, v: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetStartValue(self, v)
+
+    def SetDurationMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetDurationMin(self, m)
+
+    def SetDurationMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetDurationMax(self, m)
+
+    def SetDurationRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetDurationRange(self, mi, ma)
+
+    def SetDurationValue(self, v: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetDurationValue(self, v)
+
+    def SetEndMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetEndMin(self, m)
+
+    def SetEndMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetEndMax(self, m)
+
+    def SetEndRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetEndRange(self, mi, ma)
+
+    def SetEndValue(self, v: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetEndValue(self, v)
+
+    def SetPerformedMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetPerformedMin(self, m)
+
+    def SetPerformedMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetPerformedMax(self, m)
+
+    def SetPerformedRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetPerformedRange(self, mi, ma)
+
+    def SetPerformedValue(self, v: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetPerformedValue(self, v)
+
+    def __eq__(self, element: "IntervalVarElement") -> "bool":
+        return _pywrapcp.IntervalVarElement___eq__(self, element)
+
+    def __ne__(self, element: "IntervalVarElement") -> "bool":
+        return _pywrapcp.IntervalVarElement___ne__(self, element)
+    __swig_destroy__ = _pywrapcp.delete_IntervalVarElement
+
+ +
+ + + +
+
#   + + + IntervalVarElement(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Var(self) -> 'operations_research::IntervalVar *': +
+ +
+ View Source +
    def Var(self) -> "operations_research::IntervalVar *":
+        return _pywrapcp.IntervalVarElement_Var(self)
+
+ +
+ + + +
+
+
#   + + + def + StartMin(self) -> 'int64_t': +
+ +
+ View Source +
    def StartMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_StartMin(self)
+
+ +
+ + + +
+
+
#   + + + def + StartMax(self) -> 'int64_t': +
+ +
+ View Source +
    def StartMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_StartMax(self)
+
+ +
+ + + +
+
+
#   + + + def + StartValue(self) -> 'int64_t': +
+ +
+ View Source +
    def StartValue(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_StartValue(self)
+
+ +
+ + + +
+
+
#   + + + def + DurationMin(self) -> 'int64_t': +
+ +
+ View Source +
    def DurationMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_DurationMin(self)
+
+ +
+ + + +
+
+
#   + + + def + DurationMax(self) -> 'int64_t': +
+ +
+ View Source +
    def DurationMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_DurationMax(self)
+
+ +
+ + + +
+
+
#   + + + def + DurationValue(self) -> 'int64_t': +
+ +
+ View Source +
    def DurationValue(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_DurationValue(self)
+
+ +
+ + + +
+
+
#   + + + def + EndMin(self) -> 'int64_t': +
+ +
+ View Source +
    def EndMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_EndMin(self)
+
+ +
+ + + +
+
+
#   + + + def + EndMax(self) -> 'int64_t': +
+ +
+ View Source +
    def EndMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_EndMax(self)
+
+ +
+ + + +
+
+
#   + + + def + EndValue(self) -> 'int64_t': +
+ +
+ View Source +
    def EndValue(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_EndValue(self)
+
+ +
+ + + +
+
+
#   + + + def + PerformedMin(self) -> 'int64_t': +
+ +
+ View Source +
    def PerformedMin(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_PerformedMin(self)
+
+ +
+ + + +
+
+
#   + + + def + PerformedMax(self) -> 'int64_t': +
+ +
+ View Source +
    def PerformedMax(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_PerformedMax(self)
+
+ +
+ + + +
+
+
#   + + + def + PerformedValue(self) -> 'int64_t': +
+ +
+ View Source +
    def PerformedValue(self) -> "int64_t":
+        return _pywrapcp.IntervalVarElement_PerformedValue(self)
+
+ +
+ + + +
+
+
#   + + + def + SetStartMin(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetStartMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetStartMin(self, m)
+
+ +
+ + + +
+
+
#   + + + def + SetStartMax(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetStartMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetStartMax(self, m)
+
+ +
+ + + +
+
+
#   + + + def + SetStartRange(self, mi: 'int64_t', ma: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetStartRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetStartRange(self, mi, ma)
+
+ +
+ + + +
+
+
#   + + + def + SetStartValue(self, v: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetStartValue(self, v: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetStartValue(self, v)
+
+ +
+ + + +
+
+
#   + + + def + SetDurationMin(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetDurationMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetDurationMin(self, m)
+
+ +
+ + + +
+
+
#   + + + def + SetDurationMax(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetDurationMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetDurationMax(self, m)
+
+ +
+ + + +
+
+
#   + + + def + SetDurationRange(self, mi: 'int64_t', ma: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetDurationRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetDurationRange(self, mi, ma)
+
+ +
+ + + +
+
+
#   + + + def + SetDurationValue(self, v: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetDurationValue(self, v: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetDurationValue(self, v)
+
+ +
+ + + +
+
+
#   + + + def + SetEndMin(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetEndMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetEndMin(self, m)
+
+ +
+ + + +
+
+
#   + + + def + SetEndMax(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetEndMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetEndMax(self, m)
+
+ +
+ + + +
+
+
#   + + + def + SetEndRange(self, mi: 'int64_t', ma: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetEndRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetEndRange(self, mi, ma)
+
+ +
+ + + +
+
+
#   + + + def + SetEndValue(self, v: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetEndValue(self, v: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetEndValue(self, v)
+
+ +
+ + + +
+
+
#   + + + def + SetPerformedMin(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetPerformedMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetPerformedMin(self, m)
+
+ +
+ + + +
+
+
#   + + + def + SetPerformedMax(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetPerformedMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetPerformedMax(self, m)
+
+ +
+ + + +
+
+
#   + + + def + SetPerformedRange(self, mi: 'int64_t', ma: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetPerformedRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetPerformedRange(self, mi, ma)
+
+ +
+ + + +
+
+
#   + + + def + SetPerformedValue(self, v: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetPerformedValue(self, v: "int64_t") -> "void":
+        return _pywrapcp.IntervalVarElement_SetPerformedValue(self, v)
+
+ +
+ + + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ #   + + + class + SequenceVarElement(AssignmentElement): +
+ +
+ View Source +
class SequenceVarElement(AssignmentElement):
+    r""" The SequenceVarElement stores a partial representation of ranked interval variables in the underlying sequence variable. This representation consists of three vectors:   - the forward sequence. That is the list of interval variables     ranked first in the sequence.  The first element of the backward     sequence is the first interval in the sequence variable.   - the backward sequence. That is the list of interval variables     ranked last in the sequence. The first element of the backward     sequence is the last interval in the sequence variable.   - The list of unperformed interval variables.  Furthermore, if all performed variables are ranked, then by  convention, the forward_sequence will contain all such variables  and the backward_sequence will be empty."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Var(self) -> "operations_research::SequenceVar *":
+        return _pywrapcp.SequenceVarElement_Var(self)
+
+    def ForwardSequence(self) -> "std::vector< int > const &":
+        return _pywrapcp.SequenceVarElement_ForwardSequence(self)
+
+    def BackwardSequence(self) -> "std::vector< int > const &":
+        return _pywrapcp.SequenceVarElement_BackwardSequence(self)
+
+    def Unperformed(self) -> "std::vector< int > const &":
+        return _pywrapcp.SequenceVarElement_Unperformed(self)
+
+    def SetSequence(self, forward_sequence: "std::vector< int > const &", backward_sequence: "std::vector< int > const &", unperformed: "std::vector< int > const &") -> "void":
+        return _pywrapcp.SequenceVarElement_SetSequence(self, forward_sequence, backward_sequence, unperformed)
+
+    def SetForwardSequence(self, forward_sequence: "std::vector< int > const &") -> "void":
+        return _pywrapcp.SequenceVarElement_SetForwardSequence(self, forward_sequence)
+
+    def SetBackwardSequence(self, backward_sequence: "std::vector< int > const &") -> "void":
+        return _pywrapcp.SequenceVarElement_SetBackwardSequence(self, backward_sequence)
+
+    def SetUnperformed(self, unperformed: "std::vector< int > const &") -> "void":
+        return _pywrapcp.SequenceVarElement_SetUnperformed(self, unperformed)
+
+    def __eq__(self, element: "SequenceVarElement") -> "bool":
+        return _pywrapcp.SequenceVarElement___eq__(self, element)
+
+    def __ne__(self, element: "SequenceVarElement") -> "bool":
+        return _pywrapcp.SequenceVarElement___ne__(self, element)
+    __swig_destroy__ = _pywrapcp.delete_SequenceVarElement
+
+ +
+ +

The SequenceVarElement stores a partial representation of ranked interval variables in the underlying sequence variable. This representation consists of three vectors: - the forward sequence. That is the list of interval variables ranked first in the sequence. The first element of the backward sequence is the first interval in the sequence variable. - the backward sequence. That is the list of interval variables ranked last in the sequence. The first element of the backward sequence is the last interval in the sequence variable. - The list of unperformed interval variables. Furthermore, if all performed variables are ranked, then by convention, the forward_sequence will contain all such variables and the backward_sequence will be empty.

+
+ + +
+
#   + + + SequenceVarElement(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Var(self) -> 'operations_research::SequenceVar *': +
+ +
+ View Source +
    def Var(self) -> "operations_research::SequenceVar *":
+        return _pywrapcp.SequenceVarElement_Var(self)
+
+ +
+ + + +
+
+
#   + + + def + ForwardSequence(self) -> 'std::vector< int > const &': +
+ +
+ View Source +
    def ForwardSequence(self) -> "std::vector< int > const &":
+        return _pywrapcp.SequenceVarElement_ForwardSequence(self)
+
+ +
+ + + +
+
+
#   + + + def + BackwardSequence(self) -> 'std::vector< int > const &': +
+ +
+ View Source +
    def BackwardSequence(self) -> "std::vector< int > const &":
+        return _pywrapcp.SequenceVarElement_BackwardSequence(self)
+
+ +
+ + + +
+
+
#   + + + def + Unperformed(self) -> 'std::vector< int > const &': +
+ +
+ View Source +
    def Unperformed(self) -> "std::vector< int > const &":
+        return _pywrapcp.SequenceVarElement_Unperformed(self)
+
+ +
+ + + +
+
+
#   + + + def + SetSequence( + self, + forward_sequence: 'std::vector< int > const &', + backward_sequence: 'std::vector< int > const &', + unperformed: 'std::vector< int > const &' +) -> 'void': +
+ +
+ View Source +
    def SetSequence(self, forward_sequence: "std::vector< int > const &", backward_sequence: "std::vector< int > const &", unperformed: "std::vector< int > const &") -> "void":
+        return _pywrapcp.SequenceVarElement_SetSequence(self, forward_sequence, backward_sequence, unperformed)
+
+ +
+ + + +
+
+
#   + + + def + SetForwardSequence(self, forward_sequence: 'std::vector< int > const &') -> 'void': +
+ +
+ View Source +
    def SetForwardSequence(self, forward_sequence: "std::vector< int > const &") -> "void":
+        return _pywrapcp.SequenceVarElement_SetForwardSequence(self, forward_sequence)
+
+ +
+ + + +
+
+
#   + + + def + SetBackwardSequence(self, backward_sequence: 'std::vector< int > const &') -> 'void': +
+ +
+ View Source +
    def SetBackwardSequence(self, backward_sequence: "std::vector< int > const &") -> "void":
+        return _pywrapcp.SequenceVarElement_SetBackwardSequence(self, backward_sequence)
+
+ +
+ + + +
+
+
#   + + + def + SetUnperformed(self, unperformed: 'std::vector< int > const &') -> 'void': +
+ +
+ View Source +
    def SetUnperformed(self, unperformed: "std::vector< int > const &") -> "void":
+        return _pywrapcp.SequenceVarElement_SetUnperformed(self, unperformed)
+
+ +
+ + + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ #   + + + class + Assignment(PropagationBaseObject): +
+ +
+ View Source +
class Assignment(PropagationBaseObject):
+    r""" An Assignment is a variable -> domains mapping, used to report solutions to the user."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Clear(self) -> "void":
+        return _pywrapcp.Assignment_Clear(self)
+
+    def Empty(self) -> "bool":
+        return _pywrapcp.Assignment_Empty(self)
+
+    def Size(self) -> "int":
+        return _pywrapcp.Assignment_Size(self)
+
+    def NumIntVars(self) -> "int":
+        return _pywrapcp.Assignment_NumIntVars(self)
+
+    def NumIntervalVars(self) -> "int":
+        return _pywrapcp.Assignment_NumIntervalVars(self)
+
+    def NumSequenceVars(self) -> "int":
+        return _pywrapcp.Assignment_NumSequenceVars(self)
+
+    def Store(self) -> "void":
+        return _pywrapcp.Assignment_Store(self)
+
+    def Restore(self) -> "void":
+        return _pywrapcp.Assignment_Restore(self)
+
+    def Load(self, *args) -> "void":
+        return _pywrapcp.Assignment_Load(self, *args)
+
+    def Save(self, *args) -> "void":
+        return _pywrapcp.Assignment_Save(self, *args)
+
+    def AddObjective(self, v: "IntVar") -> "void":
+        return _pywrapcp.Assignment_AddObjective(self, v)
+
+    def Objective(self) -> "operations_research::IntVar *":
+        return _pywrapcp.Assignment_Objective(self)
+
+    def HasObjective(self) -> "bool":
+        return _pywrapcp.Assignment_HasObjective(self)
+
+    def ObjectiveMin(self) -> "int64_t":
+        return _pywrapcp.Assignment_ObjectiveMin(self)
+
+    def ObjectiveMax(self) -> "int64_t":
+        return _pywrapcp.Assignment_ObjectiveMax(self)
+
+    def ObjectiveValue(self) -> "int64_t":
+        return _pywrapcp.Assignment_ObjectiveValue(self)
+
+    def ObjectiveBound(self) -> "bool":
+        return _pywrapcp.Assignment_ObjectiveBound(self)
+
+    def SetObjectiveMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetObjectiveMin(self, m)
+
+    def SetObjectiveMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetObjectiveMax(self, m)
+
+    def SetObjectiveValue(self, value: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetObjectiveValue(self, value)
+
+    def SetObjectiveRange(self, l: "int64_t", u: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetObjectiveRange(self, l, u)
+
+    def Min(self, var: "IntVar") -> "int64_t":
+        return _pywrapcp.Assignment_Min(self, var)
+
+    def Max(self, var: "IntVar") -> "int64_t":
+        return _pywrapcp.Assignment_Max(self, var)
+
+    def Value(self, var: "IntVar") -> "int64_t":
+        return _pywrapcp.Assignment_Value(self, var)
+
+    def Bound(self, var: "IntVar") -> "bool":
+        return _pywrapcp.Assignment_Bound(self, var)
+
+    def SetMin(self, var: "IntVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetMin(self, var, m)
+
+    def SetMax(self, var: "IntVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetMax(self, var, m)
+
+    def SetRange(self, var: "IntVar", l: "int64_t", u: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetRange(self, var, l, u)
+
+    def SetValue(self, var: "IntVar", value: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetValue(self, var, value)
+
+    def StartMin(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_StartMin(self, var)
+
+    def StartMax(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_StartMax(self, var)
+
+    def StartValue(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_StartValue(self, var)
+
+    def DurationMin(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_DurationMin(self, var)
+
+    def DurationMax(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_DurationMax(self, var)
+
+    def DurationValue(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_DurationValue(self, var)
+
+    def EndMin(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_EndMin(self, var)
+
+    def EndMax(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_EndMax(self, var)
+
+    def EndValue(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_EndValue(self, var)
+
+    def PerformedMin(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_PerformedMin(self, var)
+
+    def PerformedMax(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_PerformedMax(self, var)
+
+    def PerformedValue(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_PerformedValue(self, var)
+
+    def SetStartMin(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetStartMin(self, var, m)
+
+    def SetStartMax(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetStartMax(self, var, m)
+
+    def SetStartRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetStartRange(self, var, mi, ma)
+
+    def SetStartValue(self, var: "IntervalVar", value: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetStartValue(self, var, value)
+
+    def SetDurationMin(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetDurationMin(self, var, m)
+
+    def SetDurationMax(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetDurationMax(self, var, m)
+
+    def SetDurationRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetDurationRange(self, var, mi, ma)
+
+    def SetDurationValue(self, var: "IntervalVar", value: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetDurationValue(self, var, value)
+
+    def SetEndMin(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetEndMin(self, var, m)
+
+    def SetEndMax(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetEndMax(self, var, m)
+
+    def SetEndRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetEndRange(self, var, mi, ma)
+
+    def SetEndValue(self, var: "IntervalVar", value: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetEndValue(self, var, value)
+
+    def SetPerformedMin(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetPerformedMin(self, var, m)
+
+    def SetPerformedMax(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetPerformedMax(self, var, m)
+
+    def SetPerformedRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetPerformedRange(self, var, mi, ma)
+
+    def SetPerformedValue(self, var: "IntervalVar", value: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetPerformedValue(self, var, value)
+
+    def Add(self, *args) -> "void":
+        return _pywrapcp.Assignment_Add(self, *args)
+
+    def ForwardSequence(self, var: "SequenceVar") -> "std::vector< int > const &":
+        return _pywrapcp.Assignment_ForwardSequence(self, var)
+
+    def BackwardSequence(self, var: "SequenceVar") -> "std::vector< int > const &":
+        return _pywrapcp.Assignment_BackwardSequence(self, var)
+
+    def Unperformed(self, var: "SequenceVar") -> "std::vector< int > const &":
+        return _pywrapcp.Assignment_Unperformed(self, var)
+
+    def SetSequence(self, var: "SequenceVar", forward_sequence: "std::vector< int > const &", backward_sequence: "std::vector< int > const &", unperformed: "std::vector< int > const &") -> "void":
+        return _pywrapcp.Assignment_SetSequence(self, var, forward_sequence, backward_sequence, unperformed)
+
+    def SetForwardSequence(self, var: "SequenceVar", forward_sequence: "std::vector< int > const &") -> "void":
+        return _pywrapcp.Assignment_SetForwardSequence(self, var, forward_sequence)
+
+    def SetBackwardSequence(self, var: "SequenceVar", backward_sequence: "std::vector< int > const &") -> "void":
+        return _pywrapcp.Assignment_SetBackwardSequence(self, var, backward_sequence)
+
+    def SetUnperformed(self, var: "SequenceVar", unperformed: "std::vector< int > const &") -> "void":
+        return _pywrapcp.Assignment_SetUnperformed(self, var, unperformed)
+
+    def Activate(self, *args) -> "void":
+        return _pywrapcp.Assignment_Activate(self, *args)
+
+    def Deactivate(self, *args) -> "void":
+        return _pywrapcp.Assignment_Deactivate(self, *args)
+
+    def Activated(self, *args) -> "bool":
+        return _pywrapcp.Assignment_Activated(self, *args)
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.Assignment_DebugString(self)
+
+    def IntVarContainer(self) -> "operations_research::Assignment::IntContainer const &":
+        return _pywrapcp.Assignment_IntVarContainer(self)
+
+    def MutableIntVarContainer(self) -> "operations_research::Assignment::IntContainer *":
+        return _pywrapcp.Assignment_MutableIntVarContainer(self)
+
+    def IntervalVarContainer(self) -> "operations_research::Assignment::IntervalContainer const &":
+        return _pywrapcp.Assignment_IntervalVarContainer(self)
+
+    def MutableIntervalVarContainer(self) -> "operations_research::Assignment::IntervalContainer *":
+        return _pywrapcp.Assignment_MutableIntervalVarContainer(self)
+
+    def SequenceVarContainer(self) -> "operations_research::Assignment::SequenceContainer const &":
+        return _pywrapcp.Assignment_SequenceVarContainer(self)
+
+    def MutableSequenceVarContainer(self) -> "operations_research::Assignment::SequenceContainer *":
+        return _pywrapcp.Assignment_MutableSequenceVarContainer(self)
+
+    def __eq__(self, assignment: "Assignment") -> "bool":
+        return _pywrapcp.Assignment___eq__(self, assignment)
+
+    def __ne__(self, assignment: "Assignment") -> "bool":
+        return _pywrapcp.Assignment___ne__(self, assignment)
+
+ +
+ +

An Assignment is a variable -> domains mapping, used to report solutions to the user.

+
+ + +
+
#   + + + Assignment(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Clear(self) -> 'void': +
+ +
+ View Source +
    def Clear(self) -> "void":
+        return _pywrapcp.Assignment_Clear(self)
+
+ +
+ + + +
+
+
#   + + + def + Empty(self) -> bool: +
+ +
+ View Source +
    def Empty(self) -> "bool":
+        return _pywrapcp.Assignment_Empty(self)
+
+ +
+ + + +
+
+
#   + + + def + Size(self) -> int: +
+ +
+ View Source +
    def Size(self) -> "int":
+        return _pywrapcp.Assignment_Size(self)
+
+ +
+ + + +
+
+
#   + + + def + NumIntVars(self) -> int: +
+ +
+ View Source +
    def NumIntVars(self) -> "int":
+        return _pywrapcp.Assignment_NumIntVars(self)
+
+ +
+ + + +
+
+
#   + + + def + NumIntervalVars(self) -> int: +
+ +
+ View Source +
    def NumIntervalVars(self) -> "int":
+        return _pywrapcp.Assignment_NumIntervalVars(self)
+
+ +
+ + + +
+
+
#   + + + def + NumSequenceVars(self) -> int: +
+ +
+ View Source +
    def NumSequenceVars(self) -> "int":
+        return _pywrapcp.Assignment_NumSequenceVars(self)
+
+ +
+ + + +
+
+
#   + + + def + Store(self) -> 'void': +
+ +
+ View Source +
    def Store(self) -> "void":
+        return _pywrapcp.Assignment_Store(self)
+
+ +
+ + + +
+
+
#   + + + def + Restore(self) -> 'void': +
+ +
+ View Source +
    def Restore(self) -> "void":
+        return _pywrapcp.Assignment_Restore(self)
+
+ +
+ + + +
+
+
#   + + + def + Load(self, *args) -> 'void': +
+ +
+ View Source +
    def Load(self, *args) -> "void":
+        return _pywrapcp.Assignment_Load(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + Save(self, *args) -> 'void': +
+ +
+ View Source +
    def Save(self, *args) -> "void":
+        return _pywrapcp.Assignment_Save(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + AddObjective(self, v: pywrapcp.IntVar) -> 'void': +
+ +
+ View Source +
    def AddObjective(self, v: "IntVar") -> "void":
+        return _pywrapcp.Assignment_AddObjective(self, v)
+
+ +
+ + + +
+
+
#   + + + def + Objective(self) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def Objective(self) -> "operations_research::IntVar *":
+        return _pywrapcp.Assignment_Objective(self)
+
+ +
+ + + +
+
+
#   + + + def + HasObjective(self) -> bool: +
+ +
+ View Source +
    def HasObjective(self) -> "bool":
+        return _pywrapcp.Assignment_HasObjective(self)
+
+ +
+ + + +
+
+
#   + + + def + ObjectiveMin(self) -> 'int64_t': +
+ +
+ View Source +
    def ObjectiveMin(self) -> "int64_t":
+        return _pywrapcp.Assignment_ObjectiveMin(self)
+
+ +
+ + + +
+
+
#   + + + def + ObjectiveMax(self) -> 'int64_t': +
+ +
+ View Source +
    def ObjectiveMax(self) -> "int64_t":
+        return _pywrapcp.Assignment_ObjectiveMax(self)
+
+ +
+ + + +
+
+
#   + + + def + ObjectiveValue(self) -> 'int64_t': +
+ +
+ View Source +
    def ObjectiveValue(self) -> "int64_t":
+        return _pywrapcp.Assignment_ObjectiveValue(self)
+
+ +
+ + + +
+
+
#   + + + def + ObjectiveBound(self) -> bool: +
+ +
+ View Source +
    def ObjectiveBound(self) -> "bool":
+        return _pywrapcp.Assignment_ObjectiveBound(self)
+
+ +
+ + + +
+
+
#   + + + def + SetObjectiveMin(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetObjectiveMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetObjectiveMin(self, m)
+
+ +
+ + + +
+
+
#   + + + def + SetObjectiveMax(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetObjectiveMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetObjectiveMax(self, m)
+
+ +
+ + + +
+
+
#   + + + def + SetObjectiveValue(self, value: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetObjectiveValue(self, value: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetObjectiveValue(self, value)
+
+ +
+ + + +
+
+
#   + + + def + SetObjectiveRange(self, l: 'int64_t', u: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetObjectiveRange(self, l: "int64_t", u: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetObjectiveRange(self, l, u)
+
+ +
+ + + +
+
+
#   + + + def + Min(self, var: pywrapcp.IntVar) -> 'int64_t': +
+ +
+ View Source +
    def Min(self, var: "IntVar") -> "int64_t":
+        return _pywrapcp.Assignment_Min(self, var)
+
+ +
+ + + +
+
+
#   + + + def + Max(self, var: pywrapcp.IntVar) -> 'int64_t': +
+ +
+ View Source +
    def Max(self, var: "IntVar") -> "int64_t":
+        return _pywrapcp.Assignment_Max(self, var)
+
+ +
+ + + +
+
+
#   + + + def + Value(self, var: pywrapcp.IntVar) -> 'int64_t': +
+ +
+ View Source +
    def Value(self, var: "IntVar") -> "int64_t":
+        return _pywrapcp.Assignment_Value(self, var)
+
+ +
+ + + +
+
+
#   + + + def + Bound(self, var: pywrapcp.IntVar) -> bool: +
+ +
+ View Source +
    def Bound(self, var: "IntVar") -> "bool":
+        return _pywrapcp.Assignment_Bound(self, var)
+
+ +
+ + + +
+
+
#   + + + def + SetMin(self, var: pywrapcp.IntVar, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetMin(self, var: "IntVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetMin(self, var, m)
+
+ +
+ + + +
+
+
#   + + + def + SetMax(self, var: pywrapcp.IntVar, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetMax(self, var: "IntVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetMax(self, var, m)
+
+ +
+ + + +
+
+
#   + + + def + SetRange(self, var: pywrapcp.IntVar, l: 'int64_t', u: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetRange(self, var: "IntVar", l: "int64_t", u: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetRange(self, var, l, u)
+
+ +
+ + + +
+
+
#   + + + def + SetValue(self, var: pywrapcp.IntVar, value: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetValue(self, var: "IntVar", value: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetValue(self, var, value)
+
+ +
+ + + +
+
+
#   + + + def + StartMin(self, var: pywrapcp.IntervalVar) -> 'int64_t': +
+ +
+ View Source +
    def StartMin(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_StartMin(self, var)
+
+ +
+ + + +
+
+
#   + + + def + StartMax(self, var: pywrapcp.IntervalVar) -> 'int64_t': +
+ +
+ View Source +
    def StartMax(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_StartMax(self, var)
+
+ +
+ + + +
+
+
#   + + + def + StartValue(self, var: pywrapcp.IntervalVar) -> 'int64_t': +
+ +
+ View Source +
    def StartValue(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_StartValue(self, var)
+
+ +
+ + + +
+
+
#   + + + def + DurationMin(self, var: pywrapcp.IntervalVar) -> 'int64_t': +
+ +
+ View Source +
    def DurationMin(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_DurationMin(self, var)
+
+ +
+ + + +
+
+
#   + + + def + DurationMax(self, var: pywrapcp.IntervalVar) -> 'int64_t': +
+ +
+ View Source +
    def DurationMax(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_DurationMax(self, var)
+
+ +
+ + + +
+
+
#   + + + def + DurationValue(self, var: pywrapcp.IntervalVar) -> 'int64_t': +
+ +
+ View Source +
    def DurationValue(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_DurationValue(self, var)
+
+ +
+ + + +
+
+
#   + + + def + EndMin(self, var: pywrapcp.IntervalVar) -> 'int64_t': +
+ +
+ View Source +
    def EndMin(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_EndMin(self, var)
+
+ +
+ + + +
+
+
#   + + + def + EndMax(self, var: pywrapcp.IntervalVar) -> 'int64_t': +
+ +
+ View Source +
    def EndMax(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_EndMax(self, var)
+
+ +
+ + + +
+
+
#   + + + def + EndValue(self, var: pywrapcp.IntervalVar) -> 'int64_t': +
+ +
+ View Source +
    def EndValue(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_EndValue(self, var)
+
+ +
+ + + +
+
+
#   + + + def + PerformedMin(self, var: pywrapcp.IntervalVar) -> 'int64_t': +
+ +
+ View Source +
    def PerformedMin(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_PerformedMin(self, var)
+
+ +
+ + + +
+
+
#   + + + def + PerformedMax(self, var: pywrapcp.IntervalVar) -> 'int64_t': +
+ +
+ View Source +
    def PerformedMax(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_PerformedMax(self, var)
+
+ +
+ + + +
+
+
#   + + + def + PerformedValue(self, var: pywrapcp.IntervalVar) -> 'int64_t': +
+ +
+ View Source +
    def PerformedValue(self, var: "IntervalVar") -> "int64_t":
+        return _pywrapcp.Assignment_PerformedValue(self, var)
+
+ +
+ + + +
+
+
#   + + + def + SetStartMin(self, var: pywrapcp.IntervalVar, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetStartMin(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetStartMin(self, var, m)
+
+ +
+ + + +
+
+
#   + + + def + SetStartMax(self, var: pywrapcp.IntervalVar, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetStartMax(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetStartMax(self, var, m)
+
+ +
+ + + +
+
+
#   + + + def + SetStartRange( + self, + var: pywrapcp.IntervalVar, + mi: 'int64_t', + ma: 'int64_t' +) -> 'void': +
+ +
+ View Source +
    def SetStartRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetStartRange(self, var, mi, ma)
+
+ +
+ + + +
+
+
#   + + + def + SetStartValue(self, var: pywrapcp.IntervalVar, value: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetStartValue(self, var: "IntervalVar", value: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetStartValue(self, var, value)
+
+ +
+ + + +
+
+
#   + + + def + SetDurationMin(self, var: pywrapcp.IntervalVar, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetDurationMin(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetDurationMin(self, var, m)
+
+ +
+ + + +
+
+
#   + + + def + SetDurationMax(self, var: pywrapcp.IntervalVar, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetDurationMax(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetDurationMax(self, var, m)
+
+ +
+ + + +
+
+
#   + + + def + SetDurationRange( + self, + var: pywrapcp.IntervalVar, + mi: 'int64_t', + ma: 'int64_t' +) -> 'void': +
+ +
+ View Source +
    def SetDurationRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetDurationRange(self, var, mi, ma)
+
+ +
+ + + +
+
+
#   + + + def + SetDurationValue(self, var: pywrapcp.IntervalVar, value: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetDurationValue(self, var: "IntervalVar", value: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetDurationValue(self, var, value)
+
+ +
+ + + +
+
+
#   + + + def + SetEndMin(self, var: pywrapcp.IntervalVar, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetEndMin(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetEndMin(self, var, m)
+
+ +
+ + + +
+
+
#   + + + def + SetEndMax(self, var: pywrapcp.IntervalVar, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetEndMax(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetEndMax(self, var, m)
+
+ +
+ + + +
+
+
#   + + + def + SetEndRange( + self, + var: pywrapcp.IntervalVar, + mi: 'int64_t', + ma: 'int64_t' +) -> 'void': +
+ +
+ View Source +
    def SetEndRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetEndRange(self, var, mi, ma)
+
+ +
+ + + +
+
+
#   + + + def + SetEndValue(self, var: pywrapcp.IntervalVar, value: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetEndValue(self, var: "IntervalVar", value: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetEndValue(self, var, value)
+
+ +
+ + + +
+
+
#   + + + def + SetPerformedMin(self, var: pywrapcp.IntervalVar, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetPerformedMin(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetPerformedMin(self, var, m)
+
+ +
+ + + +
+
+
#   + + + def + SetPerformedMax(self, var: pywrapcp.IntervalVar, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetPerformedMax(self, var: "IntervalVar", m: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetPerformedMax(self, var, m)
+
+ +
+ + + +
+
+
#   + + + def + SetPerformedRange( + self, + var: pywrapcp.IntervalVar, + mi: 'int64_t', + ma: 'int64_t' +) -> 'void': +
+ +
+ View Source +
    def SetPerformedRange(self, var: "IntervalVar", mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetPerformedRange(self, var, mi, ma)
+
+ +
+ + + +
+
+
#   + + + def + SetPerformedValue(self, var: pywrapcp.IntervalVar, value: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetPerformedValue(self, var: "IntervalVar", value: "int64_t") -> "void":
+        return _pywrapcp.Assignment_SetPerformedValue(self, var, value)
+
+ +
+ + + +
+
+
#   + + + def + Add(self, *args) -> 'void': +
+ +
+ View Source +
    def Add(self, *args) -> "void":
+        return _pywrapcp.Assignment_Add(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + ForwardSequence(self, var: pywrapcp.SequenceVar) -> 'std::vector< int > const &': +
+ +
+ View Source +
    def ForwardSequence(self, var: "SequenceVar") -> "std::vector< int > const &":
+        return _pywrapcp.Assignment_ForwardSequence(self, var)
+
+ +
+ + + +
+
+
#   + + + def + BackwardSequence(self, var: pywrapcp.SequenceVar) -> 'std::vector< int > const &': +
+ +
+ View Source +
    def BackwardSequence(self, var: "SequenceVar") -> "std::vector< int > const &":
+        return _pywrapcp.Assignment_BackwardSequence(self, var)
+
+ +
+ + + +
+
+
#   + + + def + Unperformed(self, var: pywrapcp.SequenceVar) -> 'std::vector< int > const &': +
+ +
+ View Source +
    def Unperformed(self, var: "SequenceVar") -> "std::vector< int > const &":
+        return _pywrapcp.Assignment_Unperformed(self, var)
+
+ +
+ + + +
+
+
#   + + + def + SetSequence( + self, + var: pywrapcp.SequenceVar, + forward_sequence: 'std::vector< int > const &', + backward_sequence: 'std::vector< int > const &', + unperformed: 'std::vector< int > const &' +) -> 'void': +
+ +
+ View Source +
    def SetSequence(self, var: "SequenceVar", forward_sequence: "std::vector< int > const &", backward_sequence: "std::vector< int > const &", unperformed: "std::vector< int > const &") -> "void":
+        return _pywrapcp.Assignment_SetSequence(self, var, forward_sequence, backward_sequence, unperformed)
+
+ +
+ + + +
+
+
#   + + + def + SetForwardSequence( + self, + var: pywrapcp.SequenceVar, + forward_sequence: 'std::vector< int > const &' +) -> 'void': +
+ +
+ View Source +
    def SetForwardSequence(self, var: "SequenceVar", forward_sequence: "std::vector< int > const &") -> "void":
+        return _pywrapcp.Assignment_SetForwardSequence(self, var, forward_sequence)
+
+ +
+ + + +
+
+
#   + + + def + SetBackwardSequence( + self, + var: pywrapcp.SequenceVar, + backward_sequence: 'std::vector< int > const &' +) -> 'void': +
+ +
+ View Source +
    def SetBackwardSequence(self, var: "SequenceVar", backward_sequence: "std::vector< int > const &") -> "void":
+        return _pywrapcp.Assignment_SetBackwardSequence(self, var, backward_sequence)
+
+ +
+ + + +
+
+
#   + + + def + SetUnperformed( + self, + var: pywrapcp.SequenceVar, + unperformed: 'std::vector< int > const &' +) -> 'void': +
+ +
+ View Source +
    def SetUnperformed(self, var: "SequenceVar", unperformed: "std::vector< int > const &") -> "void":
+        return _pywrapcp.Assignment_SetUnperformed(self, var, unperformed)
+
+ +
+ + + +
+
+
#   + + + def + Activate(self, *args) -> 'void': +
+ +
+ View Source +
    def Activate(self, *args) -> "void":
+        return _pywrapcp.Assignment_Activate(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + Deactivate(self, *args) -> 'void': +
+ +
+ View Source +
    def Deactivate(self, *args) -> "void":
+        return _pywrapcp.Assignment_Deactivate(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + Activated(self, *args) -> bool: +
+ +
+ View Source +
    def Activated(self, *args) -> "bool":
+        return _pywrapcp.Assignment_Activated(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + DebugString(self) -> 'std::string': +
+ +
+ View Source +
    def DebugString(self) -> "std::string":
+        return _pywrapcp.Assignment_DebugString(self)
+
+ +
+ + + +
+
+
#   + + + def + IntVarContainer(self) -> 'operations_research::Assignment::IntContainer const &': +
+ +
+ View Source +
    def IntVarContainer(self) -> "operations_research::Assignment::IntContainer const &":
+        return _pywrapcp.Assignment_IntVarContainer(self)
+
+ +
+ + + +
+
+
#   + + + def + MutableIntVarContainer(self) -> 'operations_research::Assignment::IntContainer *': +
+ +
+ View Source +
    def MutableIntVarContainer(self) -> "operations_research::Assignment::IntContainer *":
+        return _pywrapcp.Assignment_MutableIntVarContainer(self)
+
+ +
+ + + +
+
+
#   + + + def + IntervalVarContainer(self) -> 'operations_research::Assignment::IntervalContainer const &': +
+ +
+ View Source +
    def IntervalVarContainer(self) -> "operations_research::Assignment::IntervalContainer const &":
+        return _pywrapcp.Assignment_IntervalVarContainer(self)
+
+ +
+ + + +
+
+
#   + + + def + MutableIntervalVarContainer(self) -> 'operations_research::Assignment::IntervalContainer *': +
+ +
+ View Source +
    def MutableIntervalVarContainer(self) -> "operations_research::Assignment::IntervalContainer *":
+        return _pywrapcp.Assignment_MutableIntervalVarContainer(self)
+
+ +
+ + + +
+
+
#   + + + def + SequenceVarContainer(self) -> 'operations_research::Assignment::SequenceContainer const &': +
+ +
+ View Source +
    def SequenceVarContainer(self) -> "operations_research::Assignment::SequenceContainer const &":
+        return _pywrapcp.Assignment_SequenceVarContainer(self)
+
+ +
+ + + +
+
+
#   + + + def + MutableSequenceVarContainer(self) -> 'operations_research::Assignment::SequenceContainer *': +
+ +
+ View Source +
    def MutableSequenceVarContainer(self) -> "operations_research::Assignment::SequenceContainer *":
+        return _pywrapcp.Assignment_MutableSequenceVarContainer(self)
+
+ +
+ + + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ #   + + + class + Pack(Constraint): +
+ +
+ View Source +
class Pack(Constraint):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def AddWeightedSumLessOrEqualConstantDimension(self, *args) -> "void":
+        r"""
+        *Overload 1:*
+        Dimensions are additional constraints than can restrict what is possible with the pack constraint. It can be used to set capacity limits, to count objects per bin, to compute unassigned penalties... This dimension imposes that for all bins b, the weighted sum (weights[i]) of all objects i assigned to 'b' is less or equal 'bounds[b]'.
+
+        |
+
+        *Overload 2:*
+        This dimension imposes that for all bins b, the weighted sum (weights->Run(i)) of all objects i assigned to 'b' is less or equal to 'bounds[b]'. Ownership of the callback is transferred to the pack constraint.
+
+        |
+
+        *Overload 3:*
+        This dimension imposes that for all bins b, the weighted sum (weights->Run(i, b) of all objects i assigned to 'b' is less or equal to 'bounds[b]'. Ownership of the callback is transferred to the pack constraint.
+        """
+        return _pywrapcp.Pack_AddWeightedSumLessOrEqualConstantDimension(self, *args)
+
+    def AddWeightedSumEqualVarDimension(self, *args) -> "void":
+        r"""
+        *Overload 1:*
+        This dimension imposes that for all bins b, the weighted sum (weights[i]) of all objects i assigned to 'b' is equal to loads[b].
+
+        |
+
+        *Overload 2:*
+        This dimension imposes that for all bins b, the weighted sum (weights->Run(i, b)) of all objects i assigned to 'b' is equal to loads[b].
+        """
+        return _pywrapcp.Pack_AddWeightedSumEqualVarDimension(self, *args)
+
+    def AddSumVariableWeightsLessOrEqualConstantDimension(self, usage: "std::vector< operations_research::IntVar * > const &", capacity: "std::vector< int64_t > const &") -> "void":
+        r""" This dimension imposes: forall b in bins,    sum (i in items: usage[i] * is_assigned(i, b)) <= capacity[b] where is_assigned(i, b) is true if and only if item i is assigned to the bin b. This can be used to model shapes of items by linking variables of the same item on parallel dimensions with an allowed assignment constraint."""
+        return _pywrapcp.Pack_AddSumVariableWeightsLessOrEqualConstantDimension(self, usage, capacity)
+
+    def AddWeightedSumOfAssignedDimension(self, weights: "std::vector< int64_t > const &", cost_var: "IntVar") -> "void":
+        r""" This dimension enforces that cost_var == sum of weights[i] for all objects 'i' assigned to a bin."""
+        return _pywrapcp.Pack_AddWeightedSumOfAssignedDimension(self, weights, cost_var)
+
+    def AddCountUsedBinDimension(self, count_var: "IntVar") -> "void":
+        r""" This dimension links 'count_var' to the actual number of bins used in the pack."""
+        return _pywrapcp.Pack_AddCountUsedBinDimension(self, count_var)
+
+    def AddCountAssignedItemsDimension(self, count_var: "IntVar") -> "void":
+        r""" This dimension links 'count_var' to the actual number of items assigned to a bin in the pack."""
+        return _pywrapcp.Pack_AddCountAssignedItemsDimension(self, count_var)
+
+    def Post(self) -> "void":
+        return _pywrapcp.Pack_Post(self)
+
+    def InitialPropagateWrapper(self) -> "void":
+        return _pywrapcp.Pack_InitialPropagateWrapper(self)
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.Pack_DebugString(self)
+
+ +
+ +

A constraint is the main modeling object. It provides two methods: - Post() is responsible for creating the demons and attaching them to immediate demons(). - InitialPropagate() is called once just after Post and performs the initial propagation. The subsequent propagations will be performed by the demons Posted during the post() method.

+
+ + +
+
#   + + + Pack(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + AddWeightedSumLessOrEqualConstantDimension(self, *args) -> 'void': +
+ +
+ View Source +
    def AddWeightedSumLessOrEqualConstantDimension(self, *args) -> "void":
+        r"""
+        *Overload 1:*
+        Dimensions are additional constraints than can restrict what is possible with the pack constraint. It can be used to set capacity limits, to count objects per bin, to compute unassigned penalties... This dimension imposes that for all bins b, the weighted sum (weights[i]) of all objects i assigned to 'b' is less or equal 'bounds[b]'.
+
+        |
+
+        *Overload 2:*
+        This dimension imposes that for all bins b, the weighted sum (weights->Run(i)) of all objects i assigned to 'b' is less or equal to 'bounds[b]'. Ownership of the callback is transferred to the pack constraint.
+
+        |
+
+        *Overload 3:*
+        This dimension imposes that for all bins b, the weighted sum (weights->Run(i, b) of all objects i assigned to 'b' is less or equal to 'bounds[b]'. Ownership of the callback is transferred to the pack constraint.
+        """
+        return _pywrapcp.Pack_AddWeightedSumLessOrEqualConstantDimension(self, *args)
+
+ +
+ +

Overload 1: +Dimensions are additional constraints than can restrict what is possible with the pack constraint. It can be used to set capacity limits, to count objects per bin, to compute unassigned penalties... This dimension imposes that for all bins b, the weighted sum (weights[i]) of all objects i assigned to 'b' is less or equal 'bounds[b]'.

+ +

|

+ +

Overload 2: +This dimension imposes that for all bins b, the weighted sum (weights->Run(i)) of all objects i assigned to 'b' is less or equal to 'bounds[b]'. Ownership of the callback is transferred to the pack constraint.

+ +

|

+ +

Overload 3: +This dimension imposes that for all bins b, the weighted sum (weights->Run(i, b) of all objects i assigned to 'b' is less or equal to 'bounds[b]'. Ownership of the callback is transferred to the pack constraint.

+
+ + +
+
+
#   + + + def + AddWeightedSumEqualVarDimension(self, *args) -> 'void': +
+ +
+ View Source +
    def AddWeightedSumEqualVarDimension(self, *args) -> "void":
+        r"""
+        *Overload 1:*
+        This dimension imposes that for all bins b, the weighted sum (weights[i]) of all objects i assigned to 'b' is equal to loads[b].
+
+        |
+
+        *Overload 2:*
+        This dimension imposes that for all bins b, the weighted sum (weights->Run(i, b)) of all objects i assigned to 'b' is equal to loads[b].
+        """
+        return _pywrapcp.Pack_AddWeightedSumEqualVarDimension(self, *args)
+
+ +
+ +

Overload 1: +This dimension imposes that for all bins b, the weighted sum (weights[i]) of all objects i assigned to 'b' is equal to loads[b].

+ +

|

+ +

Overload 2: +This dimension imposes that for all bins b, the weighted sum (weights->Run(i, b)) of all objects i assigned to 'b' is equal to loads[b].

+
+ + +
+
+
#   + + + def + AddSumVariableWeightsLessOrEqualConstantDimension( + self, + usage: 'std::vector< operations_research::IntVar * > const &', + capacity: 'std::vector< int64_t > const &' +) -> 'void': +
+ +
+ View Source +
    def AddSumVariableWeightsLessOrEqualConstantDimension(self, usage: "std::vector< operations_research::IntVar * > const &", capacity: "std::vector< int64_t > const &") -> "void":
+        r""" This dimension imposes: forall b in bins,    sum (i in items: usage[i] * is_assigned(i, b)) <= capacity[b] where is_assigned(i, b) is true if and only if item i is assigned to the bin b. This can be used to model shapes of items by linking variables of the same item on parallel dimensions with an allowed assignment constraint."""
+        return _pywrapcp.Pack_AddSumVariableWeightsLessOrEqualConstantDimension(self, usage, capacity)
+
+ +
+ +

This dimension imposes: forall b in bins, sum (i in items: usage[i] * is_assigned(i, b)) <= capacity[b] where is_assigned(i, b) is true if and only if item i is assigned to the bin b. This can be used to model shapes of items by linking variables of the same item on parallel dimensions with an allowed assignment constraint.

+
+ + +
+
+
#   + + + def + AddWeightedSumOfAssignedDimension( + self, + weights: 'std::vector< int64_t > const &', + cost_var: pywrapcp.IntVar +) -> 'void': +
+ +
+ View Source +
    def AddWeightedSumOfAssignedDimension(self, weights: "std::vector< int64_t > const &", cost_var: "IntVar") -> "void":
+        r""" This dimension enforces that cost_var == sum of weights[i] for all objects 'i' assigned to a bin."""
+        return _pywrapcp.Pack_AddWeightedSumOfAssignedDimension(self, weights, cost_var)
+
+ +
+ +

This dimension enforces that cost_var == sum of weights[i] for all objects 'i' assigned to a bin.

+
+ + +
+
+
#   + + + def + AddCountUsedBinDimension(self, count_var: pywrapcp.IntVar) -> 'void': +
+ +
+ View Source +
    def AddCountUsedBinDimension(self, count_var: "IntVar") -> "void":
+        r""" This dimension links 'count_var' to the actual number of bins used in the pack."""
+        return _pywrapcp.Pack_AddCountUsedBinDimension(self, count_var)
+
+ +
+ +

This dimension links 'count_var' to the actual number of bins used in the pack.

+
+ + +
+
+
#   + + + def + AddCountAssignedItemsDimension(self, count_var: pywrapcp.IntVar) -> 'void': +
+ +
+ View Source +
    def AddCountAssignedItemsDimension(self, count_var: "IntVar") -> "void":
+        r""" This dimension links 'count_var' to the actual number of items assigned to a bin in the pack."""
+        return _pywrapcp.Pack_AddCountAssignedItemsDimension(self, count_var)
+
+ +
+ +

This dimension links 'count_var' to the actual number of items assigned to a bin in the pack.

+
+ + +
+
+
#   + + + def + Post(self) -> 'void': +
+ +
+ View Source +
    def Post(self) -> "void":
+        return _pywrapcp.Pack_Post(self)
+
+ +
+ +

This method is called when the constraint is processed by the solver. Its main usage is to attach demons to variables.

+
+ + +
+
+
#   + + + def + InitialPropagateWrapper(self) -> 'void': +
+ +
+ View Source +
    def InitialPropagateWrapper(self) -> "void":
+        return _pywrapcp.Pack_InitialPropagateWrapper(self)
+
+ +
+ +

This method performs the initial propagation of the constraint. It is called just after the post.

+
+ + +
+
+
#   + + + def + DebugString(self) -> 'std::string': +
+ +
+ View Source +
    def DebugString(self) -> "std::string":
+        return _pywrapcp.Pack_DebugString(self)
+
+ +
+ + + +
+
+
Inherited Members
+
+ + +
+
+
+
+
+ #   + + + class + DisjunctiveConstraint(Constraint): +
+ +
+ View Source +
class DisjunctiveConstraint(Constraint):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+
+    def SequenceVar(self) -> "operations_research::SequenceVar *":
+        r""" Creates a sequence variable from the constraint."""
+        return _pywrapcp.DisjunctiveConstraint_SequenceVar(self)
+
+    def SetTransitionTime(self, transition_time: "operations_research::Solver::IndexEvaluator2") -> "void":
+        r""" Add a transition time between intervals.  It forces the distance between the end of interval a and start of interval b that follows it to be at least transition_time(a, b). This function must always return a positive or null value."""
+        return _pywrapcp.DisjunctiveConstraint_SetTransitionTime(self, transition_time)
+
+    def TransitionTime(self, before_index: "int", after_index: "int") -> "int64_t":
+        return _pywrapcp.DisjunctiveConstraint_TransitionTime(self, before_index, after_index)
+
+ +
+ +

A constraint is the main modeling object. It provides two methods: - Post() is responsible for creating the demons and attaching them to immediate demons(). - InitialPropagate() is called once just after Post and performs the initial propagation. The subsequent propagations will be performed by the demons Posted during the post() method.

+
+ + +
+
#   + + + DisjunctiveConstraint(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + SequenceVar(self) -> 'operations_research::SequenceVar *': +
+ +
+ View Source +
    def SequenceVar(self) -> "operations_research::SequenceVar *":
+        r""" Creates a sequence variable from the constraint."""
+        return _pywrapcp.DisjunctiveConstraint_SequenceVar(self)
+
+ +
+ +

Creates a sequence variable from the constraint.

+
+ + +
+
+
#   + + + def + SetTransitionTime( + self, + transition_time: 'operations_research::Solver::IndexEvaluator2' +) -> 'void': +
+ +
+ View Source +
    def SetTransitionTime(self, transition_time: "operations_research::Solver::IndexEvaluator2") -> "void":
+        r""" Add a transition time between intervals.  It forces the distance between the end of interval a and start of interval b that follows it to be at least transition_time(a, b). This function must always return a positive or null value."""
+        return _pywrapcp.DisjunctiveConstraint_SetTransitionTime(self, transition_time)
+
+ +
+ +

Add a transition time between intervals. It forces the distance between the end of interval a and start of interval b that follows it to be at least transition_time(a, b). This function must always return a positive or null value.

+
+ + +
+
+
#   + + + def + TransitionTime(self, before_index: int, after_index: int) -> 'int64_t': +
+ +
+ View Source +
    def TransitionTime(self, before_index: "int", after_index: "int") -> "int64_t":
+        return _pywrapcp.DisjunctiveConstraint_TransitionTime(self, before_index, after_index)
+
+ +
+ + + +
+
+
Inherited Members
+
+ + +
+
+
+
+
+ #   + + + class + RevInteger: +
+ +
+ View Source +
class RevInteger(object):
+    r""" This class adds reversibility to a POD type. It contains the stamp optimization. i.e. the SaveValue call is done only once per node of the search tree.  Please note that actual stamps always starts at 1, thus an initial value of 0 will always trigger the first SaveValue."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, val: "long const &"):
+        _pywrapcp.RevInteger_swiginit(self, _pywrapcp.new_RevInteger(val))
+
+    def Value(self) -> "long const &":
+        return _pywrapcp.RevInteger_Value(self)
+
+    def SetValue(self, s: "Solver", val: "long const &") -> "void":
+        return _pywrapcp.RevInteger_SetValue(self, s, val)
+    __swig_destroy__ = _pywrapcp.delete_RevInteger
+
+ +
+ +

This class adds reversibility to a POD type. It contains the stamp optimization. i.e. the SaveValue call is done only once per node of the search tree. Please note that actual stamps always starts at 1, thus an initial value of 0 will always trigger the first SaveValue.

+
+ + +
+
#   + + + RevInteger(val: 'long const &') +
+ +
+ View Source +
    def __init__(self, val: "long const &"):
+        _pywrapcp.RevInteger_swiginit(self, _pywrapcp.new_RevInteger(val))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Value(self) -> 'long const &': +
+ +
+ View Source +
    def Value(self) -> "long const &":
+        return _pywrapcp.RevInteger_Value(self)
+
+ +
+ + + +
+
+
#   + + + def + SetValue(self, s: pywrapcp.Solver, val: 'long const &') -> 'void': +
+ +
+ View Source +
    def SetValue(self, s: "Solver", val: "long const &") -> "void":
+        return _pywrapcp.RevInteger_SetValue(self, s, val)
+
+ +
+ + + +
+
+
+
+ #   + + + class + NumericalRevInteger(RevInteger): +
+ +
+ View Source +
class NumericalRevInteger(RevInteger):
+    r""" Subclass of Rev<T> which adds numerical operations."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, val: "long const &"):
+        _pywrapcp.NumericalRevInteger_swiginit(self, _pywrapcp.new_NumericalRevInteger(val))
+
+    def Add(self, s: "Solver", to_add: "long const &") -> "void":
+        return _pywrapcp.NumericalRevInteger_Add(self, s, to_add)
+
+    def Incr(self, s: "Solver") -> "void":
+        return _pywrapcp.NumericalRevInteger_Incr(self, s)
+
+    def Decr(self, s: "Solver") -> "void":
+        return _pywrapcp.NumericalRevInteger_Decr(self, s)
+    __swig_destroy__ = _pywrapcp.delete_NumericalRevInteger
+
+ +
+ +

Subclass of Rev which adds numerical operations.

+
+ + +
+
#   + + + NumericalRevInteger(val: 'long const &') +
+ +
+ View Source +
    def __init__(self, val: "long const &"):
+        _pywrapcp.NumericalRevInteger_swiginit(self, _pywrapcp.new_NumericalRevInteger(val))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Add(self, s: pywrapcp.Solver, to_add: 'long const &') -> 'void': +
+ +
+ View Source +
    def Add(self, s: "Solver", to_add: "long const &") -> "void":
+        return _pywrapcp.NumericalRevInteger_Add(self, s, to_add)
+
+ +
+ + + +
+
+
#   + + + def + Incr(self, s: pywrapcp.Solver) -> 'void': +
+ +
+ View Source +
    def Incr(self, s: "Solver") -> "void":
+        return _pywrapcp.NumericalRevInteger_Incr(self, s)
+
+ +
+ + + +
+
+
#   + + + def + Decr(self, s: pywrapcp.Solver) -> 'void': +
+ +
+ View Source +
    def Decr(self, s: "Solver") -> "void":
+        return _pywrapcp.NumericalRevInteger_Decr(self, s)
+
+ +
+ + + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ #   + + + class + RevBool: +
+ +
+ View Source +
class RevBool(object):
+    r""" This class adds reversibility to a POD type. It contains the stamp optimization. i.e. the SaveValue call is done only once per node of the search tree.  Please note that actual stamps always starts at 1, thus an initial value of 0 will always trigger the first SaveValue."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, val: "bool const &"):
+        _pywrapcp.RevBool_swiginit(self, _pywrapcp.new_RevBool(val))
+
+    def Value(self) -> "bool const &":
+        return _pywrapcp.RevBool_Value(self)
+
+    def SetValue(self, s: "Solver", val: "bool const &") -> "void":
+        return _pywrapcp.RevBool_SetValue(self, s, val)
+    __swig_destroy__ = _pywrapcp.delete_RevBool
+
+ +
+ +

This class adds reversibility to a POD type. It contains the stamp optimization. i.e. the SaveValue call is done only once per node of the search tree. Please note that actual stamps always starts at 1, thus an initial value of 0 will always trigger the first SaveValue.

+
+ + +
+
#   + + + RevBool(val: 'bool const &') +
+ +
+ View Source +
    def __init__(self, val: "bool const &"):
+        _pywrapcp.RevBool_swiginit(self, _pywrapcp.new_RevBool(val))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Value(self) -> 'bool const &': +
+ +
+ View Source +
    def Value(self) -> "bool const &":
+        return _pywrapcp.RevBool_Value(self)
+
+ +
+ + + +
+
+
#   + + + def + SetValue(self, s: pywrapcp.Solver, val: 'bool const &') -> 'void': +
+ +
+ View Source +
    def SetValue(self, s: "Solver", val: "bool const &") -> "void":
+        return _pywrapcp.RevBool_SetValue(self, s, val)
+
+ +
+ + + +
+
+
+
+ #   + + + class + IntVarContainer: +
+ +
+ View Source +
class IntVarContainer(object):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Contains(self, var: "IntVar") -> "bool":
+        return _pywrapcp.IntVarContainer_Contains(self, var)
+
+    def Element(self, index: "int") -> "operations_research::IntVarElement *":
+        return _pywrapcp.IntVarContainer_Element(self, index)
+
+    def Size(self) -> "int":
+        return _pywrapcp.IntVarContainer_Size(self)
+
+    def Store(self) -> "void":
+        return _pywrapcp.IntVarContainer_Store(self)
+
+    def Restore(self) -> "void":
+        return _pywrapcp.IntVarContainer_Restore(self)
+
+    def __eq__(self, container: "IntVarContainer") -> "bool":
+        r""" Returns true if this and 'container' both represent the same V* -> E map. Runs in linear time; requires that the == operator on the type E is well defined."""
+        return _pywrapcp.IntVarContainer___eq__(self, container)
+
+    def __ne__(self, container: "IntVarContainer") -> "bool":
+        return _pywrapcp.IntVarContainer___ne__(self, container)
+    __swig_destroy__ = _pywrapcp.delete_IntVarContainer
+
+ +
+ + + +
+
#   + + + IntVarContainer(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Contains(self, var: pywrapcp.IntVar) -> bool: +
+ +
+ View Source +
    def Contains(self, var: "IntVar") -> "bool":
+        return _pywrapcp.IntVarContainer_Contains(self, var)
+
+ +
+ + + +
+
+
#   + + + def + Element(self, index: int) -> 'operations_research::IntVarElement *': +
+ +
+ View Source +
    def Element(self, index: "int") -> "operations_research::IntVarElement *":
+        return _pywrapcp.IntVarContainer_Element(self, index)
+
+ +
+ + + +
+
+
#   + + + def + Size(self) -> int: +
+ +
+ View Source +
    def Size(self) -> "int":
+        return _pywrapcp.IntVarContainer_Size(self)
+
+ +
+ + + +
+
+
#   + + + def + Store(self) -> 'void': +
+ +
+ View Source +
    def Store(self) -> "void":
+        return _pywrapcp.IntVarContainer_Store(self)
+
+ +
+ + + +
+
+
#   + + + def + Restore(self) -> 'void': +
+ +
+ View Source +
    def Restore(self) -> "void":
+        return _pywrapcp.IntVarContainer_Restore(self)
+
+ +
+ + + +
+
+
+
+ #   + + + class + IntervalVarContainer: +
+ +
+ View Source +
class IntervalVarContainer(object):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Contains(self, var: "IntervalVar") -> "bool":
+        return _pywrapcp.IntervalVarContainer_Contains(self, var)
+
+    def Element(self, index: "int") -> "operations_research::IntervalVarElement *":
+        return _pywrapcp.IntervalVarContainer_Element(self, index)
+
+    def Size(self) -> "int":
+        return _pywrapcp.IntervalVarContainer_Size(self)
+
+    def Store(self) -> "void":
+        return _pywrapcp.IntervalVarContainer_Store(self)
+
+    def Restore(self) -> "void":
+        return _pywrapcp.IntervalVarContainer_Restore(self)
+
+    def __eq__(self, container: "IntervalVarContainer") -> "bool":
+        r""" Returns true if this and 'container' both represent the same V* -> E map. Runs in linear time; requires that the == operator on the type E is well defined."""
+        return _pywrapcp.IntervalVarContainer___eq__(self, container)
+
+    def __ne__(self, container: "IntervalVarContainer") -> "bool":
+        return _pywrapcp.IntervalVarContainer___ne__(self, container)
+    __swig_destroy__ = _pywrapcp.delete_IntervalVarContainer
+
+ +
+ + + +
+
#   + + + IntervalVarContainer(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Contains(self, var: pywrapcp.IntervalVar) -> bool: +
+ +
+ View Source +
    def Contains(self, var: "IntervalVar") -> "bool":
+        return _pywrapcp.IntervalVarContainer_Contains(self, var)
+
+ +
+ + + +
+
+
#   + + + def + Element(self, index: int) -> 'operations_research::IntervalVarElement *': +
+ +
+ View Source +
    def Element(self, index: "int") -> "operations_research::IntervalVarElement *":
+        return _pywrapcp.IntervalVarContainer_Element(self, index)
+
+ +
+ + + +
+
+
#   + + + def + Size(self) -> int: +
+ +
+ View Source +
    def Size(self) -> "int":
+        return _pywrapcp.IntervalVarContainer_Size(self)
+
+ +
+ + + +
+
+
#   + + + def + Store(self) -> 'void': +
+ +
+ View Source +
    def Store(self) -> "void":
+        return _pywrapcp.IntervalVarContainer_Store(self)
+
+ +
+ + + +
+
+
#   + + + def + Restore(self) -> 'void': +
+ +
+ View Source +
    def Restore(self) -> "void":
+        return _pywrapcp.IntervalVarContainer_Restore(self)
+
+ +
+ + + +
+
+
+
+ #   + + + class + SequenceVarContainer: +
+ +
+ View Source +
class SequenceVarContainer(object):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Contains(self, var: "SequenceVar") -> "bool":
+        return _pywrapcp.SequenceVarContainer_Contains(self, var)
+
+    def Element(self, index: "int") -> "operations_research::SequenceVarElement *":
+        return _pywrapcp.SequenceVarContainer_Element(self, index)
+
+    def Size(self) -> "int":
+        return _pywrapcp.SequenceVarContainer_Size(self)
+
+    def Store(self) -> "void":
+        return _pywrapcp.SequenceVarContainer_Store(self)
+
+    def Restore(self) -> "void":
+        return _pywrapcp.SequenceVarContainer_Restore(self)
+
+    def __eq__(self, container: "SequenceVarContainer") -> "bool":
+        r""" Returns true if this and 'container' both represent the same V* -> E map. Runs in linear time; requires that the == operator on the type E is well defined."""
+        return _pywrapcp.SequenceVarContainer___eq__(self, container)
+
+    def __ne__(self, container: "SequenceVarContainer") -> "bool":
+        return _pywrapcp.SequenceVarContainer___ne__(self, container)
+    __swig_destroy__ = _pywrapcp.delete_SequenceVarContainer
+
+ +
+ + + +
+
#   + + + SequenceVarContainer(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Contains(self, var: pywrapcp.SequenceVar) -> bool: +
+ +
+ View Source +
    def Contains(self, var: "SequenceVar") -> "bool":
+        return _pywrapcp.SequenceVarContainer_Contains(self, var)
+
+ +
+ + + +
+
+
#   + + + def + Element(self, index: int) -> 'operations_research::SequenceVarElement *': +
+ +
+ View Source +
    def Element(self, index: "int") -> "operations_research::SequenceVarElement *":
+        return _pywrapcp.SequenceVarContainer_Element(self, index)
+
+ +
+ + + +
+
+
#   + + + def + Size(self) -> int: +
+ +
+ View Source +
    def Size(self) -> "int":
+        return _pywrapcp.SequenceVarContainer_Size(self)
+
+ +
+ + + +
+
+
#   + + + def + Store(self) -> 'void': +
+ +
+ View Source +
    def Store(self) -> "void":
+        return _pywrapcp.SequenceVarContainer_Store(self)
+
+ +
+ + + +
+
+
#   + + + def + Restore(self) -> 'void': +
+ +
+ View Source +
    def Restore(self) -> "void":
+        return _pywrapcp.SequenceVarContainer_Restore(self)
+
+ +
+ + + +
+
+
+
+ #   + + + class + LocalSearchOperator(BaseObject): +
+ +
+ View Source +
class LocalSearchOperator(BaseObject):
+    r""" This class represent a reversible FIFO structure. The main difference w.r.t a standard FIFO structure is that a Solver is given as parameter to the modifiers such that the solver can store the backtrack information Iterator's traversing order should not be changed, as some algorithm depend on it to be consistent. It's main use is to store a list of demons in the various classes of variables. The base class for all local search operators. A local search operator is an object that defines the neighborhood of a solution. In other words, a neighborhood is the set of solutions which can be reached from a given solution using an operator. The behavior of the LocalSearchOperator class is similar to iterators. The operator is synchronized with an assignment (gives the current values of the variables); this is done in the Start() method. Then one can iterate over the neighbors using the MakeNextNeighbor method. This method returns an assignment which represents the incremental changes to the current solution. It also returns a second assignment representing the changes to the last solution defined by the neighborhood operator; this assignment is empty if the neighborhood operator cannot track this information."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+
+    def NextNeighbor(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
+        return _pywrapcp.LocalSearchOperator_NextNeighbor(self, delta, deltadelta)
+
+    def Start(self, assignment: "Assignment") -> "void":
+        return _pywrapcp.LocalSearchOperator_Start(self, assignment)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_LocalSearchOperator(self)
+        return weakref.proxy(self)
+
+ +
+ +

This class represent a reversible FIFO structure. The main difference w.r.t a standard FIFO structure is that a Solver is given as parameter to the modifiers such that the solver can store the backtrack information Iterator's traversing order should not be changed, as some algorithm depend on it to be consistent. It's main use is to store a list of demons in the various classes of variables. The base class for all local search operators. A local search operator is an object that defines the neighborhood of a solution. In other words, a neighborhood is the set of solutions which can be reached from a given solution using an operator. The behavior of the LocalSearchOperator class is similar to iterators. The operator is synchronized with an assignment (gives the current values of the variables); this is done in the Start() method. Then one can iterate over the neighbors using the MakeNextNeighbor method. This method returns an assignment which represents the incremental changes to the current solution. It also returns a second assignment representing the changes to the last solution defined by the neighborhood operator; this assignment is empty if the neighborhood operator cannot track this information.

+
+ + +
+
#   + + + LocalSearchOperator(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + NextNeighbor( + self, + delta: pywrapcp.Assignment, + deltadelta: pywrapcp.Assignment +) -> bool: +
+ +
+ View Source +
    def NextNeighbor(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
+        return _pywrapcp.LocalSearchOperator_NextNeighbor(self, delta, deltadelta)
+
+ +
+ + + +
+
+
#   + + + def + Start(self, assignment: pywrapcp.Assignment) -> 'void': +
+ +
+ View Source +
    def Start(self, assignment: "Assignment") -> "void":
+        return _pywrapcp.LocalSearchOperator_Start(self, assignment)
+
+ +
+ + + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ #   + + + class + IntVarLocalSearchOperatorTemplate(LocalSearchOperator): +
+ +
+ View Source +
class IntVarLocalSearchOperatorTemplate(LocalSearchOperator):
+    r""" Base operator class for operators manipulating variables."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+
+    def Start(self, assignment: "Assignment") -> "void":
+        r""" This method should not be overridden. Override OnStart() instead which is called before exiting this method."""
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_Start(self, assignment)
+
+    def IsIncremental(self) -> "bool":
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_IsIncremental(self)
+
+    def Size(self) -> "int":
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_Size(self)
+
+    def Value(self, index: "int64_t") -> "long const &":
+        r""" Returns the value in the current assignment of the variable of given index."""
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_Value(self, index)
+
+    def OldValue(self, index: "int64_t") -> "long const &":
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_OldValue(self, index)
+
+    def SetValue(self, index: "int64_t", value: "long const &") -> "void":
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_SetValue(self, index, value)
+
+    def OnStart(self) -> "void":
+        r""" Called by Start() after synchronizing the operator with the current assignment. Should be overridden instead of Start() to avoid calling VarLocalSearchOperator::Start explicitly."""
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_OnStart(self)
+
+ +
+ +

Base operator class for operators manipulating variables.

+
+ + +
+
#   + + + IntVarLocalSearchOperatorTemplate(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Start(self, assignment: pywrapcp.Assignment) -> 'void': +
+ +
+ View Source +
    def Start(self, assignment: "Assignment") -> "void":
+        r""" This method should not be overridden. Override OnStart() instead which is called before exiting this method."""
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_Start(self, assignment)
+
+ +
+ +

This method should not be overridden. Override OnStart() instead which is called before exiting this method.

+
+ + +
+
+
#   + + + def + IsIncremental(self) -> bool: +
+ +
+ View Source +
    def IsIncremental(self) -> "bool":
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_IsIncremental(self)
+
+ +
+ + + +
+
+
#   + + + def + Size(self) -> int: +
+ +
+ View Source +
    def Size(self) -> "int":
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_Size(self)
+
+ +
+ + + +
+
+
#   + + + def + Value(self, index: 'int64_t') -> 'long const &': +
+ +
+ View Source +
    def Value(self, index: "int64_t") -> "long const &":
+        r""" Returns the value in the current assignment of the variable of given index."""
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_Value(self, index)
+
+ +
+ +

Returns the value in the current assignment of the variable of given index.

+
+ + +
+
+
#   + + + def + OldValue(self, index: 'int64_t') -> 'long const &': +
+ +
+ View Source +
    def OldValue(self, index: "int64_t") -> "long const &":
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_OldValue(self, index)
+
+ +
+ + + +
+
+
#   + + + def + SetValue(self, index: 'int64_t', value: 'long const &') -> 'void': +
+ +
+ View Source +
    def SetValue(self, index: "int64_t", value: "long const &") -> "void":
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_SetValue(self, index, value)
+
+ +
+ + + +
+
+
#   + + + def + OnStart(self) -> 'void': +
+ +
+ View Source +
    def OnStart(self) -> "void":
+        r""" Called by Start() after synchronizing the operator with the current assignment. Should be overridden instead of Start() to avoid calling VarLocalSearchOperator::Start explicitly."""
+        return _pywrapcp.IntVarLocalSearchOperatorTemplate_OnStart(self)
+
+ +
+ +

Called by Start() after synchronizing the operator with the current assignment. Should be overridden instead of Start() to avoid calling VarLocalSearchOperator::Start explicitly.

+
+ + +
+
+
Inherited Members
+
+ + +
+
+
+
+
+ #   + + + class + IntVarLocalSearchOperator(IntVarLocalSearchOperatorTemplate): +
+ +
+ View Source +
class IntVarLocalSearchOperator(IntVarLocalSearchOperatorTemplate):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, *args):
+        if self.__class__ == IntVarLocalSearchOperator:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.IntVarLocalSearchOperator_swiginit(self, _pywrapcp.new_IntVarLocalSearchOperator(_self, *args))
+    __swig_destroy__ = _pywrapcp.delete_IntVarLocalSearchOperator
+
+    def NextNeighbor(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
+        r""" Redefines MakeNextNeighbor to export a simpler interface. The calls to ApplyChanges() and RevertChanges() are factored in this method, hiding both delta and deltadelta from subclasses which only need to override MakeOneNeighbor(). Therefore this method should not be overridden. Override MakeOneNeighbor() instead."""
+        return _pywrapcp.IntVarLocalSearchOperator_NextNeighbor(self, delta, deltadelta)
+
+    def OneNeighbor(self) -> "bool":
+        r""" Creates a new neighbor. It returns false when the neighborhood is completely explored. MakeNextNeighbor() in a subclass of IntVarLocalSearchOperator."""
+        return _pywrapcp.IntVarLocalSearchOperator_OneNeighbor(self)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_IntVarLocalSearchOperator(self)
+        return weakref.proxy(self)
+
+ +
+ +

Base operator class for operators manipulating variables.

+
+ + +
+
#   + + + IntVarLocalSearchOperator(*args) +
+ +
+ View Source +
    def __init__(self, *args):
+        if self.__class__ == IntVarLocalSearchOperator:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.IntVarLocalSearchOperator_swiginit(self, _pywrapcp.new_IntVarLocalSearchOperator(_self, *args))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + NextNeighbor( + self, + delta: pywrapcp.Assignment, + deltadelta: pywrapcp.Assignment +) -> bool: +
+ +
+ View Source +
    def NextNeighbor(self, delta: "Assignment", deltadelta: "Assignment") -> "bool":
+        r""" Redefines MakeNextNeighbor to export a simpler interface. The calls to ApplyChanges() and RevertChanges() are factored in this method, hiding both delta and deltadelta from subclasses which only need to override MakeOneNeighbor(). Therefore this method should not be overridden. Override MakeOneNeighbor() instead."""
+        return _pywrapcp.IntVarLocalSearchOperator_NextNeighbor(self, delta, deltadelta)
+
+ +
+ +

Redefines MakeNextNeighbor to export a simpler interface. The calls to ApplyChanges() and RevertChanges() are factored in this method, hiding both delta and deltadelta from subclasses which only need to override MakeOneNeighbor(). Therefore this method should not be overridden. Override MakeOneNeighbor() instead.

+
+ + +
+
+
#   + + + def + OneNeighbor(self) -> bool: +
+ +
+ View Source +
    def OneNeighbor(self) -> "bool":
+        r""" Creates a new neighbor. It returns false when the neighborhood is completely explored. MakeNextNeighbor() in a subclass of IntVarLocalSearchOperator."""
+        return _pywrapcp.IntVarLocalSearchOperator_OneNeighbor(self)
+
+ +
+ +

Creates a new neighbor. It returns false when the neighborhood is completely explored. MakeNextNeighbor() in a subclass of IntVarLocalSearchOperator.

+
+ + +
+ +
+
+
+ #   + + + class + SequenceVarLocalSearchOperatorTemplate(LocalSearchOperator): +
+ +
+ View Source +
class SequenceVarLocalSearchOperatorTemplate(LocalSearchOperator):
+    r""" Base operator class for operators manipulating variables."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+
+    def Start(self, assignment: "Assignment") -> "void":
+        r""" This method should not be overridden. Override OnStart() instead which is called before exiting this method."""
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_Start(self, assignment)
+
+    def IsIncremental(self) -> "bool":
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_IsIncremental(self)
+
+    def Size(self) -> "int":
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_Size(self)
+
+    def Value(self, index: "int64_t") -> "std::vector< int > const &":
+        r""" Returns the value in the current assignment of the variable of given index."""
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_Value(self, index)
+
+    def OldValue(self, index: "int64_t") -> "std::vector< int > const &":
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_OldValue(self, index)
+
+    def SetValue(self, index: "int64_t", value: "std::vector< int > const &") -> "void":
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_SetValue(self, index, value)
+
+    def OnStart(self) -> "void":
+        r""" Called by Start() after synchronizing the operator with the current assignment. Should be overridden instead of Start() to avoid calling VarLocalSearchOperator::Start explicitly."""
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_OnStart(self)
+
+ +
+ +

Base operator class for operators manipulating variables.

+
+ + +
+
#   + + + SequenceVarLocalSearchOperatorTemplate(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Start(self, assignment: pywrapcp.Assignment) -> 'void': +
+ +
+ View Source +
    def Start(self, assignment: "Assignment") -> "void":
+        r""" This method should not be overridden. Override OnStart() instead which is called before exiting this method."""
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_Start(self, assignment)
+
+ +
+ +

This method should not be overridden. Override OnStart() instead which is called before exiting this method.

+
+ + +
+
+
#   + + + def + IsIncremental(self) -> bool: +
+ +
+ View Source +
    def IsIncremental(self) -> "bool":
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_IsIncremental(self)
+
+ +
+ + + +
+
+
#   + + + def + Size(self) -> int: +
+ +
+ View Source +
    def Size(self) -> "int":
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_Size(self)
+
+ +
+ + + +
+
+
#   + + + def + Value(self, index: 'int64_t') -> 'std::vector< int > const &': +
+ +
+ View Source +
    def Value(self, index: "int64_t") -> "std::vector< int > const &":
+        r""" Returns the value in the current assignment of the variable of given index."""
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_Value(self, index)
+
+ +
+ +

Returns the value in the current assignment of the variable of given index.

+
+ + +
+
+
#   + + + def + OldValue(self, index: 'int64_t') -> 'std::vector< int > const &': +
+ +
+ View Source +
    def OldValue(self, index: "int64_t") -> "std::vector< int > const &":
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_OldValue(self, index)
+
+ +
+ + + +
+
+
#   + + + def + SetValue( + self, + index: 'int64_t', + value: 'std::vector< int > const &' +) -> 'void': +
+ +
+ View Source +
    def SetValue(self, index: "int64_t", value: "std::vector< int > const &") -> "void":
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_SetValue(self, index, value)
+
+ +
+ + + +
+
+
#   + + + def + OnStart(self) -> 'void': +
+ +
+ View Source +
    def OnStart(self) -> "void":
+        r""" Called by Start() after synchronizing the operator with the current assignment. Should be overridden instead of Start() to avoid calling VarLocalSearchOperator::Start explicitly."""
+        return _pywrapcp.SequenceVarLocalSearchOperatorTemplate_OnStart(self)
+
+ +
+ +

Called by Start() after synchronizing the operator with the current assignment. Should be overridden instead of Start() to avoid calling VarLocalSearchOperator::Start explicitly.

+
+ + +
+
+
Inherited Members
+
+ + +
+
+
+
+
+ #   + + + class + SequenceVarLocalSearchOperator(SequenceVarLocalSearchOperatorTemplate): +
+ +
+ View Source +
class SequenceVarLocalSearchOperator(SequenceVarLocalSearchOperatorTemplate):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+
+ +
+ +

Base operator class for operators manipulating variables.

+
+ + +
+
#   + + + SequenceVarLocalSearchOperator(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+ +
+
+
+ #   + + + class + BaseLns(IntVarLocalSearchOperator): +
+ +
+ View Source +
class BaseLns(IntVarLocalSearchOperator):
+    r""" This is the base class for building an Lns operator. An Lns fragment is a collection of variables which will be relaxed. Fragments are built with NextFragment(), which returns false if there are no more fragments to build. Optionally one can override InitFragments, which is called from LocalSearchOperator::Start to initialize fragment data. Here's a sample relaxing one variable at a time: class OneVarLns : public BaseLns {  public:   OneVarLns(const std::vector<IntVar*>& vars) : BaseLns(vars), index_(0) {}   virtual ~OneVarLns() {}   virtual void InitFragments() { index_ = 0; }   virtual bool NextFragment() {     const int size = Size();     if (index_ < size) {       AppendToFragment(index_);       ++index_;       return true;     } else {       return false;     }   }  private:   int index_; };"""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, vars: "std::vector< operations_research::IntVar * > const &"):
+        if self.__class__ == BaseLns:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.BaseLns_swiginit(self, _pywrapcp.new_BaseLns(_self, vars))
+    __swig_destroy__ = _pywrapcp.delete_BaseLns
+
+    def InitFragments(self) -> "void":
+        return _pywrapcp.BaseLns_InitFragments(self)
+
+    def NextFragment(self) -> "bool":
+        return _pywrapcp.BaseLns_NextFragment(self)
+
+    def AppendToFragment(self, index: "int") -> "void":
+        return _pywrapcp.BaseLns_AppendToFragment(self, index)
+
+    def FragmentSize(self) -> "int":
+        return _pywrapcp.BaseLns_FragmentSize(self)
+
+    def __getitem__(self, index: "int") -> "int64_t":
+        return _pywrapcp.BaseLns___getitem__(self, index)
+
+    def __len__(self) -> "int":
+        return _pywrapcp.BaseLns___len__(self)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_BaseLns(self)
+        return weakref.proxy(self)
+
+ +
+ +

This is the base class for building an Lns operator. An Lns fragment is a collection of variables which will be relaxed. Fragments are built with NextFragment(), which returns false if there are no more fragments to build. Optionally one can override InitFragments, which is called from LocalSearchOperator::Start to initialize fragment data. Here's a sample relaxing one variable at a time: class OneVarLns : public BaseLns { public: OneVarLns(const std::vector& vars) : BaseLns(vars), index_(0) {} virtual ~OneVarLns() {} virtual void InitFragments() { index_ = 0; } virtual bool NextFragment() { const int size = Size(); if (index_ < size) { AppendToFragment(index_); ++index_; return true; } else { return false; } } private: int index_; };

+
+ + +
+
#   + + + BaseLns(vars: 'std::vector< operations_research::IntVar * > const &') +
+ +
+ View Source +
    def __init__(self, vars: "std::vector< operations_research::IntVar * > const &"):
+        if self.__class__ == BaseLns:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.BaseLns_swiginit(self, _pywrapcp.new_BaseLns(_self, vars))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + InitFragments(self) -> 'void': +
+ +
+ View Source +
    def InitFragments(self) -> "void":
+        return _pywrapcp.BaseLns_InitFragments(self)
+
+ +
+ + + +
+
+
#   + + + def + NextFragment(self) -> bool: +
+ +
+ View Source +
    def NextFragment(self) -> "bool":
+        return _pywrapcp.BaseLns_NextFragment(self)
+
+ +
+ + + +
+
+
#   + + + def + AppendToFragment(self, index: int) -> 'void': +
+ +
+ View Source +
    def AppendToFragment(self, index: "int") -> "void":
+        return _pywrapcp.BaseLns_AppendToFragment(self, index)
+
+ +
+ + + +
+
+
#   + + + def + FragmentSize(self) -> int: +
+ +
+ View Source +
    def FragmentSize(self) -> "int":
+        return _pywrapcp.BaseLns_FragmentSize(self)
+
+ +
+ + + +
+ +
+
+
+ #   + + + class + ChangeValue(IntVarLocalSearchOperator): +
+ +
+ View Source +
class ChangeValue(IntVarLocalSearchOperator):
+    r""" Defines operators which change the value of variables; each neighbor corresponds to *one* modified variable. Sub-classes have to define ModifyValue which determines what the new variable value is going to be (given the current value and the variable)."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, vars: "std::vector< operations_research::IntVar * > const &"):
+        if self.__class__ == ChangeValue:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.ChangeValue_swiginit(self, _pywrapcp.new_ChangeValue(_self, vars))
+    __swig_destroy__ = _pywrapcp.delete_ChangeValue
+
+    def ModifyValue(self, index: "int64_t", value: "int64_t") -> "int64_t":
+        return _pywrapcp.ChangeValue_ModifyValue(self, index, value)
+
+    def OneNeighbor(self) -> "bool":
+        r""" This method should not be overridden. Override ModifyValue() instead."""
+        return _pywrapcp.ChangeValue_OneNeighbor(self)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_ChangeValue(self)
+        return weakref.proxy(self)
+
+ +
+ +

Defines operators which change the value of variables; each neighbor corresponds to one modified variable. Sub-classes have to define ModifyValue which determines what the new variable value is going to be (given the current value and the variable).

+
+ + +
+
#   + + + ChangeValue(vars: 'std::vector< operations_research::IntVar * > const &') +
+ +
+ View Source +
    def __init__(self, vars: "std::vector< operations_research::IntVar * > const &"):
+        if self.__class__ == ChangeValue:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.ChangeValue_swiginit(self, _pywrapcp.new_ChangeValue(_self, vars))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + ModifyValue(self, index: 'int64_t', value: 'int64_t') -> 'int64_t': +
+ +
+ View Source +
    def ModifyValue(self, index: "int64_t", value: "int64_t") -> "int64_t":
+        return _pywrapcp.ChangeValue_ModifyValue(self, index, value)
+
+ +
+ + + +
+
+
#   + + + def + OneNeighbor(self) -> bool: +
+ +
+ View Source +
    def OneNeighbor(self) -> "bool":
+        r""" This method should not be overridden. Override ModifyValue() instead."""
+        return _pywrapcp.ChangeValue_OneNeighbor(self)
+
+ +
+ +

This method should not be overridden. Override ModifyValue() instead.

+
+ + +
+ +
+
+
+ #   + + + class + PathOperator(IntVarLocalSearchOperator): +
+ +
+ View Source +
class PathOperator(IntVarLocalSearchOperator):
+    r""" Base class of the local search operators dedicated to path modifications (a path is a set of nodes linked together by arcs). This family of neighborhoods supposes they are handling next variables representing the arcs (var[i] represents the node immediately after i on a path). Several services are provided: - arc manipulators (SetNext(), ReverseChain(), MoveChain()) - path inspectors (Next(), Prev(), IsPathEnd()) - path iterators: operators need a given number of nodes to define a   neighbor; this class provides the iteration on a given number of (base)   nodes which can be used to define a neighbor (through the BaseNode method) Subclasses only need to override MakeNeighbor to create neighbors using the services above (no direct manipulation of assignments)."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+
+    def Neighbor(self) -> "bool":
+        return _pywrapcp.PathOperator_Neighbor(self)
+
+ +
+ +

Base class of the local search operators dedicated to path modifications (a path is a set of nodes linked together by arcs). This family of neighborhoods supposes they are handling next variables representing the arcs (var[i] represents the node immediately after i on a path). Several services are provided: - arc manipulators (SetNext(), ReverseChain(), MoveChain()) - path inspectors (Next(), Prev(), IsPathEnd()) - path iterators: operators need a given number of nodes to define a neighbor; this class provides the iteration on a given number of (base) nodes which can be used to define a neighbor (through the BaseNode method) Subclasses only need to override MakeNeighbor to create neighbors using the services above (no direct manipulation of assignments).

+
+ + +
+
#   + + + PathOperator(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Neighbor(self) -> bool: +
+ +
+ View Source +
    def Neighbor(self) -> "bool":
+        return _pywrapcp.PathOperator_Neighbor(self)
+
+ +
+ + + +
+ +
+
+
+ #   + + + class + LocalSearchFilter(BaseObject): +
+ +
+ View Source +
class LocalSearchFilter(BaseObject):
+    r""" Classes to which this template function can be applied to as of 04/2014. Usage: LocalSearchOperator* op = MakeLocalSearchOperator<Relocate>(...); class TwoOpt; class Relocate; class Exchange; class Cross; class MakeActiveOperator; class MakeInactiveOperator; class MakeChainInactiveOperator; class SwapActiveOperator; class ExtendedSwapActiveOperator; class MakeActiveAndRelocate; class RelocateAndMakeActiveOperator; class RelocateAndMakeInactiveOperator; Local Search Filters are used for fast neighbor pruning. Filtering a move is done in several phases: - in the Relax phase, filters determine which parts of their internals   will be changed by the candidate, and modify intermediary State - in the Accept phase, filters check that the candidate is feasible, - if the Accept phase succeeds, the solver may decide to trigger a   Synchronize phase that makes filters change their internal representation   to the last candidate, - otherwise (Accept fails or the solver does not want to synchronize),   a Revert phase makes filters erase any intermediary State generated by the   Relax and Accept phases. A given filter has phases called with the following pattern: (Relax.Accept.Synchronize | Relax.Accept.Revert | Relax.Revert)*. Filters's Revert() is always called in the reverse order their Accept() was called, to allow late filters to use state done/undone by early filters' Accept()/Revert()."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+
+    def Accept(self, delta: "Assignment", deltadelta: "Assignment", objective_min: "int64_t", objective_max: "int64_t") -> "bool":
+        r""" Accepts a "delta" given the assignment with which the filter has been synchronized; the delta holds the variables which have been modified and their new value. If the filter represents a part of the global objective, its contribution must be between objective_min and objective_max. Sample: supposing one wants to maintain a[0,1] + b[0,1] <= 1, for the assignment (a,1), (b,0), the delta (b,1) will be rejected but the delta (a,0) will be accepted. TODO(user): Remove arguments when there are no more need for those."""
+        return _pywrapcp.LocalSearchFilter_Accept(self, delta, deltadelta, objective_min, objective_max)
+
+    def IsIncremental(self) -> "bool":
+        return _pywrapcp.LocalSearchFilter_IsIncremental(self)
+
+    def Synchronize(self, assignment: "Assignment", delta: "Assignment") -> "void":
+        r""" Synchronizes the filter with the current solution, delta being the difference with the solution passed to the previous call to Synchronize() or IncrementalSynchronize(). 'delta' can be used to incrementally synchronizing the filter with the new solution by only considering the changes in delta."""
+        return _pywrapcp.LocalSearchFilter_Synchronize(self, assignment, delta)
+    __swig_destroy__ = _pywrapcp.delete_LocalSearchFilter
+
+ +
+ +

Classes to which this template function can be applied to as of 04/2014. Usage: LocalSearchOperator* op = MakeLocalSearchOperator(...); class TwoOpt; class Relocate; class Exchange; class Cross; class MakeActiveOperator; class MakeInactiveOperator; class MakeChainInactiveOperator; class SwapActiveOperator; class ExtendedSwapActiveOperator; class MakeActiveAndRelocate; class RelocateAndMakeActiveOperator; class RelocateAndMakeInactiveOperator; Local Search Filters are used for fast neighbor pruning. Filtering a move is done in several phases: - in the Relax phase, filters determine which parts of their internals will be changed by the candidate, and modify intermediary State - in the Accept phase, filters check that the candidate is feasible, - if the Accept phase succeeds, the solver may decide to trigger a Synchronize phase that makes filters change their internal representation to the last candidate, - otherwise (Accept fails or the solver does not want to synchronize), a Revert phase makes filters erase any intermediary State generated by the Relax and Accept phases. A given filter has phases called with the following pattern: (Relax.Accept.Synchronize | Relax.Accept.Revert | Relax.Revert)*. Filters's Revert() is always called in the reverse order their Accept() was called, to allow late filters to use state done/undone by early filters' Accept()/Revert().

+
+ + +
+
#   + + + LocalSearchFilter(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Accept( + self, + delta: pywrapcp.Assignment, + deltadelta: pywrapcp.Assignment, + objective_min: 'int64_t', + objective_max: 'int64_t' +) -> bool: +
+ +
+ View Source +
    def Accept(self, delta: "Assignment", deltadelta: "Assignment", objective_min: "int64_t", objective_max: "int64_t") -> "bool":
+        r""" Accepts a "delta" given the assignment with which the filter has been synchronized; the delta holds the variables which have been modified and their new value. If the filter represents a part of the global objective, its contribution must be between objective_min and objective_max. Sample: supposing one wants to maintain a[0,1] + b[0,1] <= 1, for the assignment (a,1), (b,0), the delta (b,1) will be rejected but the delta (a,0) will be accepted. TODO(user): Remove arguments when there are no more need for those."""
+        return _pywrapcp.LocalSearchFilter_Accept(self, delta, deltadelta, objective_min, objective_max)
+
+ +
+ +

Accepts a "delta" given the assignment with which the filter has been synchronized; the delta holds the variables which have been modified and their new value. If the filter represents a part of the global objective, its contribution must be between objective_min and objective_max. Sample: supposing one wants to maintain a[0,1] + b[0,1] <= 1, for the assignment (a,1), (b,0), the delta (b,1) will be rejected but the delta (a,0) will be accepted. TODO(user): Remove arguments when there are no more need for those.

+
+ + +
+
+
#   + + + def + IsIncremental(self) -> bool: +
+ +
+ View Source +
    def IsIncremental(self) -> "bool":
+        return _pywrapcp.LocalSearchFilter_IsIncremental(self)
+
+ +
+ + + +
+
+
#   + + + def + Synchronize( + self, + assignment: pywrapcp.Assignment, + delta: pywrapcp.Assignment +) -> 'void': +
+ +
+ View Source +
    def Synchronize(self, assignment: "Assignment", delta: "Assignment") -> "void":
+        r""" Synchronizes the filter with the current solution, delta being the difference with the solution passed to the previous call to Synchronize() or IncrementalSynchronize(). 'delta' can be used to incrementally synchronizing the filter with the new solution by only considering the changes in delta."""
+        return _pywrapcp.LocalSearchFilter_Synchronize(self, assignment, delta)
+
+ +
+ +

Synchronizes the filter with the current solution, delta being the difference with the solution passed to the previous call to Synchronize() or IncrementalSynchronize(). 'delta' can be used to incrementally synchronizing the filter with the new solution by only considering the changes in delta.

+
+ + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ #   + + + class + LocalSearchFilterManager(BaseObject): +
+ +
+ View Source +
class LocalSearchFilterManager(BaseObject):
+    r""" Filter manager: when a move is made, filters are executed to decide whether the solution is feasible and compute parts of the new cost. This class schedules filter execution and composes costs as a sum."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.LocalSearchFilterManager_DebugString(self)
+
+    def __init__(self, *args):
+        _pywrapcp.LocalSearchFilterManager_swiginit(self, _pywrapcp.new_LocalSearchFilterManager(*args))
+
+    def Accept(self, monitor: "operations_research::LocalSearchMonitor *const", delta: "Assignment", deltadelta: "Assignment", objective_min: "int64_t", objective_max: "int64_t") -> "bool":
+        r""" Returns true iff all filters return true, and the sum of their accepted objectives is between objective_min and objective_max. The monitor has its Begin/EndFiltering events triggered."""
+        return _pywrapcp.LocalSearchFilterManager_Accept(self, monitor, delta, deltadelta, objective_min, objective_max)
+
+    def Synchronize(self, assignment: "Assignment", delta: "Assignment") -> "void":
+        r""" Synchronizes all filters to assignment."""
+        return _pywrapcp.LocalSearchFilterManager_Synchronize(self, assignment, delta)
+    __swig_destroy__ = _pywrapcp.delete_LocalSearchFilterManager
+
+ +
+ +

Filter manager: when a move is made, filters are executed to decide whether the solution is feasible and compute parts of the new cost. This class schedules filter execution and composes costs as a sum.

+
+ + +
+
#   + + + LocalSearchFilterManager(*args) +
+ +
+ View Source +
    def __init__(self, *args):
+        _pywrapcp.LocalSearchFilterManager_swiginit(self, _pywrapcp.new_LocalSearchFilterManager(*args))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + DebugString(self) -> 'std::string': +
+ +
+ View Source +
    def DebugString(self) -> "std::string":
+        return _pywrapcp.LocalSearchFilterManager_DebugString(self)
+
+ +
+ + + +
+
+
#   + + + def + Accept( + self, + monitor: 'operations_research::LocalSearchMonitor *const', + delta: pywrapcp.Assignment, + deltadelta: pywrapcp.Assignment, + objective_min: 'int64_t', + objective_max: 'int64_t' +) -> bool: +
+ +
+ View Source +
    def Accept(self, monitor: "operations_research::LocalSearchMonitor *const", delta: "Assignment", deltadelta: "Assignment", objective_min: "int64_t", objective_max: "int64_t") -> "bool":
+        r""" Returns true iff all filters return true, and the sum of their accepted objectives is between objective_min and objective_max. The monitor has its Begin/EndFiltering events triggered."""
+        return _pywrapcp.LocalSearchFilterManager_Accept(self, monitor, delta, deltadelta, objective_min, objective_max)
+
+ +
+ +

Returns true iff all filters return true, and the sum of their accepted objectives is between objective_min and objective_max. The monitor has its Begin/EndFiltering events triggered.

+
+ + +
+
+
#   + + + def + Synchronize( + self, + assignment: pywrapcp.Assignment, + delta: pywrapcp.Assignment +) -> 'void': +
+ +
+ View Source +
    def Synchronize(self, assignment: "Assignment", delta: "Assignment") -> "void":
+        r""" Synchronizes all filters to assignment."""
+        return _pywrapcp.LocalSearchFilterManager_Synchronize(self, assignment, delta)
+
+ +
+ +

Synchronizes all filters to assignment.

+
+ + +
+
+
+
+ #   + + + class + IntVarLocalSearchFilter(LocalSearchFilter): +
+ +
+ View Source +
class IntVarLocalSearchFilter(LocalSearchFilter):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, vars: "std::vector< operations_research::IntVar * > const &"):
+        if self.__class__ == IntVarLocalSearchFilter:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.IntVarLocalSearchFilter_swiginit(self, _pywrapcp.new_IntVarLocalSearchFilter(_self, vars))
+    __swig_destroy__ = _pywrapcp.delete_IntVarLocalSearchFilter
+
+    def Synchronize(self, assignment: "Assignment", delta: "Assignment") -> "void":
+        r""" This method should not be overridden. Override OnSynchronize() instead which is called before exiting this method."""
+        return _pywrapcp.IntVarLocalSearchFilter_Synchronize(self, assignment, delta)
+
+    def Size(self) -> "int":
+        return _pywrapcp.IntVarLocalSearchFilter_Size(self)
+
+    def Value(self, index: "int") -> "int64_t":
+        return _pywrapcp.IntVarLocalSearchFilter_Value(self, index)
+
+    def IndexFromVar(self, var: "IntVar") -> "int64_t":
+        return _pywrapcp.IntVarLocalSearchFilter_IndexFromVar(self, var)
+    def __disown__(self):
+        self.this.disown()
+        _pywrapcp.disown_IntVarLocalSearchFilter(self)
+        return weakref.proxy(self)
+
+ +
+ +

Classes to which this template function can be applied to as of 04/2014. Usage: LocalSearchOperator* op = MakeLocalSearchOperator(...); class TwoOpt; class Relocate; class Exchange; class Cross; class MakeActiveOperator; class MakeInactiveOperator; class MakeChainInactiveOperator; class SwapActiveOperator; class ExtendedSwapActiveOperator; class MakeActiveAndRelocate; class RelocateAndMakeActiveOperator; class RelocateAndMakeInactiveOperator; Local Search Filters are used for fast neighbor pruning. Filtering a move is done in several phases: - in the Relax phase, filters determine which parts of their internals will be changed by the candidate, and modify intermediary State - in the Accept phase, filters check that the candidate is feasible, - if the Accept phase succeeds, the solver may decide to trigger a Synchronize phase that makes filters change their internal representation to the last candidate, - otherwise (Accept fails or the solver does not want to synchronize), a Revert phase makes filters erase any intermediary State generated by the Relax and Accept phases. A given filter has phases called with the following pattern: (Relax.Accept.Synchronize | Relax.Accept.Revert | Relax.Revert)*. Filters's Revert() is always called in the reverse order their Accept() was called, to allow late filters to use state done/undone by early filters' Accept()/Revert().

+
+ + +
+
#   + + + IntVarLocalSearchFilter(vars: 'std::vector< operations_research::IntVar * > const &') +
+ +
+ View Source +
    def __init__(self, vars: "std::vector< operations_research::IntVar * > const &"):
+        if self.__class__ == IntVarLocalSearchFilter:
+            _self = None
+        else:
+            _self = self
+        _pywrapcp.IntVarLocalSearchFilter_swiginit(self, _pywrapcp.new_IntVarLocalSearchFilter(_self, vars))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Synchronize( + self, + assignment: pywrapcp.Assignment, + delta: pywrapcp.Assignment +) -> 'void': +
+ +
+ View Source +
    def Synchronize(self, assignment: "Assignment", delta: "Assignment") -> "void":
+        r""" This method should not be overridden. Override OnSynchronize() instead which is called before exiting this method."""
+        return _pywrapcp.IntVarLocalSearchFilter_Synchronize(self, assignment, delta)
+
+ +
+ +

This method should not be overridden. Override OnSynchronize() instead which is called before exiting this method.

+
+ + +
+
+
#   + + + def + Size(self) -> int: +
+ +
+ View Source +
    def Size(self) -> "int":
+        return _pywrapcp.IntVarLocalSearchFilter_Size(self)
+
+ +
+ + + +
+
+
#   + + + def + Value(self, index: int) -> 'int64_t': +
+ +
+ View Source +
    def Value(self, index: "int") -> "int64_t":
+        return _pywrapcp.IntVarLocalSearchFilter_Value(self, index)
+
+ +
+ + + +
+
+
#   + + + def + IndexFromVar(self, var: pywrapcp.IntVar) -> 'int64_t': +
+ +
+ View Source +
    def IndexFromVar(self, var: "IntVar") -> "int64_t":
+        return _pywrapcp.IntVarLocalSearchFilter_IndexFromVar(self, var)
+
+ +
+ + + +
+
+
Inherited Members
+
+ + +
+
+
+
+
+ #   + + + class + BooleanVar(IntVar): +
+ +
+ View Source +
class BooleanVar(IntVar):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+
+    def Min(self) -> "int64_t":
+        return _pywrapcp.BooleanVar_Min(self)
+
+    def SetMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.BooleanVar_SetMin(self, m)
+
+    def Max(self) -> "int64_t":
+        return _pywrapcp.BooleanVar_Max(self)
+
+    def SetMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.BooleanVar_SetMax(self, m)
+
+    def SetRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.BooleanVar_SetRange(self, mi, ma)
+
+    def Bound(self) -> "bool":
+        return _pywrapcp.BooleanVar_Bound(self)
+
+    def Value(self) -> "int64_t":
+        return _pywrapcp.BooleanVar_Value(self)
+
+    def RemoveValue(self, v: "int64_t") -> "void":
+        return _pywrapcp.BooleanVar_RemoveValue(self, v)
+
+    def RemoveInterval(self, l: "int64_t", u: "int64_t") -> "void":
+        return _pywrapcp.BooleanVar_RemoveInterval(self, l, u)
+
+    def WhenBound(self, d: "Demon") -> "void":
+        return _pywrapcp.BooleanVar_WhenBound(self, d)
+
+    def WhenRange(self, d: "Demon") -> "void":
+        return _pywrapcp.BooleanVar_WhenRange(self, d)
+
+    def WhenDomain(self, d: "Demon") -> "void":
+        return _pywrapcp.BooleanVar_WhenDomain(self, d)
+
+    def Size(self) -> "uint64_t":
+        return _pywrapcp.BooleanVar_Size(self)
+
+    def Contains(self, v: "int64_t") -> "bool":
+        return _pywrapcp.BooleanVar_Contains(self, v)
+
+    def HoleIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *":
+        return _pywrapcp.BooleanVar_HoleIteratorAux(self, reversible)
+
+    def DomainIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *":
+        return _pywrapcp.BooleanVar_DomainIteratorAux(self, reversible)
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.BooleanVar_DebugString(self)
+
+ +
+ +

The class IntVar is a subset of IntExpr. In addition to the IntExpr protocol, it offers persistence, removing values from the domains, and a finer model for events.

+
+ + +
+
#   + + + BooleanVar(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Min(self) -> 'int64_t': +
+ +
+ View Source +
    def Min(self) -> "int64_t":
+        return _pywrapcp.BooleanVar_Min(self)
+
+ +
+ + + +
+
+
#   + + + def + SetMin(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetMin(self, m: "int64_t") -> "void":
+        return _pywrapcp.BooleanVar_SetMin(self, m)
+
+ +
+ + + +
+
+
#   + + + def + Max(self) -> 'int64_t': +
+ +
+ View Source +
    def Max(self) -> "int64_t":
+        return _pywrapcp.BooleanVar_Max(self)
+
+ +
+ + + +
+
+
#   + + + def + SetMax(self, m: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetMax(self, m: "int64_t") -> "void":
+        return _pywrapcp.BooleanVar_SetMax(self, m)
+
+ +
+ + + +
+
+
#   + + + def + SetRange(self, mi: 'int64_t', ma: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetRange(self, mi: "int64_t", ma: "int64_t") -> "void":
+        return _pywrapcp.BooleanVar_SetRange(self, mi, ma)
+
+ +
+ +

This method sets both the min and the max of the expression.

+
+ + +
+
+
#   + + + def + Bound(self) -> bool: +
+ +
+ View Source +
    def Bound(self) -> "bool":
+        return _pywrapcp.BooleanVar_Bound(self)
+
+ +
+ +

Returns true if the min and the max of the expression are equal.

+
+ + +
+
+
#   + + + def + Value(self) -> 'int64_t': +
+ +
+ View Source +
    def Value(self) -> "int64_t":
+        return _pywrapcp.BooleanVar_Value(self)
+
+ +
+ +

This method returns the value of the variable. This method checks before that the variable is bound.

+
+ + +
+
+
#   + + + def + RemoveValue(self, v: 'int64_t') -> 'void': +
+ +
+ View Source +
    def RemoveValue(self, v: "int64_t") -> "void":
+        return _pywrapcp.BooleanVar_RemoveValue(self, v)
+
+ +
+ +

This method removes the value 'v' from the domain of the variable.

+
+ + +
+
+
#   + + + def + RemoveInterval(self, l: 'int64_t', u: 'int64_t') -> 'void': +
+ +
+ View Source +
    def RemoveInterval(self, l: "int64_t", u: "int64_t") -> "void":
+        return _pywrapcp.BooleanVar_RemoveInterval(self, l, u)
+
+ +
+ +

This method removes the interval 'l' .. 'u' from the domain of the variable. It assumes that 'l' <= 'u'.

+
+ + +
+
+
#   + + + def + WhenBound(self, d: pywrapcp.Demon) -> 'void': +
+ +
+ View Source +
    def WhenBound(self, d: "Demon") -> "void":
+        return _pywrapcp.BooleanVar_WhenBound(self, d)
+
+ +
+ +

Overload 1: +This method attaches a demon that will be awakened when the variable is bound.

+ +

|

+ +

Overload 2: +This method attaches a closure that will be awakened when the variable is bound.

+
+ + +
+
+
#   + + + def + WhenRange(self, d: pywrapcp.Demon) -> 'void': +
+ +
+ View Source +
    def WhenRange(self, d: "Demon") -> "void":
+        return _pywrapcp.BooleanVar_WhenRange(self, d)
+
+ +
+ +

Overload 1: +Attach a demon that will watch the min or the max of the expression.

+ +

|

+ +

Overload 2: +Attach a demon that will watch the min or the max of the expression.

+
+ + +
+
+
#   + + + def + WhenDomain(self, d: pywrapcp.Demon) -> 'void': +
+ +
+ View Source +
    def WhenDomain(self, d: "Demon") -> "void":
+        return _pywrapcp.BooleanVar_WhenDomain(self, d)
+
+ +
+ +

Overload 1: +This method attaches a demon that will watch any domain modification of the domain of the variable.

+ +

|

+ +

Overload 2: +This method attaches a closure that will watch any domain modification of the domain of the variable.

+
+ + +
+
+
#   + + + def + Size(self) -> 'uint64_t': +
+ +
+ View Source +
    def Size(self) -> "uint64_t":
+        return _pywrapcp.BooleanVar_Size(self)
+
+ +
+ +

This method returns the number of values in the domain of the variable.

+
+ + +
+
+
#   + + + def + Contains(self, v: 'int64_t') -> bool: +
+ +
+ View Source +
    def Contains(self, v: "int64_t") -> "bool":
+        return _pywrapcp.BooleanVar_Contains(self, v)
+
+ +
+ +

This method returns whether the value 'v' is in the domain of the variable.

+
+ + +
+
+
#   + + + def + HoleIteratorAux(self, reversible: bool) -> 'operations_research::IntVarIterator *': +
+ +
+ View Source +
    def HoleIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *":
+        return _pywrapcp.BooleanVar_HoleIteratorAux(self, reversible)
+
+ +
+ +

Creates a hole iterator. When 'reversible' is false, the returned object is created on the normal C++ heap and the solver does NOT take ownership of the object.

+
+ + +
+
+
#   + + + def + DomainIteratorAux(self, reversible: bool) -> 'operations_research::IntVarIterator *': +
+ +
+ View Source +
    def DomainIteratorAux(self, reversible: "bool") -> "operations_research::IntVarIterator *":
+        return _pywrapcp.BooleanVar_DomainIteratorAux(self, reversible)
+
+ +
+ +

Creates a domain iterator. When 'reversible' is false, the returned object is created on the normal C++ heap and the solver does NOT take ownership of the object.

+
+ + +
+
+
#   + + + def + DebugString(self) -> 'std::string': +
+ +
+ View Source +
    def DebugString(self) -> "std::string":
+        return _pywrapcp.BooleanVar_DebugString(self)
+
+ +
+ + + +
+ +
+
+
+ #   + + + class + PyDecision(Decision): +
+ +
+ View Source +
class PyDecision(Decision):
+
+  def __init__(self):
+    Decision.__init__(self)
+
+  def ApplyWrapper(self, solver):
+    try:
+       self.Apply(solver)
+    except Exception as e:
+      if 'CP Solver fail' in str(e):
+        solver.ShouldFail()
+      else:
+        raise
+
+  def RefuteWrapper(self, solver):
+    try:
+       self.Refute(solver)
+    except Exception as e:
+      if 'CP Solver fail' in str(e):
+        solver.ShouldFail()
+      else:
+        raise
+
+  def DebugString(self):
+    return "PyDecision"
+
+ +
+ +

A Decision represents a choice point in the search tree. The two main methods are Apply() to go left, or Refute() to go right.

+
+ + +
+
#   + + + PyDecision() +
+ +
+ View Source +
  def __init__(self):
+    Decision.__init__(self)
+
+ +
+ + + +
+
+
#   + + + def + ApplyWrapper(self, solver): +
+ +
+ View Source +
  def ApplyWrapper(self, solver):
+    try:
+       self.Apply(solver)
+    except Exception as e:
+      if 'CP Solver fail' in str(e):
+        solver.ShouldFail()
+      else:
+        raise
+
+ +
+ +

Apply will be called first when the decision is executed.

+
+ + +
+
+
#   + + + def + RefuteWrapper(self, solver): +
+ +
+ View Source +
  def RefuteWrapper(self, solver):
+    try:
+       self.Refute(solver)
+    except Exception as e:
+      if 'CP Solver fail' in str(e):
+        solver.ShouldFail()
+      else:
+        raise
+
+ +
+ +

Refute will be called after a backtrack.

+
+ + +
+
+
#   + + + def + DebugString(self): +
+ +
+ View Source +
  def DebugString(self):
+    return "PyDecision"
+
+ +
+ + + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ #   + + + class + PyDecisionBuilder(DecisionBuilder): +
+ +
+ View Source +
class PyDecisionBuilder(DecisionBuilder):
+
+  def __init__(self):
+    DecisionBuilder.__init__(self)
+
+  def NextWrapper(self, solver):
+    try:
+      return self.Next(solver)
+    except Exception as e:
+      if 'CP Solver fail' in str(e):
+        return solver.FailDecision()
+      else:
+        raise
+
+  def DebugString(self):
+    return "PyDecisionBuilder"
+
+ +
+ +

A DecisionBuilder is responsible for creating the search tree. The important method is Next(), which returns the next decision to execute.

+
+ + +
+
#   + + + PyDecisionBuilder() +
+ +
+ View Source +
  def __init__(self):
+    DecisionBuilder.__init__(self)
+
+ +
+ + + +
+
+
#   + + + def + NextWrapper(self, solver): +
+ +
+ View Source +
  def NextWrapper(self, solver):
+    try:
+      return self.Next(solver)
+    except Exception as e:
+      if 'CP Solver fail' in str(e):
+        return solver.FailDecision()
+      else:
+        raise
+
+ +
+ +

This is the main method of the decision builder class. It must return a decision (an instance of the class Decision). If it returns nullptr, this means that the decision builder has finished its work.

+
+ + +
+
+
#   + + + def + DebugString(self): +
+ +
+ View Source +
  def DebugString(self):
+    return "PyDecisionBuilder"
+
+ +
+ + + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ #   + + + class + PyDemon(Demon): +
+ +
+ View Source +
class PyDemon(Demon):
+
+  def RunWrapper(self, solver):
+    try:
+      self.Run(solver)
+    except Exception as e:
+      if 'CP Solver fail' in str(e):
+        solver.ShouldFail()
+      else:
+        raise
+
+  def DebugString(self):
+    return "PyDemon"
+
+ +
+ +

A Demon is the base element of a propagation queue. It is the main object responsible for implementing the actual propagation of the constraint and pruning the inconsistent values in the domains of the variables. The main concept is that demons are listeners that are attached to the variables and listen to their modifications. There are two methods: - Run() is the actual method called when the demon is processed. - priority() returns its priority. Standard priorities are slow, normal or fast. "immediate" is reserved for variables and is treated separately.

+
+ + +
+
#   + + + def + RunWrapper(self, solver): +
+ +
+ View Source +
  def RunWrapper(self, solver):
+    try:
+      self.Run(solver)
+    except Exception as e:
+      if 'CP Solver fail' in str(e):
+        solver.ShouldFail()
+      else:
+        raise
+
+ +
+ +

This is the main callback of the demon.

+
+ + +
+
+
#   + + + def + DebugString(self): +
+ +
+ View Source +
  def DebugString(self):
+    return "PyDemon"
+
+ +
+ + + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ #   + + + class + PyConstraintDemon(PyDemon): +
+ +
+ View Source +
class PyConstraintDemon(PyDemon):
+
+  def __init__(self, ct, method, delayed, *args):
+    PyDemon.__init__(self)
+    self.__constraint = ct
+    self.__method = method
+    self.__delayed = delayed
+    self.__args = args
+
+  def Run(self, solver):
+    self.__method(self.__constraint, *self.__args)
+
+  def Priority(self):
+    return Solver.DELAYED_PRIORITY if self.__delayed else Solver.NORMAL_PRIORITY
+
+  def DebugString(self):
+    return 'PyConstraintDemon'
+
+ +
+ +

A Demon is the base element of a propagation queue. It is the main object responsible for implementing the actual propagation of the constraint and pruning the inconsistent values in the domains of the variables. The main concept is that demons are listeners that are attached to the variables and listen to their modifications. There are two methods: - Run() is the actual method called when the demon is processed. - priority() returns its priority. Standard priorities are slow, normal or fast. "immediate" is reserved for variables and is treated separately.

+
+ + +
+
#   + + + PyConstraintDemon(ct, method, delayed, *args) +
+ +
+ View Source +
  def __init__(self, ct, method, delayed, *args):
+    PyDemon.__init__(self)
+    self.__constraint = ct
+    self.__method = method
+    self.__delayed = delayed
+    self.__args = args
+
+ +
+ +

This indicates the priority of a demon. Immediate demons are treated separately and corresponds to variables.

+
+ + +
+
+
#   + + + def + Run(self, solver): +
+ +
+ View Source +
  def Run(self, solver):
+    self.__method(self.__constraint, *self.__args)
+
+ +
+ + + +
+
+
#   + + + def + Priority(self): +
+ +
+ View Source +
  def Priority(self):
+    return Solver.DELAYED_PRIORITY if self.__delayed else Solver.NORMAL_PRIORITY
+
+ +
+ +

This method returns the priority of the demon. Usually a demon is fast, slow or normal. Immediate demons are reserved for internal use to maintain variables.

+
+ + +
+
+
#   + + + def + DebugString(self): +
+ +
+ View Source +
  def DebugString(self):
+    return 'PyConstraintDemon'
+
+ +
+ + + +
+
+
Inherited Members
+
+ + +
+
+
+
+
+ #   + + + class + PyConstraint(Constraint): +
+ +
+ View Source +
class PyConstraint(Constraint):
+
+  def __init__(self, solver):
+    Constraint.__init__(self, solver)
+    self.__demons = []
+
+  def Demon(self, method, *args):
+    demon = PyConstraintDemon(self, method, False, *args)
+    self.__demons.append(demon)
+    return demon
+
+  def DelayedDemon(self, method, *args):
+    demon = PyConstraintDemon(self, method, True, *args)
+    self.__demons.append(demon)
+    return demon
+
+  def InitialPropagateDemon(self):
+    return self.solver().ConstraintInitialPropagateCallback(self)
+
+  def DelayedInitialPropagateDemon(self):
+    return self.solver().DelayedConstraintInitialPropagateCallback(self)
+
+  def InitialPropagateWrapper(self):
+    try:
+      self.InitialPropagate()
+    except Exception as e:
+      if 'CP Solver fail' in str(e):
+        self.solver().ShouldFail()
+      else:
+        raise
+
+  def DebugString(self):
+    return "PyConstraint"
+
+ +
+ +

A constraint is the main modeling object. It provides two methods: - Post() is responsible for creating the demons and attaching them to immediate demons(). - InitialPropagate() is called once just after Post and performs the initial propagation. The subsequent propagations will be performed by the demons Posted during the post() method.

+
+ + +
+
#   + + + PyConstraint(solver) +
+ +
+ View Source +
  def __init__(self, solver):
+    Constraint.__init__(self, solver)
+    self.__demons = []
+
+ +
+ + + +
+
+
#   + + + def + Demon(self, method, *args): +
+ +
+ View Source +
  def Demon(self, method, *args):
+    demon = PyConstraintDemon(self, method, False, *args)
+    self.__demons.append(demon)
+    return demon
+
+ +
+ + + +
+
+
#   + + + def + DelayedDemon(self, method, *args): +
+ +
+ View Source +
  def DelayedDemon(self, method, *args):
+    demon = PyConstraintDemon(self, method, True, *args)
+    self.__demons.append(demon)
+    return demon
+
+ +
+ + + +
+
+
#   + + + def + InitialPropagateDemon(self): +
+ +
+ View Source +
  def InitialPropagateDemon(self):
+    return self.solver().ConstraintInitialPropagateCallback(self)
+
+ +
+ + + +
+
+
#   + + + def + DelayedInitialPropagateDemon(self): +
+ +
+ View Source +
  def DelayedInitialPropagateDemon(self):
+    return self.solver().DelayedConstraintInitialPropagateCallback(self)
+
+ +
+ + + +
+
+
#   + + + def + InitialPropagateWrapper(self): +
+ +
+ View Source +
  def InitialPropagateWrapper(self):
+    try:
+      self.InitialPropagate()
+    except Exception as e:
+      if 'CP Solver fail' in str(e):
+        self.solver().ShouldFail()
+      else:
+        raise
+
+ +
+ +

This method performs the initial propagation of the constraint. It is called just after the post.

+
+ + +
+
+
#   + + + def + DebugString(self): +
+ +
+ View Source +
  def DebugString(self):
+    return "PyConstraint"
+
+ +
+ + + +
+
+
Inherited Members
+
+ + +
+
+
+
+
+ #   + + + class + RoutingIndexManager: +
+ +
+ View Source +
class RoutingIndexManager(object):
+    r""" Manager for any NodeIndex <-> variable index conversion. The routing solver uses variable indices internally and through its API. These variable indices are tricky to manage directly because one Node can correspond to a multitude of variables, depending on the number of times they appear in the model, and if they're used as start and/or end points. This class aims to simplify variable index usage, allowing users to use NodeIndex instead. Usage:   .cpp}   auto starts_ends = ...;  /// These are NodeIndex.   RoutingIndexManager manager(10, 4, starts_ends);  // 10 nodes, 4 vehicles.   RoutingModel model(manager);"""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, *args):
+        _pywrapcp.RoutingIndexManager_swiginit(self, _pywrapcp.new_RoutingIndexManager(*args))
+    __swig_destroy__ = _pywrapcp.delete_RoutingIndexManager
+
+    def GetNumberOfNodes(self) -> "int":
+        return _pywrapcp.RoutingIndexManager_GetNumberOfNodes(self)
+
+    def GetNumberOfVehicles(self) -> "int":
+        return _pywrapcp.RoutingIndexManager_GetNumberOfVehicles(self)
+
+    def GetNumberOfIndices(self) -> "int":
+        return _pywrapcp.RoutingIndexManager_GetNumberOfIndices(self)
+
+    def GetStartIndex(self, vehicle: "int") -> "int64_t":
+        return _pywrapcp.RoutingIndexManager_GetStartIndex(self, vehicle)
+
+    def GetEndIndex(self, vehicle: "int") -> "int64_t":
+        return _pywrapcp.RoutingIndexManager_GetEndIndex(self, vehicle)
+
+    def NodeToIndex(self, node: "operations_research::RoutingIndexManager::NodeIndex") -> "int64_t":
+        return _pywrapcp.RoutingIndexManager_NodeToIndex(self, node)
+
+    def IndexToNode(self, index: "int64_t") -> "operations_research::RoutingIndexManager::NodeIndex":
+        return _pywrapcp.RoutingIndexManager_IndexToNode(self, index)
+
+ +
+ +

Manager for any NodeIndex <-> variable index conversion. The routing solver uses variable indices internally and through its API. These variable indices are tricky to manage directly because one Node can correspond to a multitude of variables, depending on the number of times they appear in the model, and if they're used as start and/or end points. This class aims to simplify variable index usage, allowing users to use NodeIndex instead. Usage: .cpp} auto starts_ends = ...; /// These are NodeIndex. RoutingIndexManager manager(10, 4, starts_ends); // 10 nodes, 4 vehicles. RoutingModel model(manager);

+
+ + +
+
#   + + + RoutingIndexManager(*args) +
+ +
+ View Source +
    def __init__(self, *args):
+        _pywrapcp.RoutingIndexManager_swiginit(self, _pywrapcp.new_RoutingIndexManager(*args))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + GetNumberOfNodes(self) -> int: +
+ +
+ View Source +
    def GetNumberOfNodes(self) -> "int":
+        return _pywrapcp.RoutingIndexManager_GetNumberOfNodes(self)
+
+ +
+ + + +
+
+
#   + + + def + GetNumberOfVehicles(self) -> int: +
+ +
+ View Source +
    def GetNumberOfVehicles(self) -> "int":
+        return _pywrapcp.RoutingIndexManager_GetNumberOfVehicles(self)
+
+ +
+ + + +
+
+
#   + + + def + GetNumberOfIndices(self) -> int: +
+ +
+ View Source +
    def GetNumberOfIndices(self) -> "int":
+        return _pywrapcp.RoutingIndexManager_GetNumberOfIndices(self)
+
+ +
+ + + +
+
+
#   + + + def + GetStartIndex(self, vehicle: int) -> 'int64_t': +
+ +
+ View Source +
    def GetStartIndex(self, vehicle: "int") -> "int64_t":
+        return _pywrapcp.RoutingIndexManager_GetStartIndex(self, vehicle)
+
+ +
+ + + +
+
+
#   + + + def + GetEndIndex(self, vehicle: int) -> 'int64_t': +
+ +
+ View Source +
    def GetEndIndex(self, vehicle: "int") -> "int64_t":
+        return _pywrapcp.RoutingIndexManager_GetEndIndex(self, vehicle)
+
+ +
+ + + +
+
+
#   + + + def + NodeToIndex( + self, + node: 'operations_research::RoutingIndexManager::NodeIndex' +) -> 'int64_t': +
+ +
+ View Source +
    def NodeToIndex(self, node: "operations_research::RoutingIndexManager::NodeIndex") -> "int64_t":
+        return _pywrapcp.RoutingIndexManager_NodeToIndex(self, node)
+
+ +
+ + + +
+
+
#   + + + def + IndexToNode( + self, + index: 'int64_t' +) -> 'operations_research::RoutingIndexManager::NodeIndex': +
+ +
+ View Source +
    def IndexToNode(self, index: "int64_t") -> "operations_research::RoutingIndexManager::NodeIndex":
+        return _pywrapcp.RoutingIndexManager_IndexToNode(self, index)
+
+ +
+ + + +
+
+
+
#   + + + def + DefaultRoutingModelParameters() -> 'operations_research::RoutingModelParameters': +
+ +
+ View Source +
def DefaultRoutingModelParameters() -> "operations_research::RoutingModelParameters":
+    return _pywrapcp.DefaultRoutingModelParameters()
+
+ +
+ + + +
+
+
#   + + + def + DefaultRoutingSearchParameters() -> 'operations_research::RoutingSearchParameters': +
+ +
+ View Source +
def DefaultRoutingSearchParameters() -> "operations_research::RoutingSearchParameters":
+    return _pywrapcp.DefaultRoutingSearchParameters()
+
+ +
+ + + +
+
+
#   + + + def + FindErrorInRoutingSearchParameters( + search_parameters: 'operations_research::RoutingSearchParameters const &' +) -> 'std::string': +
+ +
+ View Source +
def FindErrorInRoutingSearchParameters(search_parameters: "operations_research::RoutingSearchParameters const &") -> "std::string":
+    r""" Returns an empty std::string if the routing search parameters are valid, and a non-empty, human readable error description if they're not."""
+    return _pywrapcp.FindErrorInRoutingSearchParameters(search_parameters)
+
+ +
+ +

Returns an empty std::string if the routing search parameters are valid, and a non-empty, human readable error description if they're not.

+
+ + +
+
+
+ #   + + + class + RoutingModel: +
+ +
+ View Source +
class RoutingModel(object):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+    ROUTING_NOT_SOLVED = _pywrapcp.RoutingModel_ROUTING_NOT_SOLVED
+    r""" Problem not solved yet (before calling RoutingModel::Solve())."""
+    ROUTING_SUCCESS = _pywrapcp.RoutingModel_ROUTING_SUCCESS
+    r""" Problem solved successfully after calling RoutingModel::Solve()."""
+    ROUTING_FAIL = _pywrapcp.RoutingModel_ROUTING_FAIL
+    r""" No solution found to the problem after calling RoutingModel::Solve()."""
+    ROUTING_FAIL_TIMEOUT = _pywrapcp.RoutingModel_ROUTING_FAIL_TIMEOUT
+    r""" Time limit reached before finding a solution with RoutingModel::Solve()."""
+    ROUTING_INVALID = _pywrapcp.RoutingModel_ROUTING_INVALID
+    r""" Model, model parameters or flags are not valid."""
+    PICKUP_AND_DELIVERY_NO_ORDER = _pywrapcp.RoutingModel_PICKUP_AND_DELIVERY_NO_ORDER
+    r""" Any precedence is accepted."""
+    PICKUP_AND_DELIVERY_LIFO = _pywrapcp.RoutingModel_PICKUP_AND_DELIVERY_LIFO
+    r""" Deliveries must be performed in reverse order of pickups."""
+    PICKUP_AND_DELIVERY_FIFO = _pywrapcp.RoutingModel_PICKUP_AND_DELIVERY_FIFO
+    r""" Deliveries must be performed in the same order as pickups."""
+
+    def __init__(self, *args):
+        _pywrapcp.RoutingModel_swiginit(self, _pywrapcp.new_RoutingModel(*args))
+    __swig_destroy__ = _pywrapcp.delete_RoutingModel
+
+    def RegisterUnaryTransitVector(self, values: "std::vector< int64_t >") -> "int":
+        r""" Registers 'callback' and returns its index."""
+        return _pywrapcp.RoutingModel_RegisterUnaryTransitVector(self, values)
+
+    def RegisterUnaryTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback1") -> "int":
+        return _pywrapcp.RoutingModel_RegisterUnaryTransitCallback(self, callback)
+
+    def RegisterPositiveUnaryTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback1") -> "int":
+        return _pywrapcp.RoutingModel_RegisterPositiveUnaryTransitCallback(self, callback)
+
+    def RegisterTransitMatrix(self, values: "std::vector< std::vector< int64_t > >") -> "int":
+        return _pywrapcp.RoutingModel_RegisterTransitMatrix(self, values)
+
+    def RegisterTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback2") -> "int":
+        return _pywrapcp.RoutingModel_RegisterTransitCallback(self, callback)
+
+    def RegisterPositiveTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback2") -> "int":
+        return _pywrapcp.RoutingModel_RegisterPositiveTransitCallback(self, callback)
+
+    def TransitCallback(self, callback_index: "int") -> "operations_research::RoutingModel::TransitCallback2 const &":
+        return _pywrapcp.RoutingModel_TransitCallback(self, callback_index)
+
+    def UnaryTransitCallbackOrNull(self, callback_index: "int") -> "operations_research::RoutingModel::TransitCallback1 const &":
+        return _pywrapcp.RoutingModel_UnaryTransitCallbackOrNull(self, callback_index)
+
+    def AddDimension(self, evaluator_index: "int", slack_max: "int64_t", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
+        r""" Model creation Methods to add dimensions to routes; dimensions represent quantities accumulated at nodes along the routes. They represent quantities such as weights or volumes carried along the route, or distance or times. Quantities at a node are represented by "cumul" variables and the increase or decrease of quantities between nodes are represented by "transit" variables. These variables are linked as follows: if j == next(i), cumul(j) = cumul(i) + transit(i) + slack(i) where slack is a positive slack variable (can represent waiting times for a time dimension). Setting the value of fix_start_cumul_to_zero to true will force the "cumul" variable of the start node of all vehicles to be equal to 0. Creates a dimension where the transit variable is constrained to be equal to evaluator(i, next(i)); 'slack_max' is the upper bound of the slack variable and 'capacity' is the upper bound of the cumul variables. 'name' is the name used to reference the dimension; this name is used to get cumul and transit variables from the routing model. Returns false if a dimension with the same name has already been created (and doesn't create the new dimension). Takes ownership of the callback 'evaluator'."""
+        return _pywrapcp.RoutingModel_AddDimension(self, evaluator_index, slack_max, capacity, fix_start_cumul_to_zero, name)
+
+    def AddDimensionWithVehicleTransits(self, evaluator_indices: "std::vector< int > const &", slack_max: "int64_t", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
+        return _pywrapcp.RoutingModel_AddDimensionWithVehicleTransits(self, evaluator_indices, slack_max, capacity, fix_start_cumul_to_zero, name)
+
+    def AddDimensionWithVehicleCapacity(self, evaluator_index: "int", slack_max: "int64_t", vehicle_capacities: "std::vector< int64_t >", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
+        return _pywrapcp.RoutingModel_AddDimensionWithVehicleCapacity(self, evaluator_index, slack_max, vehicle_capacities, fix_start_cumul_to_zero, name)
+
+    def AddDimensionWithVehicleTransitAndCapacity(self, evaluator_indices: "std::vector< int > const &", slack_max: "int64_t", vehicle_capacities: "std::vector< int64_t >", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
+        return _pywrapcp.RoutingModel_AddDimensionWithVehicleTransitAndCapacity(self, evaluator_indices, slack_max, vehicle_capacities, fix_start_cumul_to_zero, name)
+
+    def AddConstantDimensionWithSlack(self, value: "int64_t", capacity: "int64_t", slack_max: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
+        r""" Creates a dimension where the transit variable is constrained to be equal to 'value'; 'capacity' is the upper bound of the cumul variables. 'name' is the name used to reference the dimension; this name is used to get cumul and transit variables from the routing model. Returns a pair consisting of an index to the registered unary transit callback and a bool denoting whether the dimension has been created. It is false if a dimension with the same name has already been created (and doesn't create the new dimension but still register a new callback)."""
+        return _pywrapcp.RoutingModel_AddConstantDimensionWithSlack(self, value, capacity, slack_max, fix_start_cumul_to_zero, name)
+
+    def AddConstantDimension(self, value: "int64_t", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
+        return _pywrapcp.RoutingModel_AddConstantDimension(self, value, capacity, fix_start_cumul_to_zero, name)
+
+    def AddVectorDimension(self, values: "std::vector< int64_t >", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
+        r""" Creates a dimension where the transit variable is constrained to be equal to 'values[i]' for node i; 'capacity' is the upper bound of the cumul variables. 'name' is the name used to reference the dimension; this name is used to get cumul and transit variables from the routing model. Returns a pair consisting of an index to the registered unary transit callback and a bool denoting whether the dimension has been created. It is false if a dimension with the same name has already been created (and doesn't create the new dimension but still register a new callback)."""
+        return _pywrapcp.RoutingModel_AddVectorDimension(self, values, capacity, fix_start_cumul_to_zero, name)
+
+    def AddMatrixDimension(self, values: "std::vector< std::vector< int64_t > >", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
+        r""" Creates a dimension where the transit variable is constrained to be equal to 'values[i][next(i)]' for node i; 'capacity' is the upper bound of the cumul variables. 'name' is the name used to reference the dimension; this name is used to get cumul and transit variables from the routing model. Returns a pair consisting of an index to the registered transit callback and a bool denoting whether the dimension has been created. It is false if a dimension with the same name has already been created (and doesn't create the new dimension but still register a new callback)."""
+        return _pywrapcp.RoutingModel_AddMatrixDimension(self, values, capacity, fix_start_cumul_to_zero, name)
+
+    def MakePathSpansAndTotalSlacks(self, dimension: "RoutingDimension", spans: "std::vector< operations_research::IntVar * >", total_slacks: "std::vector< operations_research::IntVar * >") -> "operations_research::Constraint *":
+        r""" For every vehicle of the routing model: - if total_slacks[vehicle] is not nullptr, constrains it to be the sum of   slacks on that vehicle, that is,   dimension->CumulVar(end) - dimension->CumulVar(start) -   sum_{node in path of vehicle} dimension->FixedTransitVar(node). - if spans[vehicle] is not nullptr, constrains it to be   dimension->CumulVar(end) - dimension->CumulVar(start) This does stronger propagation than a decomposition, and takes breaks into account."""
+        return _pywrapcp.RoutingModel_MakePathSpansAndTotalSlacks(self, dimension, spans, total_slacks)
+
+    def GetAllDimensionNames(self) -> "std::vector< std::string >":
+        r""" Outputs the names of all dimensions added to the routing engine."""
+        return _pywrapcp.RoutingModel_GetAllDimensionNames(self)
+
+    def GetDimensions(self) -> "std::vector< operations_research::RoutingDimension * > const &":
+        r""" Returns all dimensions of the model."""
+        return _pywrapcp.RoutingModel_GetDimensions(self)
+
+    def GetDimensionsWithSoftOrSpanCosts(self) -> "std::vector< operations_research::RoutingDimension * >":
+        r""" Returns dimensions with soft or vehicle span costs."""
+        return _pywrapcp.RoutingModel_GetDimensionsWithSoftOrSpanCosts(self)
+
+    def GetGlobalDimensionCumulOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::GlobalDimensionCumulOptimizer > > const &":
+        r""" Returns [global|local]_dimension_optimizers_, which are empty if the model has not been closed."""
+        return _pywrapcp.RoutingModel_GetGlobalDimensionCumulOptimizers(self)
+
+    def GetGlobalDimensionCumulMPOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::GlobalDimensionCumulOptimizer > > const &":
+        return _pywrapcp.RoutingModel_GetGlobalDimensionCumulMPOptimizers(self)
+
+    def GetLocalDimensionCumulOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::LocalDimensionCumulOptimizer > > const &":
+        return _pywrapcp.RoutingModel_GetLocalDimensionCumulOptimizers(self)
+
+    def GetLocalDimensionCumulMPOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::LocalDimensionCumulOptimizer > > const &":
+        return _pywrapcp.RoutingModel_GetLocalDimensionCumulMPOptimizers(self)
+
+    def GetMutableGlobalCumulOptimizer(self, dimension: "RoutingDimension") -> "operations_research::GlobalDimensionCumulOptimizer *":
+        r""" Returns the global/local dimension cumul optimizer for a given dimension, or nullptr if there is none."""
+        return _pywrapcp.RoutingModel_GetMutableGlobalCumulOptimizer(self, dimension)
+
+    def GetMutableGlobalCumulMPOptimizer(self, dimension: "RoutingDimension") -> "operations_research::GlobalDimensionCumulOptimizer *":
+        return _pywrapcp.RoutingModel_GetMutableGlobalCumulMPOptimizer(self, dimension)
+
+    def GetMutableLocalCumulOptimizer(self, dimension: "RoutingDimension") -> "operations_research::LocalDimensionCumulOptimizer *":
+        return _pywrapcp.RoutingModel_GetMutableLocalCumulOptimizer(self, dimension)
+
+    def GetMutableLocalCumulMPOptimizer(self, dimension: "RoutingDimension") -> "operations_research::LocalDimensionCumulOptimizer *":
+        return _pywrapcp.RoutingModel_GetMutableLocalCumulMPOptimizer(self, dimension)
+
+    def HasDimension(self, dimension_name: "std::string const &") -> "bool":
+        r""" Returns true if a dimension exists for a given dimension name."""
+        return _pywrapcp.RoutingModel_HasDimension(self, dimension_name)
+
+    def GetDimensionOrDie(self, dimension_name: "std::string const &") -> "operations_research::RoutingDimension const &":
+        r""" Returns a dimension from its name. Dies if the dimension does not exist."""
+        return _pywrapcp.RoutingModel_GetDimensionOrDie(self, dimension_name)
+
+    def GetMutableDimension(self, dimension_name: "std::string const &") -> "operations_research::RoutingDimension *":
+        r""" Returns a dimension from its name. Returns nullptr if the dimension does not exist."""
+        return _pywrapcp.RoutingModel_GetMutableDimension(self, dimension_name)
+
+    def SetPrimaryConstrainedDimension(self, dimension_name: "std::string const &") -> "void":
+        r""" Set the given dimension as "primary constrained". As of August 2013, this is only used by ArcIsMoreConstrainedThanArc(). "dimension" must be the name of an existing dimension, or be empty, in which case there will not be a primary dimension after this call."""
+        return _pywrapcp.RoutingModel_SetPrimaryConstrainedDimension(self, dimension_name)
+
+    def GetPrimaryConstrainedDimension(self) -> "std::string const &":
+        r""" Get the primary constrained dimension, or an empty string if it is unset."""
+        return _pywrapcp.RoutingModel_GetPrimaryConstrainedDimension(self)
+
+    def GetDimensionResourceGroupIndices(self, dimension: "RoutingDimension") -> "std::vector< int > const &":
+        r""" Returns the indices of resource groups for this dimension. This method can only be called after the model has been closed."""
+        return _pywrapcp.RoutingModel_GetDimensionResourceGroupIndices(self, dimension)
+
+    def AddDisjunction(self, *args) -> "operations_research::RoutingModel::DisjunctionIndex":
+        r""" Adds a disjunction constraint on the indices: exactly 'max_cardinality' of the indices are active. Start and end indices of any vehicle cannot be part of a disjunction. If a penalty is given, at most 'max_cardinality' of the indices can be active, and if less are active, 'penalty' is payed per inactive index. This is equivalent to adding the constraint:     p + Sum(i)active[i] == max_cardinality where p is an integer variable, and the following cost to the cost function:     p * penalty. 'penalty' must be positive to make the disjunction optional; a negative penalty will force 'max_cardinality' indices of the disjunction to be performed, and therefore p == 0. Note: passing a vector with a single index will model an optional index with a penalty cost if it is not visited."""
+        return _pywrapcp.RoutingModel_AddDisjunction(self, *args)
+
+    def GetDisjunctionIndices(self, index: "int64_t") -> "std::vector< operations_research::RoutingModel::DisjunctionIndex > const &":
+        r""" Returns the indices of the disjunctions to which an index belongs."""
+        return _pywrapcp.RoutingModel_GetDisjunctionIndices(self, index)
+
+    def GetDisjunctionPenalty(self, index: "operations_research::RoutingModel::DisjunctionIndex") -> "int64_t":
+        r""" Returns the penalty of the node disjunction of index 'index'."""
+        return _pywrapcp.RoutingModel_GetDisjunctionPenalty(self, index)
+
+    def GetDisjunctionMaxCardinality(self, index: "operations_research::RoutingModel::DisjunctionIndex") -> "int64_t":
+        r""" Returns the maximum number of possible active nodes of the node disjunction of index 'index'."""
+        return _pywrapcp.RoutingModel_GetDisjunctionMaxCardinality(self, index)
+
+    def GetNumberOfDisjunctions(self) -> "int":
+        r""" Returns the number of node disjunctions in the model."""
+        return _pywrapcp.RoutingModel_GetNumberOfDisjunctions(self)
+
+    def GetPerfectBinaryDisjunctions(self) -> "std::vector< std::pair< int64_t,int64_t > >":
+        r""" Returns the list of all perfect binary disjunctions, as pairs of variable indices: a disjunction is "perfect" when its variables do not appear in any other disjunction. Each pair is sorted (lowest variable index first), and the output vector is also sorted (lowest pairs first)."""
+        return _pywrapcp.RoutingModel_GetPerfectBinaryDisjunctions(self)
+
+    def IgnoreDisjunctionsAlreadyForcedToZero(self) -> "void":
+        r""" SPECIAL: Makes the solver ignore all the disjunctions whose active variables are all trivially zero (i.e. Max() == 0), by setting their max_cardinality to 0. This can be useful when using the BaseBinaryDisjunctionNeighborhood operators, in the context of arc-based routing."""
+        return _pywrapcp.RoutingModel_IgnoreDisjunctionsAlreadyForcedToZero(self)
+
+    def AddSoftSameVehicleConstraint(self, indices: "std::vector< int64_t > const &", cost: "int64_t") -> "void":
+        r""" Adds a soft constraint to force a set of variable indices to be on the same vehicle. If all nodes are not on the same vehicle, each extra vehicle used adds 'cost' to the cost function."""
+        return _pywrapcp.RoutingModel_AddSoftSameVehicleConstraint(self, indices, cost)
+
+    def SetAllowedVehiclesForIndex(self, vehicles: "std::vector< int > const &", index: "int64_t") -> "void":
+        r""" Sets the vehicles which can visit a given node. If the node is in a disjunction, this will not prevent it from being unperformed. Specifying an empty vector of vehicles has no effect (all vehicles will be allowed to visit the node)."""
+        return _pywrapcp.RoutingModel_SetAllowedVehiclesForIndex(self, vehicles, index)
+
+    def IsVehicleAllowedForIndex(self, vehicle: "int", index: "int64_t") -> "bool":
+        r""" Returns true if a vehicle is allowed to visit a given node."""
+        return _pywrapcp.RoutingModel_IsVehicleAllowedForIndex(self, vehicle, index)
+
+    def AddPickupAndDelivery(self, pickup: "int64_t", delivery: "int64_t") -> "void":
+        r""" Notifies that index1 and index2 form a pair of nodes which should belong to the same route. This methods helps the search find better solutions, especially in the local search phase. It should be called each time you have an equality constraint linking the vehicle variables of two node (including for instance pickup and delivery problems):     Solver* const solver = routing.solver();     int64_t index1 = manager.NodeToIndex(node1);     int64_t index2 = manager.NodeToIndex(node2);     solver->AddConstraint(solver->MakeEquality(         routing.VehicleVar(index1),         routing.VehicleVar(index2)));     routing.AddPickupAndDelivery(index1, index2);"""
+        return _pywrapcp.RoutingModel_AddPickupAndDelivery(self, pickup, delivery)
+
+    def AddPickupAndDeliverySets(self, pickup_disjunction: "operations_research::RoutingModel::DisjunctionIndex", delivery_disjunction: "operations_research::RoutingModel::DisjunctionIndex") -> "void":
+        r""" Same as AddPickupAndDelivery but notifying that the performed node from the disjunction of index 'pickup_disjunction' is on the same route as the performed node from the disjunction of index 'delivery_disjunction'."""
+        return _pywrapcp.RoutingModel_AddPickupAndDeliverySets(self, pickup_disjunction, delivery_disjunction)
+
+    def GetPickupIndexPairs(self, node_index: "int64_t") -> "std::vector< std::pair< int,int > > const &":
+        r""" Returns pairs for which the node is a pickup; the first element of each pair is the index in the pickup and delivery pairs list in which the pickup appears, the second element is its index in the pickups list."""
+        return _pywrapcp.RoutingModel_GetPickupIndexPairs(self, node_index)
+
+    def GetDeliveryIndexPairs(self, node_index: "int64_t") -> "std::vector< std::pair< int,int > > const &":
+        r""" Same as above for deliveries."""
+        return _pywrapcp.RoutingModel_GetDeliveryIndexPairs(self, node_index)
+
+    def SetPickupAndDeliveryPolicyOfAllVehicles(self, policy: "operations_research::RoutingModel::PickupAndDeliveryPolicy") -> "void":
+        r""" Sets the Pickup and delivery policy of all vehicles. It is equivalent to calling SetPickupAndDeliveryPolicyOfVehicle on all vehicles."""
+        return _pywrapcp.RoutingModel_SetPickupAndDeliveryPolicyOfAllVehicles(self, policy)
+
+    def SetPickupAndDeliveryPolicyOfVehicle(self, policy: "operations_research::RoutingModel::PickupAndDeliveryPolicy", vehicle: "int") -> "void":
+        return _pywrapcp.RoutingModel_SetPickupAndDeliveryPolicyOfVehicle(self, policy, vehicle)
+
+    def GetPickupAndDeliveryPolicyOfVehicle(self, vehicle: "int") -> "operations_research::RoutingModel::PickupAndDeliveryPolicy":
+        return _pywrapcp.RoutingModel_GetPickupAndDeliveryPolicyOfVehicle(self, vehicle)
+
+    def GetNumOfSingletonNodes(self) -> "int":
+        r""" Returns the number of non-start/end nodes which do not appear in a pickup/delivery pair."""
+        return _pywrapcp.RoutingModel_GetNumOfSingletonNodes(self)
+    TYPE_ADDED_TO_VEHICLE = _pywrapcp.RoutingModel_TYPE_ADDED_TO_VEHICLE
+    r""" When visited, the number of types 'T' on the vehicle increases by one."""
+    ADDED_TYPE_REMOVED_FROM_VEHICLE = _pywrapcp.RoutingModel_ADDED_TYPE_REMOVED_FROM_VEHICLE
+    r""" When visited, one instance of type 'T' previously added to the route (TYPE_ADDED_TO_VEHICLE), if any, is removed from the vehicle. If the type was not previously added to the route or all added instances have already been removed, this visit has no effect on the types."""
+    TYPE_ON_VEHICLE_UP_TO_VISIT = _pywrapcp.RoutingModel_TYPE_ON_VEHICLE_UP_TO_VISIT
+    r""" With the following policy, the visit enforces that type 'T' is considered on the route from its start until this node is visited."""
+    TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED = _pywrapcp.RoutingModel_TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED
+    r""" The visit doesn't have an impact on the number of types 'T' on the route, as it's (virtually) added and removed directly. This policy can be used for visits which are part of an incompatibility or requirement set without affecting the type count on the route."""
+
+    def SetVisitType(self, index: "int64_t", type: "int", type_policy: "operations_research::RoutingModel::VisitTypePolicy") -> "void":
+        return _pywrapcp.RoutingModel_SetVisitType(self, index, type, type_policy)
+
+    def GetVisitType(self, index: "int64_t") -> "int":
+        return _pywrapcp.RoutingModel_GetVisitType(self, index)
+
+    def GetSingleNodesOfType(self, type: "int") -> "std::vector< int > const &":
+        return _pywrapcp.RoutingModel_GetSingleNodesOfType(self, type)
+
+    def GetPairIndicesOfType(self, type: "int") -> "std::vector< int > const &":
+        return _pywrapcp.RoutingModel_GetPairIndicesOfType(self, type)
+
+    def GetVisitTypePolicy(self, index: "int64_t") -> "operations_research::RoutingModel::VisitTypePolicy":
+        return _pywrapcp.RoutingModel_GetVisitTypePolicy(self, index)
+
+    def CloseVisitTypes(self) -> "void":
+        r""" This function should be called once all node visit types have been set and prior to adding any incompatibilities/requirements. "close" types."""
+        return _pywrapcp.RoutingModel_CloseVisitTypes(self)
+
+    def GetNumberOfVisitTypes(self) -> "int":
+        return _pywrapcp.RoutingModel_GetNumberOfVisitTypes(self)
+
+    def AddHardTypeIncompatibility(self, type1: "int", type2: "int") -> "void":
+        r""" Incompatibilities: Two nodes with "hard" incompatible types cannot share the same route at all, while with a "temporal" incompatibility they can't be on the same route at the same time."""
+        return _pywrapcp.RoutingModel_AddHardTypeIncompatibility(self, type1, type2)
+
+    def AddTemporalTypeIncompatibility(self, type1: "int", type2: "int") -> "void":
+        return _pywrapcp.RoutingModel_AddTemporalTypeIncompatibility(self, type1, type2)
+
+    def GetHardTypeIncompatibilitiesOfType(self, type: "int") -> "absl::flat_hash_set< int > const &":
+        r""" Returns visit types incompatible with a given type."""
+        return _pywrapcp.RoutingModel_GetHardTypeIncompatibilitiesOfType(self, type)
+
+    def GetTemporalTypeIncompatibilitiesOfType(self, type: "int") -> "absl::flat_hash_set< int > const &":
+        return _pywrapcp.RoutingModel_GetTemporalTypeIncompatibilitiesOfType(self, type)
+
+    def HasHardTypeIncompatibilities(self) -> "bool":
+        r""" Returns true iff any hard (resp. temporal) type incompatibilities have been added to the model."""
+        return _pywrapcp.RoutingModel_HasHardTypeIncompatibilities(self)
+
+    def HasTemporalTypeIncompatibilities(self) -> "bool":
+        return _pywrapcp.RoutingModel_HasTemporalTypeIncompatibilities(self)
+
+    def AddSameVehicleRequiredTypeAlternatives(self, dependent_type: "int", required_type_alternatives: "absl::flat_hash_set< int >") -> "void":
+        r""" Requirements: NOTE: As of 2019-04, cycles in the requirement graph are not supported, and lead to the dependent nodes being skipped if possible (otherwise the model is considered infeasible). The following functions specify that "dependent_type" requires at least one of the types in "required_type_alternatives". For same-vehicle requirements, a node of dependent type type_D requires at least one node of type type_R among the required alternatives on the same route."""
+        return _pywrapcp.RoutingModel_AddSameVehicleRequiredTypeAlternatives(self, dependent_type, required_type_alternatives)
+
+    def AddRequiredTypeAlternativesWhenAddingType(self, dependent_type: "int", required_type_alternatives: "absl::flat_hash_set< int >") -> "void":
+        r""" If type_D depends on type_R when adding type_D, any node_D of type_D and VisitTypePolicy TYPE_ADDED_TO_VEHICLE or TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED requires at least one type_R on its vehicle at the time node_D is visited."""
+        return _pywrapcp.RoutingModel_AddRequiredTypeAlternativesWhenAddingType(self, dependent_type, required_type_alternatives)
+
+    def AddRequiredTypeAlternativesWhenRemovingType(self, dependent_type: "int", required_type_alternatives: "absl::flat_hash_set< int >") -> "void":
+        r""" The following requirements apply when visiting dependent nodes that remove their type from the route, i.e. type_R must be on the vehicle when type_D of VisitTypePolicy ADDED_TYPE_REMOVED_FROM_VEHICLE, TYPE_ON_VEHICLE_UP_TO_VISIT or TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED is visited."""
+        return _pywrapcp.RoutingModel_AddRequiredTypeAlternativesWhenRemovingType(self, dependent_type, required_type_alternatives)
+
+    def GetSameVehicleRequiredTypeAlternativesOfType(self, type: "int") -> "std::vector< absl::flat_hash_set< int > > const &":
+        r""" Returns the set of same-vehicle requirement alternatives for the given type."""
+        return _pywrapcp.RoutingModel_GetSameVehicleRequiredTypeAlternativesOfType(self, type)
+
+    def GetRequiredTypeAlternativesWhenAddingType(self, type: "int") -> "std::vector< absl::flat_hash_set< int > > const &":
+        r""" Returns the set of requirement alternatives when adding the given type."""
+        return _pywrapcp.RoutingModel_GetRequiredTypeAlternativesWhenAddingType(self, type)
+
+    def GetRequiredTypeAlternativesWhenRemovingType(self, type: "int") -> "std::vector< absl::flat_hash_set< int > > const &":
+        r""" Returns the set of requirement alternatives when removing the given type."""
+        return _pywrapcp.RoutingModel_GetRequiredTypeAlternativesWhenRemovingType(self, type)
+
+    def HasSameVehicleTypeRequirements(self) -> "bool":
+        r""" Returns true iff any same-route (resp. temporal) type requirements have been added to the model."""
+        return _pywrapcp.RoutingModel_HasSameVehicleTypeRequirements(self)
+
+    def HasTemporalTypeRequirements(self) -> "bool":
+        return _pywrapcp.RoutingModel_HasTemporalTypeRequirements(self)
+
+    def HasTypeRegulations(self) -> "bool":
+        r""" Returns true iff the model has any incompatibilities or requirements set on node types."""
+        return _pywrapcp.RoutingModel_HasTypeRegulations(self)
+
+    def UnperformedPenalty(self, var_index: "int64_t") -> "int64_t":
+        r""" Get the "unperformed" penalty of a node. This is only well defined if the node is only part of a single Disjunction, and that disjunction has a penalty. For forced active nodes returns max int64_t. In all other cases, this returns 0."""
+        return _pywrapcp.RoutingModel_UnperformedPenalty(self, var_index)
+
+    def UnperformedPenaltyOrValue(self, default_value: "int64_t", var_index: "int64_t") -> "int64_t":
+        r""" Same as above except that it returns default_value instead of 0 when penalty is not well defined (default value is passed as first argument to simplify the usage of the method in a callback)."""
+        return _pywrapcp.RoutingModel_UnperformedPenaltyOrValue(self, default_value, var_index)
+
+    def GetDepot(self) -> "int64_t":
+        r""" Returns the variable index of the first starting or ending node of all routes. If all routes start  and end at the same node (single depot), this is the node returned."""
+        return _pywrapcp.RoutingModel_GetDepot(self)
+
+    def SetMaximumNumberOfActiveVehicles(self, max_active_vehicles: "int") -> "void":
+        r""" Constrains the maximum number of active vehicles, aka the number of vehicles which do not have an empty route. For instance, this can be used to limit the number of routes in the case where there are fewer drivers than vehicles and that the fleet of vehicle is heterogeneous."""
+        return _pywrapcp.RoutingModel_SetMaximumNumberOfActiveVehicles(self, max_active_vehicles)
+
+    def GetMaximumNumberOfActiveVehicles(self) -> "int":
+        r""" Returns the maximum number of active vehicles."""
+        return _pywrapcp.RoutingModel_GetMaximumNumberOfActiveVehicles(self)
+
+    def SetArcCostEvaluatorOfAllVehicles(self, evaluator_index: "int") -> "void":
+        r""" Sets the cost function of the model such that the cost of a segment of a route between node 'from' and 'to' is evaluator(from, to), whatever the route or vehicle performing the route."""
+        return _pywrapcp.RoutingModel_SetArcCostEvaluatorOfAllVehicles(self, evaluator_index)
+
+    def SetArcCostEvaluatorOfVehicle(self, evaluator_index: "int", vehicle: "int") -> "void":
+        r""" Sets the cost function for a given vehicle route."""
+        return _pywrapcp.RoutingModel_SetArcCostEvaluatorOfVehicle(self, evaluator_index, vehicle)
+
+    def SetFixedCostOfAllVehicles(self, cost: "int64_t") -> "void":
+        r""" Sets the fixed cost of all vehicle routes. It is equivalent to calling SetFixedCostOfVehicle on all vehicle routes."""
+        return _pywrapcp.RoutingModel_SetFixedCostOfAllVehicles(self, cost)
+
+    def SetFixedCostOfVehicle(self, cost: "int64_t", vehicle: "int") -> "void":
+        r""" Sets the fixed cost of one vehicle route."""
+        return _pywrapcp.RoutingModel_SetFixedCostOfVehicle(self, cost, vehicle)
+
+    def GetFixedCostOfVehicle(self, vehicle: "int") -> "int64_t":
+        r""" Returns the route fixed cost taken into account if the route of the vehicle is not empty, aka there's at least one node on the route other than the first and last nodes."""
+        return _pywrapcp.RoutingModel_GetFixedCostOfVehicle(self, vehicle)
+
+    def SetAmortizedCostFactorsOfAllVehicles(self, linear_cost_factor: "int64_t", quadratic_cost_factor: "int64_t") -> "void":
+        r""" The following methods set the linear and quadratic cost factors of vehicles (must be positive values). The default value of these parameters is zero for all vehicles. When set, the cost_ of the model will contain terms aiming at reducing the number of vehicles used in the model, by adding the following to the objective for every vehicle v: INDICATOR(v used in the model) *   [linear_cost_factor_of_vehicle_[v]    - quadratic_cost_factor_of_vehicle_[v]*(square of length of route v)] i.e. for every used vehicle, we add the linear factor as fixed cost, and subtract the square of the route length multiplied by the quadratic factor. This second term aims at making the routes as dense as possible. Sets the linear and quadratic cost factor of all vehicles."""
+        return _pywrapcp.RoutingModel_SetAmortizedCostFactorsOfAllVehicles(self, linear_cost_factor, quadratic_cost_factor)
+
+    def SetAmortizedCostFactorsOfVehicle(self, linear_cost_factor: "int64_t", quadratic_cost_factor: "int64_t", vehicle: "int") -> "void":
+        r""" Sets the linear and quadratic cost factor of the given vehicle."""
+        return _pywrapcp.RoutingModel_SetAmortizedCostFactorsOfVehicle(self, linear_cost_factor, quadratic_cost_factor, vehicle)
+
+    def GetAmortizedLinearCostFactorOfVehicles(self) -> "std::vector< int64_t > const &":
+        return _pywrapcp.RoutingModel_GetAmortizedLinearCostFactorOfVehicles(self)
+
+    def GetAmortizedQuadraticCostFactorOfVehicles(self) -> "std::vector< int64_t > const &":
+        return _pywrapcp.RoutingModel_GetAmortizedQuadraticCostFactorOfVehicles(self)
+
+    def ConsiderEmptyRouteCostsForVehicle(self, consider_costs: "bool", vehicle: "int") -> "void":
+        return _pywrapcp.RoutingModel_ConsiderEmptyRouteCostsForVehicle(self, consider_costs, vehicle)
+
+    def AreEmptyRouteCostsConsideredForVehicle(self, vehicle: "int") -> "bool":
+        return _pywrapcp.RoutingModel_AreEmptyRouteCostsConsideredForVehicle(self, vehicle)
+
+    def SetFirstSolutionEvaluator(self, evaluator: "operations_research::Solver::IndexEvaluator2") -> "void":
+        r""" Gets/sets the evaluator used during the search. Only relevant when RoutingSearchParameters.first_solution_strategy = EVALUATOR_STRATEGY. Takes ownership of evaluator."""
+        return _pywrapcp.RoutingModel_SetFirstSolutionEvaluator(self, evaluator)
+
+    def AddLocalSearchOperator(self, ls_operator: "LocalSearchOperator") -> "void":
+        r""" Adds a local search operator to the set of operators used to solve the vehicle routing problem."""
+        return _pywrapcp.RoutingModel_AddLocalSearchOperator(self, ls_operator)
+
+    def AddSearchMonitor(self, monitor: "SearchMonitor") -> "void":
+        r""" Adds a search monitor to the search used to solve the routing model."""
+        return _pywrapcp.RoutingModel_AddSearchMonitor(self, monitor)
+
+    def AddAtSolutionCallback(self, callback: "std::function< void () >") -> "void":
+        r""" Adds a callback called each time a solution is found during the search. This is a shortcut to creating a monitor to call the callback on AtSolution() and adding it with AddSearchMonitor."""
+        return _pywrapcp.RoutingModel_AddAtSolutionCallback(self, callback)
+
+    def AddVariableMinimizedByFinalizer(self, var: "IntVar") -> "void":
+        r""" Adds a variable to minimize in the solution finalizer. The solution finalizer is called each time a solution is found during the search and allows to instantiate secondary variables (such as dimension cumul variables)."""
+        return _pywrapcp.RoutingModel_AddVariableMinimizedByFinalizer(self, var)
+
+    def AddVariableMaximizedByFinalizer(self, var: "IntVar") -> "void":
+        r""" Adds a variable to maximize in the solution finalizer (see above for information on the solution finalizer)."""
+        return _pywrapcp.RoutingModel_AddVariableMaximizedByFinalizer(self, var)
+
+    def AddWeightedVariableMinimizedByFinalizer(self, var: "IntVar", cost: "int64_t") -> "void":
+        r""" Adds a variable to minimize in the solution finalizer, with a weighted priority: the higher the more priority it has."""
+        return _pywrapcp.RoutingModel_AddWeightedVariableMinimizedByFinalizer(self, var, cost)
+
+    def AddVariableTargetToFinalizer(self, var: "IntVar", target: "int64_t") -> "void":
+        r""" Add a variable to set the closest possible to the target value in the solution finalizer."""
+        return _pywrapcp.RoutingModel_AddVariableTargetToFinalizer(self, var, target)
+
+    def CloseModel(self) -> "void":
+        r""" Closes the current routing model; after this method is called, no modification to the model can be done, but RoutesToAssignment becomes available. Note that CloseModel() is automatically called by Solve() and other methods that produce solution. This is equivalent to calling CloseModelWithParameters(DefaultRoutingSearchParameters())."""
+        return _pywrapcp.RoutingModel_CloseModel(self)
+
+    def CloseModelWithParameters(self, search_parameters: "operations_research::RoutingSearchParameters const &") -> "void":
+        r""" Same as above taking search parameters (as of 10/2015 some the parameters have to be set when closing the model)."""
+        return _pywrapcp.RoutingModel_CloseModelWithParameters(self, search_parameters)
+
+    def Solve(self, assignment: "Assignment"=None) -> "operations_research::Assignment const *":
+        r""" Solves the current routing model; closes the current model. This is equivalent to calling SolveWithParameters(DefaultRoutingSearchParameters()) or SolveFromAssignmentWithParameters(assignment,                                   DefaultRoutingSearchParameters())."""
+        return _pywrapcp.RoutingModel_Solve(self, assignment)
+
+    def SolveWithParameters(self, search_parameters: "operations_research::RoutingSearchParameters const &", solutions: "std::vector< operations_research::Assignment const * > *"=None) -> "operations_research::Assignment const *":
+        r""" Solves the current routing model with the given parameters. If 'solutions' is specified, it will contain the k best solutions found during the search (from worst to best, including the one returned by this method), where k corresponds to the 'number_of_solutions_to_collect' in 'search_parameters'. Note that the Assignment returned by the method and the ones in solutions are owned by the underlying solver and should not be deleted."""
+        return _pywrapcp.RoutingModel_SolveWithParameters(self, search_parameters, solutions)
+
+    def SolveFromAssignmentWithParameters(self, assignment: "Assignment", search_parameters: "operations_research::RoutingSearchParameters const &", solutions: "std::vector< operations_research::Assignment const * > *"=None) -> "operations_research::Assignment const *":
+        r""" Same as above, except that if assignment is not null, it will be used as the initial solution."""
+        return _pywrapcp.RoutingModel_SolveFromAssignmentWithParameters(self, assignment, search_parameters, solutions)
+
+    def SolveFromAssignmentsWithParameters(self, assignments: "std::vector< operations_research::Assignment const * > const &", search_parameters: "operations_research::RoutingSearchParameters const &", solutions: "std::vector< operations_research::Assignment const * > *"=None) -> "operations_research::Assignment const *":
+        r""" Same as above but will try all assignments in order as first solutions until one succeeds."""
+        return _pywrapcp.RoutingModel_SolveFromAssignmentsWithParameters(self, assignments, search_parameters, solutions)
+
+    def SetAssignmentFromOtherModelAssignment(self, target_assignment: "Assignment", source_model: "RoutingModel", source_assignment: "Assignment") -> "void":
+        r""" Given a "source_model" and its "source_assignment", resets "target_assignment" with the IntVar variables (nexts_, and vehicle_vars_ if costs aren't homogeneous across vehicles) of "this" model, with the values set according to those in "other_assignment". The objective_element of target_assignment is set to this->cost_."""
+        return _pywrapcp.RoutingModel_SetAssignmentFromOtherModelAssignment(self, target_assignment, source_model, source_assignment)
+
+    def ComputeLowerBound(self) -> "int64_t":
+        r""" Computes a lower bound to the routing problem solving a linear assignment problem. The routing model must be closed before calling this method. Note that problems with node disjunction constraints (including optional nodes) and non-homogenous costs are not supported (the method returns 0 in these cases)."""
+        return _pywrapcp.RoutingModel_ComputeLowerBound(self)
+
+    def status(self) -> "operations_research::RoutingModel::Status":
+        r""" Returns the current status of the routing model."""
+        return _pywrapcp.RoutingModel_status(self)
+
+    def ApplyLocks(self, locks: "std::vector< int64_t > const &") -> "operations_research::IntVar *":
+        r""" Applies a lock chain to the next search. 'locks' represents an ordered vector of nodes representing a partial route which will be fixed during the next search; it will constrain next variables such that: next[locks[i]] == locks[i+1]. Returns the next variable at the end of the locked chain; this variable is not locked. An assignment containing the locks can be obtained by calling PreAssignment()."""
+        return _pywrapcp.RoutingModel_ApplyLocks(self, locks)
+
+    def ApplyLocksToAllVehicles(self, locks: "std::vector< std::vector< int64_t > > const &", close_routes: "bool") -> "bool":
+        r""" Applies lock chains to all vehicles to the next search, such that locks[p] is the lock chain for route p. Returns false if the locks do not contain valid routes; expects that the routes do not contain the depots, i.e. there are empty vectors in place of empty routes. If close_routes is set to true, adds the end nodes to the route of each vehicle and deactivates other nodes. An assignment containing the locks can be obtained by calling PreAssignment()."""
+        return _pywrapcp.RoutingModel_ApplyLocksToAllVehicles(self, locks, close_routes)
+
+    def PreAssignment(self) -> "operations_research::Assignment const *const":
+        r""" Returns an assignment used to fix some of the variables of the problem. In practice, this assignment locks partial routes of the problem. This can be used in the context of locking the parts of the routes which have already been driven in online routing problems."""
+        return _pywrapcp.RoutingModel_PreAssignment(self)
+
+    def MutablePreAssignment(self) -> "operations_research::Assignment *":
+        return _pywrapcp.RoutingModel_MutablePreAssignment(self)
+
+    def WriteAssignment(self, file_name: "std::string const &") -> "bool":
+        r""" Writes the current solution to a file containing an AssignmentProto. Returns false if the file cannot be opened or if there is no current solution."""
+        return _pywrapcp.RoutingModel_WriteAssignment(self, file_name)
+
+    def ReadAssignment(self, file_name: "std::string const &") -> "operations_research::Assignment *":
+        r""" Reads an assignment from a file and returns the current solution. Returns nullptr if the file cannot be opened or if the assignment is not valid."""
+        return _pywrapcp.RoutingModel_ReadAssignment(self, file_name)
+
+    def RestoreAssignment(self, solution: "Assignment") -> "operations_research::Assignment *":
+        r""" Restores an assignment as a solution in the routing model and returns the new solution. Returns nullptr if the assignment is not valid."""
+        return _pywrapcp.RoutingModel_RestoreAssignment(self, solution)
+
+    def ReadAssignmentFromRoutes(self, routes: "std::vector< std::vector< int64_t > > const &", ignore_inactive_indices: "bool") -> "operations_research::Assignment *":
+        r""" Restores the routes as the current solution. Returns nullptr if the solution cannot be restored (routes do not contain a valid solution). Note that calling this method will run the solver to assign values to the dimension variables; this may take considerable amount of time, especially when using dimensions with slack."""
+        return _pywrapcp.RoutingModel_ReadAssignmentFromRoutes(self, routes, ignore_inactive_indices)
+
+    def RoutesToAssignment(self, routes: "std::vector< std::vector< int64_t > > const &", ignore_inactive_indices: "bool", close_routes: "bool", assignment: "Assignment") -> "bool":
+        r""" Fills an assignment from a specification of the routes of the vehicles. The routes are specified as lists of variable indices that appear on the routes of the vehicles. The indices of the outer vector in 'routes' correspond to vehicles IDs, the inner vector contains the variable indices on the routes for the given vehicle. The inner vectors must not contain the start and end indices, as these are determined by the routing model.  Sets the value of NextVars in the assignment, adding the variables to the assignment if necessary. The method does not touch other variables in the assignment. The method can only be called after the model is closed.  With ignore_inactive_indices set to false, this method will fail (return nullptr) in case some of the route contain indices that are deactivated in the model; when set to true, these indices will be skipped.  Returns true if routes were successfully loaded. However, such assignment still might not be a valid solution to the routing problem due to more complex constraints; it is advisible to call solver()->CheckSolution() afterwards."""
+        return _pywrapcp.RoutingModel_RoutesToAssignment(self, routes, ignore_inactive_indices, close_routes, assignment)
+
+    def AssignmentToRoutes(self, assignment: "Assignment", routes: "std::vector< std::vector< int64_t > > *const") -> "void":
+        r""" Converts the solution in the given assignment to routes for all vehicles. Expects that assignment contains a valid solution (i.e. routes for all vehicles end with an end index for that vehicle)."""
+        return _pywrapcp.RoutingModel_AssignmentToRoutes(self, assignment, routes)
+
+    def CompactAssignment(self, assignment: "Assignment") -> "operations_research::Assignment *":
+        r""" Converts the solution in the given assignment to routes for all vehicles. If the returned vector is route_indices, route_indices[i][j] is the index for jth location visited on route i. Note that contrary to AssignmentToRoutes, the vectors do include start and end locations. Returns a compacted version of the given assignment, in which all vehicles with id lower or equal to some N have non-empty routes, and all vehicles with id greater than N have empty routes. Does not take ownership of the returned object. If found, the cost of the compact assignment is the same as in the original assignment and it preserves the values of 'active' variables. Returns nullptr if a compact assignment was not found. This method only works in homogenous mode, and it only swaps equivalent vehicles (vehicles with the same start and end nodes). When creating the compact assignment, the empty plan is replaced by the route assigned to the compatible vehicle with the highest id. Note that with more complex constraints on vehicle variables, this method might fail even if a compact solution exists. This method changes the vehicle and dimension variables as necessary. While compacting the solution, only basic checks on vehicle variables are performed; if one of these checks fails no attempts to repair it are made (instead, the method returns nullptr)."""
+        return _pywrapcp.RoutingModel_CompactAssignment(self, assignment)
+
+    def CompactAndCheckAssignment(self, assignment: "Assignment") -> "operations_research::Assignment *":
+        r""" Same as CompactAssignment() but also checks the validity of the final compact solution; if it is not valid, no attempts to repair it are made (instead, the method returns nullptr)."""
+        return _pywrapcp.RoutingModel_CompactAndCheckAssignment(self, assignment)
+
+    def AddToAssignment(self, var: "IntVar") -> "void":
+        r""" Adds an extra variable to the vehicle routing assignment."""
+        return _pywrapcp.RoutingModel_AddToAssignment(self, var)
+
+    def AddIntervalToAssignment(self, interval: "IntervalVar") -> "void":
+        return _pywrapcp.RoutingModel_AddIntervalToAssignment(self, interval)
+
+    def PackCumulsOfOptimizerDimensionsFromAssignment(self, original_assignment: "Assignment", duration_limit: "absl::Duration") -> "operations_research::Assignment const *":
+        r""" For every dimension in the model with an optimizer in local/global_dimension_optimizers_, this method tries to pack the cumul values of the dimension, such that: - The cumul costs (span costs, soft lower and upper bound costs, etc) are   minimized. - The cumuls of the ends of the routes are minimized for this given   minimal cumul cost. - Given these minimal end cumuls, the route start cumuls are maximized. Returns the assignment resulting from allocating these packed cumuls with the solver, and nullptr if these cumuls could not be set by the solver."""
+        return _pywrapcp.RoutingModel_PackCumulsOfOptimizerDimensionsFromAssignment(self, original_assignment, duration_limit)
+
+    def AddLocalSearchFilter(self, filter: "LocalSearchFilter") -> "void":
+        r""" Adds a custom local search filter to the list of filters used to speed up local search by pruning unfeasible variable assignments. Calling this method after the routing model has been closed (CloseModel() or Solve() has been called) has no effect. The routing model does not take ownership of the filter."""
+        return _pywrapcp.RoutingModel_AddLocalSearchFilter(self, filter)
+
+    def Start(self, vehicle: "int") -> "int64_t":
+        r""" Model inspection. Returns the variable index of the starting node of a vehicle route."""
+        return _pywrapcp.RoutingModel_Start(self, vehicle)
+
+    def End(self, vehicle: "int") -> "int64_t":
+        r""" Returns the variable index of the ending node of a vehicle route."""
+        return _pywrapcp.RoutingModel_End(self, vehicle)
+
+    def IsStart(self, index: "int64_t") -> "bool":
+        r""" Returns true if 'index' represents the first node of a route."""
+        return _pywrapcp.RoutingModel_IsStart(self, index)
+
+    def IsEnd(self, index: "int64_t") -> "bool":
+        r""" Returns true if 'index' represents the last node of a route."""
+        return _pywrapcp.RoutingModel_IsEnd(self, index)
+
+    def VehicleIndex(self, index: "int64_t") -> "int":
+        r""" Returns the vehicle of the given start/end index, and -1 if the given index is not a vehicle start/end."""
+        return _pywrapcp.RoutingModel_VehicleIndex(self, index)
+
+    def Next(self, assignment: "Assignment", index: "int64_t") -> "int64_t":
+        r""" Assignment inspection Returns the variable index of the node directly after the node corresponding to 'index' in 'assignment'."""
+        return _pywrapcp.RoutingModel_Next(self, assignment, index)
+
+    def IsVehicleUsed(self, assignment: "Assignment", vehicle: "int") -> "bool":
+        r""" Returns true if the route of 'vehicle' is non empty in 'assignment'."""
+        return _pywrapcp.RoutingModel_IsVehicleUsed(self, assignment, vehicle)
+
+    def NextVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        r""" Returns the next variable of the node corresponding to index. Note that NextVar(index) == index is equivalent to ActiveVar(index) == 0."""
+        return _pywrapcp.RoutingModel_NextVar(self, index)
+
+    def ActiveVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        r""" Returns the active variable of the node corresponding to index."""
+        return _pywrapcp.RoutingModel_ActiveVar(self, index)
+
+    def ActiveVehicleVar(self, vehicle: "int") -> "operations_research::IntVar *":
+        r""" Returns the active variable of the vehicle. It will be equal to 1 iff the route of the vehicle is not empty, 0 otherwise."""
+        return _pywrapcp.RoutingModel_ActiveVehicleVar(self, vehicle)
+
+    def VehicleCostsConsideredVar(self, vehicle: "int") -> "operations_research::IntVar *":
+        r""" Returns the variable specifying whether or not costs are considered for vehicle."""
+        return _pywrapcp.RoutingModel_VehicleCostsConsideredVar(self, vehicle)
+
+    def VehicleVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        r""" Returns the vehicle variable of the node corresponding to index. Note that VehicleVar(index) == -1 is equivalent to ActiveVar(index) == 0."""
+        return _pywrapcp.RoutingModel_VehicleVar(self, index)
+
+    def CostVar(self) -> "operations_research::IntVar *":
+        r""" Returns the global cost variable which is being minimized."""
+        return _pywrapcp.RoutingModel_CostVar(self)
+
+    def GetArcCostForVehicle(self, from_index: "int64_t", to_index: "int64_t", vehicle: "int64_t") -> "int64_t":
+        r""" Returns the cost of the transit arc between two nodes for a given vehicle. Input are variable indices of node. This returns 0 if vehicle < 0."""
+        return _pywrapcp.RoutingModel_GetArcCostForVehicle(self, from_index, to_index, vehicle)
+
+    def CostsAreHomogeneousAcrossVehicles(self) -> "bool":
+        r""" Whether costs are homogeneous across all vehicles."""
+        return _pywrapcp.RoutingModel_CostsAreHomogeneousAcrossVehicles(self)
+
+    def GetHomogeneousCost(self, from_index: "int64_t", to_index: "int64_t") -> "int64_t":
+        r""" Returns the cost of the segment between two nodes supposing all vehicle costs are the same (returns the cost for the first vehicle otherwise)."""
+        return _pywrapcp.RoutingModel_GetHomogeneousCost(self, from_index, to_index)
+
+    def GetArcCostForFirstSolution(self, from_index: "int64_t", to_index: "int64_t") -> "int64_t":
+        r""" Returns the cost of the arc in the context of the first solution strategy. This is typically a simplification of the actual cost; see the .cc."""
+        return _pywrapcp.RoutingModel_GetArcCostForFirstSolution(self, from_index, to_index)
+
+    def GetArcCostForClass(self, from_index: "int64_t", to_index: "int64_t", cost_class_index: "int64_t") -> "int64_t":
+        r""" Returns the cost of the segment between two nodes for a given cost class. Input are variable indices of nodes and the cost class. Unlike GetArcCostForVehicle(), if cost_class is kNoCost, then the returned cost won't necessarily be zero: only some of the components of the cost that depend on the cost class will be omited. See the code for details."""
+        return _pywrapcp.RoutingModel_GetArcCostForClass(self, from_index, to_index, cost_class_index)
+
+    def GetCostClassIndexOfVehicle(self, vehicle: "int64_t") -> "operations_research::RoutingModel::CostClassIndex":
+        r""" Get the cost class index of the given vehicle."""
+        return _pywrapcp.RoutingModel_GetCostClassIndexOfVehicle(self, vehicle)
+
+    def HasVehicleWithCostClassIndex(self, cost_class_index: "operations_research::RoutingModel::CostClassIndex") -> "bool":
+        r""" Returns true iff the model contains a vehicle with the given cost_class_index."""
+        return _pywrapcp.RoutingModel_HasVehicleWithCostClassIndex(self, cost_class_index)
+
+    def GetCostClassesCount(self) -> "int":
+        r""" Returns the number of different cost classes in the model."""
+        return _pywrapcp.RoutingModel_GetCostClassesCount(self)
+
+    def GetNonZeroCostClassesCount(self) -> "int":
+        r""" Ditto, minus the 'always zero', built-in cost class."""
+        return _pywrapcp.RoutingModel_GetNonZeroCostClassesCount(self)
+
+    def GetVehicleClassIndexOfVehicle(self, vehicle: "int64_t") -> "operations_research::RoutingModel::VehicleClassIndex":
+        return _pywrapcp.RoutingModel_GetVehicleClassIndexOfVehicle(self, vehicle)
+
+    def GetVehicleOfClass(self, vehicle_class: "operations_research::RoutingModel::VehicleClassIndex") -> "int":
+        r""" Returns a vehicle of the given vehicle class, and -1 if there are no vehicles for this class."""
+        return _pywrapcp.RoutingModel_GetVehicleOfClass(self, vehicle_class)
+
+    def GetVehicleClassesCount(self) -> "int":
+        r""" Returns the number of different vehicle classes in the model."""
+        return _pywrapcp.RoutingModel_GetVehicleClassesCount(self)
+
+    def GetSameVehicleIndicesOfIndex(self, node: "int") -> "std::vector< int > const &":
+        r""" Returns variable indices of nodes constrained to be on the same route."""
+        return _pywrapcp.RoutingModel_GetSameVehicleIndicesOfIndex(self, node)
+
+    def GetVehicleTypeContainer(self) -> "operations_research::RoutingModel::VehicleTypeContainer const &":
+        return _pywrapcp.RoutingModel_GetVehicleTypeContainer(self)
+
+    def ArcIsMoreConstrainedThanArc(self, _from: "int64_t", to1: "int64_t", to2: "int64_t") -> "bool":
+        r""" Returns whether the arc from->to1 is more constrained than from->to2, taking into account, in order: - whether the destination node isn't an end node - whether the destination node is mandatory - whether the destination node is bound to the same vehicle as the source - the "primary constrained" dimension (see SetPrimaryConstrainedDimension) It then breaks ties using, in order: - the arc cost (taking unperformed penalties into account) - the size of the vehicle vars of "to1" and "to2" (lowest size wins) - the value: the lowest value of the indices to1 and to2 wins. See the .cc for details. The more constrained arc is typically preferable when building a first solution. This method is intended to be used as a callback for the BestValueByComparisonSelector value selector. Args:   from: the variable index of the source node   to1: the variable index of the first candidate destination node.   to2: the variable index of the second candidate destination node."""
+        return _pywrapcp.RoutingModel_ArcIsMoreConstrainedThanArc(self, _from, to1, to2)
+
+    def DebugOutputAssignment(self, solution_assignment: "Assignment", dimension_to_print: "std::string const &") -> "std::string":
+        r""" Print some debugging information about an assignment, including the feasible intervals of the CumulVar for dimension "dimension_to_print" at each step of the routes. If "dimension_to_print" is omitted, all dimensions will be printed."""
+        return _pywrapcp.RoutingModel_DebugOutputAssignment(self, solution_assignment, dimension_to_print)
+
+    def solver(self) -> "operations_research::Solver *":
+        r""" Returns a vector cumul_bounds, for which cumul_bounds[i][j] is a pair containing the minimum and maximum of the CumulVar of the jth node on route i. - cumul_bounds[i][j].first is the minimum. - cumul_bounds[i][j].second is the maximum. Returns the underlying constraint solver. Can be used to add extra constraints and/or modify search algorithms."""
+        return _pywrapcp.RoutingModel_solver(self)
+
+    def CheckLimit(self) -> "bool":
+        r""" Returns true if the search limit has been crossed."""
+        return _pywrapcp.RoutingModel_CheckLimit(self)
+
+    def RemainingTime(self) -> "absl::Duration":
+        r""" Returns the time left in the search limit."""
+        return _pywrapcp.RoutingModel_RemainingTime(self)
+
+    def nodes(self) -> "int":
+        r""" Sizes and indices Returns the number of nodes in the model."""
+        return _pywrapcp.RoutingModel_nodes(self)
+
+    def vehicles(self) -> "int":
+        r""" Returns the number of vehicle routes in the model."""
+        return _pywrapcp.RoutingModel_vehicles(self)
+
+    def Size(self) -> "int64_t":
+        r""" Returns the number of next variables in the model."""
+        return _pywrapcp.RoutingModel_Size(self)
+
+    def GetNumberOfDecisionsInFirstSolution(self, search_parameters: "operations_research::RoutingSearchParameters const &") -> "int64_t":
+        r""" Returns statistics on first solution search, number of decisions sent to filters, number of decisions rejected by filters."""
+        return _pywrapcp.RoutingModel_GetNumberOfDecisionsInFirstSolution(self, search_parameters)
+
+    def GetNumberOfRejectsInFirstSolution(self, search_parameters: "operations_research::RoutingSearchParameters const &") -> "int64_t":
+        return _pywrapcp.RoutingModel_GetNumberOfRejectsInFirstSolution(self, search_parameters)
+
+    def GetAutomaticFirstSolutionStrategy(self) -> "operations_research::FirstSolutionStrategy::Value":
+        r""" Returns the automatic first solution strategy selected."""
+        return _pywrapcp.RoutingModel_GetAutomaticFirstSolutionStrategy(self)
+
+    def IsMatchingModel(self) -> "bool":
+        r""" Returns true if a vehicle/node matching problem is detected."""
+        return _pywrapcp.RoutingModel_IsMatchingModel(self)
+
+    def MakeGuidedSlackFinalizer(self, dimension: "RoutingDimension", initializer: "std::function< int64_t (int64_t) >") -> "operations_research::DecisionBuilder *":
+        r""" The next few members are in the public section only for testing purposes. MakeGuidedSlackFinalizer creates a DecisionBuilder for the slacks of a dimension using a callback to choose which values to start with. The finalizer works only when all next variables in the model have been fixed. It has the following two characteristics: 1. It follows the routes defined by the nexts variables when choosing a    variable to make a decision on. 2. When it comes to choose a value for the slack of node i, the decision    builder first calls the callback with argument i, and supposingly the    returned value is x it creates decisions slack[i] = x, slack[i] = x +    1, slack[i] = x - 1, slack[i] = x + 2, etc."""
+        return _pywrapcp.RoutingModel_MakeGuidedSlackFinalizer(self, dimension, initializer)
+
+    def MakeSelfDependentDimensionFinalizer(self, dimension: "RoutingDimension") -> "operations_research::DecisionBuilder *":
+        r""" MakeSelfDependentDimensionFinalizer is a finalizer for the slacks of a self-dependent dimension. It makes an extensive use of the caches of the state dependent transits. In detail, MakeSelfDependentDimensionFinalizer returns a composition of a local search decision builder with a greedy descent operator for the cumul of the start of each route and a guided slack finalizer. Provided there are no time windows and the maximum slacks are large enough, once the cumul of the start of route is fixed, the guided finalizer can find optimal values of the slacks for the rest of the route in time proportional to the length of the route. Therefore the composed finalizer generally works in time O(log(t)*n*m), where t is the latest possible departute time, n is the number of nodes in the network and m is the number of vehicles."""
+        return _pywrapcp.RoutingModel_MakeSelfDependentDimensionFinalizer(self, dimension)
+
+ +
+ + + +
+
#   + + + RoutingModel(*args) +
+ +
+ View Source +
    def __init__(self, *args):
+        _pywrapcp.RoutingModel_swiginit(self, _pywrapcp.new_RoutingModel(*args))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + ROUTING_NOT_SOLVED = 0 +
+ +

Problem not solved yet (before calling RoutingModel::Solve()).

+
+ + +
+
+
#   + + ROUTING_SUCCESS = 1 +
+ +

Problem solved successfully after calling RoutingModel::Solve().

+
+ + +
+
+
#   + + ROUTING_FAIL = 2 +
+ +

No solution found to the problem after calling RoutingModel::Solve().

+
+ + +
+
+
#   + + ROUTING_FAIL_TIMEOUT = 3 +
+ +

Time limit reached before finding a solution with RoutingModel::Solve().

+
+ + +
+
+
#   + + ROUTING_INVALID = 4 +
+ +

Model, model parameters or flags are not valid.

+
+ + +
+
+
#   + + PICKUP_AND_DELIVERY_NO_ORDER = 0 +
+ +

Any precedence is accepted.

+
+ + +
+
+
#   + + PICKUP_AND_DELIVERY_LIFO = 1 +
+ +

Deliveries must be performed in reverse order of pickups.

+
+ + +
+
+
#   + + PICKUP_AND_DELIVERY_FIFO = 2 +
+ +

Deliveries must be performed in the same order as pickups.

+
+ + +
+
+
#   + + + def + RegisterUnaryTransitVector(self, values: 'std::vector< int64_t >') -> int: +
+ +
+ View Source +
    def RegisterUnaryTransitVector(self, values: "std::vector< int64_t >") -> "int":
+        r""" Registers 'callback' and returns its index."""
+        return _pywrapcp.RoutingModel_RegisterUnaryTransitVector(self, values)
+
+ +
+ +

Registers 'callback' and returns its index.

+
+ + +
+
+
#   + + + def + RegisterUnaryTransitCallback( + self, + callback: 'operations_research::RoutingModel::TransitCallback1' +) -> int: +
+ +
+ View Source +
    def RegisterUnaryTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback1") -> "int":
+        return _pywrapcp.RoutingModel_RegisterUnaryTransitCallback(self, callback)
+
+ +
+ + + +
+
+
#   + + + def + RegisterPositiveUnaryTransitCallback( + self, + callback: 'operations_research::RoutingModel::TransitCallback1' +) -> int: +
+ +
+ View Source +
    def RegisterPositiveUnaryTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback1") -> "int":
+        return _pywrapcp.RoutingModel_RegisterPositiveUnaryTransitCallback(self, callback)
+
+ +
+ + + +
+
+
#   + + + def + RegisterTransitMatrix(self, values: 'std::vector< std::vector< int64_t > >') -> int: +
+ +
+ View Source +
    def RegisterTransitMatrix(self, values: "std::vector< std::vector< int64_t > >") -> "int":
+        return _pywrapcp.RoutingModel_RegisterTransitMatrix(self, values)
+
+ +
+ + + +
+
+
#   + + + def + RegisterTransitCallback( + self, + callback: 'operations_research::RoutingModel::TransitCallback2' +) -> int: +
+ +
+ View Source +
    def RegisterTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback2") -> "int":
+        return _pywrapcp.RoutingModel_RegisterTransitCallback(self, callback)
+
+ +
+ + + +
+
+
#   + + + def + RegisterPositiveTransitCallback( + self, + callback: 'operations_research::RoutingModel::TransitCallback2' +) -> int: +
+ +
+ View Source +
    def RegisterPositiveTransitCallback(self, callback: "operations_research::RoutingModel::TransitCallback2") -> "int":
+        return _pywrapcp.RoutingModel_RegisterPositiveTransitCallback(self, callback)
+
+ +
+ + + +
+
+
#   + + + def + TransitCallback( + self, + callback_index: int +) -> 'operations_research::RoutingModel::TransitCallback2 const &': +
+ +
+ View Source +
    def TransitCallback(self, callback_index: "int") -> "operations_research::RoutingModel::TransitCallback2 const &":
+        return _pywrapcp.RoutingModel_TransitCallback(self, callback_index)
+
+ +
+ + + +
+
+
#   + + + def + UnaryTransitCallbackOrNull( + self, + callback_index: int +) -> 'operations_research::RoutingModel::TransitCallback1 const &': +
+ +
+ View Source +
    def UnaryTransitCallbackOrNull(self, callback_index: "int") -> "operations_research::RoutingModel::TransitCallback1 const &":
+        return _pywrapcp.RoutingModel_UnaryTransitCallbackOrNull(self, callback_index)
+
+ +
+ + + +
+
+
#   + + + def + AddDimension( + self, + evaluator_index: int, + slack_max: 'int64_t', + capacity: 'int64_t', + fix_start_cumul_to_zero: bool, + name: 'std::string const &' +) -> bool: +
+ +
+ View Source +
    def AddDimension(self, evaluator_index: "int", slack_max: "int64_t", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
+        r""" Model creation Methods to add dimensions to routes; dimensions represent quantities accumulated at nodes along the routes. They represent quantities such as weights or volumes carried along the route, or distance or times. Quantities at a node are represented by "cumul" variables and the increase or decrease of quantities between nodes are represented by "transit" variables. These variables are linked as follows: if j == next(i), cumul(j) = cumul(i) + transit(i) + slack(i) where slack is a positive slack variable (can represent waiting times for a time dimension). Setting the value of fix_start_cumul_to_zero to true will force the "cumul" variable of the start node of all vehicles to be equal to 0. Creates a dimension where the transit variable is constrained to be equal to evaluator(i, next(i)); 'slack_max' is the upper bound of the slack variable and 'capacity' is the upper bound of the cumul variables. 'name' is the name used to reference the dimension; this name is used to get cumul and transit variables from the routing model. Returns false if a dimension with the same name has already been created (and doesn't create the new dimension). Takes ownership of the callback 'evaluator'."""
+        return _pywrapcp.RoutingModel_AddDimension(self, evaluator_index, slack_max, capacity, fix_start_cumul_to_zero, name)
+
+ +
+ +

Model creation Methods to add dimensions to routes; dimensions represent quantities accumulated at nodes along the routes. They represent quantities such as weights or volumes carried along the route, or distance or times. Quantities at a node are represented by "cumul" variables and the increase or decrease of quantities between nodes are represented by "transit" variables. These variables are linked as follows: if j == next(i), cumul(j) = cumul(i) + transit(i) + slack(i) where slack is a positive slack variable (can represent waiting times for a time dimension). Setting the value of fix_start_cumul_to_zero to true will force the "cumul" variable of the start node of all vehicles to be equal to 0. Creates a dimension where the transit variable is constrained to be equal to evaluator(i, next(i)); 'slack_max' is the upper bound of the slack variable and 'capacity' is the upper bound of the cumul variables. 'name' is the name used to reference the dimension; this name is used to get cumul and transit variables from the routing model. Returns false if a dimension with the same name has already been created (and doesn't create the new dimension). Takes ownership of the callback 'evaluator'.

+
+ + +
+
+
#   + + + def + AddDimensionWithVehicleTransits( + self, + evaluator_indices: 'std::vector< int > const &', + slack_max: 'int64_t', + capacity: 'int64_t', + fix_start_cumul_to_zero: bool, + name: 'std::string const &' +) -> bool: +
+ +
+ View Source +
    def AddDimensionWithVehicleTransits(self, evaluator_indices: "std::vector< int > const &", slack_max: "int64_t", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
+        return _pywrapcp.RoutingModel_AddDimensionWithVehicleTransits(self, evaluator_indices, slack_max, capacity, fix_start_cumul_to_zero, name)
+
+ +
+ + + +
+
+
#   + + + def + AddDimensionWithVehicleCapacity( + self, + evaluator_index: int, + slack_max: 'int64_t', + vehicle_capacities: 'std::vector< int64_t >', + fix_start_cumul_to_zero: bool, + name: 'std::string const &' +) -> bool: +
+ +
+ View Source +
    def AddDimensionWithVehicleCapacity(self, evaluator_index: "int", slack_max: "int64_t", vehicle_capacities: "std::vector< int64_t >", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
+        return _pywrapcp.RoutingModel_AddDimensionWithVehicleCapacity(self, evaluator_index, slack_max, vehicle_capacities, fix_start_cumul_to_zero, name)
+
+ +
+ + + +
+
+
#   + + + def + AddDimensionWithVehicleTransitAndCapacity( + self, + evaluator_indices: 'std::vector< int > const &', + slack_max: 'int64_t', + vehicle_capacities: 'std::vector< int64_t >', + fix_start_cumul_to_zero: bool, + name: 'std::string const &' +) -> bool: +
+ +
+ View Source +
    def AddDimensionWithVehicleTransitAndCapacity(self, evaluator_indices: "std::vector< int > const &", slack_max: "int64_t", vehicle_capacities: "std::vector< int64_t >", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "bool":
+        return _pywrapcp.RoutingModel_AddDimensionWithVehicleTransitAndCapacity(self, evaluator_indices, slack_max, vehicle_capacities, fix_start_cumul_to_zero, name)
+
+ +
+ + + +
+
+
#   + + + def + AddConstantDimensionWithSlack( + self, + value: 'int64_t', + capacity: 'int64_t', + slack_max: 'int64_t', + fix_start_cumul_to_zero: bool, + name: 'std::string const &' +) -> 'std::pair< int,bool >': +
+ +
+ View Source +
    def AddConstantDimensionWithSlack(self, value: "int64_t", capacity: "int64_t", slack_max: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
+        r""" Creates a dimension where the transit variable is constrained to be equal to 'value'; 'capacity' is the upper bound of the cumul variables. 'name' is the name used to reference the dimension; this name is used to get cumul and transit variables from the routing model. Returns a pair consisting of an index to the registered unary transit callback and a bool denoting whether the dimension has been created. It is false if a dimension with the same name has already been created (and doesn't create the new dimension but still register a new callback)."""
+        return _pywrapcp.RoutingModel_AddConstantDimensionWithSlack(self, value, capacity, slack_max, fix_start_cumul_to_zero, name)
+
+ +
+ +

Creates a dimension where the transit variable is constrained to be equal to 'value'; 'capacity' is the upper bound of the cumul variables. 'name' is the name used to reference the dimension; this name is used to get cumul and transit variables from the routing model. Returns a pair consisting of an index to the registered unary transit callback and a bool denoting whether the dimension has been created. It is false if a dimension with the same name has already been created (and doesn't create the new dimension but still register a new callback).

+
+ + +
+
+
#   + + + def + AddConstantDimension( + self, + value: 'int64_t', + capacity: 'int64_t', + fix_start_cumul_to_zero: bool, + name: 'std::string const &' +) -> 'std::pair< int,bool >': +
+ +
+ View Source +
    def AddConstantDimension(self, value: "int64_t", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
+        return _pywrapcp.RoutingModel_AddConstantDimension(self, value, capacity, fix_start_cumul_to_zero, name)
+
+ +
+ + + +
+
+
#   + + + def + AddVectorDimension( + self, + values: 'std::vector< int64_t >', + capacity: 'int64_t', + fix_start_cumul_to_zero: bool, + name: 'std::string const &' +) -> 'std::pair< int,bool >': +
+ +
+ View Source +
    def AddVectorDimension(self, values: "std::vector< int64_t >", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
+        r""" Creates a dimension where the transit variable is constrained to be equal to 'values[i]' for node i; 'capacity' is the upper bound of the cumul variables. 'name' is the name used to reference the dimension; this name is used to get cumul and transit variables from the routing model. Returns a pair consisting of an index to the registered unary transit callback and a bool denoting whether the dimension has been created. It is false if a dimension with the same name has already been created (and doesn't create the new dimension but still register a new callback)."""
+        return _pywrapcp.RoutingModel_AddVectorDimension(self, values, capacity, fix_start_cumul_to_zero, name)
+
+ +
+ +

Creates a dimension where the transit variable is constrained to be equal to 'values[i]' for node i; 'capacity' is the upper bound of the cumul variables. 'name' is the name used to reference the dimension; this name is used to get cumul and transit variables from the routing model. Returns a pair consisting of an index to the registered unary transit callback and a bool denoting whether the dimension has been created. It is false if a dimension with the same name has already been created (and doesn't create the new dimension but still register a new callback).

+
+ + +
+
+
#   + + + def + AddMatrixDimension( + self, + values: 'std::vector< std::vector< int64_t > >', + capacity: 'int64_t', + fix_start_cumul_to_zero: bool, + name: 'std::string const &' +) -> 'std::pair< int,bool >': +
+ +
+ View Source +
    def AddMatrixDimension(self, values: "std::vector< std::vector< int64_t > >", capacity: "int64_t", fix_start_cumul_to_zero: "bool", name: "std::string const &") -> "std::pair< int,bool >":
+        r""" Creates a dimension where the transit variable is constrained to be equal to 'values[i][next(i)]' for node i; 'capacity' is the upper bound of the cumul variables. 'name' is the name used to reference the dimension; this name is used to get cumul and transit variables from the routing model. Returns a pair consisting of an index to the registered transit callback and a bool denoting whether the dimension has been created. It is false if a dimension with the same name has already been created (and doesn't create the new dimension but still register a new callback)."""
+        return _pywrapcp.RoutingModel_AddMatrixDimension(self, values, capacity, fix_start_cumul_to_zero, name)
+
+ +
+ +

Creates a dimension where the transit variable is constrained to be equal to 'values[i][next(i)]' for node i; 'capacity' is the upper bound of the cumul variables. 'name' is the name used to reference the dimension; this name is used to get cumul and transit variables from the routing model. Returns a pair consisting of an index to the registered transit callback and a bool denoting whether the dimension has been created. It is false if a dimension with the same name has already been created (and doesn't create the new dimension but still register a new callback).

+
+ + +
+
+
#   + + + def + MakePathSpansAndTotalSlacks( + self, + dimension: pywrapcp.RoutingDimension, + spans: 'std::vector< operations_research::IntVar * >', + total_slacks: 'std::vector< operations_research::IntVar * >' +) -> 'operations_research::Constraint *': +
+ +
+ View Source +
    def MakePathSpansAndTotalSlacks(self, dimension: "RoutingDimension", spans: "std::vector< operations_research::IntVar * >", total_slacks: "std::vector< operations_research::IntVar * >") -> "operations_research::Constraint *":
+        r""" For every vehicle of the routing model: - if total_slacks[vehicle] is not nullptr, constrains it to be the sum of   slacks on that vehicle, that is,   dimension->CumulVar(end) - dimension->CumulVar(start) -   sum_{node in path of vehicle} dimension->FixedTransitVar(node). - if spans[vehicle] is not nullptr, constrains it to be   dimension->CumulVar(end) - dimension->CumulVar(start) This does stronger propagation than a decomposition, and takes breaks into account."""
+        return _pywrapcp.RoutingModel_MakePathSpansAndTotalSlacks(self, dimension, spans, total_slacks)
+
+ +
+ +

For every vehicle of the routing model: - if total_slacks[vehicle] is not nullptr, constrains it to be the sum of slacks on that vehicle, that is, dimension->CumulVar(end) - dimension->CumulVar(start) - sum_{node in path of vehicle} dimension->FixedTransitVar(node). - if spans[vehicle] is not nullptr, constrains it to be dimension->CumulVar(end) - dimension->CumulVar(start) This does stronger propagation than a decomposition, and takes breaks into account.

+
+ + +
+
+
#   + + + def + GetAllDimensionNames(self) -> 'std::vector< std::string >': +
+ +
+ View Source +
    def GetAllDimensionNames(self) -> "std::vector< std::string >":
+        r""" Outputs the names of all dimensions added to the routing engine."""
+        return _pywrapcp.RoutingModel_GetAllDimensionNames(self)
+
+ +
+ +

Outputs the names of all dimensions added to the routing engine.

+
+ + +
+
+
#   + + + def + GetDimensions( + self +) -> 'std::vector< operations_research::RoutingDimension * > const &': +
+ +
+ View Source +
    def GetDimensions(self) -> "std::vector< operations_research::RoutingDimension * > const &":
+        r""" Returns all dimensions of the model."""
+        return _pywrapcp.RoutingModel_GetDimensions(self)
+
+ +
+ +

Returns all dimensions of the model.

+
+ + +
+
+
#   + + + def + GetDimensionsWithSoftOrSpanCosts(self) -> 'std::vector< operations_research::RoutingDimension * >': +
+ +
+ View Source +
    def GetDimensionsWithSoftOrSpanCosts(self) -> "std::vector< operations_research::RoutingDimension * >":
+        r""" Returns dimensions with soft or vehicle span costs."""
+        return _pywrapcp.RoutingModel_GetDimensionsWithSoftOrSpanCosts(self)
+
+ +
+ +

Returns dimensions with soft or vehicle span costs.

+
+ + +
+
+
#   + + + def + GetGlobalDimensionCumulOptimizers( + self +) -> 'std::vector< std::unique_ptr< operations_research::GlobalDimensionCumulOptimizer > > const &': +
+ +
+ View Source +
    def GetGlobalDimensionCumulOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::GlobalDimensionCumulOptimizer > > const &":
+        r""" Returns [global|local]_dimension_optimizers_, which are empty if the model has not been closed."""
+        return _pywrapcp.RoutingModel_GetGlobalDimensionCumulOptimizers(self)
+
+ +
+ +

Returns [global|local]_dimension_optimizers_, which are empty if the model has not been closed.

+
+ + +
+
+
#   + + + def + GetGlobalDimensionCumulMPOptimizers( + self +) -> 'std::vector< std::unique_ptr< operations_research::GlobalDimensionCumulOptimizer > > const &': +
+ +
+ View Source +
    def GetGlobalDimensionCumulMPOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::GlobalDimensionCumulOptimizer > > const &":
+        return _pywrapcp.RoutingModel_GetGlobalDimensionCumulMPOptimizers(self)
+
+ +
+ + + +
+
+
#   + + + def + GetLocalDimensionCumulOptimizers( + self +) -> 'std::vector< std::unique_ptr< operations_research::LocalDimensionCumulOptimizer > > const &': +
+ +
+ View Source +
    def GetLocalDimensionCumulOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::LocalDimensionCumulOptimizer > > const &":
+        return _pywrapcp.RoutingModel_GetLocalDimensionCumulOptimizers(self)
+
+ +
+ + + +
+
+
#   + + + def + GetLocalDimensionCumulMPOptimizers( + self +) -> 'std::vector< std::unique_ptr< operations_research::LocalDimensionCumulOptimizer > > const &': +
+ +
+ View Source +
    def GetLocalDimensionCumulMPOptimizers(self) -> "std::vector< std::unique_ptr< operations_research::LocalDimensionCumulOptimizer > > const &":
+        return _pywrapcp.RoutingModel_GetLocalDimensionCumulMPOptimizers(self)
+
+ +
+ + + +
+
+
#   + + + def + GetMutableGlobalCumulOptimizer( + self, + dimension: pywrapcp.RoutingDimension +) -> 'operations_research::GlobalDimensionCumulOptimizer *': +
+ +
+ View Source +
    def GetMutableGlobalCumulOptimizer(self, dimension: "RoutingDimension") -> "operations_research::GlobalDimensionCumulOptimizer *":
+        r""" Returns the global/local dimension cumul optimizer for a given dimension, or nullptr if there is none."""
+        return _pywrapcp.RoutingModel_GetMutableGlobalCumulOptimizer(self, dimension)
+
+ +
+ +

Returns the global/local dimension cumul optimizer for a given dimension, or nullptr if there is none.

+
+ + +
+
+
#   + + + def + GetMutableGlobalCumulMPOptimizer( + self, + dimension: pywrapcp.RoutingDimension +) -> 'operations_research::GlobalDimensionCumulOptimizer *': +
+ +
+ View Source +
    def GetMutableGlobalCumulMPOptimizer(self, dimension: "RoutingDimension") -> "operations_research::GlobalDimensionCumulOptimizer *":
+        return _pywrapcp.RoutingModel_GetMutableGlobalCumulMPOptimizer(self, dimension)
+
+ +
+ + + +
+
+
#   + + + def + GetMutableLocalCumulOptimizer( + self, + dimension: pywrapcp.RoutingDimension +) -> 'operations_research::LocalDimensionCumulOptimizer *': +
+ +
+ View Source +
    def GetMutableLocalCumulOptimizer(self, dimension: "RoutingDimension") -> "operations_research::LocalDimensionCumulOptimizer *":
+        return _pywrapcp.RoutingModel_GetMutableLocalCumulOptimizer(self, dimension)
+
+ +
+ + + +
+
+
#   + + + def + GetMutableLocalCumulMPOptimizer( + self, + dimension: pywrapcp.RoutingDimension +) -> 'operations_research::LocalDimensionCumulOptimizer *': +
+ +
+ View Source +
    def GetMutableLocalCumulMPOptimizer(self, dimension: "RoutingDimension") -> "operations_research::LocalDimensionCumulOptimizer *":
+        return _pywrapcp.RoutingModel_GetMutableLocalCumulMPOptimizer(self, dimension)
+
+ +
+ + + +
+
+
#   + + + def + HasDimension(self, dimension_name: 'std::string const &') -> bool: +
+ +
+ View Source +
    def HasDimension(self, dimension_name: "std::string const &") -> "bool":
+        r""" Returns true if a dimension exists for a given dimension name."""
+        return _pywrapcp.RoutingModel_HasDimension(self, dimension_name)
+
+ +
+ +

Returns true if a dimension exists for a given dimension name.

+
+ + +
+
+
#   + + + def + GetDimensionOrDie( + self, + dimension_name: 'std::string const &' +) -> 'operations_research::RoutingDimension const &': +
+ +
+ View Source +
    def GetDimensionOrDie(self, dimension_name: "std::string const &") -> "operations_research::RoutingDimension const &":
+        r""" Returns a dimension from its name. Dies if the dimension does not exist."""
+        return _pywrapcp.RoutingModel_GetDimensionOrDie(self, dimension_name)
+
+ +
+ +

Returns a dimension from its name. Dies if the dimension does not exist.

+
+ + +
+
+
#   + + + def + GetMutableDimension( + self, + dimension_name: 'std::string const &' +) -> 'operations_research::RoutingDimension *': +
+ +
+ View Source +
    def GetMutableDimension(self, dimension_name: "std::string const &") -> "operations_research::RoutingDimension *":
+        r""" Returns a dimension from its name. Returns nullptr if the dimension does not exist."""
+        return _pywrapcp.RoutingModel_GetMutableDimension(self, dimension_name)
+
+ +
+ +

Returns a dimension from its name. Returns nullptr if the dimension does not exist.

+
+ + +
+
+
#   + + + def + SetPrimaryConstrainedDimension(self, dimension_name: 'std::string const &') -> 'void': +
+ +
+ View Source +
    def SetPrimaryConstrainedDimension(self, dimension_name: "std::string const &") -> "void":
+        r""" Set the given dimension as "primary constrained". As of August 2013, this is only used by ArcIsMoreConstrainedThanArc(). "dimension" must be the name of an existing dimension, or be empty, in which case there will not be a primary dimension after this call."""
+        return _pywrapcp.RoutingModel_SetPrimaryConstrainedDimension(self, dimension_name)
+
+ +
+ +

Set the given dimension as "primary constrained". As of August 2013, this is only used by ArcIsMoreConstrainedThanArc(). "dimension" must be the name of an existing dimension, or be empty, in which case there will not be a primary dimension after this call.

+
+ + +
+
+
#   + + + def + GetPrimaryConstrainedDimension(self) -> 'std::string const &': +
+ +
+ View Source +
    def GetPrimaryConstrainedDimension(self) -> "std::string const &":
+        r""" Get the primary constrained dimension, or an empty string if it is unset."""
+        return _pywrapcp.RoutingModel_GetPrimaryConstrainedDimension(self)
+
+ +
+ +

Get the primary constrained dimension, or an empty string if it is unset.

+
+ + +
+
+
#   + + + def + GetDimensionResourceGroupIndices( + self, + dimension: pywrapcp.RoutingDimension +) -> 'std::vector< int > const &': +
+ +
+ View Source +
    def GetDimensionResourceGroupIndices(self, dimension: "RoutingDimension") -> "std::vector< int > const &":
+        r""" Returns the indices of resource groups for this dimension. This method can only be called after the model has been closed."""
+        return _pywrapcp.RoutingModel_GetDimensionResourceGroupIndices(self, dimension)
+
+ +
+ +

Returns the indices of resource groups for this dimension. This method can only be called after the model has been closed.

+
+ + +
+
+
#   + + + def + AddDisjunction(self, *args) -> 'operations_research::RoutingModel::DisjunctionIndex': +
+ +
+ View Source +
    def AddDisjunction(self, *args) -> "operations_research::RoutingModel::DisjunctionIndex":
+        r""" Adds a disjunction constraint on the indices: exactly 'max_cardinality' of the indices are active. Start and end indices of any vehicle cannot be part of a disjunction. If a penalty is given, at most 'max_cardinality' of the indices can be active, and if less are active, 'penalty' is payed per inactive index. This is equivalent to adding the constraint:     p + Sum(i)active[i] == max_cardinality where p is an integer variable, and the following cost to the cost function:     p * penalty. 'penalty' must be positive to make the disjunction optional; a negative penalty will force 'max_cardinality' indices of the disjunction to be performed, and therefore p == 0. Note: passing a vector with a single index will model an optional index with a penalty cost if it is not visited."""
+        return _pywrapcp.RoutingModel_AddDisjunction(self, *args)
+
+ +
+ +

Adds a disjunction constraint on the indices: exactly 'max_cardinality' of the indices are active. Start and end indices of any vehicle cannot be part of a disjunction. If a penalty is given, at most 'max_cardinality' of the indices can be active, and if less are active, 'penalty' is payed per inactive index. This is equivalent to adding the constraint: p + Sum(i)active[i] == max_cardinality where p is an integer variable, and the following cost to the cost function: p * penalty. 'penalty' must be positive to make the disjunction optional; a negative penalty will force 'max_cardinality' indices of the disjunction to be performed, and therefore p == 0. Note: passing a vector with a single index will model an optional index with a penalty cost if it is not visited.

+
+ + +
+
+
#   + + + def + GetDisjunctionIndices( + self, + index: 'int64_t' +) -> 'std::vector< operations_research::RoutingModel::DisjunctionIndex > const &': +
+ +
+ View Source +
    def GetDisjunctionIndices(self, index: "int64_t") -> "std::vector< operations_research::RoutingModel::DisjunctionIndex > const &":
+        r""" Returns the indices of the disjunctions to which an index belongs."""
+        return _pywrapcp.RoutingModel_GetDisjunctionIndices(self, index)
+
+ +
+ +

Returns the indices of the disjunctions to which an index belongs.

+
+ + +
+
+
#   + + + def + GetDisjunctionPenalty( + self, + index: 'operations_research::RoutingModel::DisjunctionIndex' +) -> 'int64_t': +
+ +
+ View Source +
    def GetDisjunctionPenalty(self, index: "operations_research::RoutingModel::DisjunctionIndex") -> "int64_t":
+        r""" Returns the penalty of the node disjunction of index 'index'."""
+        return _pywrapcp.RoutingModel_GetDisjunctionPenalty(self, index)
+
+ +
+ +

Returns the penalty of the node disjunction of index 'index'.

+
+ + +
+
+
#   + + + def + GetDisjunctionMaxCardinality( + self, + index: 'operations_research::RoutingModel::DisjunctionIndex' +) -> 'int64_t': +
+ +
+ View Source +
    def GetDisjunctionMaxCardinality(self, index: "operations_research::RoutingModel::DisjunctionIndex") -> "int64_t":
+        r""" Returns the maximum number of possible active nodes of the node disjunction of index 'index'."""
+        return _pywrapcp.RoutingModel_GetDisjunctionMaxCardinality(self, index)
+
+ +
+ +

Returns the maximum number of possible active nodes of the node disjunction of index 'index'.

+
+ + +
+
+
#   + + + def + GetNumberOfDisjunctions(self) -> int: +
+ +
+ View Source +
    def GetNumberOfDisjunctions(self) -> "int":
+        r""" Returns the number of node disjunctions in the model."""
+        return _pywrapcp.RoutingModel_GetNumberOfDisjunctions(self)
+
+ +
+ +

Returns the number of node disjunctions in the model.

+
+ + +
+
+
#   + + + def + GetPerfectBinaryDisjunctions(self) -> 'std::vector< std::pair< int64_t,int64_t > >': +
+ +
+ View Source +
    def GetPerfectBinaryDisjunctions(self) -> "std::vector< std::pair< int64_t,int64_t > >":
+        r""" Returns the list of all perfect binary disjunctions, as pairs of variable indices: a disjunction is "perfect" when its variables do not appear in any other disjunction. Each pair is sorted (lowest variable index first), and the output vector is also sorted (lowest pairs first)."""
+        return _pywrapcp.RoutingModel_GetPerfectBinaryDisjunctions(self)
+
+ +
+ +

Returns the list of all perfect binary disjunctions, as pairs of variable indices: a disjunction is "perfect" when its variables do not appear in any other disjunction. Each pair is sorted (lowest variable index first), and the output vector is also sorted (lowest pairs first).

+
+ + +
+
+
#   + + + def + IgnoreDisjunctionsAlreadyForcedToZero(self) -> 'void': +
+ +
+ View Source +
    def IgnoreDisjunctionsAlreadyForcedToZero(self) -> "void":
+        r""" SPECIAL: Makes the solver ignore all the disjunctions whose active variables are all trivially zero (i.e. Max() == 0), by setting their max_cardinality to 0. This can be useful when using the BaseBinaryDisjunctionNeighborhood operators, in the context of arc-based routing."""
+        return _pywrapcp.RoutingModel_IgnoreDisjunctionsAlreadyForcedToZero(self)
+
+ +
+ +

SPECIAL: Makes the solver ignore all the disjunctions whose active variables are all trivially zero (i.e. Max() == 0), by setting their max_cardinality to 0. This can be useful when using the BaseBinaryDisjunctionNeighborhood operators, in the context of arc-based routing.

+
+ + +
+
+
#   + + + def + AddSoftSameVehicleConstraint( + self, + indices: 'std::vector< int64_t > const &', + cost: 'int64_t' +) -> 'void': +
+ +
+ View Source +
    def AddSoftSameVehicleConstraint(self, indices: "std::vector< int64_t > const &", cost: "int64_t") -> "void":
+        r""" Adds a soft constraint to force a set of variable indices to be on the same vehicle. If all nodes are not on the same vehicle, each extra vehicle used adds 'cost' to the cost function."""
+        return _pywrapcp.RoutingModel_AddSoftSameVehicleConstraint(self, indices, cost)
+
+ +
+ +

Adds a soft constraint to force a set of variable indices to be on the same vehicle. If all nodes are not on the same vehicle, each extra vehicle used adds 'cost' to the cost function.

+
+ + +
+
+
#   + + + def + SetAllowedVehiclesForIndex( + self, + vehicles: 'std::vector< int > const &', + index: 'int64_t' +) -> 'void': +
+ +
+ View Source +
    def SetAllowedVehiclesForIndex(self, vehicles: "std::vector< int > const &", index: "int64_t") -> "void":
+        r""" Sets the vehicles which can visit a given node. If the node is in a disjunction, this will not prevent it from being unperformed. Specifying an empty vector of vehicles has no effect (all vehicles will be allowed to visit the node)."""
+        return _pywrapcp.RoutingModel_SetAllowedVehiclesForIndex(self, vehicles, index)
+
+ +
+ +

Sets the vehicles which can visit a given node. If the node is in a disjunction, this will not prevent it from being unperformed. Specifying an empty vector of vehicles has no effect (all vehicles will be allowed to visit the node).

+
+ + +
+
+
#   + + + def + IsVehicleAllowedForIndex(self, vehicle: int, index: 'int64_t') -> bool: +
+ +
+ View Source +
    def IsVehicleAllowedForIndex(self, vehicle: "int", index: "int64_t") -> "bool":
+        r""" Returns true if a vehicle is allowed to visit a given node."""
+        return _pywrapcp.RoutingModel_IsVehicleAllowedForIndex(self, vehicle, index)
+
+ +
+ +

Returns true if a vehicle is allowed to visit a given node.

+
+ + +
+
+
#   + + + def + AddPickupAndDelivery(self, pickup: 'int64_t', delivery: 'int64_t') -> 'void': +
+ +
+ View Source +
    def AddPickupAndDelivery(self, pickup: "int64_t", delivery: "int64_t") -> "void":
+        r""" Notifies that index1 and index2 form a pair of nodes which should belong to the same route. This methods helps the search find better solutions, especially in the local search phase. It should be called each time you have an equality constraint linking the vehicle variables of two node (including for instance pickup and delivery problems):     Solver* const solver = routing.solver();     int64_t index1 = manager.NodeToIndex(node1);     int64_t index2 = manager.NodeToIndex(node2);     solver->AddConstraint(solver->MakeEquality(         routing.VehicleVar(index1),         routing.VehicleVar(index2)));     routing.AddPickupAndDelivery(index1, index2);"""
+        return _pywrapcp.RoutingModel_AddPickupAndDelivery(self, pickup, delivery)
+
+ +
+ +

Notifies that index1 and index2 form a pair of nodes which should belong to the same route. This methods helps the search find better solutions, especially in the local search phase. It should be called each time you have an equality constraint linking the vehicle variables of two node (including for instance pickup and delivery problems): Solver* const solver = routing.solver(); int64_t index1 = manager.NodeToIndex(node1); int64_t index2 = manager.NodeToIndex(node2); solver->AddConstraint(solver->MakeEquality( routing.VehicleVar(index1), routing.VehicleVar(index2))); routing.AddPickupAndDelivery(index1, index2);

+
+ + +
+
+
#   + + + def + AddPickupAndDeliverySets( + self, + pickup_disjunction: 'operations_research::RoutingModel::DisjunctionIndex', + delivery_disjunction: 'operations_research::RoutingModel::DisjunctionIndex' +) -> 'void': +
+ +
+ View Source +
    def AddPickupAndDeliverySets(self, pickup_disjunction: "operations_research::RoutingModel::DisjunctionIndex", delivery_disjunction: "operations_research::RoutingModel::DisjunctionIndex") -> "void":
+        r""" Same as AddPickupAndDelivery but notifying that the performed node from the disjunction of index 'pickup_disjunction' is on the same route as the performed node from the disjunction of index 'delivery_disjunction'."""
+        return _pywrapcp.RoutingModel_AddPickupAndDeliverySets(self, pickup_disjunction, delivery_disjunction)
+
+ +
+ +

Same as AddPickupAndDelivery but notifying that the performed node from the disjunction of index 'pickup_disjunction' is on the same route as the performed node from the disjunction of index 'delivery_disjunction'.

+
+ + +
+
+
#   + + + def + GetPickupIndexPairs( + self, + node_index: 'int64_t' +) -> 'std::vector< std::pair< int,int > > const &': +
+ +
+ View Source +
    def GetPickupIndexPairs(self, node_index: "int64_t") -> "std::vector< std::pair< int,int > > const &":
+        r""" Returns pairs for which the node is a pickup; the first element of each pair is the index in the pickup and delivery pairs list in which the pickup appears, the second element is its index in the pickups list."""
+        return _pywrapcp.RoutingModel_GetPickupIndexPairs(self, node_index)
+
+ +
+ +

Returns pairs for which the node is a pickup; the first element of each pair is the index in the pickup and delivery pairs list in which the pickup appears, the second element is its index in the pickups list.

+
+ + +
+
+
#   + + + def + GetDeliveryIndexPairs( + self, + node_index: 'int64_t' +) -> 'std::vector< std::pair< int,int > > const &': +
+ +
+ View Source +
    def GetDeliveryIndexPairs(self, node_index: "int64_t") -> "std::vector< std::pair< int,int > > const &":
+        r""" Same as above for deliveries."""
+        return _pywrapcp.RoutingModel_GetDeliveryIndexPairs(self, node_index)
+
+ +
+ +

Same as above for deliveries.

+
+ + +
+
+
#   + + + def + SetPickupAndDeliveryPolicyOfAllVehicles( + self, + policy: 'operations_research::RoutingModel::PickupAndDeliveryPolicy' +) -> 'void': +
+ +
+ View Source +
    def SetPickupAndDeliveryPolicyOfAllVehicles(self, policy: "operations_research::RoutingModel::PickupAndDeliveryPolicy") -> "void":
+        r""" Sets the Pickup and delivery policy of all vehicles. It is equivalent to calling SetPickupAndDeliveryPolicyOfVehicle on all vehicles."""
+        return _pywrapcp.RoutingModel_SetPickupAndDeliveryPolicyOfAllVehicles(self, policy)
+
+ +
+ +

Sets the Pickup and delivery policy of all vehicles. It is equivalent to calling SetPickupAndDeliveryPolicyOfVehicle on all vehicles.

+
+ + +
+
+
#   + + + def + SetPickupAndDeliveryPolicyOfVehicle( + self, + policy: 'operations_research::RoutingModel::PickupAndDeliveryPolicy', + vehicle: int +) -> 'void': +
+ +
+ View Source +
    def SetPickupAndDeliveryPolicyOfVehicle(self, policy: "operations_research::RoutingModel::PickupAndDeliveryPolicy", vehicle: "int") -> "void":
+        return _pywrapcp.RoutingModel_SetPickupAndDeliveryPolicyOfVehicle(self, policy, vehicle)
+
+ +
+ + + +
+
+
#   + + + def + GetPickupAndDeliveryPolicyOfVehicle( + self, + vehicle: int +) -> 'operations_research::RoutingModel::PickupAndDeliveryPolicy': +
+ +
+ View Source +
    def GetPickupAndDeliveryPolicyOfVehicle(self, vehicle: "int") -> "operations_research::RoutingModel::PickupAndDeliveryPolicy":
+        return _pywrapcp.RoutingModel_GetPickupAndDeliveryPolicyOfVehicle(self, vehicle)
+
+ +
+ + + +
+
+
#   + + + def + GetNumOfSingletonNodes(self) -> int: +
+ +
+ View Source +
    def GetNumOfSingletonNodes(self) -> "int":
+        r""" Returns the number of non-start/end nodes which do not appear in a pickup/delivery pair."""
+        return _pywrapcp.RoutingModel_GetNumOfSingletonNodes(self)
+
+ +
+ +

Returns the number of non-start/end nodes which do not appear in a pickup/delivery pair.

+
+ + +
+
+
#   + + TYPE_ADDED_TO_VEHICLE = 0 +
+ +

When visited, the number of types 'T' on the vehicle increases by one.

+
+ + +
+
+
#   + + ADDED_TYPE_REMOVED_FROM_VEHICLE = 1 +
+ +

When visited, one instance of type 'T' previously added to the route (TYPE_ADDED_TO_VEHICLE), if any, is removed from the vehicle. If the type was not previously added to the route or all added instances have already been removed, this visit has no effect on the types.

+
+ + +
+
+
#   + + TYPE_ON_VEHICLE_UP_TO_VISIT = 2 +
+ +

With the following policy, the visit enforces that type 'T' is considered on the route from its start until this node is visited.

+
+ + +
+
+
#   + + TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED = 3 +
+ +

The visit doesn't have an impact on the number of types 'T' on the route, as it's (virtually) added and removed directly. This policy can be used for visits which are part of an incompatibility or requirement set without affecting the type count on the route.

+
+ + +
+
+
#   + + + def + SetVisitType( + self, + index: 'int64_t', + type: int, + type_policy: 'operations_research::RoutingModel::VisitTypePolicy' +) -> 'void': +
+ +
+ View Source +
    def SetVisitType(self, index: "int64_t", type: "int", type_policy: "operations_research::RoutingModel::VisitTypePolicy") -> "void":
+        return _pywrapcp.RoutingModel_SetVisitType(self, index, type, type_policy)
+
+ +
+ + + +
+
+
#   + + + def + GetVisitType(self, index: 'int64_t') -> int: +
+ +
+ View Source +
    def GetVisitType(self, index: "int64_t") -> "int":
+        return _pywrapcp.RoutingModel_GetVisitType(self, index)
+
+ +
+ + + +
+
+
#   + + + def + GetSingleNodesOfType(self, type: int) -> 'std::vector< int > const &': +
+ +
+ View Source +
    def GetSingleNodesOfType(self, type: "int") -> "std::vector< int > const &":
+        return _pywrapcp.RoutingModel_GetSingleNodesOfType(self, type)
+
+ +
+ + + +
+
+
#   + + + def + GetPairIndicesOfType(self, type: int) -> 'std::vector< int > const &': +
+ +
+ View Source +
    def GetPairIndicesOfType(self, type: "int") -> "std::vector< int > const &":
+        return _pywrapcp.RoutingModel_GetPairIndicesOfType(self, type)
+
+ +
+ + + +
+
+
#   + + + def + GetVisitTypePolicy( + self, + index: 'int64_t' +) -> 'operations_research::RoutingModel::VisitTypePolicy': +
+ +
+ View Source +
    def GetVisitTypePolicy(self, index: "int64_t") -> "operations_research::RoutingModel::VisitTypePolicy":
+        return _pywrapcp.RoutingModel_GetVisitTypePolicy(self, index)
+
+ +
+ + + +
+
+
#   + + + def + CloseVisitTypes(self) -> 'void': +
+ +
+ View Source +
    def CloseVisitTypes(self) -> "void":
+        r""" This function should be called once all node visit types have been set and prior to adding any incompatibilities/requirements. "close" types."""
+        return _pywrapcp.RoutingModel_CloseVisitTypes(self)
+
+ +
+ +

This function should be called once all node visit types have been set and prior to adding any incompatibilities/requirements. "close" types.

+
+ + +
+
+
#   + + + def + GetNumberOfVisitTypes(self) -> int: +
+ +
+ View Source +
    def GetNumberOfVisitTypes(self) -> "int":
+        return _pywrapcp.RoutingModel_GetNumberOfVisitTypes(self)
+
+ +
+ + + +
+
+
#   + + + def + AddHardTypeIncompatibility(self, type1: int, type2: int) -> 'void': +
+ +
+ View Source +
    def AddHardTypeIncompatibility(self, type1: "int", type2: "int") -> "void":
+        r""" Incompatibilities: Two nodes with "hard" incompatible types cannot share the same route at all, while with a "temporal" incompatibility they can't be on the same route at the same time."""
+        return _pywrapcp.RoutingModel_AddHardTypeIncompatibility(self, type1, type2)
+
+ +
+ +

Incompatibilities: Two nodes with "hard" incompatible types cannot share the same route at all, while with a "temporal" incompatibility they can't be on the same route at the same time.

+
+ + +
+
+
#   + + + def + AddTemporalTypeIncompatibility(self, type1: int, type2: int) -> 'void': +
+ +
+ View Source +
    def AddTemporalTypeIncompatibility(self, type1: "int", type2: "int") -> "void":
+        return _pywrapcp.RoutingModel_AddTemporalTypeIncompatibility(self, type1, type2)
+
+ +
+ + + +
+
+
#   + + + def + GetHardTypeIncompatibilitiesOfType(self, type: int) -> 'absl::flat_hash_set< int > const &': +
+ +
+ View Source +
    def GetHardTypeIncompatibilitiesOfType(self, type: "int") -> "absl::flat_hash_set< int > const &":
+        r""" Returns visit types incompatible with a given type."""
+        return _pywrapcp.RoutingModel_GetHardTypeIncompatibilitiesOfType(self, type)
+
+ +
+ +

Returns visit types incompatible with a given type.

+
+ + +
+
+
#   + + + def + GetTemporalTypeIncompatibilitiesOfType(self, type: int) -> 'absl::flat_hash_set< int > const &': +
+ +
+ View Source +
    def GetTemporalTypeIncompatibilitiesOfType(self, type: "int") -> "absl::flat_hash_set< int > const &":
+        return _pywrapcp.RoutingModel_GetTemporalTypeIncompatibilitiesOfType(self, type)
+
+ +
+ + + +
+
+
#   + + + def + HasHardTypeIncompatibilities(self) -> bool: +
+ +
+ View Source +
    def HasHardTypeIncompatibilities(self) -> "bool":
+        r""" Returns true iff any hard (resp. temporal) type incompatibilities have been added to the model."""
+        return _pywrapcp.RoutingModel_HasHardTypeIncompatibilities(self)
+
+ +
+ +

Returns true iff any hard (resp. temporal) type incompatibilities have been added to the model.

+
+ + +
+
+
#   + + + def + HasTemporalTypeIncompatibilities(self) -> bool: +
+ +
+ View Source +
    def HasTemporalTypeIncompatibilities(self) -> "bool":
+        return _pywrapcp.RoutingModel_HasTemporalTypeIncompatibilities(self)
+
+ +
+ + + +
+
+
#   + + + def + AddSameVehicleRequiredTypeAlternatives( + self, + dependent_type: int, + required_type_alternatives: 'absl::flat_hash_set< int >' +) -> 'void': +
+ +
+ View Source +
    def AddSameVehicleRequiredTypeAlternatives(self, dependent_type: "int", required_type_alternatives: "absl::flat_hash_set< int >") -> "void":
+        r""" Requirements: NOTE: As of 2019-04, cycles in the requirement graph are not supported, and lead to the dependent nodes being skipped if possible (otherwise the model is considered infeasible). The following functions specify that "dependent_type" requires at least one of the types in "required_type_alternatives". For same-vehicle requirements, a node of dependent type type_D requires at least one node of type type_R among the required alternatives on the same route."""
+        return _pywrapcp.RoutingModel_AddSameVehicleRequiredTypeAlternatives(self, dependent_type, required_type_alternatives)
+
+ +
+ +

Requirements: NOTE: As of 2019-04, cycles in the requirement graph are not supported, and lead to the dependent nodes being skipped if possible (otherwise the model is considered infeasible). The following functions specify that "dependent_type" requires at least one of the types in "required_type_alternatives". For same-vehicle requirements, a node of dependent type type_D requires at least one node of type type_R among the required alternatives on the same route.

+
+ + +
+
+
#   + + + def + AddRequiredTypeAlternativesWhenAddingType( + self, + dependent_type: int, + required_type_alternatives: 'absl::flat_hash_set< int >' +) -> 'void': +
+ +
+ View Source +
    def AddRequiredTypeAlternativesWhenAddingType(self, dependent_type: "int", required_type_alternatives: "absl::flat_hash_set< int >") -> "void":
+        r""" If type_D depends on type_R when adding type_D, any node_D of type_D and VisitTypePolicy TYPE_ADDED_TO_VEHICLE or TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED requires at least one type_R on its vehicle at the time node_D is visited."""
+        return _pywrapcp.RoutingModel_AddRequiredTypeAlternativesWhenAddingType(self, dependent_type, required_type_alternatives)
+
+ +
+ +

If type_D depends on type_R when adding type_D, any node_D of type_D and VisitTypePolicy TYPE_ADDED_TO_VEHICLE or TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED requires at least one type_R on its vehicle at the time node_D is visited.

+
+ + +
+
+
#   + + + def + AddRequiredTypeAlternativesWhenRemovingType( + self, + dependent_type: int, + required_type_alternatives: 'absl::flat_hash_set< int >' +) -> 'void': +
+ +
+ View Source +
    def AddRequiredTypeAlternativesWhenRemovingType(self, dependent_type: "int", required_type_alternatives: "absl::flat_hash_set< int >") -> "void":
+        r""" The following requirements apply when visiting dependent nodes that remove their type from the route, i.e. type_R must be on the vehicle when type_D of VisitTypePolicy ADDED_TYPE_REMOVED_FROM_VEHICLE, TYPE_ON_VEHICLE_UP_TO_VISIT or TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED is visited."""
+        return _pywrapcp.RoutingModel_AddRequiredTypeAlternativesWhenRemovingType(self, dependent_type, required_type_alternatives)
+
+ +
+ +

The following requirements apply when visiting dependent nodes that remove their type from the route, i.e. type_R must be on the vehicle when type_D of VisitTypePolicy ADDED_TYPE_REMOVED_FROM_VEHICLE, TYPE_ON_VEHICLE_UP_TO_VISIT or TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED is visited.

+
+ + +
+
+
#   + + + def + GetSameVehicleRequiredTypeAlternativesOfType( + self, + type: int +) -> 'std::vector< absl::flat_hash_set< int > > const &': +
+ +
+ View Source +
    def GetSameVehicleRequiredTypeAlternativesOfType(self, type: "int") -> "std::vector< absl::flat_hash_set< int > > const &":
+        r""" Returns the set of same-vehicle requirement alternatives for the given type."""
+        return _pywrapcp.RoutingModel_GetSameVehicleRequiredTypeAlternativesOfType(self, type)
+
+ +
+ +

Returns the set of same-vehicle requirement alternatives for the given type.

+
+ + +
+
+
#   + + + def + GetRequiredTypeAlternativesWhenAddingType( + self, + type: int +) -> 'std::vector< absl::flat_hash_set< int > > const &': +
+ +
+ View Source +
    def GetRequiredTypeAlternativesWhenAddingType(self, type: "int") -> "std::vector< absl::flat_hash_set< int > > const &":
+        r""" Returns the set of requirement alternatives when adding the given type."""
+        return _pywrapcp.RoutingModel_GetRequiredTypeAlternativesWhenAddingType(self, type)
+
+ +
+ +

Returns the set of requirement alternatives when adding the given type.

+
+ + +
+
+
#   + + + def + GetRequiredTypeAlternativesWhenRemovingType( + self, + type: int +) -> 'std::vector< absl::flat_hash_set< int > > const &': +
+ +
+ View Source +
    def GetRequiredTypeAlternativesWhenRemovingType(self, type: "int") -> "std::vector< absl::flat_hash_set< int > > const &":
+        r""" Returns the set of requirement alternatives when removing the given type."""
+        return _pywrapcp.RoutingModel_GetRequiredTypeAlternativesWhenRemovingType(self, type)
+
+ +
+ +

Returns the set of requirement alternatives when removing the given type.

+
+ + +
+
+
#   + + + def + HasSameVehicleTypeRequirements(self) -> bool: +
+ +
+ View Source +
    def HasSameVehicleTypeRequirements(self) -> "bool":
+        r""" Returns true iff any same-route (resp. temporal) type requirements have been added to the model."""
+        return _pywrapcp.RoutingModel_HasSameVehicleTypeRequirements(self)
+
+ +
+ +

Returns true iff any same-route (resp. temporal) type requirements have been added to the model.

+
+ + +
+
+
#   + + + def + HasTemporalTypeRequirements(self) -> bool: +
+ +
+ View Source +
    def HasTemporalTypeRequirements(self) -> "bool":
+        return _pywrapcp.RoutingModel_HasTemporalTypeRequirements(self)
+
+ +
+ + + +
+
+
#   + + + def + HasTypeRegulations(self) -> bool: +
+ +
+ View Source +
    def HasTypeRegulations(self) -> "bool":
+        r""" Returns true iff the model has any incompatibilities or requirements set on node types."""
+        return _pywrapcp.RoutingModel_HasTypeRegulations(self)
+
+ +
+ +

Returns true iff the model has any incompatibilities or requirements set on node types.

+
+ + +
+
+
#   + + + def + UnperformedPenalty(self, var_index: 'int64_t') -> 'int64_t': +
+ +
+ View Source +
    def UnperformedPenalty(self, var_index: "int64_t") -> "int64_t":
+        r""" Get the "unperformed" penalty of a node. This is only well defined if the node is only part of a single Disjunction, and that disjunction has a penalty. For forced active nodes returns max int64_t. In all other cases, this returns 0."""
+        return _pywrapcp.RoutingModel_UnperformedPenalty(self, var_index)
+
+ +
+ +

Get the "unperformed" penalty of a node. This is only well defined if the node is only part of a single Disjunction, and that disjunction has a penalty. For forced active nodes returns max int64_t. In all other cases, this returns 0.

+
+ + +
+
+
#   + + + def + UnperformedPenaltyOrValue(self, default_value: 'int64_t', var_index: 'int64_t') -> 'int64_t': +
+ +
+ View Source +
    def UnperformedPenaltyOrValue(self, default_value: "int64_t", var_index: "int64_t") -> "int64_t":
+        r""" Same as above except that it returns default_value instead of 0 when penalty is not well defined (default value is passed as first argument to simplify the usage of the method in a callback)."""
+        return _pywrapcp.RoutingModel_UnperformedPenaltyOrValue(self, default_value, var_index)
+
+ +
+ +

Same as above except that it returns default_value instead of 0 when penalty is not well defined (default value is passed as first argument to simplify the usage of the method in a callback).

+
+ + +
+
+
#   + + + def + GetDepot(self) -> 'int64_t': +
+ +
+ View Source +
    def GetDepot(self) -> "int64_t":
+        r""" Returns the variable index of the first starting or ending node of all routes. If all routes start  and end at the same node (single depot), this is the node returned."""
+        return _pywrapcp.RoutingModel_GetDepot(self)
+
+ +
+ +

Returns the variable index of the first starting or ending node of all routes. If all routes start and end at the same node (single depot), this is the node returned.

+
+ + +
+
+
#   + + + def + SetMaximumNumberOfActiveVehicles(self, max_active_vehicles: int) -> 'void': +
+ +
+ View Source +
    def SetMaximumNumberOfActiveVehicles(self, max_active_vehicles: "int") -> "void":
+        r""" Constrains the maximum number of active vehicles, aka the number of vehicles which do not have an empty route. For instance, this can be used to limit the number of routes in the case where there are fewer drivers than vehicles and that the fleet of vehicle is heterogeneous."""
+        return _pywrapcp.RoutingModel_SetMaximumNumberOfActiveVehicles(self, max_active_vehicles)
+
+ +
+ +

Constrains the maximum number of active vehicles, aka the number of vehicles which do not have an empty route. For instance, this can be used to limit the number of routes in the case where there are fewer drivers than vehicles and that the fleet of vehicle is heterogeneous.

+
+ + +
+
+
#   + + + def + GetMaximumNumberOfActiveVehicles(self) -> int: +
+ +
+ View Source +
    def GetMaximumNumberOfActiveVehicles(self) -> "int":
+        r""" Returns the maximum number of active vehicles."""
+        return _pywrapcp.RoutingModel_GetMaximumNumberOfActiveVehicles(self)
+
+ +
+ +

Returns the maximum number of active vehicles.

+
+ + +
+
+
#   + + + def + SetArcCostEvaluatorOfAllVehicles(self, evaluator_index: int) -> 'void': +
+ +
+ View Source +
    def SetArcCostEvaluatorOfAllVehicles(self, evaluator_index: "int") -> "void":
+        r""" Sets the cost function of the model such that the cost of a segment of a route between node 'from' and 'to' is evaluator(from, to), whatever the route or vehicle performing the route."""
+        return _pywrapcp.RoutingModel_SetArcCostEvaluatorOfAllVehicles(self, evaluator_index)
+
+ +
+ +

Sets the cost function of the model such that the cost of a segment of a route between node 'from' and 'to' is evaluator(from, to), whatever the route or vehicle performing the route.

+
+ + +
+
+
#   + + + def + SetArcCostEvaluatorOfVehicle(self, evaluator_index: int, vehicle: int) -> 'void': +
+ +
+ View Source +
    def SetArcCostEvaluatorOfVehicle(self, evaluator_index: "int", vehicle: "int") -> "void":
+        r""" Sets the cost function for a given vehicle route."""
+        return _pywrapcp.RoutingModel_SetArcCostEvaluatorOfVehicle(self, evaluator_index, vehicle)
+
+ +
+ +

Sets the cost function for a given vehicle route.

+
+ + +
+
+
#   + + + def + SetFixedCostOfAllVehicles(self, cost: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetFixedCostOfAllVehicles(self, cost: "int64_t") -> "void":
+        r""" Sets the fixed cost of all vehicle routes. It is equivalent to calling SetFixedCostOfVehicle on all vehicle routes."""
+        return _pywrapcp.RoutingModel_SetFixedCostOfAllVehicles(self, cost)
+
+ +
+ +

Sets the fixed cost of all vehicle routes. It is equivalent to calling SetFixedCostOfVehicle on all vehicle routes.

+
+ + +
+
+
#   + + + def + SetFixedCostOfVehicle(self, cost: 'int64_t', vehicle: int) -> 'void': +
+ +
+ View Source +
    def SetFixedCostOfVehicle(self, cost: "int64_t", vehicle: "int") -> "void":
+        r""" Sets the fixed cost of one vehicle route."""
+        return _pywrapcp.RoutingModel_SetFixedCostOfVehicle(self, cost, vehicle)
+
+ +
+ +

Sets the fixed cost of one vehicle route.

+
+ + +
+
+
#   + + + def + GetFixedCostOfVehicle(self, vehicle: int) -> 'int64_t': +
+ +
+ View Source +
    def GetFixedCostOfVehicle(self, vehicle: "int") -> "int64_t":
+        r""" Returns the route fixed cost taken into account if the route of the vehicle is not empty, aka there's at least one node on the route other than the first and last nodes."""
+        return _pywrapcp.RoutingModel_GetFixedCostOfVehicle(self, vehicle)
+
+ +
+ +

Returns the route fixed cost taken into account if the route of the vehicle is not empty, aka there's at least one node on the route other than the first and last nodes.

+
+ + +
+
+
#   + + + def + SetAmortizedCostFactorsOfAllVehicles( + self, + linear_cost_factor: 'int64_t', + quadratic_cost_factor: 'int64_t' +) -> 'void': +
+ +
+ View Source +
    def SetAmortizedCostFactorsOfAllVehicles(self, linear_cost_factor: "int64_t", quadratic_cost_factor: "int64_t") -> "void":
+        r""" The following methods set the linear and quadratic cost factors of vehicles (must be positive values). The default value of these parameters is zero for all vehicles. When set, the cost_ of the model will contain terms aiming at reducing the number of vehicles used in the model, by adding the following to the objective for every vehicle v: INDICATOR(v used in the model) *   [linear_cost_factor_of_vehicle_[v]    - quadratic_cost_factor_of_vehicle_[v]*(square of length of route v)] i.e. for every used vehicle, we add the linear factor as fixed cost, and subtract the square of the route length multiplied by the quadratic factor. This second term aims at making the routes as dense as possible. Sets the linear and quadratic cost factor of all vehicles."""
+        return _pywrapcp.RoutingModel_SetAmortizedCostFactorsOfAllVehicles(self, linear_cost_factor, quadratic_cost_factor)
+
+ +
+ +

The following methods set the linear and quadratic cost factors of vehicles (must be positive values). The default value of these parameters is zero for all vehicles. When set, the cost_ of the model will contain terms aiming at reducing the number of vehicles used in the model, by adding the following to the objective for every vehicle v: INDICATOR(v used in the model) * [linear_cost_factor_of_vehicle_[v] - quadratic_cost_factor_of_vehicle_[v]*(square of length of route v)] i.e. for every used vehicle, we add the linear factor as fixed cost, and subtract the square of the route length multiplied by the quadratic factor. This second term aims at making the routes as dense as possible. Sets the linear and quadratic cost factor of all vehicles.

+
+ + +
+
+
#   + + + def + SetAmortizedCostFactorsOfVehicle( + self, + linear_cost_factor: 'int64_t', + quadratic_cost_factor: 'int64_t', + vehicle: int +) -> 'void': +
+ +
+ View Source +
    def SetAmortizedCostFactorsOfVehicle(self, linear_cost_factor: "int64_t", quadratic_cost_factor: "int64_t", vehicle: "int") -> "void":
+        r""" Sets the linear and quadratic cost factor of the given vehicle."""
+        return _pywrapcp.RoutingModel_SetAmortizedCostFactorsOfVehicle(self, linear_cost_factor, quadratic_cost_factor, vehicle)
+
+ +
+ +

Sets the linear and quadratic cost factor of the given vehicle.

+
+ + +
+
+
#   + + + def + GetAmortizedLinearCostFactorOfVehicles(self) -> 'std::vector< int64_t > const &': +
+ +
+ View Source +
    def GetAmortizedLinearCostFactorOfVehicles(self) -> "std::vector< int64_t > const &":
+        return _pywrapcp.RoutingModel_GetAmortizedLinearCostFactorOfVehicles(self)
+
+ +
+ + + +
+
+
#   + + + def + GetAmortizedQuadraticCostFactorOfVehicles(self) -> 'std::vector< int64_t > const &': +
+ +
+ View Source +
    def GetAmortizedQuadraticCostFactorOfVehicles(self) -> "std::vector< int64_t > const &":
+        return _pywrapcp.RoutingModel_GetAmortizedQuadraticCostFactorOfVehicles(self)
+
+ +
+ + + +
+
+
#   + + + def + ConsiderEmptyRouteCostsForVehicle(self, consider_costs: bool, vehicle: int) -> 'void': +
+ +
+ View Source +
    def ConsiderEmptyRouteCostsForVehicle(self, consider_costs: "bool", vehicle: "int") -> "void":
+        return _pywrapcp.RoutingModel_ConsiderEmptyRouteCostsForVehicle(self, consider_costs, vehicle)
+
+ +
+ + + +
+
+
#   + + + def + AreEmptyRouteCostsConsideredForVehicle(self, vehicle: int) -> bool: +
+ +
+ View Source +
    def AreEmptyRouteCostsConsideredForVehicle(self, vehicle: "int") -> "bool":
+        return _pywrapcp.RoutingModel_AreEmptyRouteCostsConsideredForVehicle(self, vehicle)
+
+ +
+ + + +
+
+
#   + + + def + SetFirstSolutionEvaluator( + self, + evaluator: 'operations_research::Solver::IndexEvaluator2' +) -> 'void': +
+ +
+ View Source +
    def SetFirstSolutionEvaluator(self, evaluator: "operations_research::Solver::IndexEvaluator2") -> "void":
+        r""" Gets/sets the evaluator used during the search. Only relevant when RoutingSearchParameters.first_solution_strategy = EVALUATOR_STRATEGY. Takes ownership of evaluator."""
+        return _pywrapcp.RoutingModel_SetFirstSolutionEvaluator(self, evaluator)
+
+ +
+ +

Gets/sets the evaluator used during the search. Only relevant when RoutingSearchParameters.first_solution_strategy = EVALUATOR_STRATEGY. Takes ownership of evaluator.

+
+ + +
+
+
#   + + + def + AddLocalSearchOperator(self, ls_operator: pywrapcp.LocalSearchOperator) -> 'void': +
+ +
+ View Source +
    def AddLocalSearchOperator(self, ls_operator: "LocalSearchOperator") -> "void":
+        r""" Adds a local search operator to the set of operators used to solve the vehicle routing problem."""
+        return _pywrapcp.RoutingModel_AddLocalSearchOperator(self, ls_operator)
+
+ +
+ +

Adds a local search operator to the set of operators used to solve the vehicle routing problem.

+
+ + +
+
+
#   + + + def + AddSearchMonitor(self, monitor: pywrapcp.SearchMonitor) -> 'void': +
+ +
+ View Source +
    def AddSearchMonitor(self, monitor: "SearchMonitor") -> "void":
+        r""" Adds a search monitor to the search used to solve the routing model."""
+        return _pywrapcp.RoutingModel_AddSearchMonitor(self, monitor)
+
+ +
+ +

Adds a search monitor to the search used to solve the routing model.

+
+ + +
+
+
#   + + + def + AddAtSolutionCallback(self, callback: 'std::function< void () >') -> 'void': +
+ +
+ View Source +
    def AddAtSolutionCallback(self, callback: "std::function< void () >") -> "void":
+        r""" Adds a callback called each time a solution is found during the search. This is a shortcut to creating a monitor to call the callback on AtSolution() and adding it with AddSearchMonitor."""
+        return _pywrapcp.RoutingModel_AddAtSolutionCallback(self, callback)
+
+ +
+ +

Adds a callback called each time a solution is found during the search. This is a shortcut to creating a monitor to call the callback on AtSolution() and adding it with AddSearchMonitor.

+
+ + +
+
+
#   + + + def + AddVariableMinimizedByFinalizer(self, var: pywrapcp.IntVar) -> 'void': +
+ +
+ View Source +
    def AddVariableMinimizedByFinalizer(self, var: "IntVar") -> "void":
+        r""" Adds a variable to minimize in the solution finalizer. The solution finalizer is called each time a solution is found during the search and allows to instantiate secondary variables (such as dimension cumul variables)."""
+        return _pywrapcp.RoutingModel_AddVariableMinimizedByFinalizer(self, var)
+
+ +
+ +

Adds a variable to minimize in the solution finalizer. The solution finalizer is called each time a solution is found during the search and allows to instantiate secondary variables (such as dimension cumul variables).

+
+ + +
+
+
#   + + + def + AddVariableMaximizedByFinalizer(self, var: pywrapcp.IntVar) -> 'void': +
+ +
+ View Source +
    def AddVariableMaximizedByFinalizer(self, var: "IntVar") -> "void":
+        r""" Adds a variable to maximize in the solution finalizer (see above for information on the solution finalizer)."""
+        return _pywrapcp.RoutingModel_AddVariableMaximizedByFinalizer(self, var)
+
+ +
+ +

Adds a variable to maximize in the solution finalizer (see above for information on the solution finalizer).

+
+ + +
+
+
#   + + + def + AddWeightedVariableMinimizedByFinalizer(self, var: pywrapcp.IntVar, cost: 'int64_t') -> 'void': +
+ +
+ View Source +
    def AddWeightedVariableMinimizedByFinalizer(self, var: "IntVar", cost: "int64_t") -> "void":
+        r""" Adds a variable to minimize in the solution finalizer, with a weighted priority: the higher the more priority it has."""
+        return _pywrapcp.RoutingModel_AddWeightedVariableMinimizedByFinalizer(self, var, cost)
+
+ +
+ +

Adds a variable to minimize in the solution finalizer, with a weighted priority: the higher the more priority it has.

+
+ + +
+
+
#   + + + def + AddVariableTargetToFinalizer(self, var: pywrapcp.IntVar, target: 'int64_t') -> 'void': +
+ +
+ View Source +
    def AddVariableTargetToFinalizer(self, var: "IntVar", target: "int64_t") -> "void":
+        r""" Add a variable to set the closest possible to the target value in the solution finalizer."""
+        return _pywrapcp.RoutingModel_AddVariableTargetToFinalizer(self, var, target)
+
+ +
+ +

Add a variable to set the closest possible to the target value in the solution finalizer.

+
+ + +
+
+
#   + + + def + CloseModel(self) -> 'void': +
+ +
+ View Source +
    def CloseModel(self) -> "void":
+        r""" Closes the current routing model; after this method is called, no modification to the model can be done, but RoutesToAssignment becomes available. Note that CloseModel() is automatically called by Solve() and other methods that produce solution. This is equivalent to calling CloseModelWithParameters(DefaultRoutingSearchParameters())."""
+        return _pywrapcp.RoutingModel_CloseModel(self)
+
+ +
+ +

Closes the current routing model; after this method is called, no modification to the model can be done, but RoutesToAssignment becomes available. Note that CloseModel() is automatically called by Solve() and other methods that produce solution. This is equivalent to calling CloseModelWithParameters(DefaultRoutingSearchParameters()).

+
+ + +
+
+
#   + + + def + CloseModelWithParameters( + self, + search_parameters: 'operations_research::RoutingSearchParameters const &' +) -> 'void': +
+ +
+ View Source +
    def CloseModelWithParameters(self, search_parameters: "operations_research::RoutingSearchParameters const &") -> "void":
+        r""" Same as above taking search parameters (as of 10/2015 some the parameters have to be set when closing the model)."""
+        return _pywrapcp.RoutingModel_CloseModelWithParameters(self, search_parameters)
+
+ +
+ +

Same as above taking search parameters (as of 10/2015 some the parameters have to be set when closing the model).

+
+ + +
+
+
#   + + + def + Solve( + self, + assignment: pywrapcp.Assignment = None +) -> 'operations_research::Assignment const *': +
+ +
+ View Source +
    def Solve(self, assignment: "Assignment"=None) -> "operations_research::Assignment const *":
+        r""" Solves the current routing model; closes the current model. This is equivalent to calling SolveWithParameters(DefaultRoutingSearchParameters()) or SolveFromAssignmentWithParameters(assignment,                                   DefaultRoutingSearchParameters())."""
+        return _pywrapcp.RoutingModel_Solve(self, assignment)
+
+ +
+ +

Solves the current routing model; closes the current model. This is equivalent to calling SolveWithParameters(DefaultRoutingSearchParameters()) or SolveFromAssignmentWithParameters(assignment, DefaultRoutingSearchParameters()).

+
+ + +
+
+
#   + + + def + SolveWithParameters( + self, + search_parameters: 'operations_research::RoutingSearchParameters const &', + solutions: 'std::vector< operations_research::Assignment const * > *' = None +) -> 'operations_research::Assignment const *': +
+ +
+ View Source +
    def SolveWithParameters(self, search_parameters: "operations_research::RoutingSearchParameters const &", solutions: "std::vector< operations_research::Assignment const * > *"=None) -> "operations_research::Assignment const *":
+        r""" Solves the current routing model with the given parameters. If 'solutions' is specified, it will contain the k best solutions found during the search (from worst to best, including the one returned by this method), where k corresponds to the 'number_of_solutions_to_collect' in 'search_parameters'. Note that the Assignment returned by the method and the ones in solutions are owned by the underlying solver and should not be deleted."""
+        return _pywrapcp.RoutingModel_SolveWithParameters(self, search_parameters, solutions)
+
+ +
+ +

Solves the current routing model with the given parameters. If 'solutions' is specified, it will contain the k best solutions found during the search (from worst to best, including the one returned by this method), where k corresponds to the 'number_of_solutions_to_collect' in 'search_parameters'. Note that the Assignment returned by the method and the ones in solutions are owned by the underlying solver and should not be deleted.

+
+ + +
+
+
#   + + + def + SolveFromAssignmentWithParameters( + self, + assignment: pywrapcp.Assignment, + search_parameters: 'operations_research::RoutingSearchParameters const &', + solutions: 'std::vector< operations_research::Assignment const * > *' = None +) -> 'operations_research::Assignment const *': +
+ +
+ View Source +
    def SolveFromAssignmentWithParameters(self, assignment: "Assignment", search_parameters: "operations_research::RoutingSearchParameters const &", solutions: "std::vector< operations_research::Assignment const * > *"=None) -> "operations_research::Assignment const *":
+        r""" Same as above, except that if assignment is not null, it will be used as the initial solution."""
+        return _pywrapcp.RoutingModel_SolveFromAssignmentWithParameters(self, assignment, search_parameters, solutions)
+
+ +
+ +

Same as above, except that if assignment is not null, it will be used as the initial solution.

+
+ + +
+
+
#   + + + def + SolveFromAssignmentsWithParameters( + self, + assignments: 'std::vector< operations_research::Assignment const * > const &', + search_parameters: 'operations_research::RoutingSearchParameters const &', + solutions: 'std::vector< operations_research::Assignment const * > *' = None +) -> 'operations_research::Assignment const *': +
+ +
+ View Source +
    def SolveFromAssignmentsWithParameters(self, assignments: "std::vector< operations_research::Assignment const * > const &", search_parameters: "operations_research::RoutingSearchParameters const &", solutions: "std::vector< operations_research::Assignment const * > *"=None) -> "operations_research::Assignment const *":
+        r""" Same as above but will try all assignments in order as first solutions until one succeeds."""
+        return _pywrapcp.RoutingModel_SolveFromAssignmentsWithParameters(self, assignments, search_parameters, solutions)
+
+ +
+ +

Same as above but will try all assignments in order as first solutions until one succeeds.

+
+ + +
+
+
#   + + + def + SetAssignmentFromOtherModelAssignment( + self, + target_assignment: pywrapcp.Assignment, + source_model: pywrapcp.RoutingModel, + source_assignment: pywrapcp.Assignment +) -> 'void': +
+ +
+ View Source +
    def SetAssignmentFromOtherModelAssignment(self, target_assignment: "Assignment", source_model: "RoutingModel", source_assignment: "Assignment") -> "void":
+        r""" Given a "source_model" and its "source_assignment", resets "target_assignment" with the IntVar variables (nexts_, and vehicle_vars_ if costs aren't homogeneous across vehicles) of "this" model, with the values set according to those in "other_assignment". The objective_element of target_assignment is set to this->cost_."""
+        return _pywrapcp.RoutingModel_SetAssignmentFromOtherModelAssignment(self, target_assignment, source_model, source_assignment)
+
+ +
+ +

Given a "source_model" and its "source_assignment", resets "target_assignment" with the IntVar variables (nexts_, and vehicle_vars_ if costs aren't homogeneous across vehicles) of "this" model, with the values set according to those in "other_assignment". The objective_element of target_assignment is set to this->cost_.

+
+ + +
+
+
#   + + + def + ComputeLowerBound(self) -> 'int64_t': +
+ +
+ View Source +
    def ComputeLowerBound(self) -> "int64_t":
+        r""" Computes a lower bound to the routing problem solving a linear assignment problem. The routing model must be closed before calling this method. Note that problems with node disjunction constraints (including optional nodes) and non-homogenous costs are not supported (the method returns 0 in these cases)."""
+        return _pywrapcp.RoutingModel_ComputeLowerBound(self)
+
+ +
+ +

Computes a lower bound to the routing problem solving a linear assignment problem. The routing model must be closed before calling this method. Note that problems with node disjunction constraints (including optional nodes) and non-homogenous costs are not supported (the method returns 0 in these cases).

+
+ + +
+
+
#   + + + def + status(self) -> 'operations_research::RoutingModel::Status': +
+ +
+ View Source +
    def status(self) -> "operations_research::RoutingModel::Status":
+        r""" Returns the current status of the routing model."""
+        return _pywrapcp.RoutingModel_status(self)
+
+ +
+ +

Returns the current status of the routing model.

+
+ + +
+
+
#   + + + def + ApplyLocks( + self, + locks: 'std::vector< int64_t > const &' +) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def ApplyLocks(self, locks: "std::vector< int64_t > const &") -> "operations_research::IntVar *":
+        r""" Applies a lock chain to the next search. 'locks' represents an ordered vector of nodes representing a partial route which will be fixed during the next search; it will constrain next variables such that: next[locks[i]] == locks[i+1]. Returns the next variable at the end of the locked chain; this variable is not locked. An assignment containing the locks can be obtained by calling PreAssignment()."""
+        return _pywrapcp.RoutingModel_ApplyLocks(self, locks)
+
+ +
+ +

Applies a lock chain to the next search. 'locks' represents an ordered vector of nodes representing a partial route which will be fixed during the next search; it will constrain next variables such that: next[locks[i]] == locks[i+1]. Returns the next variable at the end of the locked chain; this variable is not locked. An assignment containing the locks can be obtained by calling PreAssignment().

+
+ + +
+
+
#   + + + def + ApplyLocksToAllVehicles( + self, + locks: 'std::vector< std::vector< int64_t > > const &', + close_routes: bool +) -> bool: +
+ +
+ View Source +
    def ApplyLocksToAllVehicles(self, locks: "std::vector< std::vector< int64_t > > const &", close_routes: "bool") -> "bool":
+        r""" Applies lock chains to all vehicles to the next search, such that locks[p] is the lock chain for route p. Returns false if the locks do not contain valid routes; expects that the routes do not contain the depots, i.e. there are empty vectors in place of empty routes. If close_routes is set to true, adds the end nodes to the route of each vehicle and deactivates other nodes. An assignment containing the locks can be obtained by calling PreAssignment()."""
+        return _pywrapcp.RoutingModel_ApplyLocksToAllVehicles(self, locks, close_routes)
+
+ +
+ +

Applies lock chains to all vehicles to the next search, such that locks[p] is the lock chain for route p. Returns false if the locks do not contain valid routes; expects that the routes do not contain the depots, i.e. there are empty vectors in place of empty routes. If close_routes is set to true, adds the end nodes to the route of each vehicle and deactivates other nodes. An assignment containing the locks can be obtained by calling PreAssignment().

+
+ + +
+
+
#   + + + def + PreAssignment(self) -> 'operations_research::Assignment const *const': +
+ +
+ View Source +
    def PreAssignment(self) -> "operations_research::Assignment const *const":
+        r""" Returns an assignment used to fix some of the variables of the problem. In practice, this assignment locks partial routes of the problem. This can be used in the context of locking the parts of the routes which have already been driven in online routing problems."""
+        return _pywrapcp.RoutingModel_PreAssignment(self)
+
+ +
+ +

Returns an assignment used to fix some of the variables of the problem. In practice, this assignment locks partial routes of the problem. This can be used in the context of locking the parts of the routes which have already been driven in online routing problems.

+
+ + +
+
+
#   + + + def + MutablePreAssignment(self) -> 'operations_research::Assignment *': +
+ +
+ View Source +
    def MutablePreAssignment(self) -> "operations_research::Assignment *":
+        return _pywrapcp.RoutingModel_MutablePreAssignment(self)
+
+ +
+ + + +
+
+
#   + + + def + WriteAssignment(self, file_name: 'std::string const &') -> bool: +
+ +
+ View Source +
    def WriteAssignment(self, file_name: "std::string const &") -> "bool":
+        r""" Writes the current solution to a file containing an AssignmentProto. Returns false if the file cannot be opened or if there is no current solution."""
+        return _pywrapcp.RoutingModel_WriteAssignment(self, file_name)
+
+ +
+ +

Writes the current solution to a file containing an AssignmentProto. Returns false if the file cannot be opened or if there is no current solution.

+
+ + +
+
+
#   + + + def + ReadAssignment( + self, + file_name: 'std::string const &' +) -> 'operations_research::Assignment *': +
+ +
+ View Source +
    def ReadAssignment(self, file_name: "std::string const &") -> "operations_research::Assignment *":
+        r""" Reads an assignment from a file and returns the current solution. Returns nullptr if the file cannot be opened or if the assignment is not valid."""
+        return _pywrapcp.RoutingModel_ReadAssignment(self, file_name)
+
+ +
+ +

Reads an assignment from a file and returns the current solution. Returns nullptr if the file cannot be opened or if the assignment is not valid.

+
+ + +
+
+
#   + + + def + RestoreAssignment( + self, + solution: pywrapcp.Assignment +) -> 'operations_research::Assignment *': +
+ +
+ View Source +
    def RestoreAssignment(self, solution: "Assignment") -> "operations_research::Assignment *":
+        r""" Restores an assignment as a solution in the routing model and returns the new solution. Returns nullptr if the assignment is not valid."""
+        return _pywrapcp.RoutingModel_RestoreAssignment(self, solution)
+
+ +
+ +

Restores an assignment as a solution in the routing model and returns the new solution. Returns nullptr if the assignment is not valid.

+
+ + +
+
+
#   + + + def + ReadAssignmentFromRoutes( + self, + routes: 'std::vector< std::vector< int64_t > > const &', + ignore_inactive_indices: bool +) -> 'operations_research::Assignment *': +
+ +
+ View Source +
    def ReadAssignmentFromRoutes(self, routes: "std::vector< std::vector< int64_t > > const &", ignore_inactive_indices: "bool") -> "operations_research::Assignment *":
+        r""" Restores the routes as the current solution. Returns nullptr if the solution cannot be restored (routes do not contain a valid solution). Note that calling this method will run the solver to assign values to the dimension variables; this may take considerable amount of time, especially when using dimensions with slack."""
+        return _pywrapcp.RoutingModel_ReadAssignmentFromRoutes(self, routes, ignore_inactive_indices)
+
+ +
+ +

Restores the routes as the current solution. Returns nullptr if the solution cannot be restored (routes do not contain a valid solution). Note that calling this method will run the solver to assign values to the dimension variables; this may take considerable amount of time, especially when using dimensions with slack.

+
+ + +
+
+
#   + + + def + RoutesToAssignment( + self, + routes: 'std::vector< std::vector< int64_t > > const &', + ignore_inactive_indices: bool, + close_routes: bool, + assignment: pywrapcp.Assignment +) -> bool: +
+ +
+ View Source +
    def RoutesToAssignment(self, routes: "std::vector< std::vector< int64_t > > const &", ignore_inactive_indices: "bool", close_routes: "bool", assignment: "Assignment") -> "bool":
+        r""" Fills an assignment from a specification of the routes of the vehicles. The routes are specified as lists of variable indices that appear on the routes of the vehicles. The indices of the outer vector in 'routes' correspond to vehicles IDs, the inner vector contains the variable indices on the routes for the given vehicle. The inner vectors must not contain the start and end indices, as these are determined by the routing model.  Sets the value of NextVars in the assignment, adding the variables to the assignment if necessary. The method does not touch other variables in the assignment. The method can only be called after the model is closed.  With ignore_inactive_indices set to false, this method will fail (return nullptr) in case some of the route contain indices that are deactivated in the model; when set to true, these indices will be skipped.  Returns true if routes were successfully loaded. However, such assignment still might not be a valid solution to the routing problem due to more complex constraints; it is advisible to call solver()->CheckSolution() afterwards."""
+        return _pywrapcp.RoutingModel_RoutesToAssignment(self, routes, ignore_inactive_indices, close_routes, assignment)
+
+ +
+ +

Fills an assignment from a specification of the routes of the vehicles. The routes are specified as lists of variable indices that appear on the routes of the vehicles. The indices of the outer vector in 'routes' correspond to vehicles IDs, the inner vector contains the variable indices on the routes for the given vehicle. The inner vectors must not contain the start and end indices, as these are determined by the routing model. Sets the value of NextVars in the assignment, adding the variables to the assignment if necessary. The method does not touch other variables in the assignment. The method can only be called after the model is closed. With ignore_inactive_indices set to false, this method will fail (return nullptr) in case some of the route contain indices that are deactivated in the model; when set to true, these indices will be skipped. Returns true if routes were successfully loaded. However, such assignment still might not be a valid solution to the routing problem due to more complex constraints; it is advisible to call solver()->CheckSolution() afterwards.

+
+ + +
+
+
#   + + + def + AssignmentToRoutes( + self, + assignment: pywrapcp.Assignment, + routes: 'std::vector< std::vector< int64_t > > *const' +) -> 'void': +
+ +
+ View Source +
    def AssignmentToRoutes(self, assignment: "Assignment", routes: "std::vector< std::vector< int64_t > > *const") -> "void":
+        r""" Converts the solution in the given assignment to routes for all vehicles. Expects that assignment contains a valid solution (i.e. routes for all vehicles end with an end index for that vehicle)."""
+        return _pywrapcp.RoutingModel_AssignmentToRoutes(self, assignment, routes)
+
+ +
+ +

Converts the solution in the given assignment to routes for all vehicles. Expects that assignment contains a valid solution (i.e. routes for all vehicles end with an end index for that vehicle).

+
+ + +
+
+
#   + + + def + CompactAssignment( + self, + assignment: pywrapcp.Assignment +) -> 'operations_research::Assignment *': +
+ +
+ View Source +
    def CompactAssignment(self, assignment: "Assignment") -> "operations_research::Assignment *":
+        r""" Converts the solution in the given assignment to routes for all vehicles. If the returned vector is route_indices, route_indices[i][j] is the index for jth location visited on route i. Note that contrary to AssignmentToRoutes, the vectors do include start and end locations. Returns a compacted version of the given assignment, in which all vehicles with id lower or equal to some N have non-empty routes, and all vehicles with id greater than N have empty routes. Does not take ownership of the returned object. If found, the cost of the compact assignment is the same as in the original assignment and it preserves the values of 'active' variables. Returns nullptr if a compact assignment was not found. This method only works in homogenous mode, and it only swaps equivalent vehicles (vehicles with the same start and end nodes). When creating the compact assignment, the empty plan is replaced by the route assigned to the compatible vehicle with the highest id. Note that with more complex constraints on vehicle variables, this method might fail even if a compact solution exists. This method changes the vehicle and dimension variables as necessary. While compacting the solution, only basic checks on vehicle variables are performed; if one of these checks fails no attempts to repair it are made (instead, the method returns nullptr)."""
+        return _pywrapcp.RoutingModel_CompactAssignment(self, assignment)
+
+ +
+ +

Converts the solution in the given assignment to routes for all vehicles. If the returned vector is route_indices, route_indices[i][j] is the index for jth location visited on route i. Note that contrary to AssignmentToRoutes, the vectors do include start and end locations. Returns a compacted version of the given assignment, in which all vehicles with id lower or equal to some N have non-empty routes, and all vehicles with id greater than N have empty routes. Does not take ownership of the returned object. If found, the cost of the compact assignment is the same as in the original assignment and it preserves the values of 'active' variables. Returns nullptr if a compact assignment was not found. This method only works in homogenous mode, and it only swaps equivalent vehicles (vehicles with the same start and end nodes). When creating the compact assignment, the empty plan is replaced by the route assigned to the compatible vehicle with the highest id. Note that with more complex constraints on vehicle variables, this method might fail even if a compact solution exists. This method changes the vehicle and dimension variables as necessary. While compacting the solution, only basic checks on vehicle variables are performed; if one of these checks fails no attempts to repair it are made (instead, the method returns nullptr).

+
+ + +
+
+
#   + + + def + CompactAndCheckAssignment( + self, + assignment: pywrapcp.Assignment +) -> 'operations_research::Assignment *': +
+ +
+ View Source +
    def CompactAndCheckAssignment(self, assignment: "Assignment") -> "operations_research::Assignment *":
+        r""" Same as CompactAssignment() but also checks the validity of the final compact solution; if it is not valid, no attempts to repair it are made (instead, the method returns nullptr)."""
+        return _pywrapcp.RoutingModel_CompactAndCheckAssignment(self, assignment)
+
+ +
+ +

Same as CompactAssignment() but also checks the validity of the final compact solution; if it is not valid, no attempts to repair it are made (instead, the method returns nullptr).

+
+ + +
+
+
#   + + + def + AddToAssignment(self, var: pywrapcp.IntVar) -> 'void': +
+ +
+ View Source +
    def AddToAssignment(self, var: "IntVar") -> "void":
+        r""" Adds an extra variable to the vehicle routing assignment."""
+        return _pywrapcp.RoutingModel_AddToAssignment(self, var)
+
+ +
+ +

Adds an extra variable to the vehicle routing assignment.

+
+ + +
+
+
#   + + + def + AddIntervalToAssignment(self, interval: pywrapcp.IntervalVar) -> 'void': +
+ +
+ View Source +
    def AddIntervalToAssignment(self, interval: "IntervalVar") -> "void":
+        return _pywrapcp.RoutingModel_AddIntervalToAssignment(self, interval)
+
+ +
+ + + +
+
+
#   + + + def + PackCumulsOfOptimizerDimensionsFromAssignment( + self, + original_assignment: pywrapcp.Assignment, + duration_limit: 'absl::Duration' +) -> 'operations_research::Assignment const *': +
+ +
+ View Source +
    def PackCumulsOfOptimizerDimensionsFromAssignment(self, original_assignment: "Assignment", duration_limit: "absl::Duration") -> "operations_research::Assignment const *":
+        r""" For every dimension in the model with an optimizer in local/global_dimension_optimizers_, this method tries to pack the cumul values of the dimension, such that: - The cumul costs (span costs, soft lower and upper bound costs, etc) are   minimized. - The cumuls of the ends of the routes are minimized for this given   minimal cumul cost. - Given these minimal end cumuls, the route start cumuls are maximized. Returns the assignment resulting from allocating these packed cumuls with the solver, and nullptr if these cumuls could not be set by the solver."""
+        return _pywrapcp.RoutingModel_PackCumulsOfOptimizerDimensionsFromAssignment(self, original_assignment, duration_limit)
+
+ +
+ +

For every dimension in the model with an optimizer in local/global_dimension_optimizers_, this method tries to pack the cumul values of the dimension, such that: - The cumul costs (span costs, soft lower and upper bound costs, etc) are minimized. - The cumuls of the ends of the routes are minimized for this given minimal cumul cost. - Given these minimal end cumuls, the route start cumuls are maximized. Returns the assignment resulting from allocating these packed cumuls with the solver, and nullptr if these cumuls could not be set by the solver.

+
+ + +
+
+
#   + + + def + AddLocalSearchFilter(self, filter: pywrapcp.LocalSearchFilter) -> 'void': +
+ +
+ View Source +
    def AddLocalSearchFilter(self, filter: "LocalSearchFilter") -> "void":
+        r""" Adds a custom local search filter to the list of filters used to speed up local search by pruning unfeasible variable assignments. Calling this method after the routing model has been closed (CloseModel() or Solve() has been called) has no effect. The routing model does not take ownership of the filter."""
+        return _pywrapcp.RoutingModel_AddLocalSearchFilter(self, filter)
+
+ +
+ +

Adds a custom local search filter to the list of filters used to speed up local search by pruning unfeasible variable assignments. Calling this method after the routing model has been closed (CloseModel() or Solve() has been called) has no effect. The routing model does not take ownership of the filter.

+
+ + +
+
+
#   + + + def + Start(self, vehicle: int) -> 'int64_t': +
+ +
+ View Source +
    def Start(self, vehicle: "int") -> "int64_t":
+        r""" Model inspection. Returns the variable index of the starting node of a vehicle route."""
+        return _pywrapcp.RoutingModel_Start(self, vehicle)
+
+ +
+ +

Model inspection. Returns the variable index of the starting node of a vehicle route.

+
+ + +
+
+
#   + + + def + End(self, vehicle: int) -> 'int64_t': +
+ +
+ View Source +
    def End(self, vehicle: "int") -> "int64_t":
+        r""" Returns the variable index of the ending node of a vehicle route."""
+        return _pywrapcp.RoutingModel_End(self, vehicle)
+
+ +
+ +

Returns the variable index of the ending node of a vehicle route.

+
+ + +
+
+
#   + + + def + IsStart(self, index: 'int64_t') -> bool: +
+ +
+ View Source +
    def IsStart(self, index: "int64_t") -> "bool":
+        r""" Returns true if 'index' represents the first node of a route."""
+        return _pywrapcp.RoutingModel_IsStart(self, index)
+
+ +
+ +

Returns true if 'index' represents the first node of a route.

+
+ + +
+
+
#   + + + def + IsEnd(self, index: 'int64_t') -> bool: +
+ +
+ View Source +
    def IsEnd(self, index: "int64_t") -> "bool":
+        r""" Returns true if 'index' represents the last node of a route."""
+        return _pywrapcp.RoutingModel_IsEnd(self, index)
+
+ +
+ +

Returns true if 'index' represents the last node of a route.

+
+ + +
+
+
#   + + + def + VehicleIndex(self, index: 'int64_t') -> int: +
+ +
+ View Source +
    def VehicleIndex(self, index: "int64_t") -> "int":
+        r""" Returns the vehicle of the given start/end index, and -1 if the given index is not a vehicle start/end."""
+        return _pywrapcp.RoutingModel_VehicleIndex(self, index)
+
+ +
+ +

Returns the vehicle of the given start/end index, and -1 if the given index is not a vehicle start/end.

+
+ + +
+
+
#   + + + def + Next(self, assignment: pywrapcp.Assignment, index: 'int64_t') -> 'int64_t': +
+ +
+ View Source +
    def Next(self, assignment: "Assignment", index: "int64_t") -> "int64_t":
+        r""" Assignment inspection Returns the variable index of the node directly after the node corresponding to 'index' in 'assignment'."""
+        return _pywrapcp.RoutingModel_Next(self, assignment, index)
+
+ +
+ +

Assignment inspection Returns the variable index of the node directly after the node corresponding to 'index' in 'assignment'.

+
+ + +
+
+
#   + + + def + IsVehicleUsed(self, assignment: pywrapcp.Assignment, vehicle: int) -> bool: +
+ +
+ View Source +
    def IsVehicleUsed(self, assignment: "Assignment", vehicle: "int") -> "bool":
+        r""" Returns true if the route of 'vehicle' is non empty in 'assignment'."""
+        return _pywrapcp.RoutingModel_IsVehicleUsed(self, assignment, vehicle)
+
+ +
+ +

Returns true if the route of 'vehicle' is non empty in 'assignment'.

+
+ + +
+
+
#   + + + def + NextVar(self, index: 'int64_t') -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def NextVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        r""" Returns the next variable of the node corresponding to index. Note that NextVar(index) == index is equivalent to ActiveVar(index) == 0."""
+        return _pywrapcp.RoutingModel_NextVar(self, index)
+
+ +
+ +

Returns the next variable of the node corresponding to index. Note that NextVar(index) == index is equivalent to ActiveVar(index) == 0.

+
+ + +
+
+
#   + + + def + ActiveVar(self, index: 'int64_t') -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def ActiveVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        r""" Returns the active variable of the node corresponding to index."""
+        return _pywrapcp.RoutingModel_ActiveVar(self, index)
+
+ +
+ +

Returns the active variable of the node corresponding to index.

+
+ + +
+
+
#   + + + def + ActiveVehicleVar(self, vehicle: int) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def ActiveVehicleVar(self, vehicle: "int") -> "operations_research::IntVar *":
+        r""" Returns the active variable of the vehicle. It will be equal to 1 iff the route of the vehicle is not empty, 0 otherwise."""
+        return _pywrapcp.RoutingModel_ActiveVehicleVar(self, vehicle)
+
+ +
+ +

Returns the active variable of the vehicle. It will be equal to 1 iff the route of the vehicle is not empty, 0 otherwise.

+
+ + +
+
+
#   + + + def + VehicleCostsConsideredVar(self, vehicle: int) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def VehicleCostsConsideredVar(self, vehicle: "int") -> "operations_research::IntVar *":
+        r""" Returns the variable specifying whether or not costs are considered for vehicle."""
+        return _pywrapcp.RoutingModel_VehicleCostsConsideredVar(self, vehicle)
+
+ +
+ +

Returns the variable specifying whether or not costs are considered for vehicle.

+
+ + +
+
+
#   + + + def + VehicleVar(self, index: 'int64_t') -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def VehicleVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        r""" Returns the vehicle variable of the node corresponding to index. Note that VehicleVar(index) == -1 is equivalent to ActiveVar(index) == 0."""
+        return _pywrapcp.RoutingModel_VehicleVar(self, index)
+
+ +
+ +

Returns the vehicle variable of the node corresponding to index. Note that VehicleVar(index) == -1 is equivalent to ActiveVar(index) == 0.

+
+ + +
+
+
#   + + + def + CostVar(self) -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def CostVar(self) -> "operations_research::IntVar *":
+        r""" Returns the global cost variable which is being minimized."""
+        return _pywrapcp.RoutingModel_CostVar(self)
+
+ +
+ +

Returns the global cost variable which is being minimized.

+
+ + +
+
+
#   + + + def + GetArcCostForVehicle( + self, + from_index: 'int64_t', + to_index: 'int64_t', + vehicle: 'int64_t' +) -> 'int64_t': +
+ +
+ View Source +
    def GetArcCostForVehicle(self, from_index: "int64_t", to_index: "int64_t", vehicle: "int64_t") -> "int64_t":
+        r""" Returns the cost of the transit arc between two nodes for a given vehicle. Input are variable indices of node. This returns 0 if vehicle < 0."""
+        return _pywrapcp.RoutingModel_GetArcCostForVehicle(self, from_index, to_index, vehicle)
+
+ +
+ +

Returns the cost of the transit arc between two nodes for a given vehicle. Input are variable indices of node. This returns 0 if vehicle < 0.

+
+ + +
+
+
#   + + + def + CostsAreHomogeneousAcrossVehicles(self) -> bool: +
+ +
+ View Source +
    def CostsAreHomogeneousAcrossVehicles(self) -> "bool":
+        r""" Whether costs are homogeneous across all vehicles."""
+        return _pywrapcp.RoutingModel_CostsAreHomogeneousAcrossVehicles(self)
+
+ +
+ +

Whether costs are homogeneous across all vehicles.

+
+ + +
+
+
#   + + + def + GetHomogeneousCost(self, from_index: 'int64_t', to_index: 'int64_t') -> 'int64_t': +
+ +
+ View Source +
    def GetHomogeneousCost(self, from_index: "int64_t", to_index: "int64_t") -> "int64_t":
+        r""" Returns the cost of the segment between two nodes supposing all vehicle costs are the same (returns the cost for the first vehicle otherwise)."""
+        return _pywrapcp.RoutingModel_GetHomogeneousCost(self, from_index, to_index)
+
+ +
+ +

Returns the cost of the segment between two nodes supposing all vehicle costs are the same (returns the cost for the first vehicle otherwise).

+
+ + +
+
+
#   + + + def + GetArcCostForFirstSolution(self, from_index: 'int64_t', to_index: 'int64_t') -> 'int64_t': +
+ +
+ View Source +
    def GetArcCostForFirstSolution(self, from_index: "int64_t", to_index: "int64_t") -> "int64_t":
+        r""" Returns the cost of the arc in the context of the first solution strategy. This is typically a simplification of the actual cost; see the .cc."""
+        return _pywrapcp.RoutingModel_GetArcCostForFirstSolution(self, from_index, to_index)
+
+ +
+ +

Returns the cost of the arc in the context of the first solution strategy. This is typically a simplification of the actual cost; see the .cc.

+
+ + +
+
+
#   + + + def + GetArcCostForClass( + self, + from_index: 'int64_t', + to_index: 'int64_t', + cost_class_index: 'int64_t' +) -> 'int64_t': +
+ +
+ View Source +
    def GetArcCostForClass(self, from_index: "int64_t", to_index: "int64_t", cost_class_index: "int64_t") -> "int64_t":
+        r""" Returns the cost of the segment between two nodes for a given cost class. Input are variable indices of nodes and the cost class. Unlike GetArcCostForVehicle(), if cost_class is kNoCost, then the returned cost won't necessarily be zero: only some of the components of the cost that depend on the cost class will be omited. See the code for details."""
+        return _pywrapcp.RoutingModel_GetArcCostForClass(self, from_index, to_index, cost_class_index)
+
+ +
+ +

Returns the cost of the segment between two nodes for a given cost class. Input are variable indices of nodes and the cost class. Unlike GetArcCostForVehicle(), if cost_class is kNoCost, then the returned cost won't necessarily be zero: only some of the components of the cost that depend on the cost class will be omited. See the code for details.

+
+ + +
+
+
#   + + + def + GetCostClassIndexOfVehicle( + self, + vehicle: 'int64_t' +) -> 'operations_research::RoutingModel::CostClassIndex': +
+ +
+ View Source +
    def GetCostClassIndexOfVehicle(self, vehicle: "int64_t") -> "operations_research::RoutingModel::CostClassIndex":
+        r""" Get the cost class index of the given vehicle."""
+        return _pywrapcp.RoutingModel_GetCostClassIndexOfVehicle(self, vehicle)
+
+ +
+ +

Get the cost class index of the given vehicle.

+
+ + +
+
+
#   + + + def + HasVehicleWithCostClassIndex( + self, + cost_class_index: 'operations_research::RoutingModel::CostClassIndex' +) -> bool: +
+ +
+ View Source +
    def HasVehicleWithCostClassIndex(self, cost_class_index: "operations_research::RoutingModel::CostClassIndex") -> "bool":
+        r""" Returns true iff the model contains a vehicle with the given cost_class_index."""
+        return _pywrapcp.RoutingModel_HasVehicleWithCostClassIndex(self, cost_class_index)
+
+ +
+ +

Returns true iff the model contains a vehicle with the given cost_class_index.

+
+ + +
+
+
#   + + + def + GetCostClassesCount(self) -> int: +
+ +
+ View Source +
    def GetCostClassesCount(self) -> "int":
+        r""" Returns the number of different cost classes in the model."""
+        return _pywrapcp.RoutingModel_GetCostClassesCount(self)
+
+ +
+ +

Returns the number of different cost classes in the model.

+
+ + +
+
+
#   + + + def + GetNonZeroCostClassesCount(self) -> int: +
+ +
+ View Source +
    def GetNonZeroCostClassesCount(self) -> "int":
+        r""" Ditto, minus the 'always zero', built-in cost class."""
+        return _pywrapcp.RoutingModel_GetNonZeroCostClassesCount(self)
+
+ +
+ +

Ditto, minus the 'always zero', built-in cost class.

+
+ + +
+
+
#   + + + def + GetVehicleClassIndexOfVehicle( + self, + vehicle: 'int64_t' +) -> 'operations_research::RoutingModel::VehicleClassIndex': +
+ +
+ View Source +
    def GetVehicleClassIndexOfVehicle(self, vehicle: "int64_t") -> "operations_research::RoutingModel::VehicleClassIndex":
+        return _pywrapcp.RoutingModel_GetVehicleClassIndexOfVehicle(self, vehicle)
+
+ +
+ + + +
+
+
#   + + + def + GetVehicleOfClass( + self, + vehicle_class: 'operations_research::RoutingModel::VehicleClassIndex' +) -> int: +
+ +
+ View Source +
    def GetVehicleOfClass(self, vehicle_class: "operations_research::RoutingModel::VehicleClassIndex") -> "int":
+        r""" Returns a vehicle of the given vehicle class, and -1 if there are no vehicles for this class."""
+        return _pywrapcp.RoutingModel_GetVehicleOfClass(self, vehicle_class)
+
+ +
+ +

Returns a vehicle of the given vehicle class, and -1 if there are no vehicles for this class.

+
+ + +
+
+
#   + + + def + GetVehicleClassesCount(self) -> int: +
+ +
+ View Source +
    def GetVehicleClassesCount(self) -> "int":
+        r""" Returns the number of different vehicle classes in the model."""
+        return _pywrapcp.RoutingModel_GetVehicleClassesCount(self)
+
+ +
+ +

Returns the number of different vehicle classes in the model.

+
+ + +
+
+
#   + + + def + GetSameVehicleIndicesOfIndex(self, node: int) -> 'std::vector< int > const &': +
+ +
+ View Source +
    def GetSameVehicleIndicesOfIndex(self, node: "int") -> "std::vector< int > const &":
+        r""" Returns variable indices of nodes constrained to be on the same route."""
+        return _pywrapcp.RoutingModel_GetSameVehicleIndicesOfIndex(self, node)
+
+ +
+ +

Returns variable indices of nodes constrained to be on the same route.

+
+ + +
+
+
#   + + + def + GetVehicleTypeContainer( + self +) -> 'operations_research::RoutingModel::VehicleTypeContainer const &': +
+ +
+ View Source +
    def GetVehicleTypeContainer(self) -> "operations_research::RoutingModel::VehicleTypeContainer const &":
+        return _pywrapcp.RoutingModel_GetVehicleTypeContainer(self)
+
+ +
+ + + +
+
+
#   + + + def + ArcIsMoreConstrainedThanArc(self, _from: 'int64_t', to1: 'int64_t', to2: 'int64_t') -> bool: +
+ +
+ View Source +
    def ArcIsMoreConstrainedThanArc(self, _from: "int64_t", to1: "int64_t", to2: "int64_t") -> "bool":
+        r""" Returns whether the arc from->to1 is more constrained than from->to2, taking into account, in order: - whether the destination node isn't an end node - whether the destination node is mandatory - whether the destination node is bound to the same vehicle as the source - the "primary constrained" dimension (see SetPrimaryConstrainedDimension) It then breaks ties using, in order: - the arc cost (taking unperformed penalties into account) - the size of the vehicle vars of "to1" and "to2" (lowest size wins) - the value: the lowest value of the indices to1 and to2 wins. See the .cc for details. The more constrained arc is typically preferable when building a first solution. This method is intended to be used as a callback for the BestValueByComparisonSelector value selector. Args:   from: the variable index of the source node   to1: the variable index of the first candidate destination node.   to2: the variable index of the second candidate destination node."""
+        return _pywrapcp.RoutingModel_ArcIsMoreConstrainedThanArc(self, _from, to1, to2)
+
+ +
+ +

Returns whether the arc from->to1 is more constrained than from->to2, taking into account, in order: - whether the destination node isn't an end node - whether the destination node is mandatory - whether the destination node is bound to the same vehicle as the source - the "primary constrained" dimension (see SetPrimaryConstrainedDimension) It then breaks ties using, in order: - the arc cost (taking unperformed penalties into account) - the size of the vehicle vars of "to1" and "to2" (lowest size wins) - the value: the lowest value of the indices to1 and to2 wins. See the .cc for details. The more constrained arc is typically preferable when building a first solution. This method is intended to be used as a callback for the BestValueByComparisonSelector value selector. Args: from: the variable index of the source node to1: the variable index of the first candidate destination node. to2: the variable index of the second candidate destination node.

+
+ + +
+
+
#   + + + def + DebugOutputAssignment( + self, + solution_assignment: pywrapcp.Assignment, + dimension_to_print: 'std::string const &' +) -> 'std::string': +
+ +
+ View Source +
    def DebugOutputAssignment(self, solution_assignment: "Assignment", dimension_to_print: "std::string const &") -> "std::string":
+        r""" Print some debugging information about an assignment, including the feasible intervals of the CumulVar for dimension "dimension_to_print" at each step of the routes. If "dimension_to_print" is omitted, all dimensions will be printed."""
+        return _pywrapcp.RoutingModel_DebugOutputAssignment(self, solution_assignment, dimension_to_print)
+
+ +
+ +

Print some debugging information about an assignment, including the feasible intervals of the CumulVar for dimension "dimension_to_print" at each step of the routes. If "dimension_to_print" is omitted, all dimensions will be printed.

+
+ + +
+
+
#   + + + def + solver(self) -> 'operations_research::Solver *': +
+ +
+ View Source +
    def solver(self) -> "operations_research::Solver *":
+        r""" Returns a vector cumul_bounds, for which cumul_bounds[i][j] is a pair containing the minimum and maximum of the CumulVar of the jth node on route i. - cumul_bounds[i][j].first is the minimum. - cumul_bounds[i][j].second is the maximum. Returns the underlying constraint solver. Can be used to add extra constraints and/or modify search algorithms."""
+        return _pywrapcp.RoutingModel_solver(self)
+
+ +
+ +

Returns a vector cumul_bounds, for which cumul_bounds[i][j] is a pair containing the minimum and maximum of the CumulVar of the jth node on route i. - cumul_bounds[i][j].first is the minimum. - cumul_bounds[i][j].second is the maximum. Returns the underlying constraint solver. Can be used to add extra constraints and/or modify search algorithms.

+
+ + +
+
+
#   + + + def + CheckLimit(self) -> bool: +
+ +
+ View Source +
    def CheckLimit(self) -> "bool":
+        r""" Returns true if the search limit has been crossed."""
+        return _pywrapcp.RoutingModel_CheckLimit(self)
+
+ +
+ +

Returns true if the search limit has been crossed.

+
+ + +
+
+
#   + + + def + RemainingTime(self) -> 'absl::Duration': +
+ +
+ View Source +
    def RemainingTime(self) -> "absl::Duration":
+        r""" Returns the time left in the search limit."""
+        return _pywrapcp.RoutingModel_RemainingTime(self)
+
+ +
+ +

Returns the time left in the search limit.

+
+ + +
+
+
#   + + + def + nodes(self) -> int: +
+ +
+ View Source +
    def nodes(self) -> "int":
+        r""" Sizes and indices Returns the number of nodes in the model."""
+        return _pywrapcp.RoutingModel_nodes(self)
+
+ +
+ +

Sizes and indices Returns the number of nodes in the model.

+
+ + +
+
+
#   + + + def + vehicles(self) -> int: +
+ +
+ View Source +
    def vehicles(self) -> "int":
+        r""" Returns the number of vehicle routes in the model."""
+        return _pywrapcp.RoutingModel_vehicles(self)
+
+ +
+ +

Returns the number of vehicle routes in the model.

+
+ + +
+
+
#   + + + def + Size(self) -> 'int64_t': +
+ +
+ View Source +
    def Size(self) -> "int64_t":
+        r""" Returns the number of next variables in the model."""
+        return _pywrapcp.RoutingModel_Size(self)
+
+ +
+ +

Returns the number of next variables in the model.

+
+ + +
+
+
#   + + + def + GetNumberOfDecisionsInFirstSolution( + self, + search_parameters: 'operations_research::RoutingSearchParameters const &' +) -> 'int64_t': +
+ +
+ View Source +
    def GetNumberOfDecisionsInFirstSolution(self, search_parameters: "operations_research::RoutingSearchParameters const &") -> "int64_t":
+        r""" Returns statistics on first solution search, number of decisions sent to filters, number of decisions rejected by filters."""
+        return _pywrapcp.RoutingModel_GetNumberOfDecisionsInFirstSolution(self, search_parameters)
+
+ +
+ +

Returns statistics on first solution search, number of decisions sent to filters, number of decisions rejected by filters.

+
+ + +
+
+
#   + + + def + GetNumberOfRejectsInFirstSolution( + self, + search_parameters: 'operations_research::RoutingSearchParameters const &' +) -> 'int64_t': +
+ +
+ View Source +
    def GetNumberOfRejectsInFirstSolution(self, search_parameters: "operations_research::RoutingSearchParameters const &") -> "int64_t":
+        return _pywrapcp.RoutingModel_GetNumberOfRejectsInFirstSolution(self, search_parameters)
+
+ +
+ + + +
+
+
#   + + + def + GetAutomaticFirstSolutionStrategy(self) -> 'operations_research::FirstSolutionStrategy::Value': +
+ +
+ View Source +
    def GetAutomaticFirstSolutionStrategy(self) -> "operations_research::FirstSolutionStrategy::Value":
+        r""" Returns the automatic first solution strategy selected."""
+        return _pywrapcp.RoutingModel_GetAutomaticFirstSolutionStrategy(self)
+
+ +
+ +

Returns the automatic first solution strategy selected.

+
+ + +
+
+
#   + + + def + IsMatchingModel(self) -> bool: +
+ +
+ View Source +
    def IsMatchingModel(self) -> "bool":
+        r""" Returns true if a vehicle/node matching problem is detected."""
+        return _pywrapcp.RoutingModel_IsMatchingModel(self)
+
+ +
+ +

Returns true if a vehicle/node matching problem is detected.

+
+ + +
+
+
#   + + + def + MakeGuidedSlackFinalizer( + self, + dimension: pywrapcp.RoutingDimension, + initializer: 'std::function< int64_t (int64_t) >' +) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def MakeGuidedSlackFinalizer(self, dimension: "RoutingDimension", initializer: "std::function< int64_t (int64_t) >") -> "operations_research::DecisionBuilder *":
+        r""" The next few members are in the public section only for testing purposes. MakeGuidedSlackFinalizer creates a DecisionBuilder for the slacks of a dimension using a callback to choose which values to start with. The finalizer works only when all next variables in the model have been fixed. It has the following two characteristics: 1. It follows the routes defined by the nexts variables when choosing a    variable to make a decision on. 2. When it comes to choose a value for the slack of node i, the decision    builder first calls the callback with argument i, and supposingly the    returned value is x it creates decisions slack[i] = x, slack[i] = x +    1, slack[i] = x - 1, slack[i] = x + 2, etc."""
+        return _pywrapcp.RoutingModel_MakeGuidedSlackFinalizer(self, dimension, initializer)
+
+ +
+ +

The next few members are in the public section only for testing purposes. MakeGuidedSlackFinalizer creates a DecisionBuilder for the slacks of a dimension using a callback to choose which values to start with. The finalizer works only when all next variables in the model have been fixed. It has the following two characteristics: 1. It follows the routes defined by the nexts variables when choosing a variable to make a decision on. 2. When it comes to choose a value for the slack of node i, the decision builder first calls the callback with argument i, and supposingly the returned value is x it creates decisions slack[i] = x, slack[i] = x + 1, slack[i] = x - 1, slack[i] = x + 2, etc.

+
+ + +
+
+
#   + + + def + MakeSelfDependentDimensionFinalizer( + self, + dimension: pywrapcp.RoutingDimension +) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
    def MakeSelfDependentDimensionFinalizer(self, dimension: "RoutingDimension") -> "operations_research::DecisionBuilder *":
+        r""" MakeSelfDependentDimensionFinalizer is a finalizer for the slacks of a self-dependent dimension. It makes an extensive use of the caches of the state dependent transits. In detail, MakeSelfDependentDimensionFinalizer returns a composition of a local search decision builder with a greedy descent operator for the cumul of the start of each route and a guided slack finalizer. Provided there are no time windows and the maximum slacks are large enough, once the cumul of the start of route is fixed, the guided finalizer can find optimal values of the slacks for the rest of the route in time proportional to the length of the route. Therefore the composed finalizer generally works in time O(log(t)*n*m), where t is the latest possible departute time, n is the number of nodes in the network and m is the number of vehicles."""
+        return _pywrapcp.RoutingModel_MakeSelfDependentDimensionFinalizer(self, dimension)
+
+ +
+ +

MakeSelfDependentDimensionFinalizer is a finalizer for the slacks of a self-dependent dimension. It makes an extensive use of the caches of the state dependent transits. In detail, MakeSelfDependentDimensionFinalizer returns a composition of a local search decision builder with a greedy descent operator for the cumul of the start of each route and a guided slack finalizer. Provided there are no time windows and the maximum slacks are large enough, once the cumul of the start of route is fixed, the guided finalizer can find optimal values of the slacks for the rest of the route in time proportional to the length of the route. Therefore the composed finalizer generally works in time O(log(t)nm), where t is the latest possible departute time, n is the number of nodes in the network and m is the number of vehicles.

+
+ + +
+
+
#   + + kNoPenalty = -1 +
+ + + +
+
+
#   + + kNoDisjunction = <Swig Object of type 'operations_research::RoutingModel::DisjunctionIndex *'> +
+ + + +
+
+
#   + + kNoDimension = <Swig Object of type 'operations_research::RoutingModel::DimensionIndex *'> +
+ + + +
+
+
+
+ #   + + + class + RoutingModelVisitor(BaseObject): +
+ +
+ View Source +
class RoutingModelVisitor(BaseObject):
+    r""" Routing model visitor."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self):
+        _pywrapcp.RoutingModelVisitor_swiginit(self, _pywrapcp.new_RoutingModelVisitor())
+    __swig_destroy__ = _pywrapcp.delete_RoutingModelVisitor
+
+ +
+ +

Routing model visitor.

+
+ + +
+
#   + + + RoutingModelVisitor() +
+ +
+ View Source +
    def __init__(self):
+        _pywrapcp.RoutingModelVisitor_swiginit(self, _pywrapcp.new_RoutingModelVisitor())
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + kLightElement = 'LightElement' +
+ + + +
+
+
#   + + kLightElement2 = 'LightElement2' +
+ + + +
+
+
#   + + kRemoveValues = 'RemoveValues' +
+ + + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ #   + + + class + GlobalVehicleBreaksConstraint(Constraint): +
+ +
+ View Source +
class GlobalVehicleBreaksConstraint(Constraint):
+    r""" GlobalVehicleBreaksConstraint ensures breaks constraints are enforced on all vehicles in the dimension passed to its constructor. It is intended to be used for dimensions representing time. A break constraint ensures break intervals fit on the route of a vehicle. For a given vehicle, it forces break intervals to be disjoint from visit intervals, where visit intervals start at CumulVar(node) and last for node_visit_transit[node]. Moreover, it ensures that there is enough time between two consecutive nodes of a route to do transit and vehicle breaks, i.e. if Next(nodeA) = nodeB, CumulVar(nodeA) = tA and CumulVar(nodeB) = tB, then SlackVar(nodeA) >= sum_{breaks [tA, tB)} duration(break)."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, dimension: "RoutingDimension"):
+        _pywrapcp.GlobalVehicleBreaksConstraint_swiginit(self, _pywrapcp.new_GlobalVehicleBreaksConstraint(dimension))
+
+    def DebugString(self) -> "std::string":
+        return _pywrapcp.GlobalVehicleBreaksConstraint_DebugString(self)
+
+    def Post(self) -> "void":
+        return _pywrapcp.GlobalVehicleBreaksConstraint_Post(self)
+
+    def InitialPropagateWrapper(self) -> "void":
+        return _pywrapcp.GlobalVehicleBreaksConstraint_InitialPropagateWrapper(self)
+    __swig_destroy__ = _pywrapcp.delete_GlobalVehicleBreaksConstraint
+
+ +
+ +

GlobalVehicleBreaksConstraint ensures breaks constraints are enforced on all vehicles in the dimension passed to its constructor. It is intended to be used for dimensions representing time. A break constraint ensures break intervals fit on the route of a vehicle. For a given vehicle, it forces break intervals to be disjoint from visit intervals, where visit intervals start at CumulVar(node) and last for node_visit_transit[node]. Moreover, it ensures that there is enough time between two consecutive nodes of a route to do transit and vehicle breaks, i.e. if Next(nodeA) = nodeB, CumulVar(nodeA) = tA and CumulVar(nodeB) = tB, then SlackVar(nodeA) >= sum_{breaks [tA, tB)} duration(break).

+
+ + +
+
#   + + + GlobalVehicleBreaksConstraint(dimension: pywrapcp.RoutingDimension) +
+ +
+ View Source +
    def __init__(self, dimension: "RoutingDimension"):
+        _pywrapcp.GlobalVehicleBreaksConstraint_swiginit(self, _pywrapcp.new_GlobalVehicleBreaksConstraint(dimension))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + DebugString(self) -> 'std::string': +
+ +
+ View Source +
    def DebugString(self) -> "std::string":
+        return _pywrapcp.GlobalVehicleBreaksConstraint_DebugString(self)
+
+ +
+ + + +
+
+
#   + + + def + Post(self) -> 'void': +
+ +
+ View Source +
    def Post(self) -> "void":
+        return _pywrapcp.GlobalVehicleBreaksConstraint_Post(self)
+
+ +
+ +

This method is called when the constraint is processed by the solver. Its main usage is to attach demons to variables.

+
+ + +
+
+
#   + + + def + InitialPropagateWrapper(self) -> 'void': +
+ +
+ View Source +
    def InitialPropagateWrapper(self) -> "void":
+        return _pywrapcp.GlobalVehicleBreaksConstraint_InitialPropagateWrapper(self)
+
+ +
+ +

This method performs the initial propagation of the constraint. It is called just after the post.

+
+ + +
+
+
Inherited Members
+
+ + +
+
+
+
+
+ #   + + + class + TypeRegulationsChecker: +
+ +
+ View Source +
class TypeRegulationsChecker(object):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+    __swig_destroy__ = _pywrapcp.delete_TypeRegulationsChecker
+
+    def CheckVehicle(self, vehicle: "int", next_accessor: "std::function< int64_t (int64_t) > const &") -> "bool":
+        return _pywrapcp.TypeRegulationsChecker_CheckVehicle(self, vehicle, next_accessor)
+
+ +
+ + + +
+
#   + + + TypeRegulationsChecker(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + CheckVehicle( + self, + vehicle: int, + next_accessor: 'std::function< int64_t (int64_t) > const &' +) -> bool: +
+ +
+ View Source +
    def CheckVehicle(self, vehicle: "int", next_accessor: "std::function< int64_t (int64_t) > const &") -> "bool":
+        return _pywrapcp.TypeRegulationsChecker_CheckVehicle(self, vehicle, next_accessor)
+
+ +
+ + + +
+
+
+
+ #   + + + class + TypeIncompatibilityChecker(TypeRegulationsChecker): +
+ +
+ View Source +
class TypeIncompatibilityChecker(TypeRegulationsChecker):
+    r""" Checker for type incompatibilities."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, model: "RoutingModel", check_hard_incompatibilities: "bool"):
+        _pywrapcp.TypeIncompatibilityChecker_swiginit(self, _pywrapcp.new_TypeIncompatibilityChecker(model, check_hard_incompatibilities))
+    __swig_destroy__ = _pywrapcp.delete_TypeIncompatibilityChecker
+
+ +
+ +

Checker for type incompatibilities.

+
+ + +
+
#   + + + TypeIncompatibilityChecker(model: pywrapcp.RoutingModel, check_hard_incompatibilities: bool) +
+ +
+ View Source +
    def __init__(self, model: "RoutingModel", check_hard_incompatibilities: "bool"):
+        _pywrapcp.TypeIncompatibilityChecker_swiginit(self, _pywrapcp.new_TypeIncompatibilityChecker(model, check_hard_incompatibilities))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ #   + + + class + TypeRequirementChecker(TypeRegulationsChecker): +
+ +
+ View Source +
class TypeRequirementChecker(TypeRegulationsChecker):
+    r""" Checker for type requirements."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, model: "RoutingModel"):
+        _pywrapcp.TypeRequirementChecker_swiginit(self, _pywrapcp.new_TypeRequirementChecker(model))
+    __swig_destroy__ = _pywrapcp.delete_TypeRequirementChecker
+
+ +
+ +

Checker for type requirements.

+
+ + +
+
#   + + + TypeRequirementChecker(model: pywrapcp.RoutingModel) +
+ +
+ View Source +
    def __init__(self, model: "RoutingModel"):
+        _pywrapcp.TypeRequirementChecker_swiginit(self, _pywrapcp.new_TypeRequirementChecker(model))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ #   + + + class + TypeRegulationsConstraint(Constraint): +
+ +
+ View Source +
class TypeRegulationsConstraint(Constraint):
+    r""" The following constraint ensures that incompatibilities and requirements between types are respected. It verifies both "hard" and "temporal" incompatibilities. Two nodes with hard incompatible types cannot be served by the same vehicle at all, while with a temporal incompatibility they can't be on the same route at the same time. The VisitTypePolicy of a node determines how visiting it impacts the type count on the route. For example, for - three temporally incompatible types T1 T2 and T3 - 2 pairs of nodes a1/r1 and a2/r2 of type T1 and T2 respectively, with     - a1 and a2 of VisitTypePolicy TYPE_ADDED_TO_VEHICLE     - r1 and r2 of policy ADDED_TYPE_REMOVED_FROM_VEHICLE - 3 nodes A, UV and AR of type T3, respectively with type policies   TYPE_ADDED_TO_VEHICLE, TYPE_ON_VEHICLE_UP_TO_VISIT and   TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED the configurations UV --> a1 --> r1 --> a2 --> r2,   a1 --> r1 --> a2 --> r2 --> A and a1 --> r1 --> AR --> a2 --> r2 are acceptable, whereas the configurations a1 --> a2 --> r1 --> ..., or A --> a1 --> r1 --> ..., or a1 --> r1 --> UV --> ... are not feasible. It also verifies same-vehicle and temporal type requirements. A node of type T_d with a same-vehicle requirement for type T_r needs to be served by the same vehicle as a node of type T_r. Temporal requirements, on the other hand, can take effect either when the dependent type is being added to the route or when it's removed from it, which is determined by the dependent node's VisitTypePolicy. In the above example: - If T3 is required on the same vehicle as T1, A, AR or UV must be on the   same vehicle as a1. - If T2 is required when adding T1, a2 must be visited *before* a1, and if   r2 is also visited on the route, it must be *after* a1, i.e. T2 must be on   the vehicle when a1 is visited:   ... --> a2 --> ... --> a1 --> ... --> r2 --> ... - If T3 is required when removing T1, T3 needs to be on the vehicle when   r1 is visited:   ... --> A --> ... --> r1 --> ...   OR   ... --> r1 --> ... --> UV --> ..."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, model: "RoutingModel"):
+        _pywrapcp.TypeRegulationsConstraint_swiginit(self, _pywrapcp.new_TypeRegulationsConstraint(model))
+
+    def Post(self) -> "void":
+        return _pywrapcp.TypeRegulationsConstraint_Post(self)
+
+    def InitialPropagateWrapper(self) -> "void":
+        return _pywrapcp.TypeRegulationsConstraint_InitialPropagateWrapper(self)
+    __swig_destroy__ = _pywrapcp.delete_TypeRegulationsConstraint
+
+ +
+ +

The following constraint ensures that incompatibilities and requirements between types are respected. It verifies both "hard" and "temporal" incompatibilities. Two nodes with hard incompatible types cannot be served by the same vehicle at all, while with a temporal incompatibility they can't be on the same route at the same time. The VisitTypePolicy of a node determines how visiting it impacts the type count on the route. For example, for - three temporally incompatible types T1 T2 and T3 - 2 pairs of nodes a1/r1 and a2/r2 of type T1 and T2 respectively, with - a1 and a2 of VisitTypePolicy TYPE_ADDED_TO_VEHICLE - r1 and r2 of policy ADDED_TYPE_REMOVED_FROM_VEHICLE - 3 nodes A, UV and AR of type T3, respectively with type policies TYPE_ADDED_TO_VEHICLE, TYPE_ON_VEHICLE_UP_TO_VISIT and TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED the configurations UV --> a1 --> r1 --> a2 --> r2, a1 --> r1 --> a2 --> r2 --> A and a1 --> r1 --> AR --> a2 --> r2 are acceptable, whereas the configurations a1 --> a2 --> r1 --> ..., or A --> a1 --> r1 --> ..., or a1 --> r1 --> UV --> ... are not feasible. It also verifies same-vehicle and temporal type requirements. A node of type T_d with a same-vehicle requirement for type T_r needs to be served by the same vehicle as a node of type T_r. Temporal requirements, on the other hand, can take effect either when the dependent type is being added to the route or when it's removed from it, which is determined by the dependent node's VisitTypePolicy. In the above example: - If T3 is required on the same vehicle as T1, A, AR or UV must be on the same vehicle as a1. - If T2 is required when adding T1, a2 must be visited before a1, and if r2 is also visited on the route, it must be after a1, i.e. T2 must be on the vehicle when a1 is visited: ... --> a2 --> ... --> a1 --> ... --> r2 --> ... - If T3 is required when removing T1, T3 needs to be on the vehicle when r1 is visited: ... --> A --> ... --> r1 --> ... OR ... --> r1 --> ... --> UV --> ...

+
+ + +
+
#   + + + TypeRegulationsConstraint(model: pywrapcp.RoutingModel) +
+ +
+ View Source +
    def __init__(self, model: "RoutingModel"):
+        _pywrapcp.TypeRegulationsConstraint_swiginit(self, _pywrapcp.new_TypeRegulationsConstraint(model))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Post(self) -> 'void': +
+ +
+ View Source +
    def Post(self) -> "void":
+        return _pywrapcp.TypeRegulationsConstraint_Post(self)
+
+ +
+ +

This method is called when the constraint is processed by the solver. Its main usage is to attach demons to variables.

+
+ + +
+
+
#   + + + def + InitialPropagateWrapper(self) -> 'void': +
+ +
+ View Source +
    def InitialPropagateWrapper(self) -> "void":
+        return _pywrapcp.TypeRegulationsConstraint_InitialPropagateWrapper(self)
+
+ +
+ +

This method performs the initial propagation of the constraint. It is called just after the post.

+
+ + +
+
+
Inherited Members
+
+ + +
+
+
+
+
+ #   + + + class + RoutingDimension: +
+ +
+ View Source +
class RoutingDimension(object):
+    r""" Dimensions represent quantities accumulated at nodes along the routes. They represent quantities such as weights or volumes carried along the route, or distance or times. Quantities at a node are represented by "cumul" variables and the increase or decrease of quantities between nodes are represented by "transit" variables. These variables are linked as follows: if j == next(i), cumuls(j) = cumuls(i) + transits(i) + slacks(i) +             state_dependent_transits(i) where slack is a positive slack variable (can represent waiting times for a time dimension), and state_dependent_transits is a non-purely functional version of transits_. Favour transits over state_dependent_transits when possible, because purely functional callbacks allow more optimisations and make the model faster and easier to solve. for a given vehicle, it is passed as an external vector, it would be better to have this information here."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+    __swig_destroy__ = _pywrapcp.delete_RoutingDimension
+
+    def model(self) -> "operations_research::RoutingModel *":
+        r""" Returns the model on which the dimension was created."""
+        return _pywrapcp.RoutingDimension_model(self)
+
+    def GetTransitValue(self, from_index: "int64_t", to_index: "int64_t", vehicle: "int64_t") -> "int64_t":
+        r""" Returns the transition value for a given pair of nodes (as var index); this value is the one taken by the corresponding transit variable when the 'next' variable for 'from_index' is bound to 'to_index'."""
+        return _pywrapcp.RoutingDimension_GetTransitValue(self, from_index, to_index, vehicle)
+
+    def GetTransitValueFromClass(self, from_index: "int64_t", to_index: "int64_t", vehicle_class: "int64_t") -> "int64_t":
+        r""" Same as above but taking a vehicle class of the dimension instead of a vehicle (the class of a vehicle can be obtained with vehicle_to_class())."""
+        return _pywrapcp.RoutingDimension_GetTransitValueFromClass(self, from_index, to_index, vehicle_class)
+
+    def CumulVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        r""" Get the cumul, transit and slack variables for the given node (given as int64_t var index)."""
+        return _pywrapcp.RoutingDimension_CumulVar(self, index)
+
+    def TransitVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        return _pywrapcp.RoutingDimension_TransitVar(self, index)
+
+    def FixedTransitVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        return _pywrapcp.RoutingDimension_FixedTransitVar(self, index)
+
+    def SlackVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        return _pywrapcp.RoutingDimension_SlackVar(self, index)
+
+    def SetSpanUpperBoundForVehicle(self, upper_bound: "int64_t", vehicle: "int") -> "void":
+        r""" Sets an upper bound on the dimension span on a given vehicle. This is the preferred way to limit the "length" of the route of a vehicle according to a dimension."""
+        return _pywrapcp.RoutingDimension_SetSpanUpperBoundForVehicle(self, upper_bound, vehicle)
+
+    def SetSpanCostCoefficientForVehicle(self, coefficient: "int64_t", vehicle: "int") -> "void":
+        r""" Sets a cost proportional to the dimension span on a given vehicle, or on all vehicles at once. "coefficient" must be nonnegative. This is handy to model costs proportional to idle time when the dimension represents time. The cost for a vehicle is   span_cost = coefficient * (dimension end value - dimension start value)."""
+        return _pywrapcp.RoutingDimension_SetSpanCostCoefficientForVehicle(self, coefficient, vehicle)
+
+    def SetSpanCostCoefficientForAllVehicles(self, coefficient: "int64_t") -> "void":
+        return _pywrapcp.RoutingDimension_SetSpanCostCoefficientForAllVehicles(self, coefficient)
+
+    def SetGlobalSpanCostCoefficient(self, coefficient: "int64_t") -> "void":
+        r""" Sets a cost proportional to the *global* dimension span, that is the difference between the largest value of route end cumul variables and the smallest value of route start cumul variables. In other words: global_span_cost =   coefficient * (Max(dimension end value) - Min(dimension start value))."""
+        return _pywrapcp.RoutingDimension_SetGlobalSpanCostCoefficient(self, coefficient)
+
+    def SetCumulVarSoftUpperBound(self, index: "int64_t", upper_bound: "int64_t", coefficient: "int64_t") -> "void":
+        r""" Sets a soft upper bound to the cumul variable of a given variable index. If the value of the cumul variable is greater than the bound, a cost proportional to the difference between this value and the bound is added to the cost function of the model:   cumulVar <= upper_bound -> cost = 0    cumulVar > upper_bound -> cost = coefficient * (cumulVar - upper_bound) This is also handy to model tardiness costs when the dimension represents time."""
+        return _pywrapcp.RoutingDimension_SetCumulVarSoftUpperBound(self, index, upper_bound, coefficient)
+
+    def HasCumulVarSoftUpperBound(self, index: "int64_t") -> "bool":
+        r""" Returns true if a soft upper bound has been set for a given variable index."""
+        return _pywrapcp.RoutingDimension_HasCumulVarSoftUpperBound(self, index)
+
+    def GetCumulVarSoftUpperBound(self, index: "int64_t") -> "int64_t":
+        r""" Returns the soft upper bound of a cumul variable for a given variable index. The "hard" upper bound of the variable is returned if no soft upper bound has been set."""
+        return _pywrapcp.RoutingDimension_GetCumulVarSoftUpperBound(self, index)
+
+    def GetCumulVarSoftUpperBoundCoefficient(self, index: "int64_t") -> "int64_t":
+        r""" Returns the cost coefficient of the soft upper bound of a cumul variable for a given variable index. If no soft upper bound has been set, 0 is returned."""
+        return _pywrapcp.RoutingDimension_GetCumulVarSoftUpperBoundCoefficient(self, index)
+
+    def SetCumulVarSoftLowerBound(self, index: "int64_t", lower_bound: "int64_t", coefficient: "int64_t") -> "void":
+        r""" Sets a soft lower bound to the cumul variable of a given variable index. If the value of the cumul variable is less than the bound, a cost proportional to the difference between this value and the bound is added to the cost function of the model:   cumulVar > lower_bound -> cost = 0   cumulVar <= lower_bound -> cost = coefficient * (lower_bound -               cumulVar). This is also handy to model earliness costs when the dimension represents time."""
+        return _pywrapcp.RoutingDimension_SetCumulVarSoftLowerBound(self, index, lower_bound, coefficient)
+
+    def HasCumulVarSoftLowerBound(self, index: "int64_t") -> "bool":
+        r""" Returns true if a soft lower bound has been set for a given variable index."""
+        return _pywrapcp.RoutingDimension_HasCumulVarSoftLowerBound(self, index)
+
+    def GetCumulVarSoftLowerBound(self, index: "int64_t") -> "int64_t":
+        r""" Returns the soft lower bound of a cumul variable for a given variable index. The "hard" lower bound of the variable is returned if no soft lower bound has been set."""
+        return _pywrapcp.RoutingDimension_GetCumulVarSoftLowerBound(self, index)
+
+    def GetCumulVarSoftLowerBoundCoefficient(self, index: "int64_t") -> "int64_t":
+        r""" Returns the cost coefficient of the soft lower bound of a cumul variable for a given variable index. If no soft lower bound has been set, 0 is returned."""
+        return _pywrapcp.RoutingDimension_GetCumulVarSoftLowerBoundCoefficient(self, index)
+
+    def SetBreakIntervalsOfVehicle(self, breaks: "std::vector< operations_research::IntervalVar * >", vehicle: "int", node_visit_transits: "std::vector< int64_t >") -> "void":
+        r""" Sets the breaks for a given vehicle. Breaks are represented by IntervalVars. They may interrupt transits between nodes and increase the value of corresponding slack variables. A break may take place before the start of a vehicle, after the end of a vehicle, or during a travel i -> j. In that case, the interval [break.Start(), break.End()) must be a subset of [CumulVar(i) + pre_travel(i, j), CumulVar(j) - post_travel(i, j)). In other words, a break may not overlap any node n's visit, given by [CumulVar(n) - post_travel(_, n), CumulVar(n) + pre_travel(n, _)). This formula considers post_travel(_, start) and pre_travel(end, _) to be 0; pre_travel will never be called on any (_, start) and post_travel will never we called on any (end, _). If pre_travel_evaluator or post_travel_evaluator is -1, it will be taken as a function that always returns 0. Deprecated, sets pre_travel(i, j) = node_visit_transit[i]."""
+        return _pywrapcp.RoutingDimension_SetBreakIntervalsOfVehicle(self, breaks, vehicle, node_visit_transits)
+
+    def SetBreakDistanceDurationOfVehicle(self, distance: "int64_t", duration: "int64_t", vehicle: "int") -> "void":
+        r""" With breaks supposed to be consecutive, this forces the distance between breaks of size at least minimum_break_duration to be at most distance. This supposes that the time until route start and after route end are infinite breaks."""
+        return _pywrapcp.RoutingDimension_SetBreakDistanceDurationOfVehicle(self, distance, duration, vehicle)
+
+    def InitializeBreaks(self) -> "void":
+        r""" Sets up vehicle_break_intervals_, vehicle_break_distance_duration_, pre_travel_evaluators and post_travel_evaluators."""
+        return _pywrapcp.RoutingDimension_InitializeBreaks(self)
+
+    def HasBreakConstraints(self) -> "bool":
+        r""" Returns true if any break interval or break distance was defined."""
+        return _pywrapcp.RoutingDimension_HasBreakConstraints(self)
+
+    def GetPreTravelEvaluatorOfVehicle(self, vehicle: "int") -> "int":
+        return _pywrapcp.RoutingDimension_GetPreTravelEvaluatorOfVehicle(self, vehicle)
+
+    def GetPostTravelEvaluatorOfVehicle(self, vehicle: "int") -> "int":
+        return _pywrapcp.RoutingDimension_GetPostTravelEvaluatorOfVehicle(self, vehicle)
+
+    def base_dimension(self) -> "operations_research::RoutingDimension const *":
+        r""" Returns the parent in the dependency tree if any or nullptr otherwise."""
+        return _pywrapcp.RoutingDimension_base_dimension(self)
+
+    def ShortestTransitionSlack(self, node: "int64_t") -> "int64_t":
+        r""" It makes sense to use the function only for self-dependent dimension. For such dimensions the value of the slack of a node determines the transition cost of the next transit. Provided that   1. cumul[node] is fixed,   2. next[node] and next[next[node]] (if exists) are fixed, the value of slack[node] for which cumul[next[node]] + transit[next[node]] is minimized can be found in O(1) using this function."""
+        return _pywrapcp.RoutingDimension_ShortestTransitionSlack(self, node)
+
+    def name(self) -> "std::string const &":
+        r""" Returns the name of the dimension."""
+        return _pywrapcp.RoutingDimension_name(self)
+
+    def SetPickupToDeliveryLimitFunctionForPair(self, limit_function: "operations_research::RoutingDimension::PickupToDeliveryLimitFunction", pair_index: "int") -> "void":
+        return _pywrapcp.RoutingDimension_SetPickupToDeliveryLimitFunctionForPair(self, limit_function, pair_index)
+
+    def HasPickupToDeliveryLimits(self) -> "bool":
+        return _pywrapcp.RoutingDimension_HasPickupToDeliveryLimits(self)
+
+    def AddNodePrecedence(self, first_node: "int64_t", second_node: "int64_t", offset: "int64_t") -> "void":
+        return _pywrapcp.RoutingDimension_AddNodePrecedence(self, first_node, second_node, offset)
+
+    def GetSpanUpperBoundForVehicle(self, vehicle: "int") -> "int64_t":
+        return _pywrapcp.RoutingDimension_GetSpanUpperBoundForVehicle(self, vehicle)
+
+    def GetSpanCostCoefficientForVehicle(self, vehicle: "int") -> "int64_t":
+        return _pywrapcp.RoutingDimension_GetSpanCostCoefficientForVehicle(self, vehicle)
+
+    def global_span_cost_coefficient(self) -> "int64_t":
+        return _pywrapcp.RoutingDimension_global_span_cost_coefficient(self)
+
+    def GetGlobalOptimizerOffset(self) -> "int64_t":
+        return _pywrapcp.RoutingDimension_GetGlobalOptimizerOffset(self)
+
+    def GetLocalOptimizerOffsetForVehicle(self, vehicle: "int") -> "int64_t":
+        return _pywrapcp.RoutingDimension_GetLocalOptimizerOffsetForVehicle(self, vehicle)
+
+ +
+ +

Dimensions represent quantities accumulated at nodes along the routes. They represent quantities such as weights or volumes carried along the route, or distance or times. Quantities at a node are represented by "cumul" variables and the increase or decrease of quantities between nodes are represented by "transit" variables. These variables are linked as follows: if j == next(i), cumuls(j) = cumuls(i) + transits(i) + slacks(i) + state_dependent_transits(i) where slack is a positive slack variable (can represent waiting times for a time dimension), and state_dependent_transits is a non-purely functional version of transits_. Favour transits over state_dependent_transits when possible, because purely functional callbacks allow more optimisations and make the model faster and easier to solve. for a given vehicle, it is passed as an external vector, it would be better to have this information here.

+
+ + +
+
#   + + + RoutingDimension(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + model(self) -> 'operations_research::RoutingModel *': +
+ +
+ View Source +
    def model(self) -> "operations_research::RoutingModel *":
+        r""" Returns the model on which the dimension was created."""
+        return _pywrapcp.RoutingDimension_model(self)
+
+ +
+ +

Returns the model on which the dimension was created.

+
+ + +
+
+
#   + + + def + GetTransitValue( + self, + from_index: 'int64_t', + to_index: 'int64_t', + vehicle: 'int64_t' +) -> 'int64_t': +
+ +
+ View Source +
    def GetTransitValue(self, from_index: "int64_t", to_index: "int64_t", vehicle: "int64_t") -> "int64_t":
+        r""" Returns the transition value for a given pair of nodes (as var index); this value is the one taken by the corresponding transit variable when the 'next' variable for 'from_index' is bound to 'to_index'."""
+        return _pywrapcp.RoutingDimension_GetTransitValue(self, from_index, to_index, vehicle)
+
+ +
+ +

Returns the transition value for a given pair of nodes (as var index); this value is the one taken by the corresponding transit variable when the 'next' variable for 'from_index' is bound to 'to_index'.

+
+ + +
+
+
#   + + + def + GetTransitValueFromClass( + self, + from_index: 'int64_t', + to_index: 'int64_t', + vehicle_class: 'int64_t' +) -> 'int64_t': +
+ +
+ View Source +
    def GetTransitValueFromClass(self, from_index: "int64_t", to_index: "int64_t", vehicle_class: "int64_t") -> "int64_t":
+        r""" Same as above but taking a vehicle class of the dimension instead of a vehicle (the class of a vehicle can be obtained with vehicle_to_class())."""
+        return _pywrapcp.RoutingDimension_GetTransitValueFromClass(self, from_index, to_index, vehicle_class)
+
+ +
+ +

Same as above but taking a vehicle class of the dimension instead of a vehicle (the class of a vehicle can be obtained with vehicle_to_class()).

+
+ + +
+
+
#   + + + def + CumulVar(self, index: 'int64_t') -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def CumulVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        r""" Get the cumul, transit and slack variables for the given node (given as int64_t var index)."""
+        return _pywrapcp.RoutingDimension_CumulVar(self, index)
+
+ +
+ +

Get the cumul, transit and slack variables for the given node (given as int64_t var index).

+
+ + +
+
+
#   + + + def + TransitVar(self, index: 'int64_t') -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def TransitVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        return _pywrapcp.RoutingDimension_TransitVar(self, index)
+
+ +
+ + + +
+
+
#   + + + def + FixedTransitVar(self, index: 'int64_t') -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def FixedTransitVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        return _pywrapcp.RoutingDimension_FixedTransitVar(self, index)
+
+ +
+ + + +
+
+
#   + + + def + SlackVar(self, index: 'int64_t') -> 'operations_research::IntVar *': +
+ +
+ View Source +
    def SlackVar(self, index: "int64_t") -> "operations_research::IntVar *":
+        return _pywrapcp.RoutingDimension_SlackVar(self, index)
+
+ +
+ + + +
+
+
#   + + + def + SetSpanUpperBoundForVehicle(self, upper_bound: 'int64_t', vehicle: int) -> 'void': +
+ +
+ View Source +
    def SetSpanUpperBoundForVehicle(self, upper_bound: "int64_t", vehicle: "int") -> "void":
+        r""" Sets an upper bound on the dimension span on a given vehicle. This is the preferred way to limit the "length" of the route of a vehicle according to a dimension."""
+        return _pywrapcp.RoutingDimension_SetSpanUpperBoundForVehicle(self, upper_bound, vehicle)
+
+ +
+ +

Sets an upper bound on the dimension span on a given vehicle. This is the preferred way to limit the "length" of the route of a vehicle according to a dimension.

+
+ + +
+
+
#   + + + def + SetSpanCostCoefficientForVehicle(self, coefficient: 'int64_t', vehicle: int) -> 'void': +
+ +
+ View Source +
    def SetSpanCostCoefficientForVehicle(self, coefficient: "int64_t", vehicle: "int") -> "void":
+        r""" Sets a cost proportional to the dimension span on a given vehicle, or on all vehicles at once. "coefficient" must be nonnegative. This is handy to model costs proportional to idle time when the dimension represents time. The cost for a vehicle is   span_cost = coefficient * (dimension end value - dimension start value)."""
+        return _pywrapcp.RoutingDimension_SetSpanCostCoefficientForVehicle(self, coefficient, vehicle)
+
+ +
+ +

Sets a cost proportional to the dimension span on a given vehicle, or on all vehicles at once. "coefficient" must be nonnegative. This is handy to model costs proportional to idle time when the dimension represents time. The cost for a vehicle is span_cost = coefficient * (dimension end value - dimension start value).

+
+ + +
+
+
#   + + + def + SetSpanCostCoefficientForAllVehicles(self, coefficient: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetSpanCostCoefficientForAllVehicles(self, coefficient: "int64_t") -> "void":
+        return _pywrapcp.RoutingDimension_SetSpanCostCoefficientForAllVehicles(self, coefficient)
+
+ +
+ + + +
+
+
#   + + + def + SetGlobalSpanCostCoefficient(self, coefficient: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetGlobalSpanCostCoefficient(self, coefficient: "int64_t") -> "void":
+        r""" Sets a cost proportional to the *global* dimension span, that is the difference between the largest value of route end cumul variables and the smallest value of route start cumul variables. In other words: global_span_cost =   coefficient * (Max(dimension end value) - Min(dimension start value))."""
+        return _pywrapcp.RoutingDimension_SetGlobalSpanCostCoefficient(self, coefficient)
+
+ +
+ +

Sets a cost proportional to the global dimension span, that is the difference between the largest value of route end cumul variables and the smallest value of route start cumul variables. In other words: global_span_cost = coefficient * (Max(dimension end value) - Min(dimension start value)).

+
+ + +
+
+
#   + + + def + SetCumulVarSoftUpperBound( + self, + index: 'int64_t', + upper_bound: 'int64_t', + coefficient: 'int64_t' +) -> 'void': +
+ +
+ View Source +
    def SetCumulVarSoftUpperBound(self, index: "int64_t", upper_bound: "int64_t", coefficient: "int64_t") -> "void":
+        r""" Sets a soft upper bound to the cumul variable of a given variable index. If the value of the cumul variable is greater than the bound, a cost proportional to the difference between this value and the bound is added to the cost function of the model:   cumulVar <= upper_bound -> cost = 0    cumulVar > upper_bound -> cost = coefficient * (cumulVar - upper_bound) This is also handy to model tardiness costs when the dimension represents time."""
+        return _pywrapcp.RoutingDimension_SetCumulVarSoftUpperBound(self, index, upper_bound, coefficient)
+
+ +
+ +

Sets a soft upper bound to the cumul variable of a given variable index. If the value of the cumul variable is greater than the bound, a cost proportional to the difference between this value and the bound is added to the cost function of the model: cumulVar <= upper_bound -> cost = 0 cumulVar > upper_bound -> cost = coefficient * (cumulVar - upper_bound) This is also handy to model tardiness costs when the dimension represents time.

+
+ + +
+
+
#   + + + def + HasCumulVarSoftUpperBound(self, index: 'int64_t') -> bool: +
+ +
+ View Source +
    def HasCumulVarSoftUpperBound(self, index: "int64_t") -> "bool":
+        r""" Returns true if a soft upper bound has been set for a given variable index."""
+        return _pywrapcp.RoutingDimension_HasCumulVarSoftUpperBound(self, index)
+
+ +
+ +

Returns true if a soft upper bound has been set for a given variable index.

+
+ + +
+
+
#   + + + def + GetCumulVarSoftUpperBound(self, index: 'int64_t') -> 'int64_t': +
+ +
+ View Source +
    def GetCumulVarSoftUpperBound(self, index: "int64_t") -> "int64_t":
+        r""" Returns the soft upper bound of a cumul variable for a given variable index. The "hard" upper bound of the variable is returned if no soft upper bound has been set."""
+        return _pywrapcp.RoutingDimension_GetCumulVarSoftUpperBound(self, index)
+
+ +
+ +

Returns the soft upper bound of a cumul variable for a given variable index. The "hard" upper bound of the variable is returned if no soft upper bound has been set.

+
+ + +
+
+
#   + + + def + GetCumulVarSoftUpperBoundCoefficient(self, index: 'int64_t') -> 'int64_t': +
+ +
+ View Source +
    def GetCumulVarSoftUpperBoundCoefficient(self, index: "int64_t") -> "int64_t":
+        r""" Returns the cost coefficient of the soft upper bound of a cumul variable for a given variable index. If no soft upper bound has been set, 0 is returned."""
+        return _pywrapcp.RoutingDimension_GetCumulVarSoftUpperBoundCoefficient(self, index)
+
+ +
+ +

Returns the cost coefficient of the soft upper bound of a cumul variable for a given variable index. If no soft upper bound has been set, 0 is returned.

+
+ + +
+
+
#   + + + def + SetCumulVarSoftLowerBound( + self, + index: 'int64_t', + lower_bound: 'int64_t', + coefficient: 'int64_t' +) -> 'void': +
+ +
+ View Source +
    def SetCumulVarSoftLowerBound(self, index: "int64_t", lower_bound: "int64_t", coefficient: "int64_t") -> "void":
+        r""" Sets a soft lower bound to the cumul variable of a given variable index. If the value of the cumul variable is less than the bound, a cost proportional to the difference between this value and the bound is added to the cost function of the model:   cumulVar > lower_bound -> cost = 0   cumulVar <= lower_bound -> cost = coefficient * (lower_bound -               cumulVar). This is also handy to model earliness costs when the dimension represents time."""
+        return _pywrapcp.RoutingDimension_SetCumulVarSoftLowerBound(self, index, lower_bound, coefficient)
+
+ +
+ +

Sets a soft lower bound to the cumul variable of a given variable index. If the value of the cumul variable is less than the bound, a cost proportional to the difference between this value and the bound is added to the cost function of the model: cumulVar > lower_bound -> cost = 0 cumulVar <= lower_bound -> cost = coefficient * (lower_bound - cumulVar). This is also handy to model earliness costs when the dimension represents time.

+
+ + +
+
+
#   + + + def + HasCumulVarSoftLowerBound(self, index: 'int64_t') -> bool: +
+ +
+ View Source +
    def HasCumulVarSoftLowerBound(self, index: "int64_t") -> "bool":
+        r""" Returns true if a soft lower bound has been set for a given variable index."""
+        return _pywrapcp.RoutingDimension_HasCumulVarSoftLowerBound(self, index)
+
+ +
+ +

Returns true if a soft lower bound has been set for a given variable index.

+
+ + +
+
+
#   + + + def + GetCumulVarSoftLowerBound(self, index: 'int64_t') -> 'int64_t': +
+ +
+ View Source +
    def GetCumulVarSoftLowerBound(self, index: "int64_t") -> "int64_t":
+        r""" Returns the soft lower bound of a cumul variable for a given variable index. The "hard" lower bound of the variable is returned if no soft lower bound has been set."""
+        return _pywrapcp.RoutingDimension_GetCumulVarSoftLowerBound(self, index)
+
+ +
+ +

Returns the soft lower bound of a cumul variable for a given variable index. The "hard" lower bound of the variable is returned if no soft lower bound has been set.

+
+ + +
+
+
#   + + + def + GetCumulVarSoftLowerBoundCoefficient(self, index: 'int64_t') -> 'int64_t': +
+ +
+ View Source +
    def GetCumulVarSoftLowerBoundCoefficient(self, index: "int64_t") -> "int64_t":
+        r""" Returns the cost coefficient of the soft lower bound of a cumul variable for a given variable index. If no soft lower bound has been set, 0 is returned."""
+        return _pywrapcp.RoutingDimension_GetCumulVarSoftLowerBoundCoefficient(self, index)
+
+ +
+ +

Returns the cost coefficient of the soft lower bound of a cumul variable for a given variable index. If no soft lower bound has been set, 0 is returned.

+
+ + +
+
+
#   + + + def + SetBreakIntervalsOfVehicle( + self, + breaks: 'std::vector< operations_research::IntervalVar * >', + vehicle: int, + node_visit_transits: 'std::vector< int64_t >' +) -> 'void': +
+ +
+ View Source +
    def SetBreakIntervalsOfVehicle(self, breaks: "std::vector< operations_research::IntervalVar * >", vehicle: "int", node_visit_transits: "std::vector< int64_t >") -> "void":
+        r""" Sets the breaks for a given vehicle. Breaks are represented by IntervalVars. They may interrupt transits between nodes and increase the value of corresponding slack variables. A break may take place before the start of a vehicle, after the end of a vehicle, or during a travel i -> j. In that case, the interval [break.Start(), break.End()) must be a subset of [CumulVar(i) + pre_travel(i, j), CumulVar(j) - post_travel(i, j)). In other words, a break may not overlap any node n's visit, given by [CumulVar(n) - post_travel(_, n), CumulVar(n) + pre_travel(n, _)). This formula considers post_travel(_, start) and pre_travel(end, _) to be 0; pre_travel will never be called on any (_, start) and post_travel will never we called on any (end, _). If pre_travel_evaluator or post_travel_evaluator is -1, it will be taken as a function that always returns 0. Deprecated, sets pre_travel(i, j) = node_visit_transit[i]."""
+        return _pywrapcp.RoutingDimension_SetBreakIntervalsOfVehicle(self, breaks, vehicle, node_visit_transits)
+
+ +
+ +

Sets the breaks for a given vehicle. Breaks are represented by IntervalVars. They may interrupt transits between nodes and increase the value of corresponding slack variables. A break may take place before the start of a vehicle, after the end of a vehicle, or during a travel i -> j. In that case, the interval [break.Start(), break.End()) must be a subset of [CumulVar(i) + pre_travel(i, j), CumulVar(j) - post_travel(i, j)). In other words, a break may not overlap any node n's visit, given by [CumulVar(n) - post_travel(_, n), CumulVar(n) + pre_travel(n, _)). This formula considers post_travel(_, start) and pre_travel(end, _) to be 0; pre_travel will never be called on any (_, start) and post_travel will never we called on any (end, _). If pre_travel_evaluator or post_travel_evaluator is -1, it will be taken as a function that always returns 0. Deprecated, sets pre_travel(i, j) = node_visit_transit[i].

+
+ + +
+
+
#   + + + def + SetBreakDistanceDurationOfVehicle( + self, + distance: 'int64_t', + duration: 'int64_t', + vehicle: int +) -> 'void': +
+ +
+ View Source +
    def SetBreakDistanceDurationOfVehicle(self, distance: "int64_t", duration: "int64_t", vehicle: "int") -> "void":
+        r""" With breaks supposed to be consecutive, this forces the distance between breaks of size at least minimum_break_duration to be at most distance. This supposes that the time until route start and after route end are infinite breaks."""
+        return _pywrapcp.RoutingDimension_SetBreakDistanceDurationOfVehicle(self, distance, duration, vehicle)
+
+ +
+ +

With breaks supposed to be consecutive, this forces the distance between breaks of size at least minimum_break_duration to be at most distance. This supposes that the time until route start and after route end are infinite breaks.

+
+ + +
+
+
#   + + + def + InitializeBreaks(self) -> 'void': +
+ +
+ View Source +
    def InitializeBreaks(self) -> "void":
+        r""" Sets up vehicle_break_intervals_, vehicle_break_distance_duration_, pre_travel_evaluators and post_travel_evaluators."""
+        return _pywrapcp.RoutingDimension_InitializeBreaks(self)
+
+ +
+ +

Sets up vehicle_break_intervals_, vehicle_break_distance_duration_, pre_travel_evaluators and post_travel_evaluators.

+
+ + +
+
+
#   + + + def + HasBreakConstraints(self) -> bool: +
+ +
+ View Source +
    def HasBreakConstraints(self) -> "bool":
+        r""" Returns true if any break interval or break distance was defined."""
+        return _pywrapcp.RoutingDimension_HasBreakConstraints(self)
+
+ +
+ +

Returns true if any break interval or break distance was defined.

+
+ + +
+
+
#   + + + def + GetPreTravelEvaluatorOfVehicle(self, vehicle: int) -> int: +
+ +
+ View Source +
    def GetPreTravelEvaluatorOfVehicle(self, vehicle: "int") -> "int":
+        return _pywrapcp.RoutingDimension_GetPreTravelEvaluatorOfVehicle(self, vehicle)
+
+ +
+ + + +
+
+
#   + + + def + GetPostTravelEvaluatorOfVehicle(self, vehicle: int) -> int: +
+ +
+ View Source +
    def GetPostTravelEvaluatorOfVehicle(self, vehicle: "int") -> "int":
+        return _pywrapcp.RoutingDimension_GetPostTravelEvaluatorOfVehicle(self, vehicle)
+
+ +
+ + + +
+
+
#   + + + def + base_dimension(self) -> 'operations_research::RoutingDimension const *': +
+ +
+ View Source +
    def base_dimension(self) -> "operations_research::RoutingDimension const *":
+        r""" Returns the parent in the dependency tree if any or nullptr otherwise."""
+        return _pywrapcp.RoutingDimension_base_dimension(self)
+
+ +
+ +

Returns the parent in the dependency tree if any or nullptr otherwise.

+
+ + +
+
+
#   + + + def + ShortestTransitionSlack(self, node: 'int64_t') -> 'int64_t': +
+ +
+ View Source +
    def ShortestTransitionSlack(self, node: "int64_t") -> "int64_t":
+        r""" It makes sense to use the function only for self-dependent dimension. For such dimensions the value of the slack of a node determines the transition cost of the next transit. Provided that   1. cumul[node] is fixed,   2. next[node] and next[next[node]] (if exists) are fixed, the value of slack[node] for which cumul[next[node]] + transit[next[node]] is minimized can be found in O(1) using this function."""
+        return _pywrapcp.RoutingDimension_ShortestTransitionSlack(self, node)
+
+ +
+ +

It makes sense to use the function only for self-dependent dimension. For such dimensions the value of the slack of a node determines the transition cost of the next transit. Provided that 1. cumul[node] is fixed, 2. next[node] and next[next[node]] (if exists) are fixed, the value of slack[node] for which cumul[next[node]] + transit[next[node]] is minimized can be found in O(1) using this function.

+
+ + +
+
+
#   + + + def + name(self) -> 'std::string const &': +
+ +
+ View Source +
    def name(self) -> "std::string const &":
+        r""" Returns the name of the dimension."""
+        return _pywrapcp.RoutingDimension_name(self)
+
+ +
+ +

Returns the name of the dimension.

+
+ + +
+
+
#   + + + def + SetPickupToDeliveryLimitFunctionForPair( + self, + limit_function: 'operations_research::RoutingDimension::PickupToDeliveryLimitFunction', + pair_index: int +) -> 'void': +
+ +
+ View Source +
    def SetPickupToDeliveryLimitFunctionForPair(self, limit_function: "operations_research::RoutingDimension::PickupToDeliveryLimitFunction", pair_index: "int") -> "void":
+        return _pywrapcp.RoutingDimension_SetPickupToDeliveryLimitFunctionForPair(self, limit_function, pair_index)
+
+ +
+ + + +
+
+
#   + + + def + HasPickupToDeliveryLimits(self) -> bool: +
+ +
+ View Source +
    def HasPickupToDeliveryLimits(self) -> "bool":
+        return _pywrapcp.RoutingDimension_HasPickupToDeliveryLimits(self)
+
+ +
+ + + +
+
+
#   + + + def + AddNodePrecedence( + self, + first_node: 'int64_t', + second_node: 'int64_t', + offset: 'int64_t' +) -> 'void': +
+ +
+ View Source +
    def AddNodePrecedence(self, first_node: "int64_t", second_node: "int64_t", offset: "int64_t") -> "void":
+        return _pywrapcp.RoutingDimension_AddNodePrecedence(self, first_node, second_node, offset)
+
+ +
+ + + +
+
+
#   + + + def + GetSpanUpperBoundForVehicle(self, vehicle: int) -> 'int64_t': +
+ +
+ View Source +
    def GetSpanUpperBoundForVehicle(self, vehicle: "int") -> "int64_t":
+        return _pywrapcp.RoutingDimension_GetSpanUpperBoundForVehicle(self, vehicle)
+
+ +
+ + + +
+
+
#   + + + def + GetSpanCostCoefficientForVehicle(self, vehicle: int) -> 'int64_t': +
+ +
+ View Source +
    def GetSpanCostCoefficientForVehicle(self, vehicle: "int") -> "int64_t":
+        return _pywrapcp.RoutingDimension_GetSpanCostCoefficientForVehicle(self, vehicle)
+
+ +
+ + + +
+
+
#   + + + def + global_span_cost_coefficient(self) -> 'int64_t': +
+ +
+ View Source +
    def global_span_cost_coefficient(self) -> "int64_t":
+        return _pywrapcp.RoutingDimension_global_span_cost_coefficient(self)
+
+ +
+ + + +
+
+
#   + + + def + GetGlobalOptimizerOffset(self) -> 'int64_t': +
+ +
+ View Source +
    def GetGlobalOptimizerOffset(self) -> "int64_t":
+        return _pywrapcp.RoutingDimension_GetGlobalOptimizerOffset(self)
+
+ +
+ + + +
+
+
#   + + + def + GetLocalOptimizerOffsetForVehicle(self, vehicle: int) -> 'int64_t': +
+ +
+ View Source +
    def GetLocalOptimizerOffsetForVehicle(self, vehicle: "int") -> "int64_t":
+        return _pywrapcp.RoutingDimension_GetLocalOptimizerOffsetForVehicle(self, vehicle)
+
+ +
+ + + +
+
+
+
#   + + + def + MakeSetValuesFromTargets( + solver: pywrapcp.Solver, + variables: 'std::vector< operations_research::IntVar * >', + targets: 'std::vector< int64_t >' +) -> 'operations_research::DecisionBuilder *': +
+ +
+ View Source +
def MakeSetValuesFromTargets(solver: "Solver", variables: "std::vector< operations_research::IntVar * >", targets: "std::vector< int64_t >") -> "operations_research::DecisionBuilder *":
+    r""" A decision builder which tries to assign values to variables as close as possible to target values first."""
+    return _pywrapcp.MakeSetValuesFromTargets(solver, variables, targets)
+
+ +
+ +

A decision builder which tries to assign values to variables as close as possible to target values first.

+
+ + +
+
+
#   + + + def + SolveModelWithSat( + model: pywrapcp.RoutingModel, + search_parameters: 'operations_research::RoutingSearchParameters const &', + initial_solution: pywrapcp.Assignment, + solution: pywrapcp.Assignment +) -> bool: +
+ +
+ View Source +
def SolveModelWithSat(model: "RoutingModel", search_parameters: "operations_research::RoutingSearchParameters const &", initial_solution: "Assignment", solution: "Assignment") -> "bool":
+    r""" Attempts to solve the model using the cp-sat solver. As of 5/2019, will solve the TSP corresponding to the model if it has a single vehicle. Therefore the resulting solution might not actually be feasible. Will return false if a solution could not be found."""
+    return _pywrapcp.SolveModelWithSat(model, search_parameters, initial_solution, solution)
+
+ +
+ +

Attempts to solve the model using the cp-sat solver. As of 5/2019, will solve the TSP corresponding to the model if it has a single vehicle. Therefore the resulting solution might not actually be feasible. Will return false if a solution could not be found.

+
+ + +
+ \ No newline at end of file diff --git a/docs/python/ortools/graph/pywrapgraph.html b/docs/python/ortools/graph/pywrapgraph.html index 3e03d984e6..f3c836104b 100644 --- a/docs/python/ortools/graph/pywrapgraph.html +++ b/docs/python/ortools/graph/pywrapgraph.html @@ -1,1222 +1,1814 @@ - - - -pywrapgraph API documentation - - - - - - - - - - - + + + + pywrapgraph API documentation + + + + + + - -
-
-
-

Module pywrapgraph

-
-
-
- -Expand source code - -
# This file was automatically generated by SWIG (http://www.swig.org).
-# Version 4.0.2
-#
-# Do not make changes to this file unless you know what you are doing--modify
-# the SWIG interface file instead.
-
-from sys import version_info as _swig_python_version_info
-if _swig_python_version_info < (2, 7, 0):
-    raise RuntimeError("Python 2.7 or later required")
-
-# Import the low-level C/C++ module
-if __package__ or "." in __name__:
-    from . import _pywrapgraph
-else:
-    import _pywrapgraph
-
-try:
-    import builtins as __builtin__
-except ImportError:
-    import __builtin__
-
-def _swig_repr(self):
-    try:
-        strthis = "proxy of " + self.this.__repr__()
-    except __builtin__.Exception:
-        strthis = ""
-    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
-
-
-def _swig_setattr_nondynamic_instance_variable(set):
-    def set_instance_attr(self, name, value):
-        if name == "thisown":
-            self.this.own(value)
-        elif name == "this":
-            set(self, name, value)
-        elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
-            set(self, name, value)
-        else:
-            raise AttributeError("You cannot add instance attributes to %s" % self)
-    return set_instance_attr
-
-
-def _swig_setattr_nondynamic_class_variable(set):
-    def set_class_attr(cls, name, value):
-        if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
-            set(cls, name, value)
-        else:
-            raise AttributeError("You cannot add class attributes to %s" % cls)
-    return set_class_attr
-
-
-def _swig_add_metaclass(metaclass):
-    """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
-    def wrapper(cls):
-        return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
-    return wrapper
-
-
-class _SwigNonDynamicMeta(type):
-    """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
-    __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)
-
-
-class SimpleMaxFlow(object):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self):
-        _pywrapgraph.SimpleMaxFlow_swiginit(self, _pywrapgraph.new_SimpleMaxFlow())
-
-    def AddArcWithCapacity(self, tail: "operations_research::NodeIndex", head: "operations_research::NodeIndex", capacity: "operations_research::FlowQuantity") -> "operations_research::ArcIndex":
-        return _pywrapgraph.SimpleMaxFlow_AddArcWithCapacity(self, tail, head, capacity)
-
-    def NumNodes(self) -> "operations_research::NodeIndex":
-        return _pywrapgraph.SimpleMaxFlow_NumNodes(self)
+        
+    
+
+

+pywrapgraph

+ + +
+ View Source +
# This file was automatically generated by SWIG (http://www.swig.org).
+# Version 4.0.1
+#
+# Do not make changes to this file unless you know what you are doing--modify
+# the SWIG interface file instead.
+
+from sys import version_info as _swig_python_version_info
+if _swig_python_version_info < (2, 7, 0):
+    raise RuntimeError("Python 2.7 or later required")
+
+# Import the low-level C/C++ module
+if __package__ or "." in __name__:
+    from . import _pywrapgraph
+else:
+    import _pywrapgraph
+
+try:
+    import builtins as __builtin__
+except ImportError:
+    import __builtin__
+
+def _swig_repr(self):
+    try:
+        strthis = "proxy of " + self.this.__repr__()
+    except __builtin__.Exception:
+        strthis = ""
+    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
+
+
+def _swig_setattr_nondynamic_instance_variable(set):
+    def set_instance_attr(self, name, value):
+        if name == "thisown":
+            self.this.own(value)
+        elif name == "this":
+            set(self, name, value)
+        elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
+            set(self, name, value)
+        else:
+            raise AttributeError("You cannot add instance attributes to %s" % self)
+    return set_instance_attr
+
+
+def _swig_setattr_nondynamic_class_variable(set):
+    def set_class_attr(cls, name, value):
+        if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
+            set(cls, name, value)
+        else:
+            raise AttributeError("You cannot add class attributes to %s" % cls)
+    return set_class_attr
+
+
+def _swig_add_metaclass(metaclass):
+    """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
+    def wrapper(cls):
+        return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
+    return wrapper
+
+
+class _SwigNonDynamicMeta(type):
+    """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
+    __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)
+
+
+class SimpleMaxFlow(object):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self):
+        _pywrapgraph.SimpleMaxFlow_swiginit(self, _pywrapgraph.new_SimpleMaxFlow())
+
+    def AddArcWithCapacity(self, tail: "operations_research::NodeIndex", head: "operations_research::NodeIndex", capacity: "operations_research::FlowQuantity") -> "operations_research::ArcIndex":
+        return _pywrapgraph.SimpleMaxFlow_AddArcWithCapacity(self, tail, head, capacity)
+
+    def NumNodes(self) -> "operations_research::NodeIndex":
+        return _pywrapgraph.SimpleMaxFlow_NumNodes(self)
 
-    def NumArcs(self) -> "operations_research::ArcIndex":
-        return _pywrapgraph.SimpleMaxFlow_NumArcs(self)
+    def NumArcs(self) -> "operations_research::ArcIndex":
+        return _pywrapgraph.SimpleMaxFlow_NumArcs(self)
 
-    def Tail(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
-        return _pywrapgraph.SimpleMaxFlow_Tail(self, arc)
+    def Tail(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
+        return _pywrapgraph.SimpleMaxFlow_Tail(self, arc)
 
-    def Head(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
-        return _pywrapgraph.SimpleMaxFlow_Head(self, arc)
+    def Head(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
+        return _pywrapgraph.SimpleMaxFlow_Head(self, arc)
 
-    def Capacity(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
-        return _pywrapgraph.SimpleMaxFlow_Capacity(self, arc)
-    OPTIMAL = _pywrapgraph.SimpleMaxFlow_OPTIMAL
-    POSSIBLE_OVERFLOW = _pywrapgraph.SimpleMaxFlow_POSSIBLE_OVERFLOW
-    BAD_INPUT = _pywrapgraph.SimpleMaxFlow_BAD_INPUT
-    BAD_RESULT = _pywrapgraph.SimpleMaxFlow_BAD_RESULT
+    def Capacity(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
+        return _pywrapgraph.SimpleMaxFlow_Capacity(self, arc)
+    OPTIMAL = _pywrapgraph.SimpleMaxFlow_OPTIMAL
+    POSSIBLE_OVERFLOW = _pywrapgraph.SimpleMaxFlow_POSSIBLE_OVERFLOW
+    BAD_INPUT = _pywrapgraph.SimpleMaxFlow_BAD_INPUT
+    BAD_RESULT = _pywrapgraph.SimpleMaxFlow_BAD_RESULT
 
-    def Solve(self, source: "operations_research::NodeIndex", sink: "operations_research::NodeIndex") -> "operations_research::SimpleMaxFlow::Status":
-        return _pywrapgraph.SimpleMaxFlow_Solve(self, source, sink)
+    def Solve(self, source: "operations_research::NodeIndex", sink: "operations_research::NodeIndex") -> "operations_research::SimpleMaxFlow::Status":
+        return _pywrapgraph.SimpleMaxFlow_Solve(self, source, sink)
 
-    def OptimalFlow(self) -> "operations_research::FlowQuantity":
-        return _pywrapgraph.SimpleMaxFlow_OptimalFlow(self)
+    def OptimalFlow(self) -> "operations_research::FlowQuantity":
+        return _pywrapgraph.SimpleMaxFlow_OptimalFlow(self)
 
-    def Flow(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
-        return _pywrapgraph.SimpleMaxFlow_Flow(self, arc)
+    def Flow(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
+        return _pywrapgraph.SimpleMaxFlow_Flow(self, arc)
 
-    def GetSourceSideMinCut(self) -> "void":
-        return _pywrapgraph.SimpleMaxFlow_GetSourceSideMinCut(self)
+    def GetSourceSideMinCut(self) -> "void":
+        return _pywrapgraph.SimpleMaxFlow_GetSourceSideMinCut(self)
 
-    def GetSinkSideMinCut(self) -> "void":
-        return _pywrapgraph.SimpleMaxFlow_GetSinkSideMinCut(self)
+    def GetSinkSideMinCut(self) -> "void":
+        return _pywrapgraph.SimpleMaxFlow_GetSinkSideMinCut(self)
 
-    def SetArcCapacity(self, arc: "operations_research::ArcIndex", capacity: "operations_research::FlowQuantity") -> "void":
-        return _pywrapgraph.SimpleMaxFlow_SetArcCapacity(self, arc, capacity)
-    __swig_destroy__ = _pywrapgraph.delete_SimpleMaxFlow
+    def SetArcCapacity(self, arc: "operations_research::ArcIndex", capacity: "operations_research::FlowQuantity") -> "void":
+        return _pywrapgraph.SimpleMaxFlow_SetArcCapacity(self, arc, capacity)
+    __swig_destroy__ = _pywrapgraph.delete_SimpleMaxFlow
 
-# Register SimpleMaxFlow in _pywrapgraph:
-_pywrapgraph.SimpleMaxFlow_swigregister(SimpleMaxFlow)
+# Register SimpleMaxFlow in _pywrapgraph:
+_pywrapgraph.SimpleMaxFlow_swigregister(SimpleMaxFlow)
 
-class MinCostFlowBase(object):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-    NOT_SOLVED = _pywrapgraph.MinCostFlowBase_NOT_SOLVED
-    OPTIMAL = _pywrapgraph.MinCostFlowBase_OPTIMAL
-    FEASIBLE = _pywrapgraph.MinCostFlowBase_FEASIBLE
-    INFEASIBLE = _pywrapgraph.MinCostFlowBase_INFEASIBLE
-    UNBALANCED = _pywrapgraph.MinCostFlowBase_UNBALANCED
-    BAD_RESULT = _pywrapgraph.MinCostFlowBase_BAD_RESULT
-    BAD_COST_RANGE = _pywrapgraph.MinCostFlowBase_BAD_COST_RANGE
+class MinCostFlowBase(object):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+    NOT_SOLVED = _pywrapgraph.MinCostFlowBase_NOT_SOLVED
+    OPTIMAL = _pywrapgraph.MinCostFlowBase_OPTIMAL
+    FEASIBLE = _pywrapgraph.MinCostFlowBase_FEASIBLE
+    INFEASIBLE = _pywrapgraph.MinCostFlowBase_INFEASIBLE
+    UNBALANCED = _pywrapgraph.MinCostFlowBase_UNBALANCED
+    BAD_RESULT = _pywrapgraph.MinCostFlowBase_BAD_RESULT
+    BAD_COST_RANGE = _pywrapgraph.MinCostFlowBase_BAD_COST_RANGE
 
-    def __init__(self):
-        _pywrapgraph.MinCostFlowBase_swiginit(self, _pywrapgraph.new_MinCostFlowBase())
-    __swig_destroy__ = _pywrapgraph.delete_MinCostFlowBase
+    def __init__(self):
+        _pywrapgraph.MinCostFlowBase_swiginit(self, _pywrapgraph.new_MinCostFlowBase())
+    __swig_destroy__ = _pywrapgraph.delete_MinCostFlowBase
 
-# Register MinCostFlowBase in _pywrapgraph:
-_pywrapgraph.MinCostFlowBase_swigregister(MinCostFlowBase)
+# Register MinCostFlowBase in _pywrapgraph:
+_pywrapgraph.MinCostFlowBase_swigregister(MinCostFlowBase)
 
-class SimpleMinCostFlow(MinCostFlowBase):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
+class SimpleMinCostFlow(MinCostFlowBase):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
 
-    def __init__(self, reserve_num_nodes: "operations_research::NodeIndex"=0, reserve_num_arcs: "operations_research::ArcIndex"=0):
-        _pywrapgraph.SimpleMinCostFlow_swiginit(self, _pywrapgraph.new_SimpleMinCostFlow(reserve_num_nodes, reserve_num_arcs))
+    def __init__(self, reserve_num_nodes: "operations_research::NodeIndex"=0, reserve_num_arcs: "operations_research::ArcIndex"=0):
+        _pywrapgraph.SimpleMinCostFlow_swiginit(self, _pywrapgraph.new_SimpleMinCostFlow(reserve_num_nodes, reserve_num_arcs))
 
-    def AddArcWithCapacityAndUnitCost(self, tail: "operations_research::NodeIndex", head: "operations_research::NodeIndex", capacity: "operations_research::FlowQuantity", unit_cost: "operations_research::CostValue") -> "operations_research::ArcIndex":
-        return _pywrapgraph.SimpleMinCostFlow_AddArcWithCapacityAndUnitCost(self, tail, head, capacity, unit_cost)
+    def AddArcWithCapacityAndUnitCost(self, tail: "operations_research::NodeIndex", head: "operations_research::NodeIndex", capacity: "operations_research::FlowQuantity", unit_cost: "operations_research::CostValue") -> "operations_research::ArcIndex":
+        return _pywrapgraph.SimpleMinCostFlow_AddArcWithCapacityAndUnitCost(self, tail, head, capacity, unit_cost)
 
-    def SetNodeSupply(self, node: "operations_research::NodeIndex", supply: "operations_research::FlowQuantity") -> "void":
-        return _pywrapgraph.SimpleMinCostFlow_SetNodeSupply(self, node, supply)
+    def SetNodeSupply(self, node: "operations_research::NodeIndex", supply: "operations_research::FlowQuantity") -> "void":
+        return _pywrapgraph.SimpleMinCostFlow_SetNodeSupply(self, node, supply)
 
-    def Solve(self) -> "operations_research::MinCostFlowBase::Status":
-        return _pywrapgraph.SimpleMinCostFlow_Solve(self)
+    def Solve(self) -> "operations_research::MinCostFlowBase::Status":
+        return _pywrapgraph.SimpleMinCostFlow_Solve(self)
 
-    def SolveMaxFlowWithMinCost(self) -> "operations_research::MinCostFlowBase::Status":
-        return _pywrapgraph.SimpleMinCostFlow_SolveMaxFlowWithMinCost(self)
+    def SolveMaxFlowWithMinCost(self) -> "operations_research::MinCostFlowBase::Status":
+        return _pywrapgraph.SimpleMinCostFlow_SolveMaxFlowWithMinCost(self)
 
-    def OptimalCost(self) -> "operations_research::CostValue":
-        return _pywrapgraph.SimpleMinCostFlow_OptimalCost(self)
+    def OptimalCost(self) -> "operations_research::CostValue":
+        return _pywrapgraph.SimpleMinCostFlow_OptimalCost(self)
 
-    def MaximumFlow(self) -> "operations_research::FlowQuantity":
-        return _pywrapgraph.SimpleMinCostFlow_MaximumFlow(self)
+    def MaximumFlow(self) -> "operations_research::FlowQuantity":
+        return _pywrapgraph.SimpleMinCostFlow_MaximumFlow(self)
 
-    def Flow(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
-        return _pywrapgraph.SimpleMinCostFlow_Flow(self, arc)
+    def Flow(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
+        return _pywrapgraph.SimpleMinCostFlow_Flow(self, arc)
 
-    def NumNodes(self) -> "operations_research::NodeIndex":
-        return _pywrapgraph.SimpleMinCostFlow_NumNodes(self)
+    def NumNodes(self) -> "operations_research::NodeIndex":
+        return _pywrapgraph.SimpleMinCostFlow_NumNodes(self)
 
-    def NumArcs(self) -> "operations_research::ArcIndex":
-        return _pywrapgraph.SimpleMinCostFlow_NumArcs(self)
+    def NumArcs(self) -> "operations_research::ArcIndex":
+        return _pywrapgraph.SimpleMinCostFlow_NumArcs(self)
 
-    def Tail(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
-        return _pywrapgraph.SimpleMinCostFlow_Tail(self, arc)
+    def Tail(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
+        return _pywrapgraph.SimpleMinCostFlow_Tail(self, arc)
 
-    def Head(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
-        return _pywrapgraph.SimpleMinCostFlow_Head(self, arc)
-
-    def Capacity(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
-        return _pywrapgraph.SimpleMinCostFlow_Capacity(self, arc)
-
-    def Supply(self, node: "operations_research::NodeIndex") -> "operations_research::FlowQuantity":
-        return _pywrapgraph.SimpleMinCostFlow_Supply(self, node)
-
-    def UnitCost(self, arc: "operations_research::ArcIndex") -> "operations_research::CostValue":
-        return _pywrapgraph.SimpleMinCostFlow_UnitCost(self, arc)
-    __swig_destroy__ = _pywrapgraph.delete_SimpleMinCostFlow
-
-# Register SimpleMinCostFlow in _pywrapgraph:
-_pywrapgraph.SimpleMinCostFlow_swigregister(SimpleMinCostFlow)
-
-class LinearSumAssignment(object):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self):
-        _pywrapgraph.LinearSumAssignment_swiginit(self, _pywrapgraph.new_LinearSumAssignment())
-
-    def AddArcWithCost(self, left_node: "operations_research::NodeIndex", right_node: "operations_research::NodeIndex", cost: "operations_research::CostValue") -> "operations_research::ArcIndex":
-        return _pywrapgraph.LinearSumAssignment_AddArcWithCost(self, left_node, right_node, cost)
-
-    def NumNodes(self) -> "operations_research::NodeIndex":
-        return _pywrapgraph.LinearSumAssignment_NumNodes(self)
-
-    def NumArcs(self) -> "operations_research::ArcIndex":
-        return _pywrapgraph.LinearSumAssignment_NumArcs(self)
-
-    def LeftNode(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
-        return _pywrapgraph.LinearSumAssignment_LeftNode(self, arc)
-
-    def RightNode(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
-        return _pywrapgraph.LinearSumAssignment_RightNode(self, arc)
-
-    def Cost(self, arc: "operations_research::ArcIndex") -> "operations_research::CostValue":
-        return _pywrapgraph.LinearSumAssignment_Cost(self, arc)
-    OPTIMAL = _pywrapgraph.LinearSumAssignment_OPTIMAL
-    INFEASIBLE = _pywrapgraph.LinearSumAssignment_INFEASIBLE
-    POSSIBLE_OVERFLOW = _pywrapgraph.LinearSumAssignment_POSSIBLE_OVERFLOW
-
-    def Solve(self) -> "operations_research::SimpleLinearSumAssignment::Status":
-        return _pywrapgraph.LinearSumAssignment_Solve(self)
-
-    def OptimalCost(self) -> "operations_research::CostValue":
-        return _pywrapgraph.LinearSumAssignment_OptimalCost(self)
-
-    def RightMate(self, left_node: "operations_research::NodeIndex") -> "operations_research::NodeIndex":
-        return _pywrapgraph.LinearSumAssignment_RightMate(self, left_node)
-
-    def AssignmentCost(self, left_node: "operations_research::NodeIndex") -> "operations_research::CostValue":
-        return _pywrapgraph.LinearSumAssignment_AssignmentCost(self, left_node)
-    __swig_destroy__ = _pywrapgraph.delete_LinearSumAssignment
-
-# Register LinearSumAssignment in _pywrapgraph:
-_pywrapgraph.LinearSumAssignment_swigregister(LinearSumAssignment)
-
-
-def DijkstraShortestPath(node_count: "int", start_node: "int", end_node: "int", graph: "std::function< int64_t (int,int) >", disconnected_distance: "int64_t") -> "std::vector< int > *":
-    return _pywrapgraph.DijkstraShortestPath(node_count, start_node, end_node, graph, disconnected_distance)
-
-def BellmanFordShortestPath(node_count: "int", start_node: "int", end_node: "int", graph: "std::function< int64_t (int,int) >", disconnected_distance: "int64_t") -> "std::vector< int > *":
-    return _pywrapgraph.BellmanFordShortestPath(node_count, start_node, end_node, graph, disconnected_distance)
-
-def AStarShortestPath(node_count: "int", start_node: "int", end_node: "int", graph: "std::function< int64_t (int,int) >", heuristic: "std::function< int64_t (int) >", disconnected_distance: "int64_t") -> "std::vector< int > *":
-    return _pywrapgraph.AStarShortestPath(node_count, start_node, end_node, graph, heuristic, disconnected_distance)
-
-
-
-
-
-
-
-

Functions

-
-
-def AStarShortestPath(node_count: int, start_node: int, end_node: int, graph: std::function< int64_t (int,int) >, heuristic: std::function< int64_t (int) >, disconnected_distance: int64_t) ‑> std::vector< int > * -
-
-
-
- -Expand source code - -
def AStarShortestPath(node_count: "int", start_node: "int", end_node: "int", graph: "std::function< int64_t (int,int) >", heuristic: "std::function< int64_t (int) >", disconnected_distance: "int64_t") -> "std::vector< int > *":
-    return _pywrapgraph.AStarShortestPath(node_count, start_node, end_node, graph, heuristic, disconnected_distance)
-
-
-
-def BellmanFordShortestPath(node_count: int, start_node: int, end_node: int, graph: std::function< int64_t (int,int) >, disconnected_distance: int64_t) ‑> std::vector< int > * -
-
-
-
- -Expand source code - -
def BellmanFordShortestPath(node_count: "int", start_node: "int", end_node: "int", graph: "std::function< int64_t (int,int) >", disconnected_distance: "int64_t") -> "std::vector< int > *":
-    return _pywrapgraph.BellmanFordShortestPath(node_count, start_node, end_node, graph, disconnected_distance)
-
-
-
-def DijkstraShortestPath(node_count: int, start_node: int, end_node: int, graph: std::function< int64_t (int,int) >, disconnected_distance: int64_t) ‑> std::vector< int > * -
-
-
-
- -Expand source code - -
def DijkstraShortestPath(node_count: "int", start_node: "int", end_node: "int", graph: "std::function< int64_t (int,int) >", disconnected_distance: "int64_t") -> "std::vector< int > *":
-    return _pywrapgraph.DijkstraShortestPath(node_count, start_node, end_node, graph, disconnected_distance)
-
-
-
-
-
-

Classes

-
-
-class LinearSumAssignment -
-
-
-
- -Expand source code - -
class LinearSumAssignment(object):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self):
-        _pywrapgraph.LinearSumAssignment_swiginit(self, _pywrapgraph.new_LinearSumAssignment())
-
-    def AddArcWithCost(self, left_node: "operations_research::NodeIndex", right_node: "operations_research::NodeIndex", cost: "operations_research::CostValue") -> "operations_research::ArcIndex":
-        return _pywrapgraph.LinearSumAssignment_AddArcWithCost(self, left_node, right_node, cost)
-
-    def NumNodes(self) -> "operations_research::NodeIndex":
-        return _pywrapgraph.LinearSumAssignment_NumNodes(self)
-
-    def NumArcs(self) -> "operations_research::ArcIndex":
-        return _pywrapgraph.LinearSumAssignment_NumArcs(self)
-
-    def LeftNode(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
-        return _pywrapgraph.LinearSumAssignment_LeftNode(self, arc)
-
-    def RightNode(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
-        return _pywrapgraph.LinearSumAssignment_RightNode(self, arc)
-
-    def Cost(self, arc: "operations_research::ArcIndex") -> "operations_research::CostValue":
-        return _pywrapgraph.LinearSumAssignment_Cost(self, arc)
-    OPTIMAL = _pywrapgraph.LinearSumAssignment_OPTIMAL
-    INFEASIBLE = _pywrapgraph.LinearSumAssignment_INFEASIBLE
-    POSSIBLE_OVERFLOW = _pywrapgraph.LinearSumAssignment_POSSIBLE_OVERFLOW
-
-    def Solve(self) -> "operations_research::SimpleLinearSumAssignment::Status":
-        return _pywrapgraph.LinearSumAssignment_Solve(self)
-
-    def OptimalCost(self) -> "operations_research::CostValue":
-        return _pywrapgraph.LinearSumAssignment_OptimalCost(self)
-
-    def RightMate(self, left_node: "operations_research::NodeIndex") -> "operations_research::NodeIndex":
-        return _pywrapgraph.LinearSumAssignment_RightMate(self, left_node)
-
-    def AssignmentCost(self, left_node: "operations_research::NodeIndex") -> "operations_research::CostValue":
-        return _pywrapgraph.LinearSumAssignment_AssignmentCost(self, left_node)
-    __swig_destroy__ = _pywrapgraph.delete_LinearSumAssignment
-
-

Class variables

-
-
var INFEASIBLE
-
-
-
-
var OPTIMAL
-
-
-
-
var POSSIBLE_OVERFLOW
-
-
-
-
-

Instance variables

-
-
var thisown
-
-

The membership flag

-
- -Expand source code - -
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-
-
-

Methods

-
-
-def AddArcWithCost(self, left_node: operations_research::NodeIndex, right_node: operations_research::NodeIndex, cost: operations_research::CostValue) ‑> operations_research::ArcIndex -
-
-
-
- -Expand source code - -
def AddArcWithCost(self, left_node: "operations_research::NodeIndex", right_node: "operations_research::NodeIndex", cost: "operations_research::CostValue") -> "operations_research::ArcIndex":
-    return _pywrapgraph.LinearSumAssignment_AddArcWithCost(self, left_node, right_node, cost)
-
-
-
-def AssignmentCost(self, left_node: operations_research::NodeIndex) ‑> operations_research::CostValue -
-
-
-
- -Expand source code - -
def AssignmentCost(self, left_node: "operations_research::NodeIndex") -> "operations_research::CostValue":
-    return _pywrapgraph.LinearSumAssignment_AssignmentCost(self, left_node)
-
-
-
-def Cost(self, arc: operations_research::ArcIndex) ‑> operations_research::CostValue -
-
-
-
- -Expand source code - -
def Cost(self, arc: "operations_research::ArcIndex") -> "operations_research::CostValue":
-    return _pywrapgraph.LinearSumAssignment_Cost(self, arc)
-
-
-
-def LeftNode(self, arc: operations_research::ArcIndex) ‑> operations_research::NodeIndex -
-
-
-
- -Expand source code - -
def LeftNode(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
-    return _pywrapgraph.LinearSumAssignment_LeftNode(self, arc)
-
-
-
-def NumArcs(self) ‑> operations_research::ArcIndex -
-
-
-
- -Expand source code - -
def NumArcs(self) -> "operations_research::ArcIndex":
-    return _pywrapgraph.LinearSumAssignment_NumArcs(self)
-
-
-
-def NumNodes(self) ‑> operations_research::NodeIndex -
-
-
-
- -Expand source code - -
def NumNodes(self) -> "operations_research::NodeIndex":
-    return _pywrapgraph.LinearSumAssignment_NumNodes(self)
-
-
-
-def OptimalCost(self) ‑> operations_research::CostValue -
-
-
-
- -Expand source code - -
def OptimalCost(self) -> "operations_research::CostValue":
-    return _pywrapgraph.LinearSumAssignment_OptimalCost(self)
-
-
-
-def RightMate(self, left_node: operations_research::NodeIndex) ‑> operations_research::NodeIndex -
-
-
-
- -Expand source code - -
def RightMate(self, left_node: "operations_research::NodeIndex") -> "operations_research::NodeIndex":
-    return _pywrapgraph.LinearSumAssignment_RightMate(self, left_node)
-
-
-
-def RightNode(self, arc: operations_research::ArcIndex) ‑> operations_research::NodeIndex -
-
-
-
- -Expand source code - -
def RightNode(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
-    return _pywrapgraph.LinearSumAssignment_RightNode(self, arc)
-
-
-
-def Solve(self) ‑> operations_research::SimpleLinearSumAssignment::Status -
-
-
-
- -Expand source code - -
def Solve(self) -> "operations_research::SimpleLinearSumAssignment::Status":
-    return _pywrapgraph.LinearSumAssignment_Solve(self)
-
-
-
-
-
-class MinCostFlowBase -
-
-
-
- -Expand source code - -
class MinCostFlowBase(object):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-    NOT_SOLVED = _pywrapgraph.MinCostFlowBase_NOT_SOLVED
-    OPTIMAL = _pywrapgraph.MinCostFlowBase_OPTIMAL
-    FEASIBLE = _pywrapgraph.MinCostFlowBase_FEASIBLE
-    INFEASIBLE = _pywrapgraph.MinCostFlowBase_INFEASIBLE
-    UNBALANCED = _pywrapgraph.MinCostFlowBase_UNBALANCED
-    BAD_RESULT = _pywrapgraph.MinCostFlowBase_BAD_RESULT
-    BAD_COST_RANGE = _pywrapgraph.MinCostFlowBase_BAD_COST_RANGE
-
-    def __init__(self):
-        _pywrapgraph.MinCostFlowBase_swiginit(self, _pywrapgraph.new_MinCostFlowBase())
-    __swig_destroy__ = _pywrapgraph.delete_MinCostFlowBase
-
-

Subclasses

- -

Class variables

-
-
var BAD_COST_RANGE
-
-
-
-
var BAD_RESULT
-
-
-
-
var FEASIBLE
-
-
-
-
var INFEASIBLE
-
-
-
-
var NOT_SOLVED
-
-
-
-
var OPTIMAL
-
-
-
-
var UNBALANCED
-
-
-
-
-

Instance variables

-
-
var thisown
-
-

The membership flag

-
- -Expand source code - -
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-
-
-
-
-class SimpleMaxFlow -
-
-
-
- -Expand source code - -
class SimpleMaxFlow(object):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self):
-        _pywrapgraph.SimpleMaxFlow_swiginit(self, _pywrapgraph.new_SimpleMaxFlow())
-
-    def AddArcWithCapacity(self, tail: "operations_research::NodeIndex", head: "operations_research::NodeIndex", capacity: "operations_research::FlowQuantity") -> "operations_research::ArcIndex":
-        return _pywrapgraph.SimpleMaxFlow_AddArcWithCapacity(self, tail, head, capacity)
-
-    def NumNodes(self) -> "operations_research::NodeIndex":
-        return _pywrapgraph.SimpleMaxFlow_NumNodes(self)
-
-    def NumArcs(self) -> "operations_research::ArcIndex":
-        return _pywrapgraph.SimpleMaxFlow_NumArcs(self)
-
-    def Tail(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
-        return _pywrapgraph.SimpleMaxFlow_Tail(self, arc)
-
-    def Head(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
-        return _pywrapgraph.SimpleMaxFlow_Head(self, arc)
-
-    def Capacity(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
-        return _pywrapgraph.SimpleMaxFlow_Capacity(self, arc)
-    OPTIMAL = _pywrapgraph.SimpleMaxFlow_OPTIMAL
-    POSSIBLE_OVERFLOW = _pywrapgraph.SimpleMaxFlow_POSSIBLE_OVERFLOW
-    BAD_INPUT = _pywrapgraph.SimpleMaxFlow_BAD_INPUT
-    BAD_RESULT = _pywrapgraph.SimpleMaxFlow_BAD_RESULT
-
-    def Solve(self, source: "operations_research::NodeIndex", sink: "operations_research::NodeIndex") -> "operations_research::SimpleMaxFlow::Status":
-        return _pywrapgraph.SimpleMaxFlow_Solve(self, source, sink)
-
-    def OptimalFlow(self) -> "operations_research::FlowQuantity":
-        return _pywrapgraph.SimpleMaxFlow_OptimalFlow(self)
-
-    def Flow(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
-        return _pywrapgraph.SimpleMaxFlow_Flow(self, arc)
-
-    def GetSourceSideMinCut(self) -> "void":
-        return _pywrapgraph.SimpleMaxFlow_GetSourceSideMinCut(self)
-
-    def GetSinkSideMinCut(self) -> "void":
-        return _pywrapgraph.SimpleMaxFlow_GetSinkSideMinCut(self)
-
-    def SetArcCapacity(self, arc: "operations_research::ArcIndex", capacity: "operations_research::FlowQuantity") -> "void":
-        return _pywrapgraph.SimpleMaxFlow_SetArcCapacity(self, arc, capacity)
-    __swig_destroy__ = _pywrapgraph.delete_SimpleMaxFlow
-
-

Class variables

-
-
var BAD_INPUT
-
-
-
-
var BAD_RESULT
-
-
-
-
var OPTIMAL
-
-
-
-
var POSSIBLE_OVERFLOW
-
-
-
-
-

Instance variables

-
-
var thisown
-
-

The membership flag

-
- -Expand source code - -
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-
-
-

Methods

-
-
-def AddArcWithCapacity(self, tail: operations_research::NodeIndex, head: operations_research::NodeIndex, capacity: operations_research::FlowQuantity) ‑> operations_research::ArcIndex -
-
-
-
- -Expand source code - -
def AddArcWithCapacity(self, tail: "operations_research::NodeIndex", head: "operations_research::NodeIndex", capacity: "operations_research::FlowQuantity") -> "operations_research::ArcIndex":
-    return _pywrapgraph.SimpleMaxFlow_AddArcWithCapacity(self, tail, head, capacity)
-
-
-
-def Capacity(self, arc: operations_research::ArcIndex) ‑> operations_research::FlowQuantity -
-
-
-
- -Expand source code - -
def Capacity(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
-    return _pywrapgraph.SimpleMaxFlow_Capacity(self, arc)
-
-
-
-def Flow(self, arc: operations_research::ArcIndex) ‑> operations_research::FlowQuantity -
-
-
-
- -Expand source code - -
def Flow(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
-    return _pywrapgraph.SimpleMaxFlow_Flow(self, arc)
-
-
-
-def GetSinkSideMinCut(self) ‑> void -
-
-
-
- -Expand source code - -
def GetSinkSideMinCut(self) -> "void":
-    return _pywrapgraph.SimpleMaxFlow_GetSinkSideMinCut(self)
-
-
-
-def GetSourceSideMinCut(self) ‑> void -
-
-
-
- -Expand source code - -
def GetSourceSideMinCut(self) -> "void":
-    return _pywrapgraph.SimpleMaxFlow_GetSourceSideMinCut(self)
-
-
-
-def Head(self, arc: operations_research::ArcIndex) ‑> operations_research::NodeIndex -
-
-
-
- -Expand source code - -
def Head(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
-    return _pywrapgraph.SimpleMaxFlow_Head(self, arc)
-
-
-
-def NumArcs(self) ‑> operations_research::ArcIndex -
-
-
-
- -Expand source code - -
def NumArcs(self) -> "operations_research::ArcIndex":
-    return _pywrapgraph.SimpleMaxFlow_NumArcs(self)
-
-
-
-def NumNodes(self) ‑> operations_research::NodeIndex -
-
-
-
- -Expand source code - -
def NumNodes(self) -> "operations_research::NodeIndex":
-    return _pywrapgraph.SimpleMaxFlow_NumNodes(self)
-
-
-
-def OptimalFlow(self) ‑> operations_research::FlowQuantity -
-
-
-
- -Expand source code - -
def OptimalFlow(self) -> "operations_research::FlowQuantity":
-    return _pywrapgraph.SimpleMaxFlow_OptimalFlow(self)
-
-
-
-def SetArcCapacity(self, arc: operations_research::ArcIndex, capacity: operations_research::FlowQuantity) ‑> void -
-
-
-
- -Expand source code - -
def SetArcCapacity(self, arc: "operations_research::ArcIndex", capacity: "operations_research::FlowQuantity") -> "void":
-    return _pywrapgraph.SimpleMaxFlow_SetArcCapacity(self, arc, capacity)
-
-
-
-def Solve(self, source: operations_research::NodeIndex, sink: operations_research::NodeIndex) ‑> operations_research::SimpleMaxFlow::Status -
-
-
-
- -Expand source code - -
def Solve(self, source: "operations_research::NodeIndex", sink: "operations_research::NodeIndex") -> "operations_research::SimpleMaxFlow::Status":
-    return _pywrapgraph.SimpleMaxFlow_Solve(self, source, sink)
-
-
-
-def Tail(self, arc: operations_research::ArcIndex) ‑> operations_research::NodeIndex -
-
-
-
- -Expand source code - -
def Tail(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
-    return _pywrapgraph.SimpleMaxFlow_Tail(self, arc)
-
-
-
-
-
-class SimpleMinCostFlow -(reserve_num_nodes: operations_research::NodeIndex = 0, reserve_num_arcs: operations_research::ArcIndex = 0) -
-
-
-
- -Expand source code - -
class SimpleMinCostFlow(MinCostFlowBase):
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self, reserve_num_nodes: "operations_research::NodeIndex"=0, reserve_num_arcs: "operations_research::ArcIndex"=0):
-        _pywrapgraph.SimpleMinCostFlow_swiginit(self, _pywrapgraph.new_SimpleMinCostFlow(reserve_num_nodes, reserve_num_arcs))
-
-    def AddArcWithCapacityAndUnitCost(self, tail: "operations_research::NodeIndex", head: "operations_research::NodeIndex", capacity: "operations_research::FlowQuantity", unit_cost: "operations_research::CostValue") -> "operations_research::ArcIndex":
-        return _pywrapgraph.SimpleMinCostFlow_AddArcWithCapacityAndUnitCost(self, tail, head, capacity, unit_cost)
-
-    def SetNodeSupply(self, node: "operations_research::NodeIndex", supply: "operations_research::FlowQuantity") -> "void":
-        return _pywrapgraph.SimpleMinCostFlow_SetNodeSupply(self, node, supply)
-
-    def Solve(self) -> "operations_research::MinCostFlowBase::Status":
-        return _pywrapgraph.SimpleMinCostFlow_Solve(self)
-
-    def SolveMaxFlowWithMinCost(self) -> "operations_research::MinCostFlowBase::Status":
-        return _pywrapgraph.SimpleMinCostFlow_SolveMaxFlowWithMinCost(self)
-
-    def OptimalCost(self) -> "operations_research::CostValue":
-        return _pywrapgraph.SimpleMinCostFlow_OptimalCost(self)
-
-    def MaximumFlow(self) -> "operations_research::FlowQuantity":
-        return _pywrapgraph.SimpleMinCostFlow_MaximumFlow(self)
-
-    def Flow(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
-        return _pywrapgraph.SimpleMinCostFlow_Flow(self, arc)
-
-    def NumNodes(self) -> "operations_research::NodeIndex":
-        return _pywrapgraph.SimpleMinCostFlow_NumNodes(self)
-
-    def NumArcs(self) -> "operations_research::ArcIndex":
-        return _pywrapgraph.SimpleMinCostFlow_NumArcs(self)
-
-    def Tail(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
-        return _pywrapgraph.SimpleMinCostFlow_Tail(self, arc)
-
-    def Head(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
-        return _pywrapgraph.SimpleMinCostFlow_Head(self, arc)
-
-    def Capacity(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
-        return _pywrapgraph.SimpleMinCostFlow_Capacity(self, arc)
-
-    def Supply(self, node: "operations_research::NodeIndex") -> "operations_research::FlowQuantity":
-        return _pywrapgraph.SimpleMinCostFlow_Supply(self, node)
-
-    def UnitCost(self, arc: "operations_research::ArcIndex") -> "operations_research::CostValue":
-        return _pywrapgraph.SimpleMinCostFlow_UnitCost(self, arc)
-    __swig_destroy__ = _pywrapgraph.delete_SimpleMinCostFlow
-
-

Ancestors

- -

Methods

-
-
-def AddArcWithCapacityAndUnitCost(self, tail: operations_research::NodeIndex, head: operations_research::NodeIndex, capacity: operations_research::FlowQuantity, unit_cost: operations_research::CostValue) ‑> operations_research::ArcIndex -
-
-
-
- -Expand source code - -
def AddArcWithCapacityAndUnitCost(self, tail: "operations_research::NodeIndex", head: "operations_research::NodeIndex", capacity: "operations_research::FlowQuantity", unit_cost: "operations_research::CostValue") -> "operations_research::ArcIndex":
-    return _pywrapgraph.SimpleMinCostFlow_AddArcWithCapacityAndUnitCost(self, tail, head, capacity, unit_cost)
-
-
-
-def Capacity(self, arc: operations_research::ArcIndex) ‑> operations_research::FlowQuantity -
-
-
-
- -Expand source code - -
def Capacity(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
-    return _pywrapgraph.SimpleMinCostFlow_Capacity(self, arc)
-
-
-
-def Flow(self, arc: operations_research::ArcIndex) ‑> operations_research::FlowQuantity -
-
-
-
- -Expand source code - -
def Flow(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
-    return _pywrapgraph.SimpleMinCostFlow_Flow(self, arc)
-
-
-
-def Head(self, arc: operations_research::ArcIndex) ‑> operations_research::NodeIndex -
-
-
-
- -Expand source code - -
def Head(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
-    return _pywrapgraph.SimpleMinCostFlow_Head(self, arc)
-
-
-
-def MaximumFlow(self) ‑> operations_research::FlowQuantity -
-
-
-
- -Expand source code - -
def MaximumFlow(self) -> "operations_research::FlowQuantity":
-    return _pywrapgraph.SimpleMinCostFlow_MaximumFlow(self)
-
-
-
-def NumArcs(self) ‑> operations_research::ArcIndex -
-
-
-
- -Expand source code - -
def NumArcs(self) -> "operations_research::ArcIndex":
-    return _pywrapgraph.SimpleMinCostFlow_NumArcs(self)
-
-
-
-def NumNodes(self) ‑> operations_research::NodeIndex -
-
-
-
- -Expand source code - -
def NumNodes(self) -> "operations_research::NodeIndex":
-    return _pywrapgraph.SimpleMinCostFlow_NumNodes(self)
-
-
-
-def OptimalCost(self) ‑> operations_research::CostValue -
-
-
-
- -Expand source code - -
def OptimalCost(self) -> "operations_research::CostValue":
-    return _pywrapgraph.SimpleMinCostFlow_OptimalCost(self)
-
-
-
-def SetNodeSupply(self, node: operations_research::NodeIndex, supply: operations_research::FlowQuantity) ‑> void -
-
-
-
- -Expand source code - -
def SetNodeSupply(self, node: "operations_research::NodeIndex", supply: "operations_research::FlowQuantity") -> "void":
-    return _pywrapgraph.SimpleMinCostFlow_SetNodeSupply(self, node, supply)
-
-
-
-def Solve(self) ‑> operations_research::MinCostFlowBase::Status -
-
-
-
- -Expand source code - -
def Solve(self) -> "operations_research::MinCostFlowBase::Status":
-    return _pywrapgraph.SimpleMinCostFlow_Solve(self)
-
-
-
-def SolveMaxFlowWithMinCost(self) ‑> operations_research::MinCostFlowBase::Status -
-
-
-
- -Expand source code - -
def SolveMaxFlowWithMinCost(self) -> "operations_research::MinCostFlowBase::Status":
-    return _pywrapgraph.SimpleMinCostFlow_SolveMaxFlowWithMinCost(self)
-
-
-
-def Supply(self, node: operations_research::NodeIndex) ‑> operations_research::FlowQuantity -
-
-
-
- -Expand source code - -
def Supply(self, node: "operations_research::NodeIndex") -> "operations_research::FlowQuantity":
-    return _pywrapgraph.SimpleMinCostFlow_Supply(self, node)
-
-
-
-def Tail(self, arc: operations_research::ArcIndex) ‑> operations_research::NodeIndex -
-
-
-
- -Expand source code - -
def Tail(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
-    return _pywrapgraph.SimpleMinCostFlow_Tail(self, arc)
-
-
-
-def UnitCost(self, arc: operations_research::ArcIndex) ‑> operations_research::CostValue -
-
-
-
- -Expand source code - -
def UnitCost(self, arc: "operations_research::ArcIndex") -> "operations_research::CostValue":
-    return _pywrapgraph.SimpleMinCostFlow_UnitCost(self, arc)
-
-
-
-

Inherited members

- -
-
-
-
- -
- + + + +
+
#   + + + def + AddArcWithCapacity( + self, + tail: 'operations_research::NodeIndex', + head: 'operations_research::NodeIndex', + capacity: 'operations_research::FlowQuantity' +) -> 'operations_research::ArcIndex': +
+ +
+ View Source +
    def AddArcWithCapacity(self, tail: "operations_research::NodeIndex", head: "operations_research::NodeIndex", capacity: "operations_research::FlowQuantity") -> "operations_research::ArcIndex":
+        return _pywrapgraph.SimpleMaxFlow_AddArcWithCapacity(self, tail, head, capacity)
+
+ +
+ + + +
+
+
#   + + + def + NumNodes(self) -> 'operations_research::NodeIndex': +
+ +
+ View Source +
    def NumNodes(self) -> "operations_research::NodeIndex":
+        return _pywrapgraph.SimpleMaxFlow_NumNodes(self)
+
+ +
+ + + +
+
+
#   + + + def + NumArcs(self) -> 'operations_research::ArcIndex': +
+ +
+ View Source +
    def NumArcs(self) -> "operations_research::ArcIndex":
+        return _pywrapgraph.SimpleMaxFlow_NumArcs(self)
+
+ +
+ + + +
+
+
#   + + + def + Tail( + self, + arc: 'operations_research::ArcIndex' +) -> 'operations_research::NodeIndex': +
+ +
+ View Source +
    def Tail(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
+        return _pywrapgraph.SimpleMaxFlow_Tail(self, arc)
+
+ +
+ + + +
+
+
#   + + + def + Head( + self, + arc: 'operations_research::ArcIndex' +) -> 'operations_research::NodeIndex': +
+ +
+ View Source +
    def Head(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
+        return _pywrapgraph.SimpleMaxFlow_Head(self, arc)
+
+ +
+ + + +
+
+
#   + + + def + Capacity( + self, + arc: 'operations_research::ArcIndex' +) -> 'operations_research::FlowQuantity': +
+ +
+ View Source +
    def Capacity(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
+        return _pywrapgraph.SimpleMaxFlow_Capacity(self, arc)
+
+ +
+ + + +
+
+
#   + + OPTIMAL = 0 +
+ + + +
+
+
#   + + POSSIBLE_OVERFLOW = 1 +
+ + + +
+
+
#   + + BAD_INPUT = 2 +
+ + + +
+
+
#   + + BAD_RESULT = 3 +
+ + + +
+
+
#   + + + def + Solve( + self, + source: 'operations_research::NodeIndex', + sink: 'operations_research::NodeIndex' +) -> 'operations_research::SimpleMaxFlow::Status': +
+ +
+ View Source +
    def Solve(self, source: "operations_research::NodeIndex", sink: "operations_research::NodeIndex") -> "operations_research::SimpleMaxFlow::Status":
+        return _pywrapgraph.SimpleMaxFlow_Solve(self, source, sink)
+
+ +
+ + + +
+
+
#   + + + def + OptimalFlow(self) -> 'operations_research::FlowQuantity': +
+ +
+ View Source +
    def OptimalFlow(self) -> "operations_research::FlowQuantity":
+        return _pywrapgraph.SimpleMaxFlow_OptimalFlow(self)
+
+ +
+ + + +
+
+
#   + + + def + Flow( + self, + arc: 'operations_research::ArcIndex' +) -> 'operations_research::FlowQuantity': +
+ +
+ View Source +
    def Flow(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
+        return _pywrapgraph.SimpleMaxFlow_Flow(self, arc)
+
+ +
+ + + +
+
+
#   + + + def + GetSourceSideMinCut(self) -> 'void': +
+ +
+ View Source +
    def GetSourceSideMinCut(self) -> "void":
+        return _pywrapgraph.SimpleMaxFlow_GetSourceSideMinCut(self)
+
+ +
+ + + +
+
+
#   + + + def + GetSinkSideMinCut(self) -> 'void': +
+ +
+ View Source +
    def GetSinkSideMinCut(self) -> "void":
+        return _pywrapgraph.SimpleMaxFlow_GetSinkSideMinCut(self)
+
+ +
+ + + +
+
+
#   + + + def + SetArcCapacity( + self, + arc: 'operations_research::ArcIndex', + capacity: 'operations_research::FlowQuantity' +) -> 'void': +
+ +
+ View Source +
    def SetArcCapacity(self, arc: "operations_research::ArcIndex", capacity: "operations_research::FlowQuantity") -> "void":
+        return _pywrapgraph.SimpleMaxFlow_SetArcCapacity(self, arc, capacity)
+
+ +
+ + + +
+ +
+
+ #   + + + class + MinCostFlowBase: +
+ +
+ View Source +
class MinCostFlowBase(object):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+    NOT_SOLVED = _pywrapgraph.MinCostFlowBase_NOT_SOLVED
+    OPTIMAL = _pywrapgraph.MinCostFlowBase_OPTIMAL
+    FEASIBLE = _pywrapgraph.MinCostFlowBase_FEASIBLE
+    INFEASIBLE = _pywrapgraph.MinCostFlowBase_INFEASIBLE
+    UNBALANCED = _pywrapgraph.MinCostFlowBase_UNBALANCED
+    BAD_RESULT = _pywrapgraph.MinCostFlowBase_BAD_RESULT
+    BAD_COST_RANGE = _pywrapgraph.MinCostFlowBase_BAD_COST_RANGE
+
+    def __init__(self):
+        _pywrapgraph.MinCostFlowBase_swiginit(self, _pywrapgraph.new_MinCostFlowBase())
+    __swig_destroy__ = _pywrapgraph.delete_MinCostFlowBase
+
+ +
+ + + +
+
#   + + + MinCostFlowBase() +
+ +
+ View Source +
    def __init__(self):
+        _pywrapgraph.MinCostFlowBase_swiginit(self, _pywrapgraph.new_MinCostFlowBase())
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + NOT_SOLVED = 0 +
+ + + +
+
+
#   + + OPTIMAL = 1 +
+ + + +
+
+
#   + + FEASIBLE = 2 +
+ + + +
+
+
#   + + INFEASIBLE = 3 +
+ + + +
+
+
#   + + UNBALANCED = 4 +
+ + + +
+
+
#   + + BAD_RESULT = 5 +
+ + + +
+
+
#   + + BAD_COST_RANGE = 6 +
+ + + +
+
+
+
+ #   + + + class + SimpleMinCostFlow(MinCostFlowBase): +
+ +
+ View Source +
class SimpleMinCostFlow(MinCostFlowBase):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, reserve_num_nodes: "operations_research::NodeIndex"=0, reserve_num_arcs: "operations_research::ArcIndex"=0):
+        _pywrapgraph.SimpleMinCostFlow_swiginit(self, _pywrapgraph.new_SimpleMinCostFlow(reserve_num_nodes, reserve_num_arcs))
+
+    def AddArcWithCapacityAndUnitCost(self, tail: "operations_research::NodeIndex", head: "operations_research::NodeIndex", capacity: "operations_research::FlowQuantity", unit_cost: "operations_research::CostValue") -> "operations_research::ArcIndex":
+        return _pywrapgraph.SimpleMinCostFlow_AddArcWithCapacityAndUnitCost(self, tail, head, capacity, unit_cost)
+
+    def SetNodeSupply(self, node: "operations_research::NodeIndex", supply: "operations_research::FlowQuantity") -> "void":
+        return _pywrapgraph.SimpleMinCostFlow_SetNodeSupply(self, node, supply)
+
+    def Solve(self) -> "operations_research::MinCostFlowBase::Status":
+        return _pywrapgraph.SimpleMinCostFlow_Solve(self)
+
+    def SolveMaxFlowWithMinCost(self) -> "operations_research::MinCostFlowBase::Status":
+        return _pywrapgraph.SimpleMinCostFlow_SolveMaxFlowWithMinCost(self)
+
+    def OptimalCost(self) -> "operations_research::CostValue":
+        return _pywrapgraph.SimpleMinCostFlow_OptimalCost(self)
+
+    def MaximumFlow(self) -> "operations_research::FlowQuantity":
+        return _pywrapgraph.SimpleMinCostFlow_MaximumFlow(self)
+
+    def Flow(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
+        return _pywrapgraph.SimpleMinCostFlow_Flow(self, arc)
+
+    def NumNodes(self) -> "operations_research::NodeIndex":
+        return _pywrapgraph.SimpleMinCostFlow_NumNodes(self)
+
+    def NumArcs(self) -> "operations_research::ArcIndex":
+        return _pywrapgraph.SimpleMinCostFlow_NumArcs(self)
+
+    def Tail(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
+        return _pywrapgraph.SimpleMinCostFlow_Tail(self, arc)
+
+    def Head(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
+        return _pywrapgraph.SimpleMinCostFlow_Head(self, arc)
+
+    def Capacity(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
+        return _pywrapgraph.SimpleMinCostFlow_Capacity(self, arc)
+
+    def Supply(self, node: "operations_research::NodeIndex") -> "operations_research::FlowQuantity":
+        return _pywrapgraph.SimpleMinCostFlow_Supply(self, node)
+
+    def UnitCost(self, arc: "operations_research::ArcIndex") -> "operations_research::CostValue":
+        return _pywrapgraph.SimpleMinCostFlow_UnitCost(self, arc)
+    __swig_destroy__ = _pywrapgraph.delete_SimpleMinCostFlow
+
+ +
+ + + +
+
#   + + + SimpleMinCostFlow( + reserve_num_nodes: 'operations_research::NodeIndex' = 0, + reserve_num_arcs: 'operations_research::ArcIndex' = 0 +) +
+ +
+ View Source +
    def __init__(self, reserve_num_nodes: "operations_research::NodeIndex"=0, reserve_num_arcs: "operations_research::ArcIndex"=0):
+        _pywrapgraph.SimpleMinCostFlow_swiginit(self, _pywrapgraph.new_SimpleMinCostFlow(reserve_num_nodes, reserve_num_arcs))
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + AddArcWithCapacityAndUnitCost( + self, + tail: 'operations_research::NodeIndex', + head: 'operations_research::NodeIndex', + capacity: 'operations_research::FlowQuantity', + unit_cost: 'operations_research::CostValue' +) -> 'operations_research::ArcIndex': +
+ +
+ View Source +
    def AddArcWithCapacityAndUnitCost(self, tail: "operations_research::NodeIndex", head: "operations_research::NodeIndex", capacity: "operations_research::FlowQuantity", unit_cost: "operations_research::CostValue") -> "operations_research::ArcIndex":
+        return _pywrapgraph.SimpleMinCostFlow_AddArcWithCapacityAndUnitCost(self, tail, head, capacity, unit_cost)
+
+ +
+ + + +
+
+
#   + + + def + SetNodeSupply( + self, + node: 'operations_research::NodeIndex', + supply: 'operations_research::FlowQuantity' +) -> 'void': +
+ +
+ View Source +
    def SetNodeSupply(self, node: "operations_research::NodeIndex", supply: "operations_research::FlowQuantity") -> "void":
+        return _pywrapgraph.SimpleMinCostFlow_SetNodeSupply(self, node, supply)
+
+ +
+ + + +
+
+
#   + + + def + Solve(self) -> 'operations_research::MinCostFlowBase::Status': +
+ +
+ View Source +
    def Solve(self) -> "operations_research::MinCostFlowBase::Status":
+        return _pywrapgraph.SimpleMinCostFlow_Solve(self)
+
+ +
+ + + +
+
+
#   + + + def + SolveMaxFlowWithMinCost(self) -> 'operations_research::MinCostFlowBase::Status': +
+ +
+ View Source +
    def SolveMaxFlowWithMinCost(self) -> "operations_research::MinCostFlowBase::Status":
+        return _pywrapgraph.SimpleMinCostFlow_SolveMaxFlowWithMinCost(self)
+
+ +
+ + + +
+
+
#   + + + def + OptimalCost(self) -> 'operations_research::CostValue': +
+ +
+ View Source +
    def OptimalCost(self) -> "operations_research::CostValue":
+        return _pywrapgraph.SimpleMinCostFlow_OptimalCost(self)
+
+ +
+ + + +
+
+
#   + + + def + MaximumFlow(self) -> 'operations_research::FlowQuantity': +
+ +
+ View Source +
    def MaximumFlow(self) -> "operations_research::FlowQuantity":
+        return _pywrapgraph.SimpleMinCostFlow_MaximumFlow(self)
+
+ +
+ + + +
+
+
#   + + + def + Flow( + self, + arc: 'operations_research::ArcIndex' +) -> 'operations_research::FlowQuantity': +
+ +
+ View Source +
    def Flow(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
+        return _pywrapgraph.SimpleMinCostFlow_Flow(self, arc)
+
+ +
+ + + +
+
+
#   + + + def + NumNodes(self) -> 'operations_research::NodeIndex': +
+ +
+ View Source +
    def NumNodes(self) -> "operations_research::NodeIndex":
+        return _pywrapgraph.SimpleMinCostFlow_NumNodes(self)
+
+ +
+ + + +
+
+
#   + + + def + NumArcs(self) -> 'operations_research::ArcIndex': +
+ +
+ View Source +
    def NumArcs(self) -> "operations_research::ArcIndex":
+        return _pywrapgraph.SimpleMinCostFlow_NumArcs(self)
+
+ +
+ + + +
+
+
#   + + + def + Tail( + self, + arc: 'operations_research::ArcIndex' +) -> 'operations_research::NodeIndex': +
+ +
+ View Source +
    def Tail(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
+        return _pywrapgraph.SimpleMinCostFlow_Tail(self, arc)
+
+ +
+ + + +
+
+
#   + + + def + Head( + self, + arc: 'operations_research::ArcIndex' +) -> 'operations_research::NodeIndex': +
+ +
+ View Source +
    def Head(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
+        return _pywrapgraph.SimpleMinCostFlow_Head(self, arc)
+
+ +
+ + + +
+
+
#   + + + def + Capacity( + self, + arc: 'operations_research::ArcIndex' +) -> 'operations_research::FlowQuantity': +
+ +
+ View Source +
    def Capacity(self, arc: "operations_research::ArcIndex") -> "operations_research::FlowQuantity":
+        return _pywrapgraph.SimpleMinCostFlow_Capacity(self, arc)
+
+ +
+ + + +
+
+
#   + + + def + Supply( + self, + node: 'operations_research::NodeIndex' +) -> 'operations_research::FlowQuantity': +
+ +
+ View Source +
    def Supply(self, node: "operations_research::NodeIndex") -> "operations_research::FlowQuantity":
+        return _pywrapgraph.SimpleMinCostFlow_Supply(self, node)
+
+ +
+ + + +
+
+
#   + + + def + UnitCost( + self, + arc: 'operations_research::ArcIndex' +) -> 'operations_research::CostValue': +
+ +
+ View Source +
    def UnitCost(self, arc: "operations_research::ArcIndex") -> "operations_research::CostValue":
+        return _pywrapgraph.SimpleMinCostFlow_UnitCost(self, arc)
+
+ +
+ + + +
+ +
+
+
+ #   + + + class + LinearSumAssignment: +
+ +
+ View Source +
class LinearSumAssignment(object):
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self):
+        _pywrapgraph.LinearSumAssignment_swiginit(self, _pywrapgraph.new_LinearSumAssignment())
+
+    def AddArcWithCost(self, left_node: "operations_research::NodeIndex", right_node: "operations_research::NodeIndex", cost: "operations_research::CostValue") -> "operations_research::ArcIndex":
+        return _pywrapgraph.LinearSumAssignment_AddArcWithCost(self, left_node, right_node, cost)
+
+    def NumNodes(self) -> "operations_research::NodeIndex":
+        return _pywrapgraph.LinearSumAssignment_NumNodes(self)
+
+    def NumArcs(self) -> "operations_research::ArcIndex":
+        return _pywrapgraph.LinearSumAssignment_NumArcs(self)
+
+    def LeftNode(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
+        return _pywrapgraph.LinearSumAssignment_LeftNode(self, arc)
+
+    def RightNode(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
+        return _pywrapgraph.LinearSumAssignment_RightNode(self, arc)
+
+    def Cost(self, arc: "operations_research::ArcIndex") -> "operations_research::CostValue":
+        return _pywrapgraph.LinearSumAssignment_Cost(self, arc)
+    OPTIMAL = _pywrapgraph.LinearSumAssignment_OPTIMAL
+    INFEASIBLE = _pywrapgraph.LinearSumAssignment_INFEASIBLE
+    POSSIBLE_OVERFLOW = _pywrapgraph.LinearSumAssignment_POSSIBLE_OVERFLOW
+
+    def Solve(self) -> "operations_research::SimpleLinearSumAssignment::Status":
+        return _pywrapgraph.LinearSumAssignment_Solve(self)
+
+    def OptimalCost(self) -> "operations_research::CostValue":
+        return _pywrapgraph.LinearSumAssignment_OptimalCost(self)
+
+    def RightMate(self, left_node: "operations_research::NodeIndex") -> "operations_research::NodeIndex":
+        return _pywrapgraph.LinearSumAssignment_RightMate(self, left_node)
+
+    def AssignmentCost(self, left_node: "operations_research::NodeIndex") -> "operations_research::CostValue":
+        return _pywrapgraph.LinearSumAssignment_AssignmentCost(self, left_node)
+    __swig_destroy__ = _pywrapgraph.delete_LinearSumAssignment
+
+ +
+ + + +
+
#   + + + LinearSumAssignment() +
+ +
+ View Source +
    def __init__(self):
+        _pywrapgraph.LinearSumAssignment_swiginit(self, _pywrapgraph.new_LinearSumAssignment())
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + AddArcWithCost( + self, + left_node: 'operations_research::NodeIndex', + right_node: 'operations_research::NodeIndex', + cost: 'operations_research::CostValue' +) -> 'operations_research::ArcIndex': +
+ +
+ View Source +
    def AddArcWithCost(self, left_node: "operations_research::NodeIndex", right_node: "operations_research::NodeIndex", cost: "operations_research::CostValue") -> "operations_research::ArcIndex":
+        return _pywrapgraph.LinearSumAssignment_AddArcWithCost(self, left_node, right_node, cost)
+
+ +
+ + + +
+
+
#   + + + def + NumNodes(self) -> 'operations_research::NodeIndex': +
+ +
+ View Source +
    def NumNodes(self) -> "operations_research::NodeIndex":
+        return _pywrapgraph.LinearSumAssignment_NumNodes(self)
+
+ +
+ + + +
+
+
#   + + + def + NumArcs(self) -> 'operations_research::ArcIndex': +
+ +
+ View Source +
    def NumArcs(self) -> "operations_research::ArcIndex":
+        return _pywrapgraph.LinearSumAssignment_NumArcs(self)
+
+ +
+ + + +
+
+
#   + + + def + LeftNode( + self, + arc: 'operations_research::ArcIndex' +) -> 'operations_research::NodeIndex': +
+ +
+ View Source +
    def LeftNode(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
+        return _pywrapgraph.LinearSumAssignment_LeftNode(self, arc)
+
+ +
+ + + +
+
+
#   + + + def + RightNode( + self, + arc: 'operations_research::ArcIndex' +) -> 'operations_research::NodeIndex': +
+ +
+ View Source +
    def RightNode(self, arc: "operations_research::ArcIndex") -> "operations_research::NodeIndex":
+        return _pywrapgraph.LinearSumAssignment_RightNode(self, arc)
+
+ +
+ + + +
+
+
#   + + + def + Cost( + self, + arc: 'operations_research::ArcIndex' +) -> 'operations_research::CostValue': +
+ +
+ View Source +
    def Cost(self, arc: "operations_research::ArcIndex") -> "operations_research::CostValue":
+        return _pywrapgraph.LinearSumAssignment_Cost(self, arc)
+
+ +
+ + + +
+
+
#   + + OPTIMAL = 0 +
+ + + +
+
+
#   + + INFEASIBLE = 1 +
+ + + +
+
+
#   + + POSSIBLE_OVERFLOW = 2 +
+ + + +
+
+
#   + + + def + Solve(self) -> 'operations_research::SimpleLinearSumAssignment::Status': +
+ +
+ View Source +
    def Solve(self) -> "operations_research::SimpleLinearSumAssignment::Status":
+        return _pywrapgraph.LinearSumAssignment_Solve(self)
+
+ +
+ + + +
+
+
#   + + + def + OptimalCost(self) -> 'operations_research::CostValue': +
+ +
+ View Source +
    def OptimalCost(self) -> "operations_research::CostValue":
+        return _pywrapgraph.LinearSumAssignment_OptimalCost(self)
+
+ +
+ + + +
+
+
#   + + + def + RightMate( + self, + left_node: 'operations_research::NodeIndex' +) -> 'operations_research::NodeIndex': +
+ +
+ View Source +
    def RightMate(self, left_node: "operations_research::NodeIndex") -> "operations_research::NodeIndex":
+        return _pywrapgraph.LinearSumAssignment_RightMate(self, left_node)
+
+ +
+ + + +
+
+
#   + + + def + AssignmentCost( + self, + left_node: 'operations_research::NodeIndex' +) -> 'operations_research::CostValue': +
+ +
+ View Source +
    def AssignmentCost(self, left_node: "operations_research::NodeIndex") -> "operations_research::CostValue":
+        return _pywrapgraph.LinearSumAssignment_AssignmentCost(self, left_node)
+
+ +
+ + + +
+
+
+
#   + + + def + DijkstraShortestPath( + node_count: int, + start_node: int, + end_node: int, + graph: 'std::function< int64_t (int,int) >', + disconnected_distance: 'int64_t' +) -> 'std::vector< int > *': +
+ +
+ View Source +
def DijkstraShortestPath(node_count: "int", start_node: "int", end_node: "int", graph: "std::function< int64_t (int,int) >", disconnected_distance: "int64_t") -> "std::vector< int > *":
+    return _pywrapgraph.DijkstraShortestPath(node_count, start_node, end_node, graph, disconnected_distance)
+
+ +
+ + + +
+
+
#   + + + def + BellmanFordShortestPath( + node_count: int, + start_node: int, + end_node: int, + graph: 'std::function< int64_t (int,int) >', + disconnected_distance: 'int64_t' +) -> 'std::vector< int > *': +
+ +
+ View Source +
def BellmanFordShortestPath(node_count: "int", start_node: "int", end_node: "int", graph: "std::function< int64_t (int,int) >", disconnected_distance: "int64_t") -> "std::vector< int > *":
+    return _pywrapgraph.BellmanFordShortestPath(node_count, start_node, end_node, graph, disconnected_distance)
+
+ +
+ + + +
+
+
#   + + + def + AStarShortestPath( + node_count: int, + start_node: int, + end_node: int, + graph: 'std::function< int64_t (int,int) >', + heuristic: 'std::function< int64_t (int) >', + disconnected_distance: 'int64_t' +) -> 'std::vector< int > *': +
+ +
+ View Source +
def AStarShortestPath(node_count: "int", start_node: "int", end_node: "int", graph: "std::function< int64_t (int,int) >", heuristic: "std::function< int64_t (int) >", disconnected_distance: "int64_t") -> "std::vector< int > *":
+    return _pywrapgraph.AStarShortestPath(node_count, start_node, end_node, graph, heuristic, disconnected_distance)
+
+ +
+ + + +
+ \ No newline at end of file diff --git a/docs/python/ortools/linear_solver/pywraplp.html b/docs/python/ortools/linear_solver/pywraplp.html index 1637875013..b477cc6fc1 100644 --- a/docs/python/ortools/linear_solver/pywraplp.html +++ b/docs/python/ortools/linear_solver/pywraplp.html @@ -1,4430 +1,6271 @@ - - - -pywraplp API documentation - - - - - - - - - - - + + + + pywraplp API documentation + + + + + + - -
-
-
-

Module pywraplp

-
-
-
- -Expand source code - -
# This file was automatically generated by SWIG (http://www.swig.org).
-# Version 4.0.2
-#
-# Do not make changes to this file unless you know what you are doing--modify
-# the SWIG interface file instead.
-
-from sys import version_info as _swig_python_version_info
-if _swig_python_version_info < (2, 7, 0):
-    raise RuntimeError("Python 2.7 or later required")
-
-# Import the low-level C/C++ module
-if __package__ or "." in __name__:
-    from . import _pywraplp
-else:
-    import _pywraplp
-
-try:
-    import builtins as __builtin__
-except ImportError:
-    import __builtin__
-
-def _swig_repr(self):
-    try:
-        strthis = "proxy of " + self.this.__repr__()
-    except __builtin__.Exception:
-        strthis = ""
-    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
-
-
-def _swig_setattr_nondynamic_instance_variable(set):
-    def set_instance_attr(self, name, value):
-        if name == "thisown":
-            self.this.own(value)
-        elif name == "this":
-            set(self, name, value)
-        elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
-            set(self, name, value)
-        else:
-            raise AttributeError("You cannot add instance attributes to %s" % self)
-    return set_instance_attr
-
-
-def _swig_setattr_nondynamic_class_variable(set):
-    def set_class_attr(cls, name, value):
-        if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
-            set(cls, name, value)
-        else:
-            raise AttributeError("You cannot add class attributes to %s" % cls)
-    return set_class_attr
-
-
-def _swig_add_metaclass(metaclass):
-    """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
-    def wrapper(cls):
-        return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
-    return wrapper
-
-
-class _SwigNonDynamicMeta(type):
-    """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
-    __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)
-
-
-
-import numbers
-from ortools.linear_solver.linear_solver_natural_api import OFFSET_KEY
-from ortools.linear_solver.linear_solver_natural_api import inf
-from ortools.linear_solver.linear_solver_natural_api import LinearExpr
-from ortools.linear_solver.linear_solver_natural_api import ProductCst
-from ortools.linear_solver.linear_solver_natural_api import Sum
-from ortools.linear_solver.linear_solver_natural_api import SumArray
-from ortools.linear_solver.linear_solver_natural_api import SumCst
-from ortools.linear_solver.linear_solver_natural_api import LinearConstraint
-from ortools.linear_solver.linear_solver_natural_api import VariableExpr
-
-# Remove the documentation of some functions.
-# See https://pdoc3.github.io/pdoc/doc/pdoc/#overriding-docstrings-with-
-__pdoc__ = {}
-__pdoc__['Solver_infinity'] = False
-__pdoc__['Solver_Infinity'] = False
-__pdoc__['Solver_SolveWithProto'] = False
-__pdoc__['Solver_SupportsProblemType'] = False
-__pdoc__['setup_variable_operator'] = False
-__pdoc__['Constraint.thisown'] = False
-__pdoc__['Constraint.thisown'] = False
-__pdoc__['MPSolverParameters.thisown'] = False
-__pdoc__['ModelExportOptions.thisown'] = False
-__pdoc__['Objective.thisown'] = False
-__pdoc__['Solver.thisown'] = False
-__pdoc__['Variable.thisown'] = False
-
-class Solver(object):
-    r"""
-    This mathematical programming (MP) solver class is the main class
-    though which users build and solve problems.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-    CLP_LINEAR_PROGRAMMING = _pywraplp.Solver_CLP_LINEAR_PROGRAMMING
-    GLPK_LINEAR_PROGRAMMING = _pywraplp.Solver_GLPK_LINEAR_PROGRAMMING
-    GLOP_LINEAR_PROGRAMMING = _pywraplp.Solver_GLOP_LINEAR_PROGRAMMING
-    SCIP_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_SCIP_MIXED_INTEGER_PROGRAMMING
-    GLPK_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_GLPK_MIXED_INTEGER_PROGRAMMING
-    CBC_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_CBC_MIXED_INTEGER_PROGRAMMING
-    GUROBI_LINEAR_PROGRAMMING = _pywraplp.Solver_GUROBI_LINEAR_PROGRAMMING
-    GUROBI_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_GUROBI_MIXED_INTEGER_PROGRAMMING
-    CPLEX_LINEAR_PROGRAMMING = _pywraplp.Solver_CPLEX_LINEAR_PROGRAMMING
-    CPLEX_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_CPLEX_MIXED_INTEGER_PROGRAMMING
-    XPRESS_LINEAR_PROGRAMMING = _pywraplp.Solver_XPRESS_LINEAR_PROGRAMMING
-    XPRESS_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_XPRESS_MIXED_INTEGER_PROGRAMMING
-    BOP_INTEGER_PROGRAMMING = _pywraplp.Solver_BOP_INTEGER_PROGRAMMING
-    SAT_INTEGER_PROGRAMMING = _pywraplp.Solver_SAT_INTEGER_PROGRAMMING
-
-    def __init__(self, name: "std::string const &", problem_type: "operations_research::MPSolver::OptimizationProblemType"):
-        r""" Create a solver with the given name and underlying solver backend."""
-        _pywraplp.Solver_swiginit(self, _pywraplp.new_Solver(name, problem_type))
-    __swig_destroy__ = _pywraplp.delete_Solver
-
-    @staticmethod
-    def CreateSolver(solver_id: "std::string const &") -> "operations_research::MPSolver *":
-        r"""
-        Recommended factory method to create a MPSolver instance, especially in
-        non C++ languages.
-
-        It returns a newly created solver instance if successful, or a nullptr
-        otherwise. This can occur if the relevant interface is not linked in, or if
-        a needed license is not accessible for commercial solvers.
-
-        Ownership of the solver is passed on to the caller of this method.
-        It will accept both string names of the OptimizationProblemType enum, as
-        well as a short version (i.e. "SCIP_MIXED_INTEGER_PROGRAMMING" or "SCIP").
-
-        solver_id is case insensitive, and the following names are supported:
-          - CLP_LINEAR_PROGRAMMING or CLP
-          - CBC_MIXED_INTEGER_PROGRAMMING or CBC
-          - GLOP_LINEAR_PROGRAMMING or GLOP
-          - BOP_INTEGER_PROGRAMMING or BOP
-          - SAT_INTEGER_PROGRAMMING or SAT or CP_SAT
-          - SCIP_MIXED_INTEGER_PROGRAMMING or SCIP
-          - GUROBI_LINEAR_PROGRAMMING or GUROBI_LP
-          - GUROBI_MIXED_INTEGER_PROGRAMMING or GUROBI or GUROBI_MIP
-          - CPLEX_LINEAR_PROGRAMMING or CPLEX_LP
-          - CPLEX_MIXED_INTEGER_PROGRAMMING or CPLEX or CPLEX_MIP
-          - XPRESS_LINEAR_PROGRAMMING or XPRESS_LP
-          - XPRESS_MIXED_INTEGER_PROGRAMMING or XPRESS or XPRESS_MIP
-          - GLPK_LINEAR_PROGRAMMING or GLPK_LP
-          - GLPK_MIXED_INTEGER_PROGRAMMING or GLPK or GLPK_MIP
-        """
-        return _pywraplp.Solver_CreateSolver(solver_id)
-
-    @staticmethod
-    def SupportsProblemType(problem_type: "operations_research::MPSolver::OptimizationProblemType") -> "bool":
-        r"""
-        Whether the given problem type is supported (this will depend on the
-        targets that you linked).
-        """
-        return _pywraplp.Solver_SupportsProblemType(problem_type)
-
-    def Clear(self) -> "void":
-        r"""
-        Clears the objective (including the optimization direction), all variables
-        and constraints. All the other properties of the MPSolver (like the time
-        limit) are kept untouched.
-        """
-        return _pywraplp.Solver_Clear(self)
-
-    def NumVariables(self) -> "int":
-        r""" Returns the number of variables."""
-        return _pywraplp.Solver_NumVariables(self)
-
-    def variables(self) -> "std::vector< operations_research::MPVariable * > const &":
-        r"""
-        Returns the array of variables handled by the MPSolver. (They are listed in
-        the order in which they were created.)
-        """
-        return _pywraplp.Solver_variables(self)
-
-    def variable(self, index: "int") -> "operations_research::MPVariable *":
-        r"""Returns the variable at position index."""
-        return _pywraplp.Solver_variable(self, index)
-
-    def LookupVariable(self, var_name: "std::string const &") -> "operations_research::MPVariable *":
-        r"""
-        Looks up a variable by name, and returns nullptr if it does not exist. The
-        first call has a O(n) complexity, as the variable name index is lazily
-        created upon first use. Will crash if variable names are not unique.
-        """
-        return _pywraplp.Solver_LookupVariable(self, var_name)
-
-    def Var(self, lb: "double", ub: "double", integer: "bool", name: "std::string const &") -> "operations_research::MPVariable *":
-        r"""
-        Creates a variable with the given bounds, integrality requirement and
-        name. Bounds can be finite or +/- MPSolver::infinity(). The MPSolver owns
-        the variable (i.e. the returned pointer is borrowed). Variable names are
-        optional. If you give an empty name, name() will auto-generate one for you
-        upon request.
-        """
-        return _pywraplp.Solver_Var(self, lb, ub, integer, name)
-
-    def NumVar(self, lb: "double", ub: "double", name: "std::string const &") -> "operations_research::MPVariable *":
-        r""" Creates a continuous variable."""
-        return _pywraplp.Solver_NumVar(self, lb, ub, name)
-
-    def IntVar(self, lb: "double", ub: "double", name: "std::string const &") -> "operations_research::MPVariable *":
-        r""" Creates an integer variable."""
-        return _pywraplp.Solver_IntVar(self, lb, ub, name)
-
-    def BoolVar(self, name: "std::string const &") -> "operations_research::MPVariable *":
-        r""" Creates a boolean variable."""
-        return _pywraplp.Solver_BoolVar(self, name)
-
-    def NumConstraints(self) -> "int":
-        r""" Returns the number of constraints."""
-        return _pywraplp.Solver_NumConstraints(self)
-
-    def constraints(self) -> "std::vector< operations_research::MPConstraint * > const &":
-        r"""
-        Returns the array of constraints handled by the MPSolver.
-
-        They are listed in the order in which they were created.
-        """
-        return _pywraplp.Solver_constraints(self)
-
-    def constraint(self, index: "int") -> "operations_research::MPConstraint *":
-        r""" Returns the constraint at the given index."""
-        return _pywraplp.Solver_constraint(self, index)
-
-    def LookupConstraint(self, constraint_name: "std::string const &") -> "operations_research::MPConstraint *":
-        r"""
-         Looks up a constraint by name, and returns nullptr if it does not exist.
-
-        The first call has a O(n) complexity, as the constraint name index is
-        lazily created upon first use. Will crash if constraint names are not
-        unique.
-        """
-        return _pywraplp.Solver_LookupConstraint(self, constraint_name)
-
-    def Constraint(self, *args) -> "operations_research::MPConstraint *":
-        r"""
-        *Overload 1:*
-
-        Creates a linear constraint with given bounds.
-
-        Bounds can be finite or +/- MPSolver::infinity(). The MPSolver class
-        assumes ownership of the constraint.
-
-        :rtype: :py:class:`MPConstraint`
-        :return: a pointer to the newly created constraint.
-
-        |
-
-        *Overload 2:*
-         Creates a constraint with -infinity and +infinity bounds.
-
-        |
-
-        *Overload 3:*
-         Creates a named constraint with given bounds.
-
-        |
-
-        *Overload 4:*
-         Creates a named constraint with -infinity and +infinity bounds.
-        """
-        return _pywraplp.Solver_Constraint(self, *args)
-
-    def Objective(self) -> "operations_research::MPObjective *":
-        r""" Returns the mutable objective object."""
-        return _pywraplp.Solver_Objective(self)
-    OPTIMAL = _pywraplp.Solver_OPTIMAL
-    r""" optimal."""
-    FEASIBLE = _pywraplp.Solver_FEASIBLE
-    r""" feasible, or stopped by limit."""
-    INFEASIBLE = _pywraplp.Solver_INFEASIBLE
-    r""" proven infeasible."""
-    UNBOUNDED = _pywraplp.Solver_UNBOUNDED
-    r""" proven unbounded."""
-    ABNORMAL = _pywraplp.Solver_ABNORMAL
-    r""" abnormal, i.e., error of some kind."""
-    NOT_SOLVED = _pywraplp.Solver_NOT_SOLVED
-    r""" not been solved yet."""
-
-    def Solve(self, *args) -> "operations_research::MPSolver::ResultStatus":
-        r"""
-        *Overload 1:*
-        Solves the problem using the default parameter values.
-
-        |
-
-        *Overload 2:*
-        Solves the problem using the specified parameter values.
-        """
-        return _pywraplp.Solver_Solve(self, *args)
-
-    def ComputeConstraintActivities(self) -> "std::vector< double >":
-        r"""
-        Advanced usage: compute the "activities" of all constraints, which are the
-        sums of their linear terms. The activities are returned in the same order
-        as constraints(), which is the order in which constraints were added; but
-        you can also use MPConstraint::index() to get a constraint's index.
-        """
-        return _pywraplp.Solver_ComputeConstraintActivities(self)
-
-    def VerifySolution(self, tolerance: "double", log_errors: "bool") -> "bool":
-        r"""
-        Advanced usage: Verifies the *correctness* of the solution.
-
-        It verifies that all variables must be within their domains, all
-        constraints must be satisfied, and the reported objective value must be
-        accurate.
-
-        Usage:
-        - This can only be called after Solve() was called.
-        - "tolerance" is interpreted as an absolute error threshold.
-        - For the objective value only, if the absolute error is too large,
-          the tolerance is interpreted as a relative error threshold instead.
-        - If "log_errors" is true, every single violation will be logged.
-        - If "tolerance" is negative, it will be set to infinity().
-
-        Most users should just set the --verify_solution flag and not bother using
-        this method directly.
-        """
-        return _pywraplp.Solver_VerifySolution(self, tolerance, log_errors)
-
-    def InterruptSolve(self) -> "bool":
-        r"""
-         Interrupts the Solve() execution to terminate processing if possible.
-
-        If the underlying interface supports interruption; it does that and returns
-        true regardless of whether there's an ongoing Solve() or not. The Solve()
-        call may still linger for a while depending on the conditions.  If
-        interruption is not supported; returns false and does nothing.
-        """
-        return _pywraplp.Solver_InterruptSolve(self)
-
-    def FillSolutionResponseProto(self, response: "operations_research::MPSolutionResponse *") -> "void":
-        r""" Encodes the current solution in a solution response protocol buffer."""
-        return _pywraplp.Solver_FillSolutionResponseProto(self, response)
-
-    @staticmethod
-    def SolveWithProto(model_request: "operations_research::MPModelRequest const &", response: "operations_research::MPSolutionResponse *") -> "operations_research::MPSolutionResponse *":
-        r"""
-        Solves the model encoded by a MPModelRequest protocol buffer and fills the
-        solution encoded as a MPSolutionResponse.
-
-        Note(user): This creates a temporary MPSolver and destroys it at the end.
-        If you want to keep the MPSolver alive (for debugging, or for incremental
-        solving), you should write another version of this function that creates
-        the MPSolver object on the heap and returns it.
-
-        Note(pawell): This attempts to first use `DirectlySolveProto()` (if
-        implemented). Consequently, this most likely does *not* override any of
-        the default parameters of the underlying solver. This behavior *differs*
-        from `MPSolver::Solve()` which by default sets the feasibility tolerance
-        and the gap limit (as of 2020/02/11, to 1e-7 and 0.0001, respectively).
-        """
-        return _pywraplp.Solver_SolveWithProto(model_request, response)
-
-    def ExportModelToProto(self, output_model: "operations_research::MPModelProto *") -> "void":
-        r""" Exports model to protocol buffer."""
-        return _pywraplp.Solver_ExportModelToProto(self, output_model)
-
-    def SetSolverSpecificParametersAsString(self, parameters: "std::string const &") -> "bool":
-        r"""
-        Advanced usage: pass solver specific parameters in text format.
-
-        The format is solver-specific and is the same as the corresponding solver
-        configuration file format. Returns true if the operation was successful.
-        """
-        return _pywraplp.Solver_SetSolverSpecificParametersAsString(self, parameters)
-    FREE = _pywraplp.Solver_FREE
-    AT_LOWER_BOUND = _pywraplp.Solver_AT_LOWER_BOUND
-    AT_UPPER_BOUND = _pywraplp.Solver_AT_UPPER_BOUND
-    FIXED_VALUE = _pywraplp.Solver_FIXED_VALUE
-    BASIC = _pywraplp.Solver_BASIC
-
-    @staticmethod
-    def infinity() -> "double":
-        r"""
-        Infinity.
-
-        You can use -MPSolver::infinity() for negative infinity.
-        """
-        return _pywraplp.Solver_infinity()
-
-    def EnableOutput(self) -> "void":
-        r""" Enables solver logging."""
-        return _pywraplp.Solver_EnableOutput(self)
-
-    def SuppressOutput(self) -> "void":
-        r""" Suppresses solver logging."""
-        return _pywraplp.Solver_SuppressOutput(self)
-
-    def iterations(self) -> "int64_t":
-        r""" Returns the number of simplex iterations."""
-        return _pywraplp.Solver_iterations(self)
-
-    def nodes(self) -> "int64_t":
-        r"""
-        Returns the number of branch-and-bound nodes evaluated during the solve.
-
-        Only available for discrete problems.
-        """
-        return _pywraplp.Solver_nodes(self)
-
-    def ComputeExactConditionNumber(self) -> "double":
-        r"""
-         Advanced usage: computes the exact condition number of the current scaled
-        basis: L1norm(B) * L1norm(inverse(B)), where B is the scaled basis.
-
-        This method requires that a basis exists: it should be called after Solve.
-        It is only available for continuous problems. It is implemented for GLPK
-        but not CLP because CLP does not provide the API for doing it.
-
-        The condition number measures how well the constraint matrix is conditioned
-        and can be used to predict whether numerical issues will arise during the
-        solve: the model is declared infeasible whereas it is feasible (or
-        vice-versa), the solution obtained is not optimal or violates some
-        constraints, the resolution is slow because of repeated singularities.
-
-        The rule of thumb to interpret the condition number kappa is:
-          - o kappa <= 1e7: virtually no chance of numerical issues
-          - o 1e7 < kappa <= 1e10: small chance of numerical issues
-          - o 1e10 < kappa <= 1e13: medium chance of numerical issues
-          - o kappa > 1e13: high chance of numerical issues
-
-        The computation of the condition number depends on the quality of the LU
-        decomposition, so it is not very accurate when the matrix is ill
-        conditioned.
-        """
-        return _pywraplp.Solver_ComputeExactConditionNumber(self)
-
-    def NextSolution(self) -> "bool":
-        r"""
-        Some solvers (MIP only, not LP) can produce multiple solutions to the
-        problem. Returns true when another solution is available, and updates the
-        MPVariable* objects to make the new solution queryable. Call only after
-        calling solve.
-
-        The optimality properties of the additional solutions found, and whether or
-        not the solver computes them ahead of time or when NextSolution() is called
-        is solver specific.
-
-        As of 2020-02-10, only Gurobi and SCIP support NextSolution(), see
-        linear_solver_interfaces_test for an example of how to configure these
-        solvers for multiple solutions. Other solvers return false unconditionally.
-        """
-        return _pywraplp.Solver_NextSolution(self)
-
-    def set_time_limit(self, time_limit_milliseconds: "int64_t") -> "void":
-        return _pywraplp.Solver_set_time_limit(self, time_limit_milliseconds)
-
-    def wall_time(self) -> "int64_t":
-        return _pywraplp.Solver_wall_time(self)
-
-    def LoadModelFromProto(self, input_model: "operations_research::MPModelProto const &") -> "std::string":
-        return _pywraplp.Solver_LoadModelFromProto(self, input_model)
-
-    def LoadSolutionFromProto(self, *args) -> "bool":
-        return _pywraplp.Solver_LoadSolutionFromProto(self, *args)
-
-    def ExportModelAsLpFormat(self, obfuscated: "bool") -> "std::string":
-        return _pywraplp.Solver_ExportModelAsLpFormat(self, obfuscated)
-
-    def ExportModelAsMpsFormat(self, fixed_format: "bool", obfuscated: "bool") -> "std::string":
-        return _pywraplp.Solver_ExportModelAsMpsFormat(self, fixed_format, obfuscated)
-
-    def SetHint(self, variables: "std::vector< operations_research::MPVariable * > const &", values: "std::vector< double > const &") -> "void":
-        r"""
-        Set a hint for solution.
-
-        If a feasible or almost-feasible solution to the problem is already known,
-        it may be helpful to pass it to the solver so that it can be used. A
-        solver that supports this feature will try to use this information to
-        create its initial feasible solution.
-
-        Note that it may not always be faster to give a hint like this to the
-        solver. There is also no guarantee that the solver will use this hint or
-        try to return a solution "close" to this assignment in case of multiple
-        optimal solutions.
-        """
-        return _pywraplp.Solver_SetHint(self, variables, values)
-
-    def SetNumThreads(self, num_theads: "int") -> "bool":
-        r""" Sets the number of threads to be used by the solver."""
-        return _pywraplp.Solver_SetNumThreads(self, num_theads)
-
-    def Add(self, constraint, name=''):
-      if isinstance(constraint, bool):
-        if constraint:
-          return self.RowConstraint(0, 0, name)
-        else:
-          return self.RowConstraint(1, 1, name)
-      else:
-        return constraint.Extract(self, name)
-
-    def Sum(self, expr_array):
-      result = SumArray(expr_array)
-      return result
-
-    def RowConstraint(self, *args):
-      return self.Constraint(*args)
-
-    def Minimize(self, expr):
-      objective = self.Objective()
-      objective.Clear()
-      objective.SetMinimization()
-      if isinstance(expr, numbers.Number):
-          objective.SetOffset(expr)
-      else:
-          coeffs = expr.GetCoeffs()
-          objective.SetOffset(coeffs.pop(OFFSET_KEY, 0.0))
-          for v, c, in list(coeffs.items()):
-            objective.SetCoefficient(v, float(c))
-
-    def Maximize(self, expr):
-      objective = self.Objective()
-      objective.Clear()
-      objective.SetMaximization()
-      if isinstance(expr, numbers.Number):
-          objective.SetOffset(expr)
-      else:
-          coeffs = expr.GetCoeffs()
-          objective.SetOffset(coeffs.pop(OFFSET_KEY, 0.0))
-          for v, c, in list(coeffs.items()):
-            objective.SetCoefficient(v, float(c))
-
-
-    @staticmethod
-    def Infinity() -> "double":
-        return _pywraplp.Solver_Infinity()
-
-    def SetTimeLimit(self, x: "int64_t") -> "void":
-        return _pywraplp.Solver_SetTimeLimit(self, x)
-
-    def WallTime(self) -> "int64_t":
-        return _pywraplp.Solver_WallTime(self)
-
-    def Iterations(self) -> "int64_t":
-        return _pywraplp.Solver_Iterations(self)
-
-# Register Solver in _pywraplp:
-_pywraplp.Solver_swigregister(Solver)
-
-def Solver_CreateSolver(solver_id: "std::string const &") -> "operations_research::MPSolver *":
-    r"""
-    Recommended factory method to create a MPSolver instance, especially in
-    non C++ languages.
-
-    It returns a newly created solver instance if successful, or a nullptr
-    otherwise. This can occur if the relevant interface is not linked in, or if
-    a needed license is not accessible for commercial solvers.
-
-    Ownership of the solver is passed on to the caller of this method.
-    It will accept both string names of the OptimizationProblemType enum, as
-    well as a short version (i.e. "SCIP_MIXED_INTEGER_PROGRAMMING" or "SCIP").
-
-    solver_id is case insensitive, and the following names are supported:
-      - CLP_LINEAR_PROGRAMMING or CLP
-      - CBC_MIXED_INTEGER_PROGRAMMING or CBC
-      - GLOP_LINEAR_PROGRAMMING or GLOP
-      - BOP_INTEGER_PROGRAMMING or BOP
-      - SAT_INTEGER_PROGRAMMING or SAT or CP_SAT
-      - SCIP_MIXED_INTEGER_PROGRAMMING or SCIP
-      - GUROBI_LINEAR_PROGRAMMING or GUROBI_LP
-      - GUROBI_MIXED_INTEGER_PROGRAMMING or GUROBI or GUROBI_MIP
-      - CPLEX_LINEAR_PROGRAMMING or CPLEX_LP
-      - CPLEX_MIXED_INTEGER_PROGRAMMING or CPLEX or CPLEX_MIP
-      - XPRESS_LINEAR_PROGRAMMING or XPRESS_LP
-      - XPRESS_MIXED_INTEGER_PROGRAMMING or XPRESS or XPRESS_MIP
-      - GLPK_LINEAR_PROGRAMMING or GLPK_LP
-      - GLPK_MIXED_INTEGER_PROGRAMMING or GLPK or GLPK_MIP
-    """
-    return _pywraplp.Solver_CreateSolver(solver_id)
-
-def Solver_SupportsProblemType(problem_type: "operations_research::MPSolver::OptimizationProblemType") -> "bool":
-    r"""
-    Whether the given problem type is supported (this will depend on the
-    targets that you linked).
-    """
-    return _pywraplp.Solver_SupportsProblemType(problem_type)
-
-def Solver_SolveWithProto(model_request: "operations_research::MPModelRequest const &", response: "operations_research::MPSolutionResponse *") -> "operations_research::MPSolutionResponse *":
-    r"""
-    Solves the model encoded by a MPModelRequest protocol buffer and fills the
-    solution encoded as a MPSolutionResponse.
-
-    Note(user): This creates a temporary MPSolver and destroys it at the end.
-    If you want to keep the MPSolver alive (for debugging, or for incremental
-    solving), you should write another version of this function that creates
-    the MPSolver object on the heap and returns it.
-
-    Note(pawell): This attempts to first use `DirectlySolveProto()` (if
-    implemented). Consequently, this most likely does *not* override any of
-    the default parameters of the underlying solver. This behavior *differs*
-    from `MPSolver::Solve()` which by default sets the feasibility tolerance
-    and the gap limit (as of 2020/02/11, to 1e-7 and 0.0001, respectively).
-    """
-    return _pywraplp.Solver_SolveWithProto(model_request, response)
-
-def Solver_infinity() -> "double":
-    r"""
-    Infinity.
-
-    You can use -MPSolver::infinity() for negative infinity.
-    """
-    return _pywraplp.Solver_infinity()
-
-def Solver_Infinity() -> "double":
-    return _pywraplp.Solver_Infinity()
-
-
-def __lshift__(*args) -> "std::ostream &":
-    return _pywraplp.__lshift__(*args)
-class Objective(object):
-    r""" A class to express a linear objective."""
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined")
-    __repr__ = _swig_repr
-
-    def Clear(self) -> "void":
-        r"""
-         Clears the offset, all variables and coefficients, and the optimization
-        direction.
-        """
-        return _pywraplp.Objective_Clear(self)
-
-    def SetCoefficient(self, var: "Variable", coeff: "double") -> "void":
-        r"""
-        Sets the coefficient of the variable in the objective.
-
-        If the variable does not belong to the solver, the function just returns,
-        or crashes in non-opt mode.
-        """
-        return _pywraplp.Objective_SetCoefficient(self, var, coeff)
-
-    def GetCoefficient(self, var: "Variable") -> "double":
-        r"""
-         Gets the coefficient of a given variable in the objective
-
-        It returns 0 if the variable does not appear in the objective).
-        """
-        return _pywraplp.Objective_GetCoefficient(self, var)
-
-    def SetOffset(self, value: "double") -> "void":
-        r""" Sets the constant term in the objective."""
-        return _pywraplp.Objective_SetOffset(self, value)
-
-    def offset(self) -> "double":
-        r""" Gets the constant term in the objective."""
-        return _pywraplp.Objective_offset(self)
-
-    def SetOptimizationDirection(self, maximize: "bool") -> "void":
-        r""" Sets the optimization direction (maximize: true or minimize: false)."""
-        return _pywraplp.Objective_SetOptimizationDirection(self, maximize)
-
-    def SetMinimization(self) -> "void":
-        r""" Sets the optimization direction to minimize."""
-        return _pywraplp.Objective_SetMinimization(self)
-
-    def SetMaximization(self) -> "void":
-        r""" Sets the optimization direction to maximize."""
-        return _pywraplp.Objective_SetMaximization(self)
-
-    def maximization(self) -> "bool":
-        r""" Is the optimization direction set to maximize?"""
-        return _pywraplp.Objective_maximization(self)
-
-    def minimization(self) -> "bool":
-        r""" Is the optimization direction set to minimize?"""
-        return _pywraplp.Objective_minimization(self)
-
-    def Value(self) -> "double":
-        r"""
-        Returns the objective value of the best solution found so far.
-
-        It is the optimal objective value if the problem has been solved to
-        optimality.
-
-        Note: the objective value may be slightly different than what you could
-        compute yourself using ``MPVariable::solution_value();`` please use the
-        --verify_solution flag to gain confidence about the numerical stability of
-        your solution.
-        """
-        return _pywraplp.Objective_Value(self)
-
-    def BestBound(self) -> "double":
-        r"""
-        Returns the best objective bound.
-
-        In case of minimization, it is a lower bound on the objective value of the
-        optimal integer solution. Only available for discrete problems.
-        """
-        return _pywraplp.Objective_BestBound(self)
+        
+    
+
+

+pywraplp

+ + +
+ View Source +
# This file was automatically generated by SWIG (http://www.swig.org).
+# Version 4.0.1
+#
+# Do not make changes to this file unless you know what you are doing--modify
+# the SWIG interface file instead.
+
+from sys import version_info as _swig_python_version_info
+if _swig_python_version_info < (2, 7, 0):
+    raise RuntimeError("Python 2.7 or later required")
+
+# Import the low-level C/C++ module
+if __package__ or "." in __name__:
+    from . import _pywraplp
+else:
+    import _pywraplp
+
+try:
+    import builtins as __builtin__
+except ImportError:
+    import __builtin__
+
+def _swig_repr(self):
+    try:
+        strthis = "proxy of " + self.this.__repr__()
+    except __builtin__.Exception:
+        strthis = ""
+    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
+
+
+def _swig_setattr_nondynamic_instance_variable(set):
+    def set_instance_attr(self, name, value):
+        if name == "thisown":
+            self.this.own(value)
+        elif name == "this":
+            set(self, name, value)
+        elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
+            set(self, name, value)
+        else:
+            raise AttributeError("You cannot add instance attributes to %s" % self)
+    return set_instance_attr
+
+
+def _swig_setattr_nondynamic_class_variable(set):
+    def set_class_attr(cls, name, value):
+        if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
+            set(cls, name, value)
+        else:
+            raise AttributeError("You cannot add class attributes to %s" % cls)
+    return set_class_attr
+
+
+def _swig_add_metaclass(metaclass):
+    """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
+    def wrapper(cls):
+        return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
+    return wrapper
+
+
+class _SwigNonDynamicMeta(type):
+    """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
+    __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)
+
+
+
+import numbers
+from ortools.linear_solver.linear_solver_natural_api import OFFSET_KEY
+from ortools.linear_solver.linear_solver_natural_api import inf
+from ortools.linear_solver.linear_solver_natural_api import LinearExpr
+from ortools.linear_solver.linear_solver_natural_api import ProductCst
+from ortools.linear_solver.linear_solver_natural_api import Sum
+from ortools.linear_solver.linear_solver_natural_api import SumArray
+from ortools.linear_solver.linear_solver_natural_api import SumCst
+from ortools.linear_solver.linear_solver_natural_api import LinearConstraint
+from ortools.linear_solver.linear_solver_natural_api import VariableExpr
+
+# Remove the documentation of some functions.
+# See https://pdoc3.github.io/pdoc/doc/pdoc/#overriding-docstrings-with-
+__pdoc__ = {}
+__pdoc__['Solver_infinity'] = False
+__pdoc__['Solver_Infinity'] = False
+__pdoc__['Solver_SolveWithProto'] = False
+__pdoc__['Solver_SupportsProblemType'] = False
+__pdoc__['setup_variable_operator'] = False
+__pdoc__['Constraint.thisown'] = False
+__pdoc__['Constraint.thisown'] = False
+__pdoc__['MPSolverParameters.thisown'] = False
+__pdoc__['ModelExportOptions.thisown'] = False
+__pdoc__['Objective.thisown'] = False
+__pdoc__['Solver.thisown'] = False
+__pdoc__['Variable.thisown'] = False
+
+class Solver(object):
+    r"""
+    This mathematical programming (MP) solver class is the main class
+    though which users build and solve problems.
+    """
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+    CLP_LINEAR_PROGRAMMING = _pywraplp.Solver_CLP_LINEAR_PROGRAMMING
+    GLPK_LINEAR_PROGRAMMING = _pywraplp.Solver_GLPK_LINEAR_PROGRAMMING
+    GLOP_LINEAR_PROGRAMMING = _pywraplp.Solver_GLOP_LINEAR_PROGRAMMING
+    SCIP_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_SCIP_MIXED_INTEGER_PROGRAMMING
+    GLPK_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_GLPK_MIXED_INTEGER_PROGRAMMING
+    CBC_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_CBC_MIXED_INTEGER_PROGRAMMING
+    GUROBI_LINEAR_PROGRAMMING = _pywraplp.Solver_GUROBI_LINEAR_PROGRAMMING
+    GUROBI_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_GUROBI_MIXED_INTEGER_PROGRAMMING
+    CPLEX_LINEAR_PROGRAMMING = _pywraplp.Solver_CPLEX_LINEAR_PROGRAMMING
+    CPLEX_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_CPLEX_MIXED_INTEGER_PROGRAMMING
+    XPRESS_LINEAR_PROGRAMMING = _pywraplp.Solver_XPRESS_LINEAR_PROGRAMMING
+    XPRESS_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_XPRESS_MIXED_INTEGER_PROGRAMMING
+    BOP_INTEGER_PROGRAMMING = _pywraplp.Solver_BOP_INTEGER_PROGRAMMING
+    SAT_INTEGER_PROGRAMMING = _pywraplp.Solver_SAT_INTEGER_PROGRAMMING
+
+    def __init__(self, name: "std::string const &", problem_type: "operations_research::MPSolver::OptimizationProblemType"):
+        r""" Create a solver with the given name and underlying solver backend."""
+        _pywraplp.Solver_swiginit(self, _pywraplp.new_Solver(name, problem_type))
+    __swig_destroy__ = _pywraplp.delete_Solver
+
+    @staticmethod
+    def CreateSolver(solver_id: "std::string const &") -> "operations_research::MPSolver *":
+        r"""
+        Recommended factory method to create a MPSolver instance, especially in
+        non C++ languages.
+
+        It returns a newly created solver instance if successful, or a nullptr
+        otherwise. This can occur if the relevant interface is not linked in, or if
+        a needed license is not accessible for commercial solvers.
+
+        Ownership of the solver is passed on to the caller of this method.
+        It will accept both string names of the OptimizationProblemType enum, as
+        well as a short version (i.e. "SCIP_MIXED_INTEGER_PROGRAMMING" or "SCIP").
+
+        solver_id is case insensitive, and the following names are supported:
+          - CLP_LINEAR_PROGRAMMING or CLP
+          - CBC_MIXED_INTEGER_PROGRAMMING or CBC
+          - GLOP_LINEAR_PROGRAMMING or GLOP
+          - BOP_INTEGER_PROGRAMMING or BOP
+          - SAT_INTEGER_PROGRAMMING or SAT or CP_SAT
+          - SCIP_MIXED_INTEGER_PROGRAMMING or SCIP
+          - GUROBI_LINEAR_PROGRAMMING or GUROBI_LP
+          - GUROBI_MIXED_INTEGER_PROGRAMMING or GUROBI or GUROBI_MIP
+          - CPLEX_LINEAR_PROGRAMMING or CPLEX_LP
+          - CPLEX_MIXED_INTEGER_PROGRAMMING or CPLEX or CPLEX_MIP
+          - XPRESS_LINEAR_PROGRAMMING or XPRESS_LP
+          - XPRESS_MIXED_INTEGER_PROGRAMMING or XPRESS or XPRESS_MIP
+          - GLPK_LINEAR_PROGRAMMING or GLPK_LP
+          - GLPK_MIXED_INTEGER_PROGRAMMING or GLPK or GLPK_MIP
+        """
+        return _pywraplp.Solver_CreateSolver(solver_id)
+
+    @staticmethod
+    def SupportsProblemType(problem_type: "operations_research::MPSolver::OptimizationProblemType") -> "bool":
+        r"""
+        Whether the given problem type is supported (this will depend on the
+        targets that you linked).
+        """
+        return _pywraplp.Solver_SupportsProblemType(problem_type)
+
+    def Clear(self) -> "void":
+        r"""
+        Clears the objective (including the optimization direction), all variables
+        and constraints. All the other properties of the MPSolver (like the time
+        limit) are kept untouched.
+        """
+        return _pywraplp.Solver_Clear(self)
+
+    def NumVariables(self) -> "int":
+        r""" Returns the number of variables."""
+        return _pywraplp.Solver_NumVariables(self)
+
+    def variables(self) -> "std::vector< operations_research::MPVariable * > const &":
+        r"""
+        Returns the array of variables handled by the MPSolver. (They are listed in
+        the order in which they were created.)
+        """
+        return _pywraplp.Solver_variables(self)
+
+    def variable(self, index: "int") -> "operations_research::MPVariable *":
+        r"""Returns the variable at position index."""
+        return _pywraplp.Solver_variable(self, index)
+
+    def LookupVariable(self, var_name: "std::string const &") -> "operations_research::MPVariable *":
+        r"""
+        Looks up a variable by name, and returns nullptr if it does not exist. The
+        first call has a O(n) complexity, as the variable name index is lazily
+        created upon first use. Will crash if variable names are not unique.
+        """
+        return _pywraplp.Solver_LookupVariable(self, var_name)
+
+    def Var(self, lb: "double", ub: "double", integer: "bool", name: "std::string const &") -> "operations_research::MPVariable *":
+        r"""
+        Creates a variable with the given bounds, integrality requirement and
+        name. Bounds can be finite or +/- MPSolver::infinity(). The MPSolver owns
+        the variable (i.e. the returned pointer is borrowed). Variable names are
+        optional. If you give an empty name, name() will auto-generate one for you
+        upon request.
+        """
+        return _pywraplp.Solver_Var(self, lb, ub, integer, name)
+
+    def NumVar(self, lb: "double", ub: "double", name: "std::string const &") -> "operations_research::MPVariable *":
+        r""" Creates a continuous variable."""
+        return _pywraplp.Solver_NumVar(self, lb, ub, name)
+
+    def IntVar(self, lb: "double", ub: "double", name: "std::string const &") -> "operations_research::MPVariable *":
+        r""" Creates an integer variable."""
+        return _pywraplp.Solver_IntVar(self, lb, ub, name)
+
+    def BoolVar(self, name: "std::string const &") -> "operations_research::MPVariable *":
+        r""" Creates a boolean variable."""
+        return _pywraplp.Solver_BoolVar(self, name)
+
+    def NumConstraints(self) -> "int":
+        r""" Returns the number of constraints."""
+        return _pywraplp.Solver_NumConstraints(self)
+
+    def constraints(self) -> "std::vector< operations_research::MPConstraint * > const &":
+        r"""
+        Returns the array of constraints handled by the MPSolver.
+
+        They are listed in the order in which they were created.
+        """
+        return _pywraplp.Solver_constraints(self)
+
+    def constraint(self, index: "int") -> "operations_research::MPConstraint *":
+        r""" Returns the constraint at the given index."""
+        return _pywraplp.Solver_constraint(self, index)
+
+    def LookupConstraint(self, constraint_name: "std::string const &") -> "operations_research::MPConstraint *":
+        r"""
+         Looks up a constraint by name, and returns nullptr if it does not exist.
+
+        The first call has a O(n) complexity, as the constraint name index is
+        lazily created upon first use. Will crash if constraint names are not
+        unique.
+        """
+        return _pywraplp.Solver_LookupConstraint(self, constraint_name)
+
+    def Constraint(self, *args) -> "operations_research::MPConstraint *":
+        r"""
+        *Overload 1:*
+
+        Creates a linear constraint with given bounds.
+
+        Bounds can be finite or +/- MPSolver::infinity(). The MPSolver class
+        assumes ownership of the constraint.
+
+        :rtype: :py:class:`MPConstraint`
+        :return: a pointer to the newly created constraint.
+
+        |
+
+        *Overload 2:*
+         Creates a constraint with -infinity and +infinity bounds.
+
+        |
+
+        *Overload 3:*
+         Creates a named constraint with given bounds.
+
+        |
+
+        *Overload 4:*
+         Creates a named constraint with -infinity and +infinity bounds.
+        """
+        return _pywraplp.Solver_Constraint(self, *args)
+
+    def Objective(self) -> "operations_research::MPObjective *":
+        r""" Returns the mutable objective object."""
+        return _pywraplp.Solver_Objective(self)
+    OPTIMAL = _pywraplp.Solver_OPTIMAL
+    r""" optimal."""
+    FEASIBLE = _pywraplp.Solver_FEASIBLE
+    r""" feasible, or stopped by limit."""
+    INFEASIBLE = _pywraplp.Solver_INFEASIBLE
+    r""" proven infeasible."""
+    UNBOUNDED = _pywraplp.Solver_UNBOUNDED
+    r""" proven unbounded."""
+    ABNORMAL = _pywraplp.Solver_ABNORMAL
+    r""" abnormal, i.e., error of some kind."""
+    NOT_SOLVED = _pywraplp.Solver_NOT_SOLVED
+    r""" not been solved yet."""
+
+    def Solve(self, *args) -> "operations_research::MPSolver::ResultStatus":
+        r"""
+        *Overload 1:*
+        Solves the problem using the default parameter values.
+
+        |
+
+        *Overload 2:*
+        Solves the problem using the specified parameter values.
+        """
+        return _pywraplp.Solver_Solve(self, *args)
+
+    def ComputeConstraintActivities(self) -> "std::vector< double >":
+        r"""
+        Advanced usage: compute the "activities" of all constraints, which are the
+        sums of their linear terms. The activities are returned in the same order
+        as constraints(), which is the order in which constraints were added; but
+        you can also use MPConstraint::index() to get a constraint's index.
+        """
+        return _pywraplp.Solver_ComputeConstraintActivities(self)
+
+    def VerifySolution(self, tolerance: "double", log_errors: "bool") -> "bool":
+        r"""
+        Advanced usage: Verifies the *correctness* of the solution.
+
+        It verifies that all variables must be within their domains, all
+        constraints must be satisfied, and the reported objective value must be
+        accurate.
+
+        Usage:
+        - This can only be called after Solve() was called.
+        - "tolerance" is interpreted as an absolute error threshold.
+        - For the objective value only, if the absolute error is too large,
+          the tolerance is interpreted as a relative error threshold instead.
+        - If "log_errors" is true, every single violation will be logged.
+        - If "tolerance" is negative, it will be set to infinity().
+
+        Most users should just set the --verify_solution flag and not bother using
+        this method directly.
+        """
+        return _pywraplp.Solver_VerifySolution(self, tolerance, log_errors)
+
+    def InterruptSolve(self) -> "bool":
+        r"""
+         Interrupts the Solve() execution to terminate processing if possible.
+
+        If the underlying interface supports interruption; it does that and returns
+        true regardless of whether there's an ongoing Solve() or not. The Solve()
+        call may still linger for a while depending on the conditions.  If
+        interruption is not supported; returns false and does nothing.
+        MPSolver::SolverTypeSupportsInterruption can be used to check if
+        interruption is supported for a given solver type.
+        """
+        return _pywraplp.Solver_InterruptSolve(self)
+
+    def FillSolutionResponseProto(self, response: "operations_research::MPSolutionResponse *") -> "void":
+        r""" Encodes the current solution in a solution response protocol buffer."""
+        return _pywraplp.Solver_FillSolutionResponseProto(self, response)
+
+    @staticmethod
+    def SolveWithProto(model_request: "operations_research::MPModelRequest const &", response: "operations_research::MPSolutionResponse *", interrupt: "std::atomic< bool > const *"=None) -> "operations_research::MPSolutionResponse *":
+        r"""
+        Solves the model encoded by a MPModelRequest protocol buffer and fills the
+        solution encoded as a MPSolutionResponse. The solve is stopped prematurely
+        if interrupt is non-null at set to true during (or before) solving.
+        Interruption is only supported if SolverTypeSupportsInterruption() returns
+        true for the requested solver. Passing a non-null interruption with any
+        other solver type immediately returns an MPSOLVER_INCOMPATIBLE_OPTIONS
+        error.
+
+        Note(user): This attempts to first use `DirectlySolveProto()` (if
+        implemented). Consequently, this most likely does *not* override any of
+        the default parameters of the underlying solver. This behavior *differs*
+        from `MPSolver::Solve()` which by default sets the feasibility tolerance
+        and the gap limit (as of 2020/02/11, to 1e-7 and 0.0001, respectively).
+        """
+        return _pywraplp.Solver_SolveWithProto(model_request, response, interrupt)
+
+    def ExportModelToProto(self, output_model: "operations_research::MPModelProto *") -> "void":
+        r""" Exports model to protocol buffer."""
+        return _pywraplp.Solver_ExportModelToProto(self, output_model)
+
+    def SetSolverSpecificParametersAsString(self, parameters: "std::string const &") -> "bool":
+        r"""
+        Advanced usage: pass solver specific parameters in text format.
+
+        The format is solver-specific and is the same as the corresponding solver
+        configuration file format. Returns true if the operation was successful.
+        """
+        return _pywraplp.Solver_SetSolverSpecificParametersAsString(self, parameters)
+    FREE = _pywraplp.Solver_FREE
+    AT_LOWER_BOUND = _pywraplp.Solver_AT_LOWER_BOUND
+    AT_UPPER_BOUND = _pywraplp.Solver_AT_UPPER_BOUND
+    FIXED_VALUE = _pywraplp.Solver_FIXED_VALUE
+    BASIC = _pywraplp.Solver_BASIC
+
+    @staticmethod
+    def infinity() -> "double":
+        r"""
+        Infinity.
+
+        You can use -MPSolver::infinity() for negative infinity.
+        """
+        return _pywraplp.Solver_infinity()
+
+    def EnableOutput(self) -> "void":
+        r""" Enables solver logging."""
+        return _pywraplp.Solver_EnableOutput(self)
+
+    def SuppressOutput(self) -> "void":
+        r""" Suppresses solver logging."""
+        return _pywraplp.Solver_SuppressOutput(self)
+
+    def iterations(self) -> "int64_t":
+        r""" Returns the number of simplex iterations."""
+        return _pywraplp.Solver_iterations(self)
+
+    def nodes(self) -> "int64_t":
+        r"""
+        Returns the number of branch-and-bound nodes evaluated during the solve.
+
+        Only available for discrete problems.
+        """
+        return _pywraplp.Solver_nodes(self)
+
+    def ComputeExactConditionNumber(self) -> "double":
+        r"""
+         Advanced usage: computes the exact condition number of the current scaled
+        basis: L1norm(B) * L1norm(inverse(B)), where B is the scaled basis.
+
+        This method requires that a basis exists: it should be called after Solve.
+        It is only available for continuous problems. It is implemented for GLPK
+        but not CLP because CLP does not provide the API for doing it.
+
+        The condition number measures how well the constraint matrix is conditioned
+        and can be used to predict whether numerical issues will arise during the
+        solve: the model is declared infeasible whereas it is feasible (or
+        vice-versa), the solution obtained is not optimal or violates some
+        constraints, the resolution is slow because of repeated singularities.
+
+        The rule of thumb to interpret the condition number kappa is:
+          - o kappa <= 1e7: virtually no chance of numerical issues
+          - o 1e7 < kappa <= 1e10: small chance of numerical issues
+          - o 1e10 < kappa <= 1e13: medium chance of numerical issues
+          - o kappa > 1e13: high chance of numerical issues
+
+        The computation of the condition number depends on the quality of the LU
+        decomposition, so it is not very accurate when the matrix is ill
+        conditioned.
+        """
+        return _pywraplp.Solver_ComputeExactConditionNumber(self)
+
+    def NextSolution(self) -> "bool":
+        r"""
+        Some solvers (MIP only, not LP) can produce multiple solutions to the
+        problem. Returns true when another solution is available, and updates the
+        MPVariable* objects to make the new solution queryable. Call only after
+        calling solve.
+
+        The optimality properties of the additional solutions found, and whether or
+        not the solver computes them ahead of time or when NextSolution() is called
+        is solver specific.
+
+        As of 2020-02-10, only Gurobi and SCIP support NextSolution(), see
+        linear_solver_interfaces_test for an example of how to configure these
+        solvers for multiple solutions. Other solvers return false unconditionally.
+        """
+        return _pywraplp.Solver_NextSolution(self)
+
+    def set_time_limit(self, time_limit_milliseconds: "int64_t") -> "void":
+        return _pywraplp.Solver_set_time_limit(self, time_limit_milliseconds)
+
+    def wall_time(self) -> "int64_t":
+        return _pywraplp.Solver_wall_time(self)
+
+    def LoadModelFromProto(self, input_model: "operations_research::MPModelProto const &") -> "std::string":
+        return _pywraplp.Solver_LoadModelFromProto(self, input_model)
+
+    def LoadSolutionFromProto(self, *args) -> "bool":
+        return _pywraplp.Solver_LoadSolutionFromProto(self, *args)
+
+    def ExportModelAsLpFormat(self, obfuscated: "bool") -> "std::string":
+        return _pywraplp.Solver_ExportModelAsLpFormat(self, obfuscated)
+
+    def ExportModelAsMpsFormat(self, fixed_format: "bool", obfuscated: "bool") -> "std::string":
+        return _pywraplp.Solver_ExportModelAsMpsFormat(self, fixed_format, obfuscated)
+
+    def SetHint(self, variables: "std::vector< operations_research::MPVariable * > const &", values: "std::vector< double > const &") -> "void":
+        r""" Set a hint for solution. If a feasible or almost-feasible solution to the problem is already known, it may be helpful to pass it to the solver so that it can be used. A solver that supports this feature will try to use this information to create its initial feasible solution. Note that it may not always be faster to give a hint like this to the solver. There is also no guarantee that the solver will use this hint or try to return a solution "close" to this assignment in case of multiple optimal solutions."""
+        return _pywraplp.Solver_SetHint(self, variables, values)
+
+    def SetNumThreads(self, num_theads: "int") -> "bool":
+        r""" Sets the number of threads to be used by the solver."""
+        return _pywraplp.Solver_SetNumThreads(self, num_theads)
+
+    def Add(self, constraint, name=''):
+      if isinstance(constraint, bool):
+        if constraint:
+          return self.RowConstraint(0, 0, name)
+        else:
+          return self.RowConstraint(1, 1, name)
+      else:
+        return constraint.Extract(self, name)
+
+    def Sum(self, expr_array):
+      result = SumArray(expr_array)
+      return result
+
+    def RowConstraint(self, *args):
+      return self.Constraint(*args)
+
+    def Minimize(self, expr):
+      objective = self.Objective()
+      objective.Clear()
+      objective.SetMinimization()
+      if isinstance(expr, numbers.Number):
+          objective.SetOffset(expr)
+      else:
+          coeffs = expr.GetCoeffs()
+          objective.SetOffset(coeffs.pop(OFFSET_KEY, 0.0))
+          for v, c, in list(coeffs.items()):
+            objective.SetCoefficient(v, float(c))
+
+    def Maximize(self, expr):
+      objective = self.Objective()
+      objective.Clear()
+      objective.SetMaximization()
+      if isinstance(expr, numbers.Number):
+          objective.SetOffset(expr)
+      else:
+          coeffs = expr.GetCoeffs()
+          objective.SetOffset(coeffs.pop(OFFSET_KEY, 0.0))
+          for v, c, in list(coeffs.items()):
+            objective.SetCoefficient(v, float(c))
+
+
+    @staticmethod
+    def Infinity() -> "double":
+        return _pywraplp.Solver_Infinity()
+
+    def SetTimeLimit(self, x: "int64_t") -> "void":
+        return _pywraplp.Solver_SetTimeLimit(self, x)
+
+    def WallTime(self) -> "int64_t":
+        return _pywraplp.Solver_WallTime(self)
+
+    def Iterations(self) -> "int64_t":
+        return _pywraplp.Solver_Iterations(self)
+
+# Register Solver in _pywraplp:
+_pywraplp.Solver_swigregister(Solver)
+
+def Solver_CreateSolver(solver_id: "std::string const &") -> "operations_research::MPSolver *":
+    r"""
+    Recommended factory method to create a MPSolver instance, especially in
+    non C++ languages.
+
+    It returns a newly created solver instance if successful, or a nullptr
+    otherwise. This can occur if the relevant interface is not linked in, or if
+    a needed license is not accessible for commercial solvers.
+
+    Ownership of the solver is passed on to the caller of this method.
+    It will accept both string names of the OptimizationProblemType enum, as
+    well as a short version (i.e. "SCIP_MIXED_INTEGER_PROGRAMMING" or "SCIP").
+
+    solver_id is case insensitive, and the following names are supported:
+      - CLP_LINEAR_PROGRAMMING or CLP
+      - CBC_MIXED_INTEGER_PROGRAMMING or CBC
+      - GLOP_LINEAR_PROGRAMMING or GLOP
+      - BOP_INTEGER_PROGRAMMING or BOP
+      - SAT_INTEGER_PROGRAMMING or SAT or CP_SAT
+      - SCIP_MIXED_INTEGER_PROGRAMMING or SCIP
+      - GUROBI_LINEAR_PROGRAMMING or GUROBI_LP
+      - GUROBI_MIXED_INTEGER_PROGRAMMING or GUROBI or GUROBI_MIP
+      - CPLEX_LINEAR_PROGRAMMING or CPLEX_LP
+      - CPLEX_MIXED_INTEGER_PROGRAMMING or CPLEX or CPLEX_MIP
+      - XPRESS_LINEAR_PROGRAMMING or XPRESS_LP
+      - XPRESS_MIXED_INTEGER_PROGRAMMING or XPRESS or XPRESS_MIP
+      - GLPK_LINEAR_PROGRAMMING or GLPK_LP
+      - GLPK_MIXED_INTEGER_PROGRAMMING or GLPK or GLPK_MIP
+    """
+    return _pywraplp.Solver_CreateSolver(solver_id)
+
+def Solver_SupportsProblemType(problem_type: "operations_research::MPSolver::OptimizationProblemType") -> "bool":
+    r"""
+    Whether the given problem type is supported (this will depend on the
+    targets that you linked).
+    """
+    return _pywraplp.Solver_SupportsProblemType(problem_type)
+
+def Solver_SolveWithProto(model_request: "operations_research::MPModelRequest const &", response: "operations_research::MPSolutionResponse *", interrupt: "std::atomic< bool > const *"=None) -> "operations_research::MPSolutionResponse *":
+    r"""
+    Solves the model encoded by a MPModelRequest protocol buffer and fills the
+    solution encoded as a MPSolutionResponse. The solve is stopped prematurely
+    if interrupt is non-null at set to true during (or before) solving.
+    Interruption is only supported if SolverTypeSupportsInterruption() returns
+    true for the requested solver. Passing a non-null interruption with any
+    other solver type immediately returns an MPSOLVER_INCOMPATIBLE_OPTIONS
+    error.
+
+    Note(user): This attempts to first use `DirectlySolveProto()` (if
+    implemented). Consequently, this most likely does *not* override any of
+    the default parameters of the underlying solver. This behavior *differs*
+    from `MPSolver::Solve()` which by default sets the feasibility tolerance
+    and the gap limit (as of 2020/02/11, to 1e-7 and 0.0001, respectively).
+    """
+    return _pywraplp.Solver_SolveWithProto(model_request, response, interrupt)
+
+def Solver_infinity() -> "double":
+    r"""
+    Infinity.
+
+    You can use -MPSolver::infinity() for negative infinity.
+    """
+    return _pywraplp.Solver_infinity()
+
+def Solver_Infinity() -> "double":
+    return _pywraplp.Solver_Infinity()
+
+
+def __lshift__(*args) -> "std::ostream &":
+    return _pywraplp.__lshift__(*args)
+class Objective(object):
+    r""" A class to express a linear objective."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Clear(self) -> "void":
+        r"""
+         Clears the offset, all variables and coefficients, and the optimization
+        direction.
+        """
+        return _pywraplp.Objective_Clear(self)
+
+    def SetCoefficient(self, var: "Variable", coeff: "double") -> "void":
+        r"""
+        Sets the coefficient of the variable in the objective.
+
+        If the variable does not belong to the solver, the function just returns,
+        or crashes in non-opt mode.
+        """
+        return _pywraplp.Objective_SetCoefficient(self, var, coeff)
+
+    def GetCoefficient(self, var: "Variable") -> "double":
+        r"""
+         Gets the coefficient of a given variable in the objective
+
+        It returns 0 if the variable does not appear in the objective).
+        """
+        return _pywraplp.Objective_GetCoefficient(self, var)
+
+    def SetOffset(self, value: "double") -> "void":
+        r""" Sets the constant term in the objective."""
+        return _pywraplp.Objective_SetOffset(self, value)
+
+    def offset(self) -> "double":
+        r""" Gets the constant term in the objective."""
+        return _pywraplp.Objective_offset(self)
+
+    def SetOptimizationDirection(self, maximize: "bool") -> "void":
+        r""" Sets the optimization direction (maximize: true or minimize: false)."""
+        return _pywraplp.Objective_SetOptimizationDirection(self, maximize)
+
+    def SetMinimization(self) -> "void":
+        r""" Sets the optimization direction to minimize."""
+        return _pywraplp.Objective_SetMinimization(self)
+
+    def SetMaximization(self) -> "void":
+        r""" Sets the optimization direction to maximize."""
+        return _pywraplp.Objective_SetMaximization(self)
+
+    def maximization(self) -> "bool":
+        r""" Is the optimization direction set to maximize?"""
+        return _pywraplp.Objective_maximization(self)
+
+    def minimization(self) -> "bool":
+        r""" Is the optimization direction set to minimize?"""
+        return _pywraplp.Objective_minimization(self)
+
+    def Value(self) -> "double":
+        r"""
+        Returns the objective value of the best solution found so far.
+
+        It is the optimal objective value if the problem has been solved to
+        optimality.
+
+        Note: the objective value may be slightly different than what you could
+        compute yourself using ``MPVariable::solution_value();`` please use the
+        --verify_solution flag to gain confidence about the numerical stability of
+        your solution.
+        """
+        return _pywraplp.Objective_Value(self)
+
+    def BestBound(self) -> "double":
+        r"""
+        Returns the best objective bound.
+
+        In case of minimization, it is a lower bound on the objective value of the
+        optimal integer solution. Only available for discrete problems.
+        """
+        return _pywraplp.Objective_BestBound(self)
 
-    def Offset(self) -> "double":
-        return _pywraplp.Objective_Offset(self)
-    __swig_destroy__ = _pywraplp.delete_Objective
+    def Offset(self) -> "double":
+        return _pywraplp.Objective_Offset(self)
+    __swig_destroy__ = _pywraplp.delete_Objective
 
-# Register Objective in _pywraplp:
-_pywraplp.Objective_swigregister(Objective)
+# Register Objective in _pywraplp:
+_pywraplp.Objective_swigregister(Objective)
 
-class Variable(object):
-    r""" The class for variables of a Mathematical Programming (MP) model."""
+class Variable(object):
+    r""" The class for variables of a Mathematical Programming (MP) model."""
 
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
 
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined")
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
 
-    def name(self) -> "std::string const &":
-        r""" Returns the name of the variable."""
-        return _pywraplp.Variable_name(self)
+    def name(self) -> "std::string const &":
+        r""" Returns the name of the variable."""
+        return _pywraplp.Variable_name(self)
 
-    def SetInteger(self, integer: "bool") -> "void":
-        r""" Sets the integrality requirement of the variable."""
-        return _pywraplp.Variable_SetInteger(self, integer)
+    def SetInteger(self, integer: "bool") -> "void":
+        r""" Sets the integrality requirement of the variable."""
+        return _pywraplp.Variable_SetInteger(self, integer)
 
-    def integer(self) -> "bool":
-        r""" Returns the integrality requirement of the variable."""
-        return _pywraplp.Variable_integer(self)
+    def integer(self) -> "bool":
+        r""" Returns the integrality requirement of the variable."""
+        return _pywraplp.Variable_integer(self)
 
-    def solution_value(self) -> "double":
-        r"""
-        Returns the value of the variable in the current solution.
+    def solution_value(self) -> "double":
+        r"""
+        Returns the value of the variable in the current solution.
 
-        If the variable is integer, then the value will always be an integer (the
-        underlying solver handles floating-point values only, but this function
-        automatically rounds it to the nearest integer; see: man 3 round).
-        """
-        return _pywraplp.Variable_solution_value(self)
+        If the variable is integer, then the value will always be an integer (the
+        underlying solver handles floating-point values only, but this function
+        automatically rounds it to the nearest integer; see: man 3 round).
+        """
+        return _pywraplp.Variable_solution_value(self)
 
-    def index(self) -> "int":
-        r""" Returns the index of the variable in the MPSolver::variables_."""
-        return _pywraplp.Variable_index(self)
+    def index(self) -> "int":
+        r""" Returns the index of the variable in the MPSolver::variables_."""
+        return _pywraplp.Variable_index(self)
 
-    def lb(self) -> "double":
-        r""" Returns the lower bound."""
-        return _pywraplp.Variable_lb(self)
+    def lb(self) -> "double":
+        r""" Returns the lower bound."""
+        return _pywraplp.Variable_lb(self)
 
-    def ub(self) -> "double":
-        r""" Returns the upper bound."""
-        return _pywraplp.Variable_ub(self)
+    def ub(self) -> "double":
+        r""" Returns the upper bound."""
+        return _pywraplp.Variable_ub(self)
 
-    def SetBounds(self, lb: "double", ub: "double") -> "void":
-        r""" Sets both the lower and upper bounds."""
-        return _pywraplp.Variable_SetBounds(self, lb, ub)
+    def SetBounds(self, lb: "double", ub: "double") -> "void":
+        r""" Sets both the lower and upper bounds."""
+        return _pywraplp.Variable_SetBounds(self, lb, ub)
 
-    def reduced_cost(self) -> "double":
-        r"""
-        Advanced usage: returns the reduced cost of the variable in the current
-        solution (only available for continuous problems).
-        """
-        return _pywraplp.Variable_reduced_cost(self)
+    def reduced_cost(self) -> "double":
+        r"""
+        Advanced usage: returns the reduced cost of the variable in the current
+        solution (only available for continuous problems).
+        """
+        return _pywraplp.Variable_reduced_cost(self)
 
-    def basis_status(self) -> "operations_research::MPSolver::BasisStatus":
-        r"""
-        Advanced usage: returns the basis status of the variable in the current
-        solution (only available for continuous problems).
+    def basis_status(self) -> "operations_research::MPSolver::BasisStatus":
+        r"""
+        Advanced usage: returns the basis status of the variable in the current
+        solution (only available for continuous problems).
 
-        See also: MPSolver::BasisStatus.
-        """
-        return _pywraplp.Variable_basis_status(self)
+        See also: MPSolver::BasisStatus.
+        """
+        return _pywraplp.Variable_basis_status(self)
 
-    def branching_priority(self) -> "int":
-        r"""
-        Advanced usage: Certain MIP solvers (e.g. Gurobi or SCIP) allow you to set
-        a per-variable priority for determining which variable to branch on.
+    def branching_priority(self) -> "int":
+        r"""
+        Advanced usage: Certain MIP solvers (e.g. Gurobi or SCIP) allow you to set
+        a per-variable priority for determining which variable to branch on.
 
-        A value of 0 is treated as default, and is equivalent to not setting the
-        branching priority. The solver looks first to branch on fractional
-        variables in higher priority levels. As of 2019-05, only Gurobi and SCIP
-        support setting branching priority; all other solvers will simply ignore
-        this annotation.
-        """
-        return _pywraplp.Variable_branching_priority(self)
+        A value of 0 is treated as default, and is equivalent to not setting the
+        branching priority. The solver looks first to branch on fractional
+        variables in higher priority levels. As of 2019-05, only Gurobi and SCIP
+        support setting branching priority; all other solvers will simply ignore
+        this annotation.
+        """
+        return _pywraplp.Variable_branching_priority(self)
 
-    def SetBranchingPriority(self, priority: "int") -> "void":
-        return _pywraplp.Variable_SetBranchingPriority(self, priority)
+    def SetBranchingPriority(self, priority: "int") -> "void":
+        return _pywraplp.Variable_SetBranchingPriority(self, priority)
 
-    def __str__(self) -> "std::string":
-        return _pywraplp.Variable___str__(self)
+    def __str__(self) -> "std::string":
+        return _pywraplp.Variable___str__(self)
 
-    def __repr__(self) -> "std::string":
-        return _pywraplp.Variable___repr__(self)
+    def __repr__(self) -> "std::string":
+        return _pywraplp.Variable___repr__(self)
 
-    def __getattr__(self, name):
-      return getattr(VariableExpr(self), name)
+    def __getattr__(self, name):
+      return getattr(VariableExpr(self), name)
 
 
-    def SolutionValue(self) -> "double":
-        return _pywraplp.Variable_SolutionValue(self)
+    def SolutionValue(self) -> "double":
+        return _pywraplp.Variable_SolutionValue(self)
 
-    def Integer(self) -> "bool":
-        return _pywraplp.Variable_Integer(self)
+    def Integer(self) -> "bool":
+        return _pywraplp.Variable_Integer(self)
 
-    def Lb(self) -> "double":
-        return _pywraplp.Variable_Lb(self)
+    def Lb(self) -> "double":
+        return _pywraplp.Variable_Lb(self)
 
-    def Ub(self) -> "double":
-        return _pywraplp.Variable_Ub(self)
+    def Ub(self) -> "double":
+        return _pywraplp.Variable_Ub(self)
 
-    def SetLb(self, x: "double") -> "void":
-        return _pywraplp.Variable_SetLb(self, x)
+    def SetLb(self, x: "double") -> "void":
+        return _pywraplp.Variable_SetLb(self, x)
 
-    def SetUb(self, x: "double") -> "void":
-        return _pywraplp.Variable_SetUb(self, x)
+    def SetUb(self, x: "double") -> "void":
+        return _pywraplp.Variable_SetUb(self, x)
 
-    def ReducedCost(self) -> "double":
-        return _pywraplp.Variable_ReducedCost(self)
-    __swig_destroy__ = _pywraplp.delete_Variable
+    def ReducedCost(self) -> "double":
+        return _pywraplp.Variable_ReducedCost(self)
+    __swig_destroy__ = _pywraplp.delete_Variable
 
-# Register Variable in _pywraplp:
-_pywraplp.Variable_swigregister(Variable)
+# Register Variable in _pywraplp:
+_pywraplp.Variable_swigregister(Variable)
 
-class Constraint(object):
-    r"""
-    The class for constraints of a Mathematical Programming (MP) model.
+class Constraint(object):
+    r"""
+    The class for constraints of a Mathematical Programming (MP) model.
 
-    A constraint is represented as a linear equation or inequality.
-    """
+    A constraint is represented as a linear equation or inequality.
+    """
 
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
 
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined")
-    __repr__ = _swig_repr
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
 
-    def name(self) -> "std::string const &":
-        r""" Returns the name of the constraint."""
-        return _pywraplp.Constraint_name(self)
+    def name(self) -> "std::string const &":
+        r""" Returns the name of the constraint."""
+        return _pywraplp.Constraint_name(self)
 
-    def Clear(self) -> "void":
-        r""" Clears all variables and coefficients. Does not clear the bounds."""
-        return _pywraplp.Constraint_Clear(self)
+    def Clear(self) -> "void":
+        r""" Clears all variables and coefficients. Does not clear the bounds."""
+        return _pywraplp.Constraint_Clear(self)
 
-    def SetCoefficient(self, var: "Variable", coeff: "double") -> "void":
-        r"""
-        Sets the coefficient of the variable on the constraint.
+    def SetCoefficient(self, var: "Variable", coeff: "double") -> "void":
+        r"""
+        Sets the coefficient of the variable on the constraint.
 
-        If the variable does not belong to the solver, the function just returns,
-        or crashes in non-opt mode.
-        """
-        return _pywraplp.Constraint_SetCoefficient(self, var, coeff)
-
-    def GetCoefficient(self, var: "Variable") -> "double":
-        r"""
-        Gets the coefficient of a given variable on the constraint (which is 0 if
-        the variable does not appear in the constraint).
-        """
-        return _pywraplp.Constraint_GetCoefficient(self, var)
-
-    def lb(self) -> "double":
-        r""" Returns the lower bound."""
-        return _pywraplp.Constraint_lb(self)
-
-    def ub(self) -> "double":
-        r""" Returns the upper bound."""
-        return _pywraplp.Constraint_ub(self)
-
-    def SetBounds(self, lb: "double", ub: "double") -> "void":
-        r""" Sets both the lower and upper bounds."""
-        return _pywraplp.Constraint_SetBounds(self, lb, ub)
-
-    def set_is_lazy(self, laziness: "bool") -> "void":
-        r"""
-        Advanced usage: sets the constraint "laziness".
-
-        **This is only supported for SCIP and has no effect on other
-        solvers.**
-
-        When **laziness** is true, the constraint is only considered by the Linear
-        Programming solver if its current solution violates the constraint. In this
-        case, the constraint is definitively added to the problem. This may be
-        useful in some MIP problems, and may have a dramatic impact on performance.
-
-        For more info see: http://tinyurl.com/lazy-constraints.
-        """
-        return _pywraplp.Constraint_set_is_lazy(self, laziness)
-
-    def index(self) -> "int":
-        r""" Returns the index of the constraint in the MPSolver::constraints_."""
-        return _pywraplp.Constraint_index(self)
-
-    def dual_value(self) -> "double":
-        r"""
-        Advanced usage: returns the dual value of the constraint in the current
-        solution (only available for continuous problems).
-        """
-        return _pywraplp.Constraint_dual_value(self)
-
-    def basis_status(self) -> "operations_research::MPSolver::BasisStatus":
-        r"""
-        Advanced usage: returns the basis status of the constraint.
-
-        It is only available for continuous problems).
-
-        Note that if a constraint "linear_expression in [lb, ub]" is transformed
-        into "linear_expression + slack = 0" with slack in [-ub, -lb], then this
-        status is the same as the status of the slack variable with AT_UPPER_BOUND
-        and AT_LOWER_BOUND swapped.
-
-        See also: MPSolver::BasisStatus.
-        """
-        return _pywraplp.Constraint_basis_status(self)
-
-    def Lb(self) -> "double":
-        return _pywraplp.Constraint_Lb(self)
-
-    def Ub(self) -> "double":
-        return _pywraplp.Constraint_Ub(self)
-
-    def SetLb(self, x: "double") -> "void":
-        return _pywraplp.Constraint_SetLb(self, x)
-
-    def SetUb(self, x: "double") -> "void":
-        return _pywraplp.Constraint_SetUb(self, x)
-
-    def DualValue(self) -> "double":
-        return _pywraplp.Constraint_DualValue(self)
-    __swig_destroy__ = _pywraplp.delete_Constraint
-
-# Register Constraint in _pywraplp:
-_pywraplp.Constraint_swigregister(Constraint)
-
-class MPSolverParameters(object):
-    r"""
-    This class stores parameter settings for LP and MIP solvers. Some parameters
-    are marked as advanced: do not change their values unless you know what you
-    are doing!
-
-    For developers: how to add a new parameter:
-    - Add the new Foo parameter in the DoubleParam or IntegerParam enum.
-    - If it is a categorical param, add a FooValues enum.
-    - Decide if the wrapper should define a default value for it: yes
-      if it controls the properties of the solution (example:
-      tolerances) or if it consistently improves performance, no
-      otherwise. If yes, define kDefaultFoo.
-    - Add a foo_value_ member and, if no default value is defined, a
-      foo_is_default_ member.
-    - Add code to handle Foo in Set...Param, Reset...Param,
-      Get...Param, Reset and the constructor.
-    - In class MPSolverInterface, add a virtual method SetFoo, add it
-      to SetCommonParameters or SetMIPParameters, and implement it for
-      each solver. Sometimes, parameters need to be implemented
-      differently, see for example the INCREMENTALITY implementation.
-    - Add a test in linear_solver_test.cc.
-
-    TODO(user): store the parameter values in a protocol buffer
-    instead. We need to figure out how to deal with the subtleties of
-    the default values.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-    RELATIVE_MIP_GAP = _pywraplp.MPSolverParameters_RELATIVE_MIP_GAP
-    r""" Limit for relative MIP gap."""
-    PRIMAL_TOLERANCE = _pywraplp.MPSolverParameters_PRIMAL_TOLERANCE
-    r"""
-    Advanced usage: tolerance for primal feasibility of basic solutions.
-
-    This does not control the integer feasibility tolerance of integer
-    solutions for MIP or the tolerance used during presolve.
-    """
-    DUAL_TOLERANCE = _pywraplp.MPSolverParameters_DUAL_TOLERANCE
-    r""" Advanced usage: tolerance for dual feasibility of basic solutions."""
-    PRESOLVE = _pywraplp.MPSolverParameters_PRESOLVE
-    r""" Advanced usage: presolve mode."""
-    LP_ALGORITHM = _pywraplp.MPSolverParameters_LP_ALGORITHM
-    r""" Algorithm to solve linear programs."""
-    INCREMENTALITY = _pywraplp.MPSolverParameters_INCREMENTALITY
-    r""" Advanced usage: incrementality from one solve to the next."""
-    SCALING = _pywraplp.MPSolverParameters_SCALING
-    r""" Advanced usage: enable or disable matrix scaling."""
-    PRESOLVE_OFF = _pywraplp.MPSolverParameters_PRESOLVE_OFF
-    r""" Presolve is off."""
-    PRESOLVE_ON = _pywraplp.MPSolverParameters_PRESOLVE_ON
-    r""" Presolve is on."""
-    DUAL = _pywraplp.MPSolverParameters_DUAL
-    r""" Dual simplex."""
-    PRIMAL = _pywraplp.MPSolverParameters_PRIMAL
-    r""" Primal simplex."""
-    BARRIER = _pywraplp.MPSolverParameters_BARRIER
-    r""" Barrier algorithm."""
-    INCREMENTALITY_OFF = _pywraplp.MPSolverParameters_INCREMENTALITY_OFF
-    r""" Start solve from scratch."""
-    INCREMENTALITY_ON = _pywraplp.MPSolverParameters_INCREMENTALITY_ON
-    r"""
-    Reuse results from previous solve as much as the underlying solver
-    allows.
-    """
-    SCALING_OFF = _pywraplp.MPSolverParameters_SCALING_OFF
-    r""" Scaling is off."""
-    SCALING_ON = _pywraplp.MPSolverParameters_SCALING_ON
-    r""" Scaling is on."""
-
-    def __init__(self):
-        r""" The constructor sets all parameters to their default value."""
-        _pywraplp.MPSolverParameters_swiginit(self, _pywraplp.new_MPSolverParameters())
-
-    def SetDoubleParam(self, param: "operations_research::MPSolverParameters::DoubleParam", value: "double") -> "void":
-        r""" Sets a double parameter to a specific value."""
-        return _pywraplp.MPSolverParameters_SetDoubleParam(self, param, value)
-
-    def SetIntegerParam(self, param: "operations_research::MPSolverParameters::IntegerParam", value: "int") -> "void":
-        r""" Sets a integer parameter to a specific value."""
-        return _pywraplp.MPSolverParameters_SetIntegerParam(self, param, value)
-
-    def GetDoubleParam(self, param: "operations_research::MPSolverParameters::DoubleParam") -> "double":
-        r""" Returns the value of a double parameter."""
-        return _pywraplp.MPSolverParameters_GetDoubleParam(self, param)
-
-    def GetIntegerParam(self, param: "operations_research::MPSolverParameters::IntegerParam") -> "int":
-        r""" Returns the value of an integer parameter."""
-        return _pywraplp.MPSolverParameters_GetIntegerParam(self, param)
-    __swig_destroy__ = _pywraplp.delete_MPSolverParameters
-
-# Register MPSolverParameters in _pywraplp:
-_pywraplp.MPSolverParameters_swigregister(MPSolverParameters)
-cvar = _pywraplp.cvar
-MPSolverParameters.kDefaultRelativeMipGap = _pywraplp.cvar.MPSolverParameters_kDefaultRelativeMipGap
-MPSolverParameters.kDefaultPrimalTolerance = _pywraplp.cvar.MPSolverParameters_kDefaultPrimalTolerance
-MPSolverParameters.kDefaultDualTolerance = _pywraplp.cvar.MPSolverParameters_kDefaultDualTolerance
-MPSolverParameters.kDefaultPresolve = _pywraplp.cvar.MPSolverParameters_kDefaultPresolve
-MPSolverParameters.kDefaultIncrementality = _pywraplp.cvar.MPSolverParameters_kDefaultIncrementality
-
-class ModelExportOptions(object):
-    r""" Export options."""
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self):
-        _pywraplp.ModelExportOptions_swiginit(self, _pywraplp.new_ModelExportOptions())
-    __swig_destroy__ = _pywraplp.delete_ModelExportOptions
-
-# Register ModelExportOptions in _pywraplp:
-_pywraplp.ModelExportOptions_swigregister(ModelExportOptions)
-
-
-def ExportModelAsLpFormat(*args) -> "std::string":
-    return _pywraplp.ExportModelAsLpFormat(*args)
-
-def ExportModelAsMpsFormat(*args) -> "std::string":
-    return _pywraplp.ExportModelAsMpsFormat(*args)
-
-def FindErrorInModelProto(input_model: "operations_research::MPModelProto const &") -> "std::string":
-    return _pywraplp.FindErrorInModelProto(input_model)
-
-def setup_variable_operator(opname):
-  setattr(Variable, opname,
-          lambda self, *args: getattr(VariableExpr(self), opname)(*args))
-for opname in LinearExpr.OVERRIDDEN_OPERATOR_METHODS:
-  setup_variable_operator(opname)
-
-
-
-
-
-
-
-

Functions

-
-
-def ExportModelAsLpFormat(*args) ‑> std::string -
-
-
-
- -Expand source code - -
def ExportModelAsLpFormat(*args) -> "std::string":
-    return _pywraplp.ExportModelAsLpFormat(*args)
-
-
-
-def ExportModelAsMpsFormat(*args) ‑> std::string -
-
-
-
- -Expand source code - -
def ExportModelAsMpsFormat(*args) -> "std::string":
-    return _pywraplp.ExportModelAsMpsFormat(*args)
-
-
-
-def FindErrorInModelProto(input_model: operations_research::MPModelProto const &) ‑> std::string -
-
-
-
- -Expand source code - -
def FindErrorInModelProto(input_model: "operations_research::MPModelProto const &") -> "std::string":
-    return _pywraplp.FindErrorInModelProto(input_model)
-
-
-
-def Solver_CreateSolver(solver_id: std::string const &) ‑> operations_research::MPSolver * -
-
-

Recommended factory method to create a MPSolver instance, especially in -non C++ languages.

-

It returns a newly created solver instance if successful, or a nullptr -otherwise. This can occur if the relevant interface is not linked in, or if -a needed license is not accessible for commercial solvers.

-

Ownership of the solver is passed on to the caller of this method. -It will accept both string names of the OptimizationProblemType enum, as -well as a short version (i.e. "SCIP_MIXED_INTEGER_PROGRAMMING" or "SCIP").

-

solver_id is case insensitive, and the following names are supported: -- CLP_LINEAR_PROGRAMMING or CLP -- CBC_MIXED_INTEGER_PROGRAMMING or CBC -- GLOP_LINEAR_PROGRAMMING or GLOP -- BOP_INTEGER_PROGRAMMING or BOP -- SAT_INTEGER_PROGRAMMING or SAT or CP_SAT -- SCIP_MIXED_INTEGER_PROGRAMMING or SCIP -- GUROBI_LINEAR_PROGRAMMING or GUROBI_LP -- GUROBI_MIXED_INTEGER_PROGRAMMING or GUROBI or GUROBI_MIP -- CPLEX_LINEAR_PROGRAMMING or CPLEX_LP -- CPLEX_MIXED_INTEGER_PROGRAMMING or CPLEX or CPLEX_MIP -- XPRESS_LINEAR_PROGRAMMING or XPRESS_LP -- XPRESS_MIXED_INTEGER_PROGRAMMING or XPRESS or XPRESS_MIP -- GLPK_LINEAR_PROGRAMMING or GLPK_LP -- GLPK_MIXED_INTEGER_PROGRAMMING or GLPK or GLPK_MIP

-
- -Expand source code - -
def Solver_CreateSolver(solver_id: "std::string const &") -> "operations_research::MPSolver *":
-    r"""
-    Recommended factory method to create a MPSolver instance, especially in
-    non C++ languages.
-
-    It returns a newly created solver instance if successful, or a nullptr
-    otherwise. This can occur if the relevant interface is not linked in, or if
-    a needed license is not accessible for commercial solvers.
-
-    Ownership of the solver is passed on to the caller of this method.
-    It will accept both string names of the OptimizationProblemType enum, as
-    well as a short version (i.e. "SCIP_MIXED_INTEGER_PROGRAMMING" or "SCIP").
-
-    solver_id is case insensitive, and the following names are supported:
-      - CLP_LINEAR_PROGRAMMING or CLP
-      - CBC_MIXED_INTEGER_PROGRAMMING or CBC
-      - GLOP_LINEAR_PROGRAMMING or GLOP
-      - BOP_INTEGER_PROGRAMMING or BOP
-      - SAT_INTEGER_PROGRAMMING or SAT or CP_SAT
-      - SCIP_MIXED_INTEGER_PROGRAMMING or SCIP
-      - GUROBI_LINEAR_PROGRAMMING or GUROBI_LP
-      - GUROBI_MIXED_INTEGER_PROGRAMMING or GUROBI or GUROBI_MIP
-      - CPLEX_LINEAR_PROGRAMMING or CPLEX_LP
-      - CPLEX_MIXED_INTEGER_PROGRAMMING or CPLEX or CPLEX_MIP
-      - XPRESS_LINEAR_PROGRAMMING or XPRESS_LP
-      - XPRESS_MIXED_INTEGER_PROGRAMMING or XPRESS or XPRESS_MIP
-      - GLPK_LINEAR_PROGRAMMING or GLPK_LP
-      - GLPK_MIXED_INTEGER_PROGRAMMING or GLPK or GLPK_MIP
-    """
-    return _pywraplp.Solver_CreateSolver(solver_id)
-
-
-
-
-
-

Classes

-
-
-class Constraint -(*args, **kwargs) -
-
-

The class for constraints of a Mathematical Programming (MP) model.

-

A constraint is represented as a linear equation or inequality.

-
- -Expand source code - -
class Constraint(object):
-    r"""
-    The class for constraints of a Mathematical Programming (MP) model.
-
-    A constraint is represented as a linear equation or inequality.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined")
-    __repr__ = _swig_repr
-
-    def name(self) -> "std::string const &":
-        r""" Returns the name of the constraint."""
-        return _pywraplp.Constraint_name(self)
-
-    def Clear(self) -> "void":
-        r""" Clears all variables and coefficients. Does not clear the bounds."""
-        return _pywraplp.Constraint_Clear(self)
-
-    def SetCoefficient(self, var: "Variable", coeff: "double") -> "void":
-        r"""
-        Sets the coefficient of the variable on the constraint.
-
-        If the variable does not belong to the solver, the function just returns,
-        or crashes in non-opt mode.
-        """
-        return _pywraplp.Constraint_SetCoefficient(self, var, coeff)
-
-    def GetCoefficient(self, var: "Variable") -> "double":
-        r"""
-        Gets the coefficient of a given variable on the constraint (which is 0 if
-        the variable does not appear in the constraint).
-        """
-        return _pywraplp.Constraint_GetCoefficient(self, var)
-
-    def lb(self) -> "double":
-        r""" Returns the lower bound."""
-        return _pywraplp.Constraint_lb(self)
-
-    def ub(self) -> "double":
-        r""" Returns the upper bound."""
-        return _pywraplp.Constraint_ub(self)
-
-    def SetBounds(self, lb: "double", ub: "double") -> "void":
-        r""" Sets both the lower and upper bounds."""
-        return _pywraplp.Constraint_SetBounds(self, lb, ub)
-
-    def set_is_lazy(self, laziness: "bool") -> "void":
-        r"""
-        Advanced usage: sets the constraint "laziness".
-
-        **This is only supported for SCIP and has no effect on other
-        solvers.**
-
-        When **laziness** is true, the constraint is only considered by the Linear
-        Programming solver if its current solution violates the constraint. In this
-        case, the constraint is definitively added to the problem. This may be
-        useful in some MIP problems, and may have a dramatic impact on performance.
-
-        For more info see: http://tinyurl.com/lazy-constraints.
-        """
-        return _pywraplp.Constraint_set_is_lazy(self, laziness)
-
-    def index(self) -> "int":
-        r""" Returns the index of the constraint in the MPSolver::constraints_."""
-        return _pywraplp.Constraint_index(self)
-
-    def dual_value(self) -> "double":
-        r"""
-        Advanced usage: returns the dual value of the constraint in the current
-        solution (only available for continuous problems).
-        """
-        return _pywraplp.Constraint_dual_value(self)
-
-    def basis_status(self) -> "operations_research::MPSolver::BasisStatus":
-        r"""
-        Advanced usage: returns the basis status of the constraint.
-
-        It is only available for continuous problems).
-
-        Note that if a constraint "linear_expression in [lb, ub]" is transformed
-        into "linear_expression + slack = 0" with slack in [-ub, -lb], then this
-        status is the same as the status of the slack variable with AT_UPPER_BOUND
-        and AT_LOWER_BOUND swapped.
-
-        See also: MPSolver::BasisStatus.
-        """
-        return _pywraplp.Constraint_basis_status(self)
-
-    def Lb(self) -> "double":
-        return _pywraplp.Constraint_Lb(self)
-
-    def Ub(self) -> "double":
-        return _pywraplp.Constraint_Ub(self)
-
-    def SetLb(self, x: "double") -> "void":
-        return _pywraplp.Constraint_SetLb(self, x)
-
-    def SetUb(self, x: "double") -> "void":
-        return _pywraplp.Constraint_SetUb(self, x)
-
-    def DualValue(self) -> "double":
-        return _pywraplp.Constraint_DualValue(self)
-    __swig_destroy__ = _pywraplp.delete_Constraint
-
-

Methods

-
-
-def Clear(self) ‑> void -
-
-

Clears all variables and coefficients. Does not clear the bounds.

-
- -Expand source code - -
def Clear(self) -> "void":
-    r""" Clears all variables and coefficients. Does not clear the bounds."""
-    return _pywraplp.Constraint_Clear(self)
-
-
-
-def DualValue(self) ‑> double -
-
-
-
- -Expand source code - -
def DualValue(self) -> "double":
-    return _pywraplp.Constraint_DualValue(self)
-
-
-
-def GetCoefficient(self, var: Variable) ‑> double -
-
-

Gets the coefficient of a given variable on the constraint (which is 0 if -the variable does not appear in the constraint).

-
- -Expand source code - -
def GetCoefficient(self, var: "Variable") -> "double":
-    r"""
-    Gets the coefficient of a given variable on the constraint (which is 0 if
-    the variable does not appear in the constraint).
-    """
-    return _pywraplp.Constraint_GetCoefficient(self, var)
-
-
-
-def Lb(self) ‑> double -
-
-
-
- -Expand source code - -
def Lb(self) -> "double":
-    return _pywraplp.Constraint_Lb(self)
-
-
-
-def SetBounds(self, lb: double, ub: double) ‑> void -
-
-

Sets both the lower and upper bounds.

-
- -Expand source code - -
def SetBounds(self, lb: "double", ub: "double") -> "void":
-    r""" Sets both the lower and upper bounds."""
-    return _pywraplp.Constraint_SetBounds(self, lb, ub)
-
-
-
-def SetCoefficient(self, var: Variable, coeff: double) ‑> void -
-
-

Sets the coefficient of the variable on the constraint.

-

If the variable does not belong to the solver, the function just returns, -or crashes in non-opt mode.

-
- -Expand source code - -
def SetCoefficient(self, var: "Variable", coeff: "double") -> "void":
-    r"""
-    Sets the coefficient of the variable on the constraint.
-
-    If the variable does not belong to the solver, the function just returns,
-    or crashes in non-opt mode.
-    """
-    return _pywraplp.Constraint_SetCoefficient(self, var, coeff)
-
-
-
-def SetLb(self, x: double) ‑> void -
-
-
-
- -Expand source code - -
def SetLb(self, x: "double") -> "void":
-    return _pywraplp.Constraint_SetLb(self, x)
-
-
-
-def SetUb(self, x: double) ‑> void -
-
-
-
- -Expand source code - -
def SetUb(self, x: "double") -> "void":
-    return _pywraplp.Constraint_SetUb(self, x)
-
-
-
-def Ub(self) ‑> double -
-
-
-
- -Expand source code - -
def Ub(self) -> "double":
-    return _pywraplp.Constraint_Ub(self)
-
-
-
-def basis_status(self) ‑> operations_research::MPSolver::BasisStatus -
-
-

Advanced usage: returns the basis status of the constraint.

-

It is only available for continuous problems).

-

Note that if a constraint "linear_expression in [lb, ub]" is transformed -into "linear_expression + slack = 0" with slack in [-ub, -lb], then this -status is the same as the status of the slack variable with AT_UPPER_BOUND -and AT_LOWER_BOUND swapped.

-

See also: MPSolver::BasisStatus.

-
- -Expand source code - -
def basis_status(self) -> "operations_research::MPSolver::BasisStatus":
-    r"""
-    Advanced usage: returns the basis status of the constraint.
-
-    It is only available for continuous problems).
-
-    Note that if a constraint "linear_expression in [lb, ub]" is transformed
-    into "linear_expression + slack = 0" with slack in [-ub, -lb], then this
-    status is the same as the status of the slack variable with AT_UPPER_BOUND
-    and AT_LOWER_BOUND swapped.
-
-    See also: MPSolver::BasisStatus.
-    """
-    return _pywraplp.Constraint_basis_status(self)
-
-
-
-def dual_value(self) ‑> double -
-
-

Advanced usage: returns the dual value of the constraint in the current -solution (only available for continuous problems).

-
- -Expand source code - -
def dual_value(self) -> "double":
-    r"""
-    Advanced usage: returns the dual value of the constraint in the current
-    solution (only available for continuous problems).
-    """
-    return _pywraplp.Constraint_dual_value(self)
-
-
-
-def index(self) ‑> int -
-
-

Returns the index of the constraint in the MPSolver::constraints_.

-
- -Expand source code - -
def index(self) -> "int":
-    r""" Returns the index of the constraint in the MPSolver::constraints_."""
-    return _pywraplp.Constraint_index(self)
-
-
-
-def lb(self) ‑> double -
-
-

Returns the lower bound.

-
- -Expand source code - -
def lb(self) -> "double":
-    r""" Returns the lower bound."""
-    return _pywraplp.Constraint_lb(self)
-
-
-
-def name(self) ‑> std::string const & -
-
-

Returns the name of the constraint.

-
- -Expand source code - -
def name(self) -> "std::string const &":
-    r""" Returns the name of the constraint."""
-    return _pywraplp.Constraint_name(self)
-
-
-
-def set_is_lazy(self, laziness: bool) ‑> void -
-
-

Advanced usage: sets the constraint "laziness".

-

This is only supported for SCIP and has no effect on other -solvers.

-

When laziness is true, the constraint is only considered by the Linear -Programming solver if its current solution violates the constraint. In this -case, the constraint is definitively added to the problem. This may be -useful in some MIP problems, and may have a dramatic impact on performance.

-

For more info see: http://tinyurl.com/lazy-constraints.

-
- -Expand source code - -
def set_is_lazy(self, laziness: "bool") -> "void":
-    r"""
-    Advanced usage: sets the constraint "laziness".
-
-    **This is only supported for SCIP and has no effect on other
-    solvers.**
-
-    When **laziness** is true, the constraint is only considered by the Linear
-    Programming solver if its current solution violates the constraint. In this
-    case, the constraint is definitively added to the problem. This may be
-    useful in some MIP problems, and may have a dramatic impact on performance.
-
-    For more info see: http://tinyurl.com/lazy-constraints.
-    """
-    return _pywraplp.Constraint_set_is_lazy(self, laziness)
-
-
-
-def ub(self) ‑> double -
-
-

Returns the upper bound.

-
- -Expand source code - -
def ub(self) -> "double":
-    r""" Returns the upper bound."""
-    return _pywraplp.Constraint_ub(self)
-
-
-
-
-
-class MPSolverParameters -
-
-

This class stores parameter settings for LP and MIP solvers. Some parameters -are marked as advanced: do not change their values unless you know what you -are doing!

-

For developers: how to add a new parameter: -- Add the new Foo parameter in the DoubleParam or IntegerParam enum. -- If it is a categorical param, add a FooValues enum. -- Decide if the wrapper should define a default value for it: yes -if it controls the properties of the solution (example: -tolerances) or if it consistently improves performance, no -otherwise. If yes, define kDefaultFoo. -- Add a foo_value_ member and, if no default value is defined, a -foo_is_default_ member. -- Add code to handle Foo in Set…Param, Reset…Param, -Get…Param, Reset and the constructor. -- In class MPSolverInterface, add a virtual method SetFoo, add it -to SetCommonParameters or SetMIPParameters, and implement it for -each solver. Sometimes, parameters need to be implemented -differently, see for example the INCREMENTALITY implementation. -- Add a test in linear_solver_test.cc.

-

TODO(user): store the parameter values in a protocol buffer -instead. We need to figure out how to deal with the subtleties of -the default values.

-

The constructor sets all parameters to their default value.

-
- -Expand source code - -
class MPSolverParameters(object):
-    r"""
-    This class stores parameter settings for LP and MIP solvers. Some parameters
-    are marked as advanced: do not change their values unless you know what you
-    are doing!
-
-    For developers: how to add a new parameter:
-    - Add the new Foo parameter in the DoubleParam or IntegerParam enum.
-    - If it is a categorical param, add a FooValues enum.
-    - Decide if the wrapper should define a default value for it: yes
-      if it controls the properties of the solution (example:
-      tolerances) or if it consistently improves performance, no
-      otherwise. If yes, define kDefaultFoo.
-    - Add a foo_value_ member and, if no default value is defined, a
-      foo_is_default_ member.
-    - Add code to handle Foo in Set...Param, Reset...Param,
-      Get...Param, Reset and the constructor.
-    - In class MPSolverInterface, add a virtual method SetFoo, add it
-      to SetCommonParameters or SetMIPParameters, and implement it for
-      each solver. Sometimes, parameters need to be implemented
-      differently, see for example the INCREMENTALITY implementation.
-    - Add a test in linear_solver_test.cc.
-
-    TODO(user): store the parameter values in a protocol buffer
-    instead. We need to figure out how to deal with the subtleties of
-    the default values.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-    RELATIVE_MIP_GAP = _pywraplp.MPSolverParameters_RELATIVE_MIP_GAP
-    r""" Limit for relative MIP gap."""
-    PRIMAL_TOLERANCE = _pywraplp.MPSolverParameters_PRIMAL_TOLERANCE
-    r"""
-    Advanced usage: tolerance for primal feasibility of basic solutions.
-
-    This does not control the integer feasibility tolerance of integer
-    solutions for MIP or the tolerance used during presolve.
-    """
-    DUAL_TOLERANCE = _pywraplp.MPSolverParameters_DUAL_TOLERANCE
-    r""" Advanced usage: tolerance for dual feasibility of basic solutions."""
-    PRESOLVE = _pywraplp.MPSolverParameters_PRESOLVE
-    r""" Advanced usage: presolve mode."""
-    LP_ALGORITHM = _pywraplp.MPSolverParameters_LP_ALGORITHM
-    r""" Algorithm to solve linear programs."""
-    INCREMENTALITY = _pywraplp.MPSolverParameters_INCREMENTALITY
-    r""" Advanced usage: incrementality from one solve to the next."""
-    SCALING = _pywraplp.MPSolverParameters_SCALING
-    r""" Advanced usage: enable or disable matrix scaling."""
-    PRESOLVE_OFF = _pywraplp.MPSolverParameters_PRESOLVE_OFF
-    r""" Presolve is off."""
-    PRESOLVE_ON = _pywraplp.MPSolverParameters_PRESOLVE_ON
-    r""" Presolve is on."""
-    DUAL = _pywraplp.MPSolverParameters_DUAL
-    r""" Dual simplex."""
-    PRIMAL = _pywraplp.MPSolverParameters_PRIMAL
-    r""" Primal simplex."""
-    BARRIER = _pywraplp.MPSolverParameters_BARRIER
-    r""" Barrier algorithm."""
-    INCREMENTALITY_OFF = _pywraplp.MPSolverParameters_INCREMENTALITY_OFF
-    r""" Start solve from scratch."""
-    INCREMENTALITY_ON = _pywraplp.MPSolverParameters_INCREMENTALITY_ON
-    r"""
-    Reuse results from previous solve as much as the underlying solver
-    allows.
-    """
-    SCALING_OFF = _pywraplp.MPSolverParameters_SCALING_OFF
-    r""" Scaling is off."""
-    SCALING_ON = _pywraplp.MPSolverParameters_SCALING_ON
-    r""" Scaling is on."""
-
-    def __init__(self):
-        r""" The constructor sets all parameters to their default value."""
-        _pywraplp.MPSolverParameters_swiginit(self, _pywraplp.new_MPSolverParameters())
-
-    def SetDoubleParam(self, param: "operations_research::MPSolverParameters::DoubleParam", value: "double") -> "void":
-        r""" Sets a double parameter to a specific value."""
-        return _pywraplp.MPSolverParameters_SetDoubleParam(self, param, value)
-
-    def SetIntegerParam(self, param: "operations_research::MPSolverParameters::IntegerParam", value: "int") -> "void":
-        r""" Sets a integer parameter to a specific value."""
-        return _pywraplp.MPSolverParameters_SetIntegerParam(self, param, value)
-
-    def GetDoubleParam(self, param: "operations_research::MPSolverParameters::DoubleParam") -> "double":
-        r""" Returns the value of a double parameter."""
-        return _pywraplp.MPSolverParameters_GetDoubleParam(self, param)
-
-    def GetIntegerParam(self, param: "operations_research::MPSolverParameters::IntegerParam") -> "int":
-        r""" Returns the value of an integer parameter."""
-        return _pywraplp.MPSolverParameters_GetIntegerParam(self, param)
-    __swig_destroy__ = _pywraplp.delete_MPSolverParameters
-
-

Class variables

-
-
var BARRIER
-
-

Barrier algorithm.

-
-
var DUAL
-
-

Dual simplex.

-
-
var DUAL_TOLERANCE
-
-

Advanced usage: tolerance for dual feasibility of basic solutions.

-
-
var INCREMENTALITY
-
-

Advanced usage: incrementality from one solve to the next.

-
-
var INCREMENTALITY_OFF
-
-

Start solve from scratch.

-
-
var INCREMENTALITY_ON
-
-

Reuse results from previous solve as much as the underlying solver -allows.

-
-
var LP_ALGORITHM
-
-

Algorithm to solve linear programs.

-
-
var PRESOLVE
-
-

Advanced usage: presolve mode.

-
-
var PRESOLVE_OFF
-
-

Presolve is off.

-
-
var PRESOLVE_ON
-
-

Presolve is on.

-
-
var PRIMAL
-
-

Primal simplex.

-
-
var PRIMAL_TOLERANCE
-
-

Advanced usage: tolerance for primal feasibility of basic solutions.

-

This does not control the integer feasibility tolerance of integer -solutions for MIP or the tolerance used during presolve.

-
-
var RELATIVE_MIP_GAP
-
-

Limit for relative MIP gap.

-
-
var SCALING
-
-

Advanced usage: enable or disable matrix scaling.

-
-
var SCALING_OFF
-
-

Scaling is off.

-
-
var SCALING_ON
-
-

Scaling is on.

-
-
var kDefaultDualTolerance
-
-
-
-
var kDefaultIncrementality
-
-
-
-
var kDefaultPresolve
-
-
-
-
var kDefaultPrimalTolerance
-
-
-
-
var kDefaultRelativeMipGap
-
-
-
-
-

Methods

-
-
-def GetDoubleParam(self, param: operations_research::MPSolverParameters::DoubleParam) ‑> double -
-
-

Returns the value of a double parameter.

-
- -Expand source code - -
def GetDoubleParam(self, param: "operations_research::MPSolverParameters::DoubleParam") -> "double":
-    r""" Returns the value of a double parameter."""
-    return _pywraplp.MPSolverParameters_GetDoubleParam(self, param)
-
-
-
-def GetIntegerParam(self, param: operations_research::MPSolverParameters::IntegerParam) ‑> int -
-
-

Returns the value of an integer parameter.

-
- -Expand source code - -
def GetIntegerParam(self, param: "operations_research::MPSolverParameters::IntegerParam") -> "int":
-    r""" Returns the value of an integer parameter."""
-    return _pywraplp.MPSolverParameters_GetIntegerParam(self, param)
-
-
-
-def SetDoubleParam(self, param: operations_research::MPSolverParameters::DoubleParam, value: double) ‑> void -
-
-

Sets a double parameter to a specific value.

-
- -Expand source code - -
def SetDoubleParam(self, param: "operations_research::MPSolverParameters::DoubleParam", value: "double") -> "void":
-    r""" Sets a double parameter to a specific value."""
-    return _pywraplp.MPSolverParameters_SetDoubleParam(self, param, value)
-
-
-
-def SetIntegerParam(self, param: operations_research::MPSolverParameters::IntegerParam, value: int) ‑> void -
-
-

Sets a integer parameter to a specific value.

-
- -Expand source code - -
def SetIntegerParam(self, param: "operations_research::MPSolverParameters::IntegerParam", value: "int") -> "void":
-    r""" Sets a integer parameter to a specific value."""
-    return _pywraplp.MPSolverParameters_SetIntegerParam(self, param, value)
-
-
-
-
-
-class ModelExportOptions -
-
-

Export options.

-
- -Expand source code - -
class ModelExportOptions(object):
-    r""" Export options."""
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self):
-        _pywraplp.ModelExportOptions_swiginit(self, _pywraplp.new_ModelExportOptions())
-    __swig_destroy__ = _pywraplp.delete_ModelExportOptions
-
-
-
-class Objective -(*args, **kwargs) -
-
-

A class to express a linear objective.

-
- -Expand source code - -
class Objective(object):
-    r""" A class to express a linear objective."""
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined")
-    __repr__ = _swig_repr
-
-    def Clear(self) -> "void":
-        r"""
-         Clears the offset, all variables and coefficients, and the optimization
-        direction.
-        """
-        return _pywraplp.Objective_Clear(self)
-
-    def SetCoefficient(self, var: "Variable", coeff: "double") -> "void":
-        r"""
-        Sets the coefficient of the variable in the objective.
-
-        If the variable does not belong to the solver, the function just returns,
-        or crashes in non-opt mode.
-        """
-        return _pywraplp.Objective_SetCoefficient(self, var, coeff)
-
-    def GetCoefficient(self, var: "Variable") -> "double":
-        r"""
-         Gets the coefficient of a given variable in the objective
-
-        It returns 0 if the variable does not appear in the objective).
-        """
-        return _pywraplp.Objective_GetCoefficient(self, var)
-
-    def SetOffset(self, value: "double") -> "void":
-        r""" Sets the constant term in the objective."""
-        return _pywraplp.Objective_SetOffset(self, value)
-
-    def offset(self) -> "double":
-        r""" Gets the constant term in the objective."""
-        return _pywraplp.Objective_offset(self)
-
-    def SetOptimizationDirection(self, maximize: "bool") -> "void":
-        r""" Sets the optimization direction (maximize: true or minimize: false)."""
-        return _pywraplp.Objective_SetOptimizationDirection(self, maximize)
-
-    def SetMinimization(self) -> "void":
-        r""" Sets the optimization direction to minimize."""
-        return _pywraplp.Objective_SetMinimization(self)
-
-    def SetMaximization(self) -> "void":
-        r""" Sets the optimization direction to maximize."""
-        return _pywraplp.Objective_SetMaximization(self)
-
-    def maximization(self) -> "bool":
-        r""" Is the optimization direction set to maximize?"""
-        return _pywraplp.Objective_maximization(self)
-
-    def minimization(self) -> "bool":
-        r""" Is the optimization direction set to minimize?"""
-        return _pywraplp.Objective_minimization(self)
-
-    def Value(self) -> "double":
-        r"""
-        Returns the objective value of the best solution found so far.
-
-        It is the optimal objective value if the problem has been solved to
-        optimality.
-
-        Note: the objective value may be slightly different than what you could
-        compute yourself using ``MPVariable::solution_value();`` please use the
-        --verify_solution flag to gain confidence about the numerical stability of
-        your solution.
-        """
-        return _pywraplp.Objective_Value(self)
-
-    def BestBound(self) -> "double":
-        r"""
-        Returns the best objective bound.
-
-        In case of minimization, it is a lower bound on the objective value of the
-        optimal integer solution. Only available for discrete problems.
-        """
-        return _pywraplp.Objective_BestBound(self)
-
-    def Offset(self) -> "double":
-        return _pywraplp.Objective_Offset(self)
-    __swig_destroy__ = _pywraplp.delete_Objective
-
-

Methods

-
-
-def BestBound(self) ‑> double -
-
-

Returns the best objective bound.

-

In case of minimization, it is a lower bound on the objective value of the -optimal integer solution. Only available for discrete problems.

-
- -Expand source code - -
def BestBound(self) -> "double":
-    r"""
-    Returns the best objective bound.
-
-    In case of minimization, it is a lower bound on the objective value of the
-    optimal integer solution. Only available for discrete problems.
-    """
-    return _pywraplp.Objective_BestBound(self)
-
-
-
-def Clear(self) ‑> void -
-
-

Clears the offset, all variables and coefficients, and the optimization -direction.

-
- -Expand source code - -
def Clear(self) -> "void":
-    r"""
-     Clears the offset, all variables and coefficients, and the optimization
-    direction.
-    """
-    return _pywraplp.Objective_Clear(self)
-
-
-
-def GetCoefficient(self, var: Variable) ‑> double -
-
-

Gets the coefficient of a given variable in the objective

-

It returns 0 if the variable does not appear in the objective).

-
- -Expand source code - -
def GetCoefficient(self, var: "Variable") -> "double":
-    r"""
-     Gets the coefficient of a given variable in the objective
-
-    It returns 0 if the variable does not appear in the objective).
-    """
-    return _pywraplp.Objective_GetCoefficient(self, var)
-
-
-
-def Offset(self) ‑> double -
-
-
-
- -Expand source code - -
def Offset(self) -> "double":
-    return _pywraplp.Objective_Offset(self)
-
-
-
-def SetCoefficient(self, var: Variable, coeff: double) ‑> void -
-
-

Sets the coefficient of the variable in the objective.

-

If the variable does not belong to the solver, the function just returns, -or crashes in non-opt mode.

-
- -Expand source code - -
def SetCoefficient(self, var: "Variable", coeff: "double") -> "void":
-    r"""
-    Sets the coefficient of the variable in the objective.
-
-    If the variable does not belong to the solver, the function just returns,
-    or crashes in non-opt mode.
-    """
-    return _pywraplp.Objective_SetCoefficient(self, var, coeff)
-
-
-
-def SetMaximization(self) ‑> void -
-
-

Sets the optimization direction to maximize.

-
- -Expand source code - -
def SetMaximization(self) -> "void":
-    r""" Sets the optimization direction to maximize."""
-    return _pywraplp.Objective_SetMaximization(self)
-
-
-
-def SetMinimization(self) ‑> void -
-
-

Sets the optimization direction to minimize.

-
- -Expand source code - -
def SetMinimization(self) -> "void":
-    r""" Sets the optimization direction to minimize."""
-    return _pywraplp.Objective_SetMinimization(self)
-
-
-
-def SetOffset(self, value: double) ‑> void -
-
-

Sets the constant term in the objective.

-
- -Expand source code - -
def SetOffset(self, value: "double") -> "void":
-    r""" Sets the constant term in the objective."""
-    return _pywraplp.Objective_SetOffset(self, value)
-
-
-
-def SetOptimizationDirection(self, maximize: bool) ‑> void -
-
-

Sets the optimization direction (maximize: true or minimize: false).

-
- -Expand source code - -
def SetOptimizationDirection(self, maximize: "bool") -> "void":
-    r""" Sets the optimization direction (maximize: true or minimize: false)."""
-    return _pywraplp.Objective_SetOptimizationDirection(self, maximize)
-
-
-
-def Value(self) ‑> double -
-
-

Returns the objective value of the best solution found so far.

-

It is the optimal objective value if the problem has been solved to -optimality.

-

Note: the objective value may be slightly different than what you could -compute yourself using MPVariable::solution_value(); please use the -–verify_solution flag to gain confidence about the numerical stability of -your solution.

-
- -Expand source code - -
def Value(self) -> "double":
-    r"""
-    Returns the objective value of the best solution found so far.
-
-    It is the optimal objective value if the problem has been solved to
-    optimality.
-
-    Note: the objective value may be slightly different than what you could
-    compute yourself using ``MPVariable::solution_value();`` please use the
-    --verify_solution flag to gain confidence about the numerical stability of
-    your solution.
-    """
-    return _pywraplp.Objective_Value(self)
-
-
-
-def maximization(self) ‑> bool -
-
-

Is the optimization direction set to maximize?

-
- -Expand source code - -
def maximization(self) -> "bool":
-    r""" Is the optimization direction set to maximize?"""
-    return _pywraplp.Objective_maximization(self)
-
-
-
-def minimization(self) ‑> bool -
-
-

Is the optimization direction set to minimize?

-
- -Expand source code - -
def minimization(self) -> "bool":
-    r""" Is the optimization direction set to minimize?"""
-    return _pywraplp.Objective_minimization(self)
-
-
-
-def offset(self) ‑> double -
-
-

Gets the constant term in the objective.

-
- -Expand source code - -
def offset(self) -> "double":
-    r""" Gets the constant term in the objective."""
-    return _pywraplp.Objective_offset(self)
-
-
-
-
-
-class Solver -(name: std::string const &, problem_type: operations_research::MPSolver::OptimizationProblemType) -
-
-

This mathematical programming (MP) solver class is the main class + If the variable does not belong to the solver, the function just returns, + or crashes in non-opt mode. + """ + return _pywraplp.Constraint_SetCoefficient(self, var, coeff) + + def GetCoefficient(self, var: "Variable") -> "double": + r""" + Gets the coefficient of a given variable on the constraint (which is 0 if + the variable does not appear in the constraint). + """ + return _pywraplp.Constraint_GetCoefficient(self, var) + + def lb(self) -> "double": + r""" Returns the lower bound.""" + return _pywraplp.Constraint_lb(self) + + def ub(self) -> "double": + r""" Returns the upper bound.""" + return _pywraplp.Constraint_ub(self) + + def SetBounds(self, lb: "double", ub: "double") -> "void": + r""" Sets both the lower and upper bounds.""" + return _pywraplp.Constraint_SetBounds(self, lb, ub) + + def set_is_lazy(self, laziness: "bool") -> "void": + r""" + Advanced usage: sets the constraint "laziness". + + **This is only supported for SCIP and has no effect on other + solvers.** + + When **laziness** is true, the constraint is only considered by the Linear + Programming solver if its current solution violates the constraint. In this + case, the constraint is definitively added to the problem. This may be + useful in some MIP problems, and may have a dramatic impact on performance. + + For more info see: http://tinyurl.com/lazy-constraints. + """ + return _pywraplp.Constraint_set_is_lazy(self, laziness) + + def index(self) -> "int": + r""" Returns the index of the constraint in the MPSolver::constraints_.""" + return _pywraplp.Constraint_index(self) + + def dual_value(self) -> "double": + r""" + Advanced usage: returns the dual value of the constraint in the current + solution (only available for continuous problems). + """ + return _pywraplp.Constraint_dual_value(self) + + def basis_status(self) -> "operations_research::MPSolver::BasisStatus": + r""" + Advanced usage: returns the basis status of the constraint. + + It is only available for continuous problems). + + Note that if a constraint "linear_expression in [lb, ub]" is transformed + into "linear_expression + slack = 0" with slack in [-ub, -lb], then this + status is the same as the status of the slack variable with AT_UPPER_BOUND + and AT_LOWER_BOUND swapped. + + See also: MPSolver::BasisStatus. + """ + return _pywraplp.Constraint_basis_status(self) + + def Lb(self) -> "double": + return _pywraplp.Constraint_Lb(self) + + def Ub(self) -> "double": + return _pywraplp.Constraint_Ub(self) + + def SetLb(self, x: "double") -> "void": + return _pywraplp.Constraint_SetLb(self, x) + + def SetUb(self, x: "double") -> "void": + return _pywraplp.Constraint_SetUb(self, x) + + def DualValue(self) -> "double": + return _pywraplp.Constraint_DualValue(self) + __swig_destroy__ = _pywraplp.delete_Constraint + +# Register Constraint in _pywraplp: +_pywraplp.Constraint_swigregister(Constraint) + +class MPSolverParameters(object): + r""" + This class stores parameter settings for LP and MIP solvers. Some parameters + are marked as advanced: do not change their values unless you know what you + are doing! + + For developers: how to add a new parameter: + - Add the new Foo parameter in the DoubleParam or IntegerParam enum. + - If it is a categorical param, add a FooValues enum. + - Decide if the wrapper should define a default value for it: yes + if it controls the properties of the solution (example: + tolerances) or if it consistently improves performance, no + otherwise. If yes, define kDefaultFoo. + - Add a foo_value_ member and, if no default value is defined, a + foo_is_default_ member. + - Add code to handle Foo in Set...Param, Reset...Param, + Get...Param, Reset and the constructor. + - In class MPSolverInterface, add a virtual method SetFoo, add it + to SetCommonParameters or SetMIPParameters, and implement it for + each solver. Sometimes, parameters need to be implemented + differently, see for example the INCREMENTALITY implementation. + - Add a test in linear_solver_test.cc. + + TODO(user): store the parameter values in a protocol buffer + instead. We need to figure out how to deal with the subtleties of + the default values. + """ + + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + RELATIVE_MIP_GAP = _pywraplp.MPSolverParameters_RELATIVE_MIP_GAP + r""" Limit for relative MIP gap.""" + PRIMAL_TOLERANCE = _pywraplp.MPSolverParameters_PRIMAL_TOLERANCE + r""" + Advanced usage: tolerance for primal feasibility of basic solutions. + + This does not control the integer feasibility tolerance of integer + solutions for MIP or the tolerance used during presolve. + """ + DUAL_TOLERANCE = _pywraplp.MPSolverParameters_DUAL_TOLERANCE + r""" Advanced usage: tolerance for dual feasibility of basic solutions.""" + PRESOLVE = _pywraplp.MPSolverParameters_PRESOLVE + r""" Advanced usage: presolve mode.""" + LP_ALGORITHM = _pywraplp.MPSolverParameters_LP_ALGORITHM + r""" Algorithm to solve linear programs.""" + INCREMENTALITY = _pywraplp.MPSolverParameters_INCREMENTALITY + r""" Advanced usage: incrementality from one solve to the next.""" + SCALING = _pywraplp.MPSolverParameters_SCALING + r""" Advanced usage: enable or disable matrix scaling.""" + PRESOLVE_OFF = _pywraplp.MPSolverParameters_PRESOLVE_OFF + r""" Presolve is off.""" + PRESOLVE_ON = _pywraplp.MPSolverParameters_PRESOLVE_ON + r""" Presolve is on.""" + DUAL = _pywraplp.MPSolverParameters_DUAL + r""" Dual simplex.""" + PRIMAL = _pywraplp.MPSolverParameters_PRIMAL + r""" Primal simplex.""" + BARRIER = _pywraplp.MPSolverParameters_BARRIER + r""" Barrier algorithm.""" + INCREMENTALITY_OFF = _pywraplp.MPSolverParameters_INCREMENTALITY_OFF + r""" Start solve from scratch.""" + INCREMENTALITY_ON = _pywraplp.MPSolverParameters_INCREMENTALITY_ON + r""" + Reuse results from previous solve as much as the underlying solver + allows. + """ + SCALING_OFF = _pywraplp.MPSolverParameters_SCALING_OFF + r""" Scaling is off.""" + SCALING_ON = _pywraplp.MPSolverParameters_SCALING_ON + r""" Scaling is on.""" + + def __init__(self): + r""" The constructor sets all parameters to their default value.""" + _pywraplp.MPSolverParameters_swiginit(self, _pywraplp.new_MPSolverParameters()) + + def SetDoubleParam(self, param: "operations_research::MPSolverParameters::DoubleParam", value: "double") -> "void": + r""" Sets a double parameter to a specific value.""" + return _pywraplp.MPSolverParameters_SetDoubleParam(self, param, value) + + def SetIntegerParam(self, param: "operations_research::MPSolverParameters::IntegerParam", value: "int") -> "void": + r""" Sets a integer parameter to a specific value.""" + return _pywraplp.MPSolverParameters_SetIntegerParam(self, param, value) + + def GetDoubleParam(self, param: "operations_research::MPSolverParameters::DoubleParam") -> "double": + r""" Returns the value of a double parameter.""" + return _pywraplp.MPSolverParameters_GetDoubleParam(self, param) + + def GetIntegerParam(self, param: "operations_research::MPSolverParameters::IntegerParam") -> "int": + r""" Returns the value of an integer parameter.""" + return _pywraplp.MPSolverParameters_GetIntegerParam(self, param) + __swig_destroy__ = _pywraplp.delete_MPSolverParameters + +# Register MPSolverParameters in _pywraplp: +_pywraplp.MPSolverParameters_swigregister(MPSolverParameters) +cvar = _pywraplp.cvar +MPSolverParameters.kDefaultRelativeMipGap = _pywraplp.cvar.MPSolverParameters_kDefaultRelativeMipGap +MPSolverParameters.kDefaultPrimalTolerance = _pywraplp.cvar.MPSolverParameters_kDefaultPrimalTolerance +MPSolverParameters.kDefaultDualTolerance = _pywraplp.cvar.MPSolverParameters_kDefaultDualTolerance +MPSolverParameters.kDefaultPresolve = _pywraplp.cvar.MPSolverParameters_kDefaultPresolve +MPSolverParameters.kDefaultIncrementality = _pywraplp.cvar.MPSolverParameters_kDefaultIncrementality + +class ModelExportOptions(object): + r""" Export options.""" + + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self): + _pywraplp.ModelExportOptions_swiginit(self, _pywraplp.new_ModelExportOptions()) + __swig_destroy__ = _pywraplp.delete_ModelExportOptions + +# Register ModelExportOptions in _pywraplp: +_pywraplp.ModelExportOptions_swigregister(ModelExportOptions) + + +def ExportModelAsLpFormat(*args) -> "std::string": + return _pywraplp.ExportModelAsLpFormat(*args) + +def ExportModelAsMpsFormat(*args) -> "std::string": + return _pywraplp.ExportModelAsMpsFormat(*args) + +def FindErrorInModelProto(input_model: "operations_research::MPModelProto const &") -> "std::string": + return _pywraplp.FindErrorInModelProto(input_model) + +def setup_variable_operator(opname): + setattr(Variable, opname, + lambda self, *args: getattr(VariableExpr(self), opname)(*args)) +for opname in LinearExpr.OVERRIDDEN_OPERATOR_METHODS: + setup_variable_operator(opname) +

+ +
+ +
+
+
+ #   + + + class + Solver: +
+ +
+ View Source +
class Solver(object):
+    r"""
+    This mathematical programming (MP) solver class is the main class
+    though which users build and solve problems.
+    """
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+    CLP_LINEAR_PROGRAMMING = _pywraplp.Solver_CLP_LINEAR_PROGRAMMING
+    GLPK_LINEAR_PROGRAMMING = _pywraplp.Solver_GLPK_LINEAR_PROGRAMMING
+    GLOP_LINEAR_PROGRAMMING = _pywraplp.Solver_GLOP_LINEAR_PROGRAMMING
+    SCIP_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_SCIP_MIXED_INTEGER_PROGRAMMING
+    GLPK_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_GLPK_MIXED_INTEGER_PROGRAMMING
+    CBC_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_CBC_MIXED_INTEGER_PROGRAMMING
+    GUROBI_LINEAR_PROGRAMMING = _pywraplp.Solver_GUROBI_LINEAR_PROGRAMMING
+    GUROBI_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_GUROBI_MIXED_INTEGER_PROGRAMMING
+    CPLEX_LINEAR_PROGRAMMING = _pywraplp.Solver_CPLEX_LINEAR_PROGRAMMING
+    CPLEX_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_CPLEX_MIXED_INTEGER_PROGRAMMING
+    XPRESS_LINEAR_PROGRAMMING = _pywraplp.Solver_XPRESS_LINEAR_PROGRAMMING
+    XPRESS_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_XPRESS_MIXED_INTEGER_PROGRAMMING
+    BOP_INTEGER_PROGRAMMING = _pywraplp.Solver_BOP_INTEGER_PROGRAMMING
+    SAT_INTEGER_PROGRAMMING = _pywraplp.Solver_SAT_INTEGER_PROGRAMMING
+
+    def __init__(self, name: "std::string const &", problem_type: "operations_research::MPSolver::OptimizationProblemType"):
+        r""" Create a solver with the given name and underlying solver backend."""
+        _pywraplp.Solver_swiginit(self, _pywraplp.new_Solver(name, problem_type))
+    __swig_destroy__ = _pywraplp.delete_Solver
+
+    @staticmethod
+    def CreateSolver(solver_id: "std::string const &") -> "operations_research::MPSolver *":
+        r"""
+        Recommended factory method to create a MPSolver instance, especially in
+        non C++ languages.
+
+        It returns a newly created solver instance if successful, or a nullptr
+        otherwise. This can occur if the relevant interface is not linked in, or if
+        a needed license is not accessible for commercial solvers.
+
+        Ownership of the solver is passed on to the caller of this method.
+        It will accept both string names of the OptimizationProblemType enum, as
+        well as a short version (i.e. "SCIP_MIXED_INTEGER_PROGRAMMING" or "SCIP").
+
+        solver_id is case insensitive, and the following names are supported:
+          - CLP_LINEAR_PROGRAMMING or CLP
+          - CBC_MIXED_INTEGER_PROGRAMMING or CBC
+          - GLOP_LINEAR_PROGRAMMING or GLOP
+          - BOP_INTEGER_PROGRAMMING or BOP
+          - SAT_INTEGER_PROGRAMMING or SAT or CP_SAT
+          - SCIP_MIXED_INTEGER_PROGRAMMING or SCIP
+          - GUROBI_LINEAR_PROGRAMMING or GUROBI_LP
+          - GUROBI_MIXED_INTEGER_PROGRAMMING or GUROBI or GUROBI_MIP
+          - CPLEX_LINEAR_PROGRAMMING or CPLEX_LP
+          - CPLEX_MIXED_INTEGER_PROGRAMMING or CPLEX or CPLEX_MIP
+          - XPRESS_LINEAR_PROGRAMMING or XPRESS_LP
+          - XPRESS_MIXED_INTEGER_PROGRAMMING or XPRESS or XPRESS_MIP
+          - GLPK_LINEAR_PROGRAMMING or GLPK_LP
+          - GLPK_MIXED_INTEGER_PROGRAMMING or GLPK or GLPK_MIP
+        """
+        return _pywraplp.Solver_CreateSolver(solver_id)
+
+    @staticmethod
+    def SupportsProblemType(problem_type: "operations_research::MPSolver::OptimizationProblemType") -> "bool":
+        r"""
+        Whether the given problem type is supported (this will depend on the
+        targets that you linked).
+        """
+        return _pywraplp.Solver_SupportsProblemType(problem_type)
+
+    def Clear(self) -> "void":
+        r"""
+        Clears the objective (including the optimization direction), all variables
+        and constraints. All the other properties of the MPSolver (like the time
+        limit) are kept untouched.
+        """
+        return _pywraplp.Solver_Clear(self)
+
+    def NumVariables(self) -> "int":
+        r""" Returns the number of variables."""
+        return _pywraplp.Solver_NumVariables(self)
+
+    def variables(self) -> "std::vector< operations_research::MPVariable * > const &":
+        r"""
+        Returns the array of variables handled by the MPSolver. (They are listed in
+        the order in which they were created.)
+        """
+        return _pywraplp.Solver_variables(self)
+
+    def variable(self, index: "int") -> "operations_research::MPVariable *":
+        r"""Returns the variable at position index."""
+        return _pywraplp.Solver_variable(self, index)
+
+    def LookupVariable(self, var_name: "std::string const &") -> "operations_research::MPVariable *":
+        r"""
+        Looks up a variable by name, and returns nullptr if it does not exist. The
+        first call has a O(n) complexity, as the variable name index is lazily
+        created upon first use. Will crash if variable names are not unique.
+        """
+        return _pywraplp.Solver_LookupVariable(self, var_name)
+
+    def Var(self, lb: "double", ub: "double", integer: "bool", name: "std::string const &") -> "operations_research::MPVariable *":
+        r"""
+        Creates a variable with the given bounds, integrality requirement and
+        name. Bounds can be finite or +/- MPSolver::infinity(). The MPSolver owns
+        the variable (i.e. the returned pointer is borrowed). Variable names are
+        optional. If you give an empty name, name() will auto-generate one for you
+        upon request.
+        """
+        return _pywraplp.Solver_Var(self, lb, ub, integer, name)
+
+    def NumVar(self, lb: "double", ub: "double", name: "std::string const &") -> "operations_research::MPVariable *":
+        r""" Creates a continuous variable."""
+        return _pywraplp.Solver_NumVar(self, lb, ub, name)
+
+    def IntVar(self, lb: "double", ub: "double", name: "std::string const &") -> "operations_research::MPVariable *":
+        r""" Creates an integer variable."""
+        return _pywraplp.Solver_IntVar(self, lb, ub, name)
+
+    def BoolVar(self, name: "std::string const &") -> "operations_research::MPVariable *":
+        r""" Creates a boolean variable."""
+        return _pywraplp.Solver_BoolVar(self, name)
+
+    def NumConstraints(self) -> "int":
+        r""" Returns the number of constraints."""
+        return _pywraplp.Solver_NumConstraints(self)
+
+    def constraints(self) -> "std::vector< operations_research::MPConstraint * > const &":
+        r"""
+        Returns the array of constraints handled by the MPSolver.
+
+        They are listed in the order in which they were created.
+        """
+        return _pywraplp.Solver_constraints(self)
+
+    def constraint(self, index: "int") -> "operations_research::MPConstraint *":
+        r""" Returns the constraint at the given index."""
+        return _pywraplp.Solver_constraint(self, index)
+
+    def LookupConstraint(self, constraint_name: "std::string const &") -> "operations_research::MPConstraint *":
+        r"""
+         Looks up a constraint by name, and returns nullptr if it does not exist.
+
+        The first call has a O(n) complexity, as the constraint name index is
+        lazily created upon first use. Will crash if constraint names are not
+        unique.
+        """
+        return _pywraplp.Solver_LookupConstraint(self, constraint_name)
+
+    def Constraint(self, *args) -> "operations_research::MPConstraint *":
+        r"""
+        *Overload 1:*
+
+        Creates a linear constraint with given bounds.
+
+        Bounds can be finite or +/- MPSolver::infinity(). The MPSolver class
+        assumes ownership of the constraint.
+
+        :rtype: :py:class:`MPConstraint`
+        :return: a pointer to the newly created constraint.
+
+        |
+
+        *Overload 2:*
+         Creates a constraint with -infinity and +infinity bounds.
+
+        |
+
+        *Overload 3:*
+         Creates a named constraint with given bounds.
+
+        |
+
+        *Overload 4:*
+         Creates a named constraint with -infinity and +infinity bounds.
+        """
+        return _pywraplp.Solver_Constraint(self, *args)
+
+    def Objective(self) -> "operations_research::MPObjective *":
+        r""" Returns the mutable objective object."""
+        return _pywraplp.Solver_Objective(self)
+    OPTIMAL = _pywraplp.Solver_OPTIMAL
+    r""" optimal."""
+    FEASIBLE = _pywraplp.Solver_FEASIBLE
+    r""" feasible, or stopped by limit."""
+    INFEASIBLE = _pywraplp.Solver_INFEASIBLE
+    r""" proven infeasible."""
+    UNBOUNDED = _pywraplp.Solver_UNBOUNDED
+    r""" proven unbounded."""
+    ABNORMAL = _pywraplp.Solver_ABNORMAL
+    r""" abnormal, i.e., error of some kind."""
+    NOT_SOLVED = _pywraplp.Solver_NOT_SOLVED
+    r""" not been solved yet."""
+
+    def Solve(self, *args) -> "operations_research::MPSolver::ResultStatus":
+        r"""
+        *Overload 1:*
+        Solves the problem using the default parameter values.
+
+        |
+
+        *Overload 2:*
+        Solves the problem using the specified parameter values.
+        """
+        return _pywraplp.Solver_Solve(self, *args)
+
+    def ComputeConstraintActivities(self) -> "std::vector< double >":
+        r"""
+        Advanced usage: compute the "activities" of all constraints, which are the
+        sums of their linear terms. The activities are returned in the same order
+        as constraints(), which is the order in which constraints were added; but
+        you can also use MPConstraint::index() to get a constraint's index.
+        """
+        return _pywraplp.Solver_ComputeConstraintActivities(self)
+
+    def VerifySolution(self, tolerance: "double", log_errors: "bool") -> "bool":
+        r"""
+        Advanced usage: Verifies the *correctness* of the solution.
+
+        It verifies that all variables must be within their domains, all
+        constraints must be satisfied, and the reported objective value must be
+        accurate.
+
+        Usage:
+        - This can only be called after Solve() was called.
+        - "tolerance" is interpreted as an absolute error threshold.
+        - For the objective value only, if the absolute error is too large,
+          the tolerance is interpreted as a relative error threshold instead.
+        - If "log_errors" is true, every single violation will be logged.
+        - If "tolerance" is negative, it will be set to infinity().
+
+        Most users should just set the --verify_solution flag and not bother using
+        this method directly.
+        """
+        return _pywraplp.Solver_VerifySolution(self, tolerance, log_errors)
+
+    def InterruptSolve(self) -> "bool":
+        r"""
+         Interrupts the Solve() execution to terminate processing if possible.
+
+        If the underlying interface supports interruption; it does that and returns
+        true regardless of whether there's an ongoing Solve() or not. The Solve()
+        call may still linger for a while depending on the conditions.  If
+        interruption is not supported; returns false and does nothing.
+        MPSolver::SolverTypeSupportsInterruption can be used to check if
+        interruption is supported for a given solver type.
+        """
+        return _pywraplp.Solver_InterruptSolve(self)
+
+    def FillSolutionResponseProto(self, response: "operations_research::MPSolutionResponse *") -> "void":
+        r""" Encodes the current solution in a solution response protocol buffer."""
+        return _pywraplp.Solver_FillSolutionResponseProto(self, response)
+
+    @staticmethod
+    def SolveWithProto(model_request: "operations_research::MPModelRequest const &", response: "operations_research::MPSolutionResponse *", interrupt: "std::atomic< bool > const *"=None) -> "operations_research::MPSolutionResponse *":
+        r"""
+        Solves the model encoded by a MPModelRequest protocol buffer and fills the
+        solution encoded as a MPSolutionResponse. The solve is stopped prematurely
+        if interrupt is non-null at set to true during (or before) solving.
+        Interruption is only supported if SolverTypeSupportsInterruption() returns
+        true for the requested solver. Passing a non-null interruption with any
+        other solver type immediately returns an MPSOLVER_INCOMPATIBLE_OPTIONS
+        error.
+
+        Note(user): This attempts to first use `DirectlySolveProto()` (if
+        implemented). Consequently, this most likely does *not* override any of
+        the default parameters of the underlying solver. This behavior *differs*
+        from `MPSolver::Solve()` which by default sets the feasibility tolerance
+        and the gap limit (as of 2020/02/11, to 1e-7 and 0.0001, respectively).
+        """
+        return _pywraplp.Solver_SolveWithProto(model_request, response, interrupt)
+
+    def ExportModelToProto(self, output_model: "operations_research::MPModelProto *") -> "void":
+        r""" Exports model to protocol buffer."""
+        return _pywraplp.Solver_ExportModelToProto(self, output_model)
+
+    def SetSolverSpecificParametersAsString(self, parameters: "std::string const &") -> "bool":
+        r"""
+        Advanced usage: pass solver specific parameters in text format.
+
+        The format is solver-specific and is the same as the corresponding solver
+        configuration file format. Returns true if the operation was successful.
+        """
+        return _pywraplp.Solver_SetSolverSpecificParametersAsString(self, parameters)
+    FREE = _pywraplp.Solver_FREE
+    AT_LOWER_BOUND = _pywraplp.Solver_AT_LOWER_BOUND
+    AT_UPPER_BOUND = _pywraplp.Solver_AT_UPPER_BOUND
+    FIXED_VALUE = _pywraplp.Solver_FIXED_VALUE
+    BASIC = _pywraplp.Solver_BASIC
+
+    @staticmethod
+    def infinity() -> "double":
+        r"""
+        Infinity.
+
+        You can use -MPSolver::infinity() for negative infinity.
+        """
+        return _pywraplp.Solver_infinity()
+
+    def EnableOutput(self) -> "void":
+        r""" Enables solver logging."""
+        return _pywraplp.Solver_EnableOutput(self)
+
+    def SuppressOutput(self) -> "void":
+        r""" Suppresses solver logging."""
+        return _pywraplp.Solver_SuppressOutput(self)
+
+    def iterations(self) -> "int64_t":
+        r""" Returns the number of simplex iterations."""
+        return _pywraplp.Solver_iterations(self)
+
+    def nodes(self) -> "int64_t":
+        r"""
+        Returns the number of branch-and-bound nodes evaluated during the solve.
+
+        Only available for discrete problems.
+        """
+        return _pywraplp.Solver_nodes(self)
+
+    def ComputeExactConditionNumber(self) -> "double":
+        r"""
+         Advanced usage: computes the exact condition number of the current scaled
+        basis: L1norm(B) * L1norm(inverse(B)), where B is the scaled basis.
+
+        This method requires that a basis exists: it should be called after Solve.
+        It is only available for continuous problems. It is implemented for GLPK
+        but not CLP because CLP does not provide the API for doing it.
+
+        The condition number measures how well the constraint matrix is conditioned
+        and can be used to predict whether numerical issues will arise during the
+        solve: the model is declared infeasible whereas it is feasible (or
+        vice-versa), the solution obtained is not optimal or violates some
+        constraints, the resolution is slow because of repeated singularities.
+
+        The rule of thumb to interpret the condition number kappa is:
+          - o kappa <= 1e7: virtually no chance of numerical issues
+          - o 1e7 < kappa <= 1e10: small chance of numerical issues
+          - o 1e10 < kappa <= 1e13: medium chance of numerical issues
+          - o kappa > 1e13: high chance of numerical issues
+
+        The computation of the condition number depends on the quality of the LU
+        decomposition, so it is not very accurate when the matrix is ill
+        conditioned.
+        """
+        return _pywraplp.Solver_ComputeExactConditionNumber(self)
+
+    def NextSolution(self) -> "bool":
+        r"""
+        Some solvers (MIP only, not LP) can produce multiple solutions to the
+        problem. Returns true when another solution is available, and updates the
+        MPVariable* objects to make the new solution queryable. Call only after
+        calling solve.
+
+        The optimality properties of the additional solutions found, and whether or
+        not the solver computes them ahead of time or when NextSolution() is called
+        is solver specific.
+
+        As of 2020-02-10, only Gurobi and SCIP support NextSolution(), see
+        linear_solver_interfaces_test for an example of how to configure these
+        solvers for multiple solutions. Other solvers return false unconditionally.
+        """
+        return _pywraplp.Solver_NextSolution(self)
+
+    def set_time_limit(self, time_limit_milliseconds: "int64_t") -> "void":
+        return _pywraplp.Solver_set_time_limit(self, time_limit_milliseconds)
+
+    def wall_time(self) -> "int64_t":
+        return _pywraplp.Solver_wall_time(self)
+
+    def LoadModelFromProto(self, input_model: "operations_research::MPModelProto const &") -> "std::string":
+        return _pywraplp.Solver_LoadModelFromProto(self, input_model)
+
+    def LoadSolutionFromProto(self, *args) -> "bool":
+        return _pywraplp.Solver_LoadSolutionFromProto(self, *args)
+
+    def ExportModelAsLpFormat(self, obfuscated: "bool") -> "std::string":
+        return _pywraplp.Solver_ExportModelAsLpFormat(self, obfuscated)
+
+    def ExportModelAsMpsFormat(self, fixed_format: "bool", obfuscated: "bool") -> "std::string":
+        return _pywraplp.Solver_ExportModelAsMpsFormat(self, fixed_format, obfuscated)
+
+    def SetHint(self, variables: "std::vector< operations_research::MPVariable * > const &", values: "std::vector< double > const &") -> "void":
+        r""" Set a hint for solution. If a feasible or almost-feasible solution to the problem is already known, it may be helpful to pass it to the solver so that it can be used. A solver that supports this feature will try to use this information to create its initial feasible solution. Note that it may not always be faster to give a hint like this to the solver. There is also no guarantee that the solver will use this hint or try to return a solution "close" to this assignment in case of multiple optimal solutions."""
+        return _pywraplp.Solver_SetHint(self, variables, values)
+
+    def SetNumThreads(self, num_theads: "int") -> "bool":
+        r""" Sets the number of threads to be used by the solver."""
+        return _pywraplp.Solver_SetNumThreads(self, num_theads)
+
+    def Add(self, constraint, name=''):
+      if isinstance(constraint, bool):
+        if constraint:
+          return self.RowConstraint(0, 0, name)
+        else:
+          return self.RowConstraint(1, 1, name)
+      else:
+        return constraint.Extract(self, name)
+
+    def Sum(self, expr_array):
+      result = SumArray(expr_array)
+      return result
+
+    def RowConstraint(self, *args):
+      return self.Constraint(*args)
+
+    def Minimize(self, expr):
+      objective = self.Objective()
+      objective.Clear()
+      objective.SetMinimization()
+      if isinstance(expr, numbers.Number):
+          objective.SetOffset(expr)
+      else:
+          coeffs = expr.GetCoeffs()
+          objective.SetOffset(coeffs.pop(OFFSET_KEY, 0.0))
+          for v, c, in list(coeffs.items()):
+            objective.SetCoefficient(v, float(c))
+
+    def Maximize(self, expr):
+      objective = self.Objective()
+      objective.Clear()
+      objective.SetMaximization()
+      if isinstance(expr, numbers.Number):
+          objective.SetOffset(expr)
+      else:
+          coeffs = expr.GetCoeffs()
+          objective.SetOffset(coeffs.pop(OFFSET_KEY, 0.0))
+          for v, c, in list(coeffs.items()):
+            objective.SetCoefficient(v, float(c))
+
+
+    @staticmethod
+    def Infinity() -> "double":
+        return _pywraplp.Solver_Infinity()
+
+    def SetTimeLimit(self, x: "int64_t") -> "void":
+        return _pywraplp.Solver_SetTimeLimit(self, x)
+
+    def WallTime(self) -> "int64_t":
+        return _pywraplp.Solver_WallTime(self)
+
+    def Iterations(self) -> "int64_t":
+        return _pywraplp.Solver_Iterations(self)
+
+ +
+ +

This mathematical programming (MP) solver class is the main class though which users build and solve problems.

-

Create a solver with the given name and underlying solver backend.

-
- -Expand source code - -
class Solver(object):
-    r"""
-    This mathematical programming (MP) solver class is the main class
-    though which users build and solve problems.
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-    CLP_LINEAR_PROGRAMMING = _pywraplp.Solver_CLP_LINEAR_PROGRAMMING
-    GLPK_LINEAR_PROGRAMMING = _pywraplp.Solver_GLPK_LINEAR_PROGRAMMING
-    GLOP_LINEAR_PROGRAMMING = _pywraplp.Solver_GLOP_LINEAR_PROGRAMMING
-    SCIP_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_SCIP_MIXED_INTEGER_PROGRAMMING
-    GLPK_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_GLPK_MIXED_INTEGER_PROGRAMMING
-    CBC_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_CBC_MIXED_INTEGER_PROGRAMMING
-    GUROBI_LINEAR_PROGRAMMING = _pywraplp.Solver_GUROBI_LINEAR_PROGRAMMING
-    GUROBI_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_GUROBI_MIXED_INTEGER_PROGRAMMING
-    CPLEX_LINEAR_PROGRAMMING = _pywraplp.Solver_CPLEX_LINEAR_PROGRAMMING
-    CPLEX_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_CPLEX_MIXED_INTEGER_PROGRAMMING
-    XPRESS_LINEAR_PROGRAMMING = _pywraplp.Solver_XPRESS_LINEAR_PROGRAMMING
-    XPRESS_MIXED_INTEGER_PROGRAMMING = _pywraplp.Solver_XPRESS_MIXED_INTEGER_PROGRAMMING
-    BOP_INTEGER_PROGRAMMING = _pywraplp.Solver_BOP_INTEGER_PROGRAMMING
-    SAT_INTEGER_PROGRAMMING = _pywraplp.Solver_SAT_INTEGER_PROGRAMMING
-
-    def __init__(self, name: "std::string const &", problem_type: "operations_research::MPSolver::OptimizationProblemType"):
-        r""" Create a solver with the given name and underlying solver backend."""
-        _pywraplp.Solver_swiginit(self, _pywraplp.new_Solver(name, problem_type))
-    __swig_destroy__ = _pywraplp.delete_Solver
-
-    @staticmethod
-    def CreateSolver(solver_id: "std::string const &") -> "operations_research::MPSolver *":
-        r"""
-        Recommended factory method to create a MPSolver instance, especially in
-        non C++ languages.
-
-        It returns a newly created solver instance if successful, or a nullptr
-        otherwise. This can occur if the relevant interface is not linked in, or if
-        a needed license is not accessible for commercial solvers.
-
-        Ownership of the solver is passed on to the caller of this method.
-        It will accept both string names of the OptimizationProblemType enum, as
-        well as a short version (i.e. "SCIP_MIXED_INTEGER_PROGRAMMING" or "SCIP").
-
-        solver_id is case insensitive, and the following names are supported:
-          - CLP_LINEAR_PROGRAMMING or CLP
-          - CBC_MIXED_INTEGER_PROGRAMMING or CBC
-          - GLOP_LINEAR_PROGRAMMING or GLOP
-          - BOP_INTEGER_PROGRAMMING or BOP
-          - SAT_INTEGER_PROGRAMMING or SAT or CP_SAT
-          - SCIP_MIXED_INTEGER_PROGRAMMING or SCIP
-          - GUROBI_LINEAR_PROGRAMMING or GUROBI_LP
-          - GUROBI_MIXED_INTEGER_PROGRAMMING or GUROBI or GUROBI_MIP
-          - CPLEX_LINEAR_PROGRAMMING or CPLEX_LP
-          - CPLEX_MIXED_INTEGER_PROGRAMMING or CPLEX or CPLEX_MIP
-          - XPRESS_LINEAR_PROGRAMMING or XPRESS_LP
-          - XPRESS_MIXED_INTEGER_PROGRAMMING or XPRESS or XPRESS_MIP
-          - GLPK_LINEAR_PROGRAMMING or GLPK_LP
-          - GLPK_MIXED_INTEGER_PROGRAMMING or GLPK or GLPK_MIP
-        """
-        return _pywraplp.Solver_CreateSolver(solver_id)
-
-    @staticmethod
-    def SupportsProblemType(problem_type: "operations_research::MPSolver::OptimizationProblemType") -> "bool":
-        r"""
-        Whether the given problem type is supported (this will depend on the
-        targets that you linked).
-        """
-        return _pywraplp.Solver_SupportsProblemType(problem_type)
-
-    def Clear(self) -> "void":
-        r"""
-        Clears the objective (including the optimization direction), all variables
-        and constraints. All the other properties of the MPSolver (like the time
-        limit) are kept untouched.
-        """
-        return _pywraplp.Solver_Clear(self)
-
-    def NumVariables(self) -> "int":
-        r""" Returns the number of variables."""
-        return _pywraplp.Solver_NumVariables(self)
-
-    def variables(self) -> "std::vector< operations_research::MPVariable * > const &":
-        r"""
-        Returns the array of variables handled by the MPSolver. (They are listed in
-        the order in which they were created.)
-        """
-        return _pywraplp.Solver_variables(self)
-
-    def variable(self, index: "int") -> "operations_research::MPVariable *":
-        r"""Returns the variable at position index."""
-        return _pywraplp.Solver_variable(self, index)
-
-    def LookupVariable(self, var_name: "std::string const &") -> "operations_research::MPVariable *":
-        r"""
-        Looks up a variable by name, and returns nullptr if it does not exist. The
-        first call has a O(n) complexity, as the variable name index is lazily
-        created upon first use. Will crash if variable names are not unique.
-        """
-        return _pywraplp.Solver_LookupVariable(self, var_name)
-
-    def Var(self, lb: "double", ub: "double", integer: "bool", name: "std::string const &") -> "operations_research::MPVariable *":
-        r"""
-        Creates a variable with the given bounds, integrality requirement and
-        name. Bounds can be finite or +/- MPSolver::infinity(). The MPSolver owns
-        the variable (i.e. the returned pointer is borrowed). Variable names are
-        optional. If you give an empty name, name() will auto-generate one for you
-        upon request.
-        """
-        return _pywraplp.Solver_Var(self, lb, ub, integer, name)
-
-    def NumVar(self, lb: "double", ub: "double", name: "std::string const &") -> "operations_research::MPVariable *":
-        r""" Creates a continuous variable."""
-        return _pywraplp.Solver_NumVar(self, lb, ub, name)
-
-    def IntVar(self, lb: "double", ub: "double", name: "std::string const &") -> "operations_research::MPVariable *":
-        r""" Creates an integer variable."""
-        return _pywraplp.Solver_IntVar(self, lb, ub, name)
-
-    def BoolVar(self, name: "std::string const &") -> "operations_research::MPVariable *":
-        r""" Creates a boolean variable."""
-        return _pywraplp.Solver_BoolVar(self, name)
-
-    def NumConstraints(self) -> "int":
-        r""" Returns the number of constraints."""
-        return _pywraplp.Solver_NumConstraints(self)
-
-    def constraints(self) -> "std::vector< operations_research::MPConstraint * > const &":
-        r"""
-        Returns the array of constraints handled by the MPSolver.
-
-        They are listed in the order in which they were created.
-        """
-        return _pywraplp.Solver_constraints(self)
-
-    def constraint(self, index: "int") -> "operations_research::MPConstraint *":
-        r""" Returns the constraint at the given index."""
-        return _pywraplp.Solver_constraint(self, index)
-
-    def LookupConstraint(self, constraint_name: "std::string const &") -> "operations_research::MPConstraint *":
-        r"""
-         Looks up a constraint by name, and returns nullptr if it does not exist.
-
-        The first call has a O(n) complexity, as the constraint name index is
-        lazily created upon first use. Will crash if constraint names are not
-        unique.
-        """
-        return _pywraplp.Solver_LookupConstraint(self, constraint_name)
-
-    def Constraint(self, *args) -> "operations_research::MPConstraint *":
-        r"""
-        *Overload 1:*
-
-        Creates a linear constraint with given bounds.
-
-        Bounds can be finite or +/- MPSolver::infinity(). The MPSolver class
-        assumes ownership of the constraint.
-
-        :rtype: :py:class:`MPConstraint`
-        :return: a pointer to the newly created constraint.
-
-        |
-
-        *Overload 2:*
-         Creates a constraint with -infinity and +infinity bounds.
-
-        |
-
-        *Overload 3:*
-         Creates a named constraint with given bounds.
-
-        |
-
-        *Overload 4:*
-         Creates a named constraint with -infinity and +infinity bounds.
-        """
-        return _pywraplp.Solver_Constraint(self, *args)
-
-    def Objective(self) -> "operations_research::MPObjective *":
-        r""" Returns the mutable objective object."""
-        return _pywraplp.Solver_Objective(self)
-    OPTIMAL = _pywraplp.Solver_OPTIMAL
-    r""" optimal."""
-    FEASIBLE = _pywraplp.Solver_FEASIBLE
-    r""" feasible, or stopped by limit."""
-    INFEASIBLE = _pywraplp.Solver_INFEASIBLE
-    r""" proven infeasible."""
-    UNBOUNDED = _pywraplp.Solver_UNBOUNDED
-    r""" proven unbounded."""
-    ABNORMAL = _pywraplp.Solver_ABNORMAL
-    r""" abnormal, i.e., error of some kind."""
-    NOT_SOLVED = _pywraplp.Solver_NOT_SOLVED
-    r""" not been solved yet."""
-
-    def Solve(self, *args) -> "operations_research::MPSolver::ResultStatus":
-        r"""
-        *Overload 1:*
-        Solves the problem using the default parameter values.
-
-        |
-
-        *Overload 2:*
-        Solves the problem using the specified parameter values.
-        """
-        return _pywraplp.Solver_Solve(self, *args)
-
-    def ComputeConstraintActivities(self) -> "std::vector< double >":
-        r"""
-        Advanced usage: compute the "activities" of all constraints, which are the
-        sums of their linear terms. The activities are returned in the same order
-        as constraints(), which is the order in which constraints were added; but
-        you can also use MPConstraint::index() to get a constraint's index.
-        """
-        return _pywraplp.Solver_ComputeConstraintActivities(self)
-
-    def VerifySolution(self, tolerance: "double", log_errors: "bool") -> "bool":
-        r"""
-        Advanced usage: Verifies the *correctness* of the solution.
-
-        It verifies that all variables must be within their domains, all
-        constraints must be satisfied, and the reported objective value must be
-        accurate.
-
-        Usage:
-        - This can only be called after Solve() was called.
-        - "tolerance" is interpreted as an absolute error threshold.
-        - For the objective value only, if the absolute error is too large,
-          the tolerance is interpreted as a relative error threshold instead.
-        - If "log_errors" is true, every single violation will be logged.
-        - If "tolerance" is negative, it will be set to infinity().
-
-        Most users should just set the --verify_solution flag and not bother using
-        this method directly.
-        """
-        return _pywraplp.Solver_VerifySolution(self, tolerance, log_errors)
-
-    def InterruptSolve(self) -> "bool":
-        r"""
-         Interrupts the Solve() execution to terminate processing if possible.
-
-        If the underlying interface supports interruption; it does that and returns
-        true regardless of whether there's an ongoing Solve() or not. The Solve()
-        call may still linger for a while depending on the conditions.  If
-        interruption is not supported; returns false and does nothing.
-        """
-        return _pywraplp.Solver_InterruptSolve(self)
-
-    def FillSolutionResponseProto(self, response: "operations_research::MPSolutionResponse *") -> "void":
-        r""" Encodes the current solution in a solution response protocol buffer."""
-        return _pywraplp.Solver_FillSolutionResponseProto(self, response)
-
-    @staticmethod
-    def SolveWithProto(model_request: "operations_research::MPModelRequest const &", response: "operations_research::MPSolutionResponse *") -> "operations_research::MPSolutionResponse *":
-        r"""
-        Solves the model encoded by a MPModelRequest protocol buffer and fills the
-        solution encoded as a MPSolutionResponse.
-
-        Note(user): This creates a temporary MPSolver and destroys it at the end.
-        If you want to keep the MPSolver alive (for debugging, or for incremental
-        solving), you should write another version of this function that creates
-        the MPSolver object on the heap and returns it.
-
-        Note(pawell): This attempts to first use `DirectlySolveProto()` (if
-        implemented). Consequently, this most likely does *not* override any of
-        the default parameters of the underlying solver. This behavior *differs*
-        from `MPSolver::Solve()` which by default sets the feasibility tolerance
-        and the gap limit (as of 2020/02/11, to 1e-7 and 0.0001, respectively).
-        """
-        return _pywraplp.Solver_SolveWithProto(model_request, response)
-
-    def ExportModelToProto(self, output_model: "operations_research::MPModelProto *") -> "void":
-        r""" Exports model to protocol buffer."""
-        return _pywraplp.Solver_ExportModelToProto(self, output_model)
-
-    def SetSolverSpecificParametersAsString(self, parameters: "std::string const &") -> "bool":
-        r"""
-        Advanced usage: pass solver specific parameters in text format.
-
-        The format is solver-specific and is the same as the corresponding solver
-        configuration file format. Returns true if the operation was successful.
-        """
-        return _pywraplp.Solver_SetSolverSpecificParametersAsString(self, parameters)
-    FREE = _pywraplp.Solver_FREE
-    AT_LOWER_BOUND = _pywraplp.Solver_AT_LOWER_BOUND
-    AT_UPPER_BOUND = _pywraplp.Solver_AT_UPPER_BOUND
-    FIXED_VALUE = _pywraplp.Solver_FIXED_VALUE
-    BASIC = _pywraplp.Solver_BASIC
-
-    @staticmethod
-    def infinity() -> "double":
-        r"""
-        Infinity.
-
-        You can use -MPSolver::infinity() for negative infinity.
-        """
-        return _pywraplp.Solver_infinity()
-
-    def EnableOutput(self) -> "void":
-        r""" Enables solver logging."""
-        return _pywraplp.Solver_EnableOutput(self)
-
-    def SuppressOutput(self) -> "void":
-        r""" Suppresses solver logging."""
-        return _pywraplp.Solver_SuppressOutput(self)
-
-    def iterations(self) -> "int64_t":
-        r""" Returns the number of simplex iterations."""
-        return _pywraplp.Solver_iterations(self)
-
-    def nodes(self) -> "int64_t":
-        r"""
-        Returns the number of branch-and-bound nodes evaluated during the solve.
-
-        Only available for discrete problems.
-        """
-        return _pywraplp.Solver_nodes(self)
-
-    def ComputeExactConditionNumber(self) -> "double":
-        r"""
-         Advanced usage: computes the exact condition number of the current scaled
-        basis: L1norm(B) * L1norm(inverse(B)), where B is the scaled basis.
-
-        This method requires that a basis exists: it should be called after Solve.
-        It is only available for continuous problems. It is implemented for GLPK
-        but not CLP because CLP does not provide the API for doing it.
-
-        The condition number measures how well the constraint matrix is conditioned
-        and can be used to predict whether numerical issues will arise during the
-        solve: the model is declared infeasible whereas it is feasible (or
-        vice-versa), the solution obtained is not optimal or violates some
-        constraints, the resolution is slow because of repeated singularities.
-
-        The rule of thumb to interpret the condition number kappa is:
-          - o kappa <= 1e7: virtually no chance of numerical issues
-          - o 1e7 < kappa <= 1e10: small chance of numerical issues
-          - o 1e10 < kappa <= 1e13: medium chance of numerical issues
-          - o kappa > 1e13: high chance of numerical issues
-
-        The computation of the condition number depends on the quality of the LU
-        decomposition, so it is not very accurate when the matrix is ill
-        conditioned.
-        """
-        return _pywraplp.Solver_ComputeExactConditionNumber(self)
-
-    def NextSolution(self) -> "bool":
-        r"""
-        Some solvers (MIP only, not LP) can produce multiple solutions to the
-        problem. Returns true when another solution is available, and updates the
-        MPVariable* objects to make the new solution queryable. Call only after
-        calling solve.
-
-        The optimality properties of the additional solutions found, and whether or
-        not the solver computes them ahead of time or when NextSolution() is called
-        is solver specific.
-
-        As of 2020-02-10, only Gurobi and SCIP support NextSolution(), see
-        linear_solver_interfaces_test for an example of how to configure these
-        solvers for multiple solutions. Other solvers return false unconditionally.
-        """
-        return _pywraplp.Solver_NextSolution(self)
-
-    def set_time_limit(self, time_limit_milliseconds: "int64_t") -> "void":
-        return _pywraplp.Solver_set_time_limit(self, time_limit_milliseconds)
-
-    def wall_time(self) -> "int64_t":
-        return _pywraplp.Solver_wall_time(self)
-
-    def LoadModelFromProto(self, input_model: "operations_research::MPModelProto const &") -> "std::string":
-        return _pywraplp.Solver_LoadModelFromProto(self, input_model)
-
-    def LoadSolutionFromProto(self, *args) -> "bool":
-        return _pywraplp.Solver_LoadSolutionFromProto(self, *args)
-
-    def ExportModelAsLpFormat(self, obfuscated: "bool") -> "std::string":
-        return _pywraplp.Solver_ExportModelAsLpFormat(self, obfuscated)
-
-    def ExportModelAsMpsFormat(self, fixed_format: "bool", obfuscated: "bool") -> "std::string":
-        return _pywraplp.Solver_ExportModelAsMpsFormat(self, fixed_format, obfuscated)
-
-    def SetHint(self, variables: "std::vector< operations_research::MPVariable * > const &", values: "std::vector< double > const &") -> "void":
-        r"""
-        Set a hint for solution.
-
-        If a feasible or almost-feasible solution to the problem is already known,
-        it may be helpful to pass it to the solver so that it can be used. A
-        solver that supports this feature will try to use this information to
-        create its initial feasible solution.
-
-        Note that it may not always be faster to give a hint like this to the
-        solver. There is also no guarantee that the solver will use this hint or
-        try to return a solution "close" to this assignment in case of multiple
-        optimal solutions.
-        """
-        return _pywraplp.Solver_SetHint(self, variables, values)
-
-    def SetNumThreads(self, num_theads: "int") -> "bool":
-        r""" Sets the number of threads to be used by the solver."""
-        return _pywraplp.Solver_SetNumThreads(self, num_theads)
-
-    def Add(self, constraint, name=''):
-      if isinstance(constraint, bool):
-        if constraint:
-          return self.RowConstraint(0, 0, name)
-        else:
-          return self.RowConstraint(1, 1, name)
-      else:
-        return constraint.Extract(self, name)
-
-    def Sum(self, expr_array):
-      result = SumArray(expr_array)
-      return result
-
-    def RowConstraint(self, *args):
-      return self.Constraint(*args)
-
-    def Minimize(self, expr):
-      objective = self.Objective()
-      objective.Clear()
-      objective.SetMinimization()
-      if isinstance(expr, numbers.Number):
-          objective.SetOffset(expr)
-      else:
-          coeffs = expr.GetCoeffs()
-          objective.SetOffset(coeffs.pop(OFFSET_KEY, 0.0))
-          for v, c, in list(coeffs.items()):
-            objective.SetCoefficient(v, float(c))
-
-    def Maximize(self, expr):
-      objective = self.Objective()
-      objective.Clear()
-      objective.SetMaximization()
-      if isinstance(expr, numbers.Number):
-          objective.SetOffset(expr)
-      else:
-          coeffs = expr.GetCoeffs()
-          objective.SetOffset(coeffs.pop(OFFSET_KEY, 0.0))
-          for v, c, in list(coeffs.items()):
-            objective.SetCoefficient(v, float(c))
-
-
-    @staticmethod
-    def Infinity() -> "double":
-        return _pywraplp.Solver_Infinity()
-
-    def SetTimeLimit(self, x: "int64_t") -> "void":
-        return _pywraplp.Solver_SetTimeLimit(self, x)
-
-    def WallTime(self) -> "int64_t":
-        return _pywraplp.Solver_WallTime(self)
-
-    def Iterations(self) -> "int64_t":
-        return _pywraplp.Solver_Iterations(self)
-
-

Class variables

-
-
var ABNORMAL
-
-

abnormal, i.e., error of some kind.

-
-
var AT_LOWER_BOUND
-
-
-
-
var AT_UPPER_BOUND
-
-
-
-
var BASIC
-
-
-
-
var BOP_INTEGER_PROGRAMMING
-
-
-
-
var CBC_MIXED_INTEGER_PROGRAMMING
-
-
-
-
var CLP_LINEAR_PROGRAMMING
-
-
-
-
var CPLEX_LINEAR_PROGRAMMING
-
-
-
-
var CPLEX_MIXED_INTEGER_PROGRAMMING
-
-
-
-
var FEASIBLE
-
-

feasible, or stopped by limit.

-
-
var FIXED_VALUE
-
-
-
-
var FREE
-
-
-
-
var GLOP_LINEAR_PROGRAMMING
-
-
-
-
var GLPK_LINEAR_PROGRAMMING
-
-
-
-
var GLPK_MIXED_INTEGER_PROGRAMMING
-
-
-
-
var GUROBI_LINEAR_PROGRAMMING
-
-
-
-
var GUROBI_MIXED_INTEGER_PROGRAMMING
-
-
-
-
var INFEASIBLE
-
-

proven infeasible.

-
-
var NOT_SOLVED
-
-

not been solved yet.

-
-
var OPTIMAL
-
-

optimal.

-
-
var SAT_INTEGER_PROGRAMMING
-
-
-
-
var SCIP_MIXED_INTEGER_PROGRAMMING
-
-
-
-
var UNBOUNDED
-
-

proven unbounded.

-
-
var XPRESS_LINEAR_PROGRAMMING
-
-
-
-
var XPRESS_MIXED_INTEGER_PROGRAMMING
-
-
-
-
-

Static methods

-
-
-def CreateSolver(solver_id: std::string const &) ‑> operations_research::MPSolver * -
-
-

Recommended factory method to create a MPSolver instance, especially in +

+ + +
+
#   + + + Solver( + name: 'std::string const &', + problem_type: 'operations_research::MPSolver::OptimizationProblemType' +) +
+ +
+ View Source +
    def __init__(self, name: "std::string const &", problem_type: "operations_research::MPSolver::OptimizationProblemType"):
+        r""" Create a solver with the given name and underlying solver backend."""
+        _pywraplp.Solver_swiginit(self, _pywraplp.new_Solver(name, problem_type))
+
+ +
+ +

Create a solver with the given name and underlying solver backend.

+
+ + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + CLP_LINEAR_PROGRAMMING = 0 +
+ + + +
+
+
#   + + GLPK_LINEAR_PROGRAMMING = 1 +
+ + + +
+
+
#   + + GLOP_LINEAR_PROGRAMMING = 2 +
+ + + +
+
+
#   + + SCIP_MIXED_INTEGER_PROGRAMMING = 3 +
+ + + +
+
+
#   + + GLPK_MIXED_INTEGER_PROGRAMMING = 4 +
+ + + +
+
+
#   + + CBC_MIXED_INTEGER_PROGRAMMING = 5 +
+ + + +
+
+
#   + + GUROBI_LINEAR_PROGRAMMING = 6 +
+ + + +
+
+
#   + + GUROBI_MIXED_INTEGER_PROGRAMMING = 7 +
+ + + +
+
+
#   + + CPLEX_LINEAR_PROGRAMMING = 10 +
+ + + +
+
+
#   + + CPLEX_MIXED_INTEGER_PROGRAMMING = 11 +
+ + + +
+
+
#   + + XPRESS_LINEAR_PROGRAMMING = 101 +
+ + + +
+
+
#   + + XPRESS_MIXED_INTEGER_PROGRAMMING = 102 +
+ + + +
+
+
#   + + BOP_INTEGER_PROGRAMMING = 12 +
+ + + +
+
+
#   + + SAT_INTEGER_PROGRAMMING = 14 +
+ + + +
+
+
#   + +
@staticmethod
+ + def + CreateSolver( + solver_id: 'std::string const &' +) -> 'operations_research::MPSolver *': +
+ +
+ View Source +
    @staticmethod
+    def CreateSolver(solver_id: "std::string const &") -> "operations_research::MPSolver *":
+        r"""
+        Recommended factory method to create a MPSolver instance, especially in
+        non C++ languages.
+
+        It returns a newly created solver instance if successful, or a nullptr
+        otherwise. This can occur if the relevant interface is not linked in, or if
+        a needed license is not accessible for commercial solvers.
+
+        Ownership of the solver is passed on to the caller of this method.
+        It will accept both string names of the OptimizationProblemType enum, as
+        well as a short version (i.e. "SCIP_MIXED_INTEGER_PROGRAMMING" or "SCIP").
+
+        solver_id is case insensitive, and the following names are supported:
+          - CLP_LINEAR_PROGRAMMING or CLP
+          - CBC_MIXED_INTEGER_PROGRAMMING or CBC
+          - GLOP_LINEAR_PROGRAMMING or GLOP
+          - BOP_INTEGER_PROGRAMMING or BOP
+          - SAT_INTEGER_PROGRAMMING or SAT or CP_SAT
+          - SCIP_MIXED_INTEGER_PROGRAMMING or SCIP
+          - GUROBI_LINEAR_PROGRAMMING or GUROBI_LP
+          - GUROBI_MIXED_INTEGER_PROGRAMMING or GUROBI or GUROBI_MIP
+          - CPLEX_LINEAR_PROGRAMMING or CPLEX_LP
+          - CPLEX_MIXED_INTEGER_PROGRAMMING or CPLEX or CPLEX_MIP
+          - XPRESS_LINEAR_PROGRAMMING or XPRESS_LP
+          - XPRESS_MIXED_INTEGER_PROGRAMMING or XPRESS or XPRESS_MIP
+          - GLPK_LINEAR_PROGRAMMING or GLPK_LP
+          - GLPK_MIXED_INTEGER_PROGRAMMING or GLPK or GLPK_MIP
+        """
+        return _pywraplp.Solver_CreateSolver(solver_id)
+
+ +
+ +

Recommended factory method to create a MPSolver instance, especially in non C++ languages.

+

It returns a newly created solver instance if successful, or a nullptr otherwise. This can occur if the relevant interface is not linked in, or if a needed license is not accessible for commercial solvers.

+

Ownership of the solver is passed on to the caller of this method. It will accept both string names of the OptimizationProblemType enum, as well as a short version (i.e. "SCIP_MIXED_INTEGER_PROGRAMMING" or "SCIP").

-

solver_id is case insensitive, and the following names are supported: -- CLP_LINEAR_PROGRAMMING or CLP -- CBC_MIXED_INTEGER_PROGRAMMING or CBC -- GLOP_LINEAR_PROGRAMMING or GLOP -- BOP_INTEGER_PROGRAMMING or BOP -- SAT_INTEGER_PROGRAMMING or SAT or CP_SAT -- SCIP_MIXED_INTEGER_PROGRAMMING or SCIP -- GUROBI_LINEAR_PROGRAMMING or GUROBI_LP -- GUROBI_MIXED_INTEGER_PROGRAMMING or GUROBI or GUROBI_MIP -- CPLEX_LINEAR_PROGRAMMING or CPLEX_LP -- CPLEX_MIXED_INTEGER_PROGRAMMING or CPLEX or CPLEX_MIP -- XPRESS_LINEAR_PROGRAMMING or XPRESS_LP -- XPRESS_MIXED_INTEGER_PROGRAMMING or XPRESS or XPRESS_MIP -- GLPK_LINEAR_PROGRAMMING or GLPK_LP -- GLPK_MIXED_INTEGER_PROGRAMMING or GLPK or GLPK_MIP

-
- -Expand source code - -
@staticmethod
-def CreateSolver(solver_id: "std::string const &") -> "operations_research::MPSolver *":
-    r"""
-    Recommended factory method to create a MPSolver instance, especially in
-    non C++ languages.
 
-    It returns a newly created solver instance if successful, or a nullptr
-    otherwise. This can occur if the relevant interface is not linked in, or if
-    a needed license is not accessible for commercial solvers.
+

solver_id is case insensitive, and the following names are supported:

- Ownership of the solver is passed on to the caller of this method. - It will accept both string names of the OptimizationProblemType enum, as - well as a short version (i.e. "SCIP_MIXED_INTEGER_PROGRAMMING" or "SCIP"). +
    +
  • CLP_LINEAR_PROGRAMMING or CLP
  • +
  • CBC_MIXED_INTEGER_PROGRAMMING or CBC
  • +
  • GLOP_LINEAR_PROGRAMMING or GLOP
  • +
  • BOP_INTEGER_PROGRAMMING or BOP
  • +
  • SAT_INTEGER_PROGRAMMING or SAT or CP_SAT
  • +
  • SCIP_MIXED_INTEGER_PROGRAMMING or SCIP
  • +
  • GUROBI_LINEAR_PROGRAMMING or GUROBI_LP
  • +
  • GUROBI_MIXED_INTEGER_PROGRAMMING or GUROBI or GUROBI_MIP
  • +
  • CPLEX_LINEAR_PROGRAMMING or CPLEX_LP
  • +
  • CPLEX_MIXED_INTEGER_PROGRAMMING or CPLEX or CPLEX_MIP
  • +
  • XPRESS_LINEAR_PROGRAMMING or XPRESS_LP
  • +
  • XPRESS_MIXED_INTEGER_PROGRAMMING or XPRESS or XPRESS_MIP
  • +
  • GLPK_LINEAR_PROGRAMMING or GLPK_LP
  • +
  • GLPK_MIXED_INTEGER_PROGRAMMING or GLPK or GLPK_MIP
  • +
+
- solver_id is case insensitive, and the following names are supported: - - CLP_LINEAR_PROGRAMMING or CLP - - CBC_MIXED_INTEGER_PROGRAMMING or CBC - - GLOP_LINEAR_PROGRAMMING or GLOP - - BOP_INTEGER_PROGRAMMING or BOP - - SAT_INTEGER_PROGRAMMING or SAT or CP_SAT - - SCIP_MIXED_INTEGER_PROGRAMMING or SCIP - - GUROBI_LINEAR_PROGRAMMING or GUROBI_LP - - GUROBI_MIXED_INTEGER_PROGRAMMING or GUROBI or GUROBI_MIP - - CPLEX_LINEAR_PROGRAMMING or CPLEX_LP - - CPLEX_MIXED_INTEGER_PROGRAMMING or CPLEX or CPLEX_MIP - - XPRESS_LINEAR_PROGRAMMING or XPRESS_LP - - XPRESS_MIXED_INTEGER_PROGRAMMING or XPRESS or XPRESS_MIP - - GLPK_LINEAR_PROGRAMMING or GLPK_LP - - GLPK_MIXED_INTEGER_PROGRAMMING or GLPK or GLPK_MIP - """ - return _pywraplp.Solver_CreateSolver(solver_id) - -
-
-def Infinity() ‑> double -
-
-
-
- -Expand source code - -
@staticmethod
-def Infinity() -> "double":
-    return _pywraplp.Solver_Infinity()
-
-
-
-def SolveWithProto(model_request: operations_research::MPModelRequest const &, response: operations_research::MPSolutionResponse *) ‑> operations_research::MPSolutionResponse * -
-
-

Solves the model encoded by a MPModelRequest protocol buffer and fills the -solution encoded as a MPSolutionResponse.

-

Note(user): This creates a temporary MPSolver and destroys it at the end. -If you want to keep the MPSolver alive (for debugging, or for incremental -solving), you should write another version of this function that creates -the MPSolver object on the heap and returns it.

-

Note(pawell): This attempts to first use DirectlySolveProto() (if + +

+
+
#   + +
@staticmethod
+ + def + SupportsProblemType( + problem_type: 'operations_research::MPSolver::OptimizationProblemType' +) -> bool: +
+ +
+ View Source +
    @staticmethod
+    def SupportsProblemType(problem_type: "operations_research::MPSolver::OptimizationProblemType") -> "bool":
+        r"""
+        Whether the given problem type is supported (this will depend on the
+        targets that you linked).
+        """
+        return _pywraplp.Solver_SupportsProblemType(problem_type)
+
+ +
+ +

Whether the given problem type is supported (this will depend on the +targets that you linked).

+
+ + +
+
+
#   + + + def + Clear(self) -> 'void': +
+ +
+ View Source +
    def Clear(self) -> "void":
+        r"""
+        Clears the objective (including the optimization direction), all variables
+        and constraints. All the other properties of the MPSolver (like the time
+        limit) are kept untouched.
+        """
+        return _pywraplp.Solver_Clear(self)
+
+ +
+ +

Clears the objective (including the optimization direction), all variables +and constraints. All the other properties of the MPSolver (like the time +limit) are kept untouched.

+
+ + +
+
+
#   + + + def + NumVariables(self) -> int: +
+ +
+ View Source +
    def NumVariables(self) -> "int":
+        r""" Returns the number of variables."""
+        return _pywraplp.Solver_NumVariables(self)
+
+ +
+ +

Returns the number of variables.

+
+ + +
+
+
#   + + + def + variables(self) -> 'std::vector< operations_research::MPVariable * > const &': +
+ +
+ View Source +
    def variables(self) -> "std::vector< operations_research::MPVariable * > const &":
+        r"""
+        Returns the array of variables handled by the MPSolver. (They are listed in
+        the order in which they were created.)
+        """
+        return _pywraplp.Solver_variables(self)
+
+ +
+ +

Returns the array of variables handled by the MPSolver. (They are listed in +the order in which they were created.)

+
+ + +
+
+
#   + + + def + variable(self, index: int) -> 'operations_research::MPVariable *': +
+ +
+ View Source +
    def variable(self, index: "int") -> "operations_research::MPVariable *":
+        r"""Returns the variable at position index."""
+        return _pywraplp.Solver_variable(self, index)
+
+ +
+ +

Returns the variable at position index.

+
+ + +
+
+
#   + + + def + LookupVariable( + self, + var_name: 'std::string const &' +) -> 'operations_research::MPVariable *': +
+ +
+ View Source +
    def LookupVariable(self, var_name: "std::string const &") -> "operations_research::MPVariable *":
+        r"""
+        Looks up a variable by name, and returns nullptr if it does not exist. The
+        first call has a O(n) complexity, as the variable name index is lazily
+        created upon first use. Will crash if variable names are not unique.
+        """
+        return _pywraplp.Solver_LookupVariable(self, var_name)
+
+ +
+ +

Looks up a variable by name, and returns nullptr if it does not exist. The +first call has a O(n) complexity, as the variable name index is lazily +created upon first use. Will crash if variable names are not unique.

+
+ + +
+
+
#   + + + def + Var( + self, + lb: 'double', + ub: 'double', + integer: bool, + name: 'std::string const &' +) -> 'operations_research::MPVariable *': +
+ +
+ View Source +
    def Var(self, lb: "double", ub: "double", integer: "bool", name: "std::string const &") -> "operations_research::MPVariable *":
+        r"""
+        Creates a variable with the given bounds, integrality requirement and
+        name. Bounds can be finite or +/- MPSolver::infinity(). The MPSolver owns
+        the variable (i.e. the returned pointer is borrowed). Variable names are
+        optional. If you give an empty name, name() will auto-generate one for you
+        upon request.
+        """
+        return _pywraplp.Solver_Var(self, lb, ub, integer, name)
+
+ +
+ +

Creates a variable with the given bounds, integrality requirement and +name. Bounds can be finite or +/- MPSolver::infinity(). The MPSolver owns +the variable (i.e. the returned pointer is borrowed). Variable names are +optional. If you give an empty name, name() will auto-generate one for you +upon request.

+
+ + +
+
+
#   + + + def + NumVar( + self, + lb: 'double', + ub: 'double', + name: 'std::string const &' +) -> 'operations_research::MPVariable *': +
+ +
+ View Source +
    def NumVar(self, lb: "double", ub: "double", name: "std::string const &") -> "operations_research::MPVariable *":
+        r""" Creates a continuous variable."""
+        return _pywraplp.Solver_NumVar(self, lb, ub, name)
+
+ +
+ +

Creates a continuous variable.

+
+ + +
+
+
#   + + + def + IntVar( + self, + lb: 'double', + ub: 'double', + name: 'std::string const &' +) -> 'operations_research::MPVariable *': +
+ +
+ View Source +
    def IntVar(self, lb: "double", ub: "double", name: "std::string const &") -> "operations_research::MPVariable *":
+        r""" Creates an integer variable."""
+        return _pywraplp.Solver_IntVar(self, lb, ub, name)
+
+ +
+ +

Creates an integer variable.

+
+ + +
+
+
#   + + + def + BoolVar( + self, + name: 'std::string const &' +) -> 'operations_research::MPVariable *': +
+ +
+ View Source +
    def BoolVar(self, name: "std::string const &") -> "operations_research::MPVariable *":
+        r""" Creates a boolean variable."""
+        return _pywraplp.Solver_BoolVar(self, name)
+
+ +
+ +

Creates a boolean variable.

+
+ + +
+
+
#   + + + def + NumConstraints(self) -> int: +
+ +
+ View Source +
    def NumConstraints(self) -> "int":
+        r""" Returns the number of constraints."""
+        return _pywraplp.Solver_NumConstraints(self)
+
+ +
+ +

Returns the number of constraints.

+
+ + +
+
+
#   + + + def + constraints(self) -> 'std::vector< operations_research::MPConstraint * > const &': +
+ +
+ View Source +
    def constraints(self) -> "std::vector< operations_research::MPConstraint * > const &":
+        r"""
+        Returns the array of constraints handled by the MPSolver.
+
+        They are listed in the order in which they were created.
+        """
+        return _pywraplp.Solver_constraints(self)
+
+ +
+ +

Returns the array of constraints handled by the MPSolver.

+ +

They are listed in the order in which they were created.

+
+ + +
+
+
#   + + + def + constraint(self, index: int) -> 'operations_research::MPConstraint *': +
+ +
+ View Source +
    def constraint(self, index: "int") -> "operations_research::MPConstraint *":
+        r""" Returns the constraint at the given index."""
+        return _pywraplp.Solver_constraint(self, index)
+
+ +
+ +

Returns the constraint at the given index.

+
+ + +
+
+
#   + + + def + LookupConstraint( + self, + constraint_name: 'std::string const &' +) -> 'operations_research::MPConstraint *': +
+ +
+ View Source +
    def LookupConstraint(self, constraint_name: "std::string const &") -> "operations_research::MPConstraint *":
+        r"""
+         Looks up a constraint by name, and returns nullptr if it does not exist.
+
+        The first call has a O(n) complexity, as the constraint name index is
+        lazily created upon first use. Will crash if constraint names are not
+        unique.
+        """
+        return _pywraplp.Solver_LookupConstraint(self, constraint_name)
+
+ +
+ +

Looks up a constraint by name, and returns nullptr if it does not exist.

+ +

The first call has a O(n) complexity, as the constraint name index is +lazily created upon first use. Will crash if constraint names are not +unique.

+
+ + +
+
+
#   + + + def + Constraint(self, *args) -> 'operations_research::MPConstraint *': +
+ +
+ View Source +
    def Constraint(self, *args) -> "operations_research::MPConstraint *":
+        r"""
+        *Overload 1:*
+
+        Creates a linear constraint with given bounds.
+
+        Bounds can be finite or +/- MPSolver::infinity(). The MPSolver class
+        assumes ownership of the constraint.
+
+        :rtype: :py:class:`MPConstraint`
+        :return: a pointer to the newly created constraint.
+
+        |
+
+        *Overload 2:*
+         Creates a constraint with -infinity and +infinity bounds.
+
+        |
+
+        *Overload 3:*
+         Creates a named constraint with given bounds.
+
+        |
+
+        *Overload 4:*
+         Creates a named constraint with -infinity and +infinity bounds.
+        """
+        return _pywraplp.Solver_Constraint(self, *args)
+
+ +
+ +

Overload 1:

+ +

Creates a linear constraint with given bounds.

+ +

Bounds can be finite or +/- MPSolver::infinity(). The MPSolver class +assumes ownership of the constraint.

+ +

:rtype: MPConstraint +:return: a pointer to the newly created constraint.

+ +

|

+ +

Overload 2: + Creates a constraint with -infinity and +infinity bounds.

+ +

|

+ +

Overload 3: + Creates a named constraint with given bounds.

+ +

|

+ +

Overload 4: + Creates a named constraint with -infinity and +infinity bounds.

+
+ + +
+
+
#   + + + def + Objective(self) -> 'operations_research::MPObjective *': +
+ +
+ View Source +
    def Objective(self) -> "operations_research::MPObjective *":
+        r""" Returns the mutable objective object."""
+        return _pywraplp.Solver_Objective(self)
+
+ +
+ +

Returns the mutable objective object.

+
+ + +
+
+
#   + + OPTIMAL = 0 +
+ +

optimal.

+
+ + +
+
+
#   + + FEASIBLE = 1 +
+ +

feasible, or stopped by limit.

+
+ + +
+
+
#   + + INFEASIBLE = 2 +
+ +

proven infeasible.

+
+ + +
+
+
#   + + UNBOUNDED = 3 +
+ +

proven unbounded.

+
+ + +
+
+
#   + + ABNORMAL = 4 +
+ +

abnormal, i.e., error of some kind.

+
+ + +
+
+
#   + + NOT_SOLVED = 6 +
+ +

not been solved yet.

+
+ + +
+
+
#   + + + def + Solve(self, *args) -> 'operations_research::MPSolver::ResultStatus': +
+ +
+ View Source +
    def Solve(self, *args) -> "operations_research::MPSolver::ResultStatus":
+        r"""
+        *Overload 1:*
+        Solves the problem using the default parameter values.
+
+        |
+
+        *Overload 2:*
+        Solves the problem using the specified parameter values.
+        """
+        return _pywraplp.Solver_Solve(self, *args)
+
+ +
+ +

Overload 1: +Solves the problem using the default parameter values.

+ +

|

+ +

Overload 2: +Solves the problem using the specified parameter values.

+
+ + +
+
+
#   + + + def + ComputeConstraintActivities(self) -> 'std::vector< double >': +
+ +
+ View Source +
    def ComputeConstraintActivities(self) -> "std::vector< double >":
+        r"""
+        Advanced usage: compute the "activities" of all constraints, which are the
+        sums of their linear terms. The activities are returned in the same order
+        as constraints(), which is the order in which constraints were added; but
+        you can also use MPConstraint::index() to get a constraint's index.
+        """
+        return _pywraplp.Solver_ComputeConstraintActivities(self)
+
+ +
+ +

Advanced usage: compute the "activities" of all constraints, which are the +sums of their linear terms. The activities are returned in the same order +as constraints(), which is the order in which constraints were added; but +you can also use MPConstraint::index() to get a constraint's index.

+
+ + +
+
+
#   + + + def + VerifySolution(self, tolerance: 'double', log_errors: bool) -> bool: +
+ +
+ View Source +
    def VerifySolution(self, tolerance: "double", log_errors: "bool") -> "bool":
+        r"""
+        Advanced usage: Verifies the *correctness* of the solution.
+
+        It verifies that all variables must be within their domains, all
+        constraints must be satisfied, and the reported objective value must be
+        accurate.
+
+        Usage:
+        - This can only be called after Solve() was called.
+        - "tolerance" is interpreted as an absolute error threshold.
+        - For the objective value only, if the absolute error is too large,
+          the tolerance is interpreted as a relative error threshold instead.
+        - If "log_errors" is true, every single violation will be logged.
+        - If "tolerance" is negative, it will be set to infinity().
+
+        Most users should just set the --verify_solution flag and not bother using
+        this method directly.
+        """
+        return _pywraplp.Solver_VerifySolution(self, tolerance, log_errors)
+
+ +
+ +

Advanced usage: Verifies the correctness of the solution.

+ +

It verifies that all variables must be within their domains, all +constraints must be satisfied, and the reported objective value must be +accurate.

+ +

Usage:

+ +
    +
  • This can only be called after Solve() was called.
  • +
  • "tolerance" is interpreted as an absolute error threshold.
  • +
  • For the objective value only, if the absolute error is too large, +the tolerance is interpreted as a relative error threshold instead.
  • +
  • If "log_errors" is true, every single violation will be logged.
  • +
  • If "tolerance" is negative, it will be set to infinity().
  • +
+ +

Most users should just set the --verify_solution flag and not bother using +this method directly.

+
+ + +
+
+
#   + + + def + InterruptSolve(self) -> bool: +
+ +
+ View Source +
    def InterruptSolve(self) -> "bool":
+        r"""
+         Interrupts the Solve() execution to terminate processing if possible.
+
+        If the underlying interface supports interruption; it does that and returns
+        true regardless of whether there's an ongoing Solve() or not. The Solve()
+        call may still linger for a while depending on the conditions.  If
+        interruption is not supported; returns false and does nothing.
+        MPSolver::SolverTypeSupportsInterruption can be used to check if
+        interruption is supported for a given solver type.
+        """
+        return _pywraplp.Solver_InterruptSolve(self)
+
+ +
+ +

Interrupts the Solve() execution to terminate processing if possible.

+ +

If the underlying interface supports interruption; it does that and returns +true regardless of whether there's an ongoing Solve() or not. The Solve() +call may still linger for a while depending on the conditions. If +interruption is not supported; returns false and does nothing. +MPSolver::SolverTypeSupportsInterruption can be used to check if +interruption is supported for a given solver type.

+
+ + +
+
+
#   + + + def + FillSolutionResponseProto( + self, + response: 'operations_research::MPSolutionResponse *' +) -> 'void': +
+ +
+ View Source +
    def FillSolutionResponseProto(self, response: "operations_research::MPSolutionResponse *") -> "void":
+        r""" Encodes the current solution in a solution response protocol buffer."""
+        return _pywraplp.Solver_FillSolutionResponseProto(self, response)
+
+ +
+ +

Encodes the current solution in a solution response protocol buffer.

+
+ + +
+
+
#   + +
@staticmethod
+ + def + SolveWithProto( + model_request: 'operations_research::MPModelRequest const &', + response: 'operations_research::MPSolutionResponse *', + interrupt: 'std::atomic< bool > const *' = None +) -> 'operations_research::MPSolutionResponse *': +
+ +
+ View Source +
    @staticmethod
+    def SolveWithProto(model_request: "operations_research::MPModelRequest const &", response: "operations_research::MPSolutionResponse *", interrupt: "std::atomic< bool > const *"=None) -> "operations_research::MPSolutionResponse *":
+        r"""
+        Solves the model encoded by a MPModelRequest protocol buffer and fills the
+        solution encoded as a MPSolutionResponse. The solve is stopped prematurely
+        if interrupt is non-null at set to true during (or before) solving.
+        Interruption is only supported if SolverTypeSupportsInterruption() returns
+        true for the requested solver. Passing a non-null interruption with any
+        other solver type immediately returns an MPSOLVER_INCOMPATIBLE_OPTIONS
+        error.
+
+        Note(user): This attempts to first use `DirectlySolveProto()` (if
+        implemented). Consequently, this most likely does *not* override any of
+        the default parameters of the underlying solver. This behavior *differs*
+        from `MPSolver::Solve()` which by default sets the feasibility tolerance
+        and the gap limit (as of 2020/02/11, to 1e-7 and 0.0001, respectively).
+        """
+        return _pywraplp.Solver_SolveWithProto(model_request, response, interrupt)
+
+ +
+ +

Solves the model encoded by a MPModelRequest protocol buffer and fills the +solution encoded as a MPSolutionResponse. The solve is stopped prematurely +if interrupt is non-null at set to true during (or before) solving. +Interruption is only supported if SolverTypeSupportsInterruption() returns +true for the requested solver. Passing a non-null interruption with any +other solver type immediately returns an MPSOLVER_INCOMPATIBLE_OPTIONS +error.

+ +

Note(user): This attempts to first use DirectlySolveProto() (if implemented). Consequently, this most likely does not override any of the default parameters of the underlying solver. This behavior differs from MPSolver::Solve() which by default sets the feasibility tolerance -and the gap limit (as of 2020/02/11, to 1e-7 and 0.0001, respectively).

-
- -Expand source code - -
@staticmethod
-def SolveWithProto(model_request: "operations_research::MPModelRequest const &", response: "operations_research::MPSolutionResponse *") -> "operations_research::MPSolutionResponse *":
-    r"""
-    Solves the model encoded by a MPModelRequest protocol buffer and fills the
-    solution encoded as a MPSolutionResponse.
+and the gap limit (as of 2020/02/11, to 1e-7 and 0.0001, respectively).

+
- Note(user): This creates a temporary MPSolver and destroys it at the end. - If you want to keep the MPSolver alive (for debugging, or for incremental - solving), you should write another version of this function that creates - the MPSolver object on the heap and returns it. - Note(pawell): This attempts to first use `DirectlySolveProto()` (if - implemented). Consequently, this most likely does *not* override any of - the default parameters of the underlying solver. This behavior *differs* - from `MPSolver::Solve()` which by default sets the feasibility tolerance - and the gap limit (as of 2020/02/11, to 1e-7 and 0.0001, respectively). - """ - return _pywraplp.Solver_SolveWithProto(model_request, response) - -
-
-def SupportsProblemType(problem_type: operations_research::MPSolver::OptimizationProblemType) ‑> bool -
-
-

Whether the given problem type is supported (this will depend on the -targets that you linked).

-
- -Expand source code - -
@staticmethod
-def SupportsProblemType(problem_type: "operations_research::MPSolver::OptimizationProblemType") -> "bool":
-    r"""
-    Whether the given problem type is supported (this will depend on the
-    targets that you linked).
-    """
-    return _pywraplp.Solver_SupportsProblemType(problem_type)
-
-
-
-def infinity() ‑> double -
-
-

Infinity.

-

You can use -MPSolver::infinity() for negative infinity.

-
- -Expand source code - -
@staticmethod
-def infinity() -> "double":
-    r"""
-    Infinity.
+                            
+                            
+
#   - You can use -MPSolver::infinity() for negative infinity. - """ - return _pywraplp.Solver_infinity()
-
-
-
-

Methods

-
-
-def Add(self, constraint, name='') -
-
-
-
- -Expand source code - -
def Add(self, constraint, name=''):
-  if isinstance(constraint, bool):
-    if constraint:
-      return self.RowConstraint(0, 0, name)
-    else:
-      return self.RowConstraint(1, 1, name)
-  else:
-    return constraint.Extract(self, name)
-
-
-
-def BoolVar(self, name: std::string const &) ‑> operations_research::MPVariable * -
-
-

Creates a boolean variable.

-
- -Expand source code - -
def BoolVar(self, name: "std::string const &") -> "operations_research::MPVariable *":
-    r""" Creates a boolean variable."""
-    return _pywraplp.Solver_BoolVar(self, name)
-
-
-
-def Clear(self) ‑> void -
-
-

Clears the objective (including the optimization direction), all variables -and constraints. All the other properties of the MPSolver (like the time -limit) are kept untouched.

-
- -Expand source code - -
def Clear(self) -> "void":
-    r"""
-    Clears the objective (including the optimization direction), all variables
-    and constraints. All the other properties of the MPSolver (like the time
-    limit) are kept untouched.
-    """
-    return _pywraplp.Solver_Clear(self)
-
-
-
-def ComputeConstraintActivities(self) ‑> std::vector< double > -
-
-

Advanced usage: compute the "activities" of all constraints, which are the -sums of their linear terms. The activities are returned in the same order -as constraints(), which is the order in which constraints were added; but -you can also use MPConstraint::index() to get a constraint's index.

-
- -Expand source code - -
def ComputeConstraintActivities(self) -> "std::vector< double >":
-    r"""
-    Advanced usage: compute the "activities" of all constraints, which are the
-    sums of their linear terms. The activities are returned in the same order
-    as constraints(), which is the order in which constraints were added; but
-    you can also use MPConstraint::index() to get a constraint's index.
-    """
-    return _pywraplp.Solver_ComputeConstraintActivities(self)
-
-
-
-def ComputeExactConditionNumber(self) ‑> double -
-
-

Advanced usage: computes the exact condition number of the current scaled + + def + ExportModelToProto(self, output_model: 'operations_research::MPModelProto *') -> 'void': +

+ +
+ View Source +
    def ExportModelToProto(self, output_model: "operations_research::MPModelProto *") -> "void":
+        r""" Exports model to protocol buffer."""
+        return _pywraplp.Solver_ExportModelToProto(self, output_model)
+
+ +
+ +

Exports model to protocol buffer.

+
+ + + +
+
#   + + + def + SetSolverSpecificParametersAsString(self, parameters: 'std::string const &') -> bool: +
+ +
+ View Source +
    def SetSolverSpecificParametersAsString(self, parameters: "std::string const &") -> "bool":
+        r"""
+        Advanced usage: pass solver specific parameters in text format.
+
+        The format is solver-specific and is the same as the corresponding solver
+        configuration file format. Returns true if the operation was successful.
+        """
+        return _pywraplp.Solver_SetSolverSpecificParametersAsString(self, parameters)
+
+ +
+ +

Advanced usage: pass solver specific parameters in text format.

+ +

The format is solver-specific and is the same as the corresponding solver +configuration file format. Returns true if the operation was successful.

+
+ + +
+
+
#   + + FREE = 0 +
+ + + +
+
+
#   + + AT_LOWER_BOUND = 1 +
+ + + +
+
+
#   + + AT_UPPER_BOUND = 2 +
+ + + +
+
+
#   + + FIXED_VALUE = 3 +
+ + + +
+
+
#   + + BASIC = 4 +
+ + + +
+
+
#   + +
@staticmethod
+ + def + infinity() -> 'double': +
+ +
+ View Source +
    @staticmethod
+    def infinity() -> "double":
+        r"""
+        Infinity.
+
+        You can use -MPSolver::infinity() for negative infinity.
+        """
+        return _pywraplp.Solver_infinity()
+
+ +
+ +

Infinity.

+ +

You can use -MPSolver::infinity() for negative infinity.

+
+ + +
+
+
#   + + + def + EnableOutput(self) -> 'void': +
+ +
+ View Source +
    def EnableOutput(self) -> "void":
+        r""" Enables solver logging."""
+        return _pywraplp.Solver_EnableOutput(self)
+
+ +
+ +

Enables solver logging.

+
+ + +
+
+
#   + + + def + SuppressOutput(self) -> 'void': +
+ +
+ View Source +
    def SuppressOutput(self) -> "void":
+        r""" Suppresses solver logging."""
+        return _pywraplp.Solver_SuppressOutput(self)
+
+ +
+ +

Suppresses solver logging.

+
+ + +
+
+
#   + + + def + iterations(self) -> 'int64_t': +
+ +
+ View Source +
    def iterations(self) -> "int64_t":
+        r""" Returns the number of simplex iterations."""
+        return _pywraplp.Solver_iterations(self)
+
+ +
+ +

Returns the number of simplex iterations.

+
+ + +
+
+
#   + + + def + nodes(self) -> 'int64_t': +
+ +
+ View Source +
    def nodes(self) -> "int64_t":
+        r"""
+        Returns the number of branch-and-bound nodes evaluated during the solve.
+
+        Only available for discrete problems.
+        """
+        return _pywraplp.Solver_nodes(self)
+
+ +
+ +

Returns the number of branch-and-bound nodes evaluated during the solve.

+ +

Only available for discrete problems.

+
+ + +
+
+
#   + + + def + ComputeExactConditionNumber(self) -> 'double': +
+ +
+ View Source +
    def ComputeExactConditionNumber(self) -> "double":
+        r"""
+         Advanced usage: computes the exact condition number of the current scaled
+        basis: L1norm(B) * L1norm(inverse(B)), where B is the scaled basis.
+
+        This method requires that a basis exists: it should be called after Solve.
+        It is only available for continuous problems. It is implemented for GLPK
+        but not CLP because CLP does not provide the API for doing it.
+
+        The condition number measures how well the constraint matrix is conditioned
+        and can be used to predict whether numerical issues will arise during the
+        solve: the model is declared infeasible whereas it is feasible (or
+        vice-versa), the solution obtained is not optimal or violates some
+        constraints, the resolution is slow because of repeated singularities.
+
+        The rule of thumb to interpret the condition number kappa is:
+          - o kappa <= 1e7: virtually no chance of numerical issues
+          - o 1e7 < kappa <= 1e10: small chance of numerical issues
+          - o 1e10 < kappa <= 1e13: medium chance of numerical issues
+          - o kappa > 1e13: high chance of numerical issues
+
+        The computation of the condition number depends on the quality of the LU
+        decomposition, so it is not very accurate when the matrix is ill
+        conditioned.
+        """
+        return _pywraplp.Solver_ComputeExactConditionNumber(self)
+
+ +
+ +

Advanced usage: computes the exact condition number of the current scaled basis: L1norm(B) * L1norm(inverse(B)), where B is the scaled basis.

+

This method requires that a basis exists: it should be called after Solve. It is only available for continuous problems. It is implemented for GLPK but not CLP because CLP does not provide the API for doing it.

+

The condition number measures how well the constraint matrix is conditioned and can be used to predict whether numerical issues will arise during the solve: the model is declared infeasible whereas it is feasible (or vice-versa), the solution obtained is not optimal or violates some constraints, the resolution is slow because of repeated singularities.

-

The rule of thumb to interpret the condition number kappa is: -- o kappa <= 1e7: virtually no chance of numerical issues -- o 1e7 < kappa <= 1e10: small chance of numerical issues -- o 1e10 < kappa <= 1e13: medium chance of numerical issues -- o kappa > 1e13: high chance of numerical issues

+ +
The rule of thumb to interpret the condition number kappa is
+ +
+
    +
  • o kappa <= 1e7: virtually no chance of numerical issues
  • +
  • o 1e7 < kappa <= 1e10: small chance of numerical issues
  • +
  • o 1e10 < kappa <= 1e13: medium chance of numerical issues
  • +
  • o kappa > 1e13: high chance of numerical issues
  • +
+
+

The computation of the condition number depends on the quality of the LU decomposition, so it is not very accurate when the matrix is ill -conditioned.

-
- -Expand source code - -
def ComputeExactConditionNumber(self) -> "double":
-    r"""
-     Advanced usage: computes the exact condition number of the current scaled
-    basis: L1norm(B) * L1norm(inverse(B)), where B is the scaled basis.
+conditioned.

+
- This method requires that a basis exists: it should be called after Solve. - It is only available for continuous problems. It is implemented for GLPK - but not CLP because CLP does not provide the API for doing it. - The condition number measures how well the constraint matrix is conditioned - and can be used to predict whether numerical issues will arise during the - solve: the model is declared infeasible whereas it is feasible (or - vice-versa), the solution obtained is not optimal or violates some - constraints, the resolution is slow because of repeated singularities. + +
+
#   - The rule of thumb to interpret the condition number kappa is: - - o kappa <= 1e7: virtually no chance of numerical issues - - o 1e7 < kappa <= 1e10: small chance of numerical issues - - o 1e10 < kappa <= 1e13: medium chance of numerical issues - - o kappa > 1e13: high chance of numerical issues + + def + NextSolution(self) -> bool: +
- The computation of the condition number depends on the quality of the LU - decomposition, so it is not very accurate when the matrix is ill - conditioned. - """ - return _pywraplp.Solver_ComputeExactConditionNumber(self)
- -
-
-def Constraint(self, *args) ‑> operations_research::MPConstraint * -
-
-

Overload 1:

-

Creates a linear constraint with given bounds.

-

Bounds can be finite or +/- MPSolver::infinity(). The MPSolver class -assumes ownership of the constraint.

-

:rtype: :py:class:MPConstraint -:return: a pointer to the newly created constraint.

-

|

-

Overload 2: -Creates a constraint with -infinity and +infinity bounds.

-

|

-

Overload 3: -Creates a named constraint with given bounds.

-

|

-

Overload 4: -Creates a named constraint with -infinity and +infinity bounds.

-
- -Expand source code - -
def Constraint(self, *args) -> "operations_research::MPConstraint *":
-    r"""
-    *Overload 1:*
+                
+ View Source +
    def NextSolution(self) -> "bool":
+        r"""
+        Some solvers (MIP only, not LP) can produce multiple solutions to the
+        problem. Returns true when another solution is available, and updates the
+        MPVariable* objects to make the new solution queryable. Call only after
+        calling solve.
 
-    Creates a linear constraint with given bounds.
+        The optimality properties of the additional solutions found, and whether or
+        not the solver computes them ahead of time or when NextSolution() is called
+        is solver specific.
 
-    Bounds can be finite or +/- MPSolver::infinity(). The MPSolver class
-    assumes ownership of the constraint.
+        As of 2020-02-10, only Gurobi and SCIP support NextSolution(), see
+        linear_solver_interfaces_test for an example of how to configure these
+        solvers for multiple solutions. Other solvers return false unconditionally.
+        """
+        return _pywraplp.Solver_NextSolution(self)
+
- :rtype: :py:class:`MPConstraint` - :return: a pointer to the newly created constraint. +
- | - - *Overload 2:* - Creates a constraint with -infinity and +infinity bounds. - - | - - *Overload 3:* - Creates a named constraint with given bounds. - - | - - *Overload 4:* - Creates a named constraint with -infinity and +infinity bounds. - """ - return _pywraplp.Solver_Constraint(self, *args)
-
-
-
-def EnableOutput(self) ‑> void -
-
-

Enables solver logging.

-
- -Expand source code - -
def EnableOutput(self) -> "void":
-    r""" Enables solver logging."""
-    return _pywraplp.Solver_EnableOutput(self)
-
-
-
-def ExportModelAsLpFormat(self, obfuscated: bool) ‑> std::string -
-
-
-
- -Expand source code - -
def ExportModelAsLpFormat(self, obfuscated: "bool") -> "std::string":
-    return _pywraplp.Solver_ExportModelAsLpFormat(self, obfuscated)
-
-
-
-def ExportModelAsMpsFormat(self, fixed_format: bool, obfuscated: bool) ‑> std::string -
-
-
-
- -Expand source code - -
def ExportModelAsMpsFormat(self, fixed_format: "bool", obfuscated: "bool") -> "std::string":
-    return _pywraplp.Solver_ExportModelAsMpsFormat(self, fixed_format, obfuscated)
-
-
-
-def ExportModelToProto(self, output_model: operations_research::MPModelProto *) ‑> void -
-
-

Exports model to protocol buffer.

-
- -Expand source code - -
def ExportModelToProto(self, output_model: "operations_research::MPModelProto *") -> "void":
-    r""" Exports model to protocol buffer."""
-    return _pywraplp.Solver_ExportModelToProto(self, output_model)
-
-
-
-def FillSolutionResponseProto(self, response: operations_research::MPSolutionResponse *) ‑> void -
-
-

Encodes the current solution in a solution response protocol buffer.

-
- -Expand source code - -
def FillSolutionResponseProto(self, response: "operations_research::MPSolutionResponse *") -> "void":
-    r""" Encodes the current solution in a solution response protocol buffer."""
-    return _pywraplp.Solver_FillSolutionResponseProto(self, response)
-
-
-
-def IntVar(self, lb: double, ub: double, name: std::string const &) ‑> operations_research::MPVariable * -
-
-

Creates an integer variable.

-
- -Expand source code - -
def IntVar(self, lb: "double", ub: "double", name: "std::string const &") -> "operations_research::MPVariable *":
-    r""" Creates an integer variable."""
-    return _pywraplp.Solver_IntVar(self, lb, ub, name)
-
-
-
-def InterruptSolve(self) ‑> bool -
-
-

Interrupts the Solve() execution to terminate processing if possible.

-

If the underlying interface supports interruption; it does that and returns -true regardless of whether there's an ongoing Solve() or not. The Solve() -call may still linger for a while depending on the conditions. -If -interruption is not supported; returns false and does nothing.

-
- -Expand source code - -
def InterruptSolve(self) -> "bool":
-    r"""
-     Interrupts the Solve() execution to terminate processing if possible.
-
-    If the underlying interface supports interruption; it does that and returns
-    true regardless of whether there's an ongoing Solve() or not. The Solve()
-    call may still linger for a while depending on the conditions.  If
-    interruption is not supported; returns false and does nothing.
-    """
-    return _pywraplp.Solver_InterruptSolve(self)
-
-
-
-def Iterations(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def Iterations(self) -> "int64_t":
-    return _pywraplp.Solver_Iterations(self)
-
-
-
-def LoadModelFromProto(self, input_model: operations_research::MPModelProto const &) ‑> std::string -
-
-
-
- -Expand source code - -
def LoadModelFromProto(self, input_model: "operations_research::MPModelProto const &") -> "std::string":
-    return _pywraplp.Solver_LoadModelFromProto(self, input_model)
-
-
-
-def LoadSolutionFromProto(self, *args) ‑> bool -
-
-
-
- -Expand source code - -
def LoadSolutionFromProto(self, *args) -> "bool":
-    return _pywraplp.Solver_LoadSolutionFromProto(self, *args)
-
-
-
-def LookupConstraint(self, constraint_name: std::string const &) ‑> operations_research::MPConstraint * -
-
-

Looks up a constraint by name, and returns nullptr if it does not exist.

-

The first call has a O(n) complexity, as the constraint name index is -lazily created upon first use. Will crash if constraint names are not -unique.

-
- -Expand source code - -
def LookupConstraint(self, constraint_name: "std::string const &") -> "operations_research::MPConstraint *":
-    r"""
-     Looks up a constraint by name, and returns nullptr if it does not exist.
-
-    The first call has a O(n) complexity, as the constraint name index is
-    lazily created upon first use. Will crash if constraint names are not
-    unique.
-    """
-    return _pywraplp.Solver_LookupConstraint(self, constraint_name)
-
-
-
-def LookupVariable(self, var_name: std::string const &) ‑> operations_research::MPVariable * -
-
-

Looks up a variable by name, and returns nullptr if it does not exist. The -first call has a O(n) complexity, as the variable name index is lazily -created upon first use. Will crash if variable names are not unique.

-
- -Expand source code - -
def LookupVariable(self, var_name: "std::string const &") -> "operations_research::MPVariable *":
-    r"""
-    Looks up a variable by name, and returns nullptr if it does not exist. The
-    first call has a O(n) complexity, as the variable name index is lazily
-    created upon first use. Will crash if variable names are not unique.
-    """
-    return _pywraplp.Solver_LookupVariable(self, var_name)
-
-
-
-def Maximize(self, expr) -
-
-
-
- -Expand source code - -
def Maximize(self, expr):
-  objective = self.Objective()
-  objective.Clear()
-  objective.SetMaximization()
-  if isinstance(expr, numbers.Number):
-      objective.SetOffset(expr)
-  else:
-      coeffs = expr.GetCoeffs()
-      objective.SetOffset(coeffs.pop(OFFSET_KEY, 0.0))
-      for v, c, in list(coeffs.items()):
-        objective.SetCoefficient(v, float(c))
-
-
-
-def Minimize(self, expr) -
-
-
-
- -Expand source code - -
def Minimize(self, expr):
-  objective = self.Objective()
-  objective.Clear()
-  objective.SetMinimization()
-  if isinstance(expr, numbers.Number):
-      objective.SetOffset(expr)
-  else:
-      coeffs = expr.GetCoeffs()
-      objective.SetOffset(coeffs.pop(OFFSET_KEY, 0.0))
-      for v, c, in list(coeffs.items()):
-        objective.SetCoefficient(v, float(c))
-
-
-
-def NextSolution(self) ‑> bool -
-
-

Some solvers (MIP only, not LP) can produce multiple solutions to the +

Some solvers (MIP only, not LP) can produce multiple solutions to the problem. Returns true when another solution is available, and updates the MPVariable* objects to make the new solution queryable. Call only after calling solve.

+

The optimality properties of the additional solutions found, and whether or not the solver computes them ahead of time or when NextSolution() is called is solver specific.

+

As of 2020-02-10, only Gurobi and SCIP support NextSolution(), see linear_solver_interfaces_test for an example of how to configure these -solvers for multiple solutions. Other solvers return false unconditionally.

-
- -Expand source code - -
def NextSolution(self) -> "bool":
-    r"""
-    Some solvers (MIP only, not LP) can produce multiple solutions to the
-    problem. Returns true when another solution is available, and updates the
-    MPVariable* objects to make the new solution queryable. Call only after
-    calling solve.
-
-    The optimality properties of the additional solutions found, and whether or
-    not the solver computes them ahead of time or when NextSolution() is called
-    is solver specific.
-
-    As of 2020-02-10, only Gurobi and SCIP support NextSolution(), see
-    linear_solver_interfaces_test for an example of how to configure these
-    solvers for multiple solutions. Other solvers return false unconditionally.
-    """
-    return _pywraplp.Solver_NextSolution(self)
-
-
-
-def NumConstraints(self) ‑> int -
-
-

Returns the number of constraints.

-
- -Expand source code - -
def NumConstraints(self) -> "int":
-    r""" Returns the number of constraints."""
-    return _pywraplp.Solver_NumConstraints(self)
-
-
-
-def NumVar(self, lb: double, ub: double, name: std::string const &) ‑> operations_research::MPVariable * -
-
-

Creates a continuous variable.

-
- -Expand source code - -
def NumVar(self, lb: "double", ub: "double", name: "std::string const &") -> "operations_research::MPVariable *":
-    r""" Creates a continuous variable."""
-    return _pywraplp.Solver_NumVar(self, lb, ub, name)
-
-
-
-def NumVariables(self) ‑> int -
-
-

Returns the number of variables.

-
- -Expand source code - -
def NumVariables(self) -> "int":
-    r""" Returns the number of variables."""
-    return _pywraplp.Solver_NumVariables(self)
-
-
-
-def Objective(self) ‑> operations_research::MPObjective * -
-
-

Returns the mutable objective object.

-
- -Expand source code - -
def Objective(self) -> "operations_research::MPObjective *":
-    r""" Returns the mutable objective object."""
-    return _pywraplp.Solver_Objective(self)
-
-
-
-def RowConstraint(self, *args) -
-
-
-
- -Expand source code - -
def RowConstraint(self, *args):
-  return self.Constraint(*args)
-
-
-
-def SetHint(self, variables: std::vector< operations_research::MPVariable * > const &, values: std::vector< double > const &) ‑> void -
-
-

Set a hint for solution.

-

If a feasible or almost-feasible solution to the problem is already known, -it may be helpful to pass it to the solver so that it can be used. A -solver that supports this feature will try to use this information to -create its initial feasible solution.

-

Note that it may not always be faster to give a hint like this to the -solver. There is also no guarantee that the solver will use this hint or -try to return a solution "close" to this assignment in case of multiple -optimal solutions.

-
- -Expand source code - -
def SetHint(self, variables: "std::vector< operations_research::MPVariable * > const &", values: "std::vector< double > const &") -> "void":
-    r"""
-    Set a hint for solution.
-
-    If a feasible or almost-feasible solution to the problem is already known,
-    it may be helpful to pass it to the solver so that it can be used. A
-    solver that supports this feature will try to use this information to
-    create its initial feasible solution.
-
-    Note that it may not always be faster to give a hint like this to the
-    solver. There is also no guarantee that the solver will use this hint or
-    try to return a solution "close" to this assignment in case of multiple
-    optimal solutions.
-    """
-    return _pywraplp.Solver_SetHint(self, variables, values)
-
-
-
-def SetNumThreads(self, num_theads: int) ‑> bool -
-
-

Sets the number of threads to be used by the solver.

-
- -Expand source code - -
def SetNumThreads(self, num_theads: "int") -> "bool":
-    r""" Sets the number of threads to be used by the solver."""
-    return _pywraplp.Solver_SetNumThreads(self, num_theads)
-
-
-
-def SetSolverSpecificParametersAsString(self, parameters: std::string const &) ‑> bool -
-
-

Advanced usage: pass solver specific parameters in text format.

-

The format is solver-specific and is the same as the corresponding solver -configuration file format. Returns true if the operation was successful.

-
- -Expand source code - -
def SetSolverSpecificParametersAsString(self, parameters: "std::string const &") -> "bool":
-    r"""
-    Advanced usage: pass solver specific parameters in text format.
-
-    The format is solver-specific and is the same as the corresponding solver
-    configuration file format. Returns true if the operation was successful.
-    """
-    return _pywraplp.Solver_SetSolverSpecificParametersAsString(self, parameters)
-
-
-
-def SetTimeLimit(self, x: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def SetTimeLimit(self, x: "int64_t") -> "void":
-    return _pywraplp.Solver_SetTimeLimit(self, x)
-
-
-
-def Solve(self, *args) ‑> operations_research::MPSolver::ResultStatus -
-
-

Overload 1: -Solves the problem using the default parameter values.

-

|

-

Overload 2: -Solves the problem using the specified parameter values.

-
- -Expand source code - -
def Solve(self, *args) -> "operations_research::MPSolver::ResultStatus":
-    r"""
-    *Overload 1:*
-    Solves the problem using the default parameter values.
-
-    |
-
-    *Overload 2:*
-    Solves the problem using the specified parameter values.
-    """
-    return _pywraplp.Solver_Solve(self, *args)
-
-
-
-def Sum(self, expr_array) -
-
-
-
- -Expand source code - -
def Sum(self, expr_array):
-  result = SumArray(expr_array)
-  return result
-
-
-
-def SuppressOutput(self) ‑> void -
-
-

Suppresses solver logging.

-
- -Expand source code - -
def SuppressOutput(self) -> "void":
-    r""" Suppresses solver logging."""
-    return _pywraplp.Solver_SuppressOutput(self)
-
-
-
-def Var(self, lb: double, ub: double, integer: bool, name: std::string const &) ‑> operations_research::MPVariable * -
-
-

Creates a variable with the given bounds, integrality requirement and -name. Bounds can be finite or +/- MPSolver::infinity(). The MPSolver owns -the variable (i.e. the returned pointer is borrowed). Variable names are -optional. If you give an empty name, name() will auto-generate one for you -upon request.

-
- -Expand source code - -
def Var(self, lb: "double", ub: "double", integer: "bool", name: "std::string const &") -> "operations_research::MPVariable *":
-    r"""
-    Creates a variable with the given bounds, integrality requirement and
-    name. Bounds can be finite or +/- MPSolver::infinity(). The MPSolver owns
-    the variable (i.e. the returned pointer is borrowed). Variable names are
-    optional. If you give an empty name, name() will auto-generate one for you
-    upon request.
-    """
-    return _pywraplp.Solver_Var(self, lb, ub, integer, name)
-
-
-
-def VerifySolution(self, tolerance: double, log_errors: bool) ‑> bool -
-
-

Advanced usage: Verifies the correctness of the solution.

-

It verifies that all variables must be within their domains, all -constraints must be satisfied, and the reported objective value must be -accurate.

-

Usage: -- This can only be called after Solve() was called. -- "tolerance" is interpreted as an absolute error threshold. -- For the objective value only, if the absolute error is too large, -the tolerance is interpreted as a relative error threshold instead. -- If "log_errors" is true, every single violation will be logged. -- If "tolerance" is negative, it will be set to infinity().

-

Most users should just set the –verify_solution flag and not bother using -this method directly.

-
- -Expand source code - -
def VerifySolution(self, tolerance: "double", log_errors: "bool") -> "bool":
-    r"""
-    Advanced usage: Verifies the *correctness* of the solution.
-
-    It verifies that all variables must be within their domains, all
-    constraints must be satisfied, and the reported objective value must be
-    accurate.
-
-    Usage:
-    - This can only be called after Solve() was called.
-    - "tolerance" is interpreted as an absolute error threshold.
-    - For the objective value only, if the absolute error is too large,
-      the tolerance is interpreted as a relative error threshold instead.
-    - If "log_errors" is true, every single violation will be logged.
-    - If "tolerance" is negative, it will be set to infinity().
-
-    Most users should just set the --verify_solution flag and not bother using
-    this method directly.
-    """
-    return _pywraplp.Solver_VerifySolution(self, tolerance, log_errors)
-
-
-
-def WallTime(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def WallTime(self) -> "int64_t":
-    return _pywraplp.Solver_WallTime(self)
-
-
-
-def constraint(self, index: int) ‑> operations_research::MPConstraint * -
-
-

Returns the constraint at the given index.

-
- -Expand source code - -
def constraint(self, index: "int") -> "operations_research::MPConstraint *":
-    r""" Returns the constraint at the given index."""
-    return _pywraplp.Solver_constraint(self, index)
-
-
-
-def constraints(self) ‑> std::vector< operations_research::MPConstraint * > const & -
-
-

Returns the array of constraints handled by the MPSolver.

-

They are listed in the order in which they were created.

-
- -Expand source code - -
def constraints(self) -> "std::vector< operations_research::MPConstraint * > const &":
-    r"""
-    Returns the array of constraints handled by the MPSolver.
-
-    They are listed in the order in which they were created.
-    """
-    return _pywraplp.Solver_constraints(self)
-
-
-
-def iterations(self) ‑> int64_t -
-
-

Returns the number of simplex iterations.

-
- -Expand source code - -
def iterations(self) -> "int64_t":
-    r""" Returns the number of simplex iterations."""
-    return _pywraplp.Solver_iterations(self)
-
-
-
-def nodes(self) ‑> int64_t -
-
-

Returns the number of branch-and-bound nodes evaluated during the solve.

-

Only available for discrete problems.

-
- -Expand source code - -
def nodes(self) -> "int64_t":
-    r"""
-    Returns the number of branch-and-bound nodes evaluated during the solve.
-
-    Only available for discrete problems.
-    """
-    return _pywraplp.Solver_nodes(self)
-
-
-
-def set_time_limit(self, time_limit_milliseconds: int64_t) ‑> void -
-
-
-
- -Expand source code - -
def set_time_limit(self, time_limit_milliseconds: "int64_t") -> "void":
-    return _pywraplp.Solver_set_time_limit(self, time_limit_milliseconds)
-
-
-
-def variable(self, index: int) ‑> operations_research::MPVariable * -
-
-

Returns the variable at position index.

-
- -Expand source code - -
def variable(self, index: "int") -> "operations_research::MPVariable *":
-    r"""Returns the variable at position index."""
-    return _pywraplp.Solver_variable(self, index)
-
-
-
-def variables(self) ‑> std::vector< operations_research::MPVariable * > const & -
-
-

Returns the array of variables handled by the MPSolver. (They are listed in -the order in which they were created.)

-
- -Expand source code - -
def variables(self) -> "std::vector< operations_research::MPVariable * > const &":
-    r"""
-    Returns the array of variables handled by the MPSolver. (They are listed in
-    the order in which they were created.)
-    """
-    return _pywraplp.Solver_variables(self)
-
-
-
-def wall_time(self) ‑> int64_t -
-
-
-
- -Expand source code - -
def wall_time(self) -> "int64_t":
-    return _pywraplp.Solver_wall_time(self)
-
-
-
- -
-class Variable -(*args, **kwargs) -
-
-

The class for variables of a Mathematical Programming (MP) model.

-
- -Expand source code - -
class Variable(object):
-    r""" The class for variables of a Mathematical Programming (MP) model."""
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined")
-
-    def name(self) -> "std::string const &":
-        r""" Returns the name of the variable."""
-        return _pywraplp.Variable_name(self)
-
-    def SetInteger(self, integer: "bool") -> "void":
-        r""" Sets the integrality requirement of the variable."""
-        return _pywraplp.Variable_SetInteger(self, integer)
-
-    def integer(self) -> "bool":
-        r""" Returns the integrality requirement of the variable."""
-        return _pywraplp.Variable_integer(self)
-
-    def solution_value(self) -> "double":
-        r"""
-        Returns the value of the variable in the current solution.
-
-        If the variable is integer, then the value will always be an integer (the
-        underlying solver handles floating-point values only, but this function
-        automatically rounds it to the nearest integer; see: man 3 round).
-        """
-        return _pywraplp.Variable_solution_value(self)
-
-    def index(self) -> "int":
-        r""" Returns the index of the variable in the MPSolver::variables_."""
-        return _pywraplp.Variable_index(self)
-
-    def lb(self) -> "double":
-        r""" Returns the lower bound."""
-        return _pywraplp.Variable_lb(self)
-
-    def ub(self) -> "double":
-        r""" Returns the upper bound."""
-        return _pywraplp.Variable_ub(self)
-
-    def SetBounds(self, lb: "double", ub: "double") -> "void":
-        r""" Sets both the lower and upper bounds."""
-        return _pywraplp.Variable_SetBounds(self, lb, ub)
-
-    def reduced_cost(self) -> "double":
-        r"""
-        Advanced usage: returns the reduced cost of the variable in the current
-        solution (only available for continuous problems).
-        """
-        return _pywraplp.Variable_reduced_cost(self)
-
-    def basis_status(self) -> "operations_research::MPSolver::BasisStatus":
-        r"""
-        Advanced usage: returns the basis status of the variable in the current
-        solution (only available for continuous problems).
-
-        See also: MPSolver::BasisStatus.
-        """
-        return _pywraplp.Variable_basis_status(self)
-
-    def branching_priority(self) -> "int":
-        r"""
-        Advanced usage: Certain MIP solvers (e.g. Gurobi or SCIP) allow you to set
-        a per-variable priority for determining which variable to branch on.
-
-        A value of 0 is treated as default, and is equivalent to not setting the
-        branching priority. The solver looks first to branch on fractional
-        variables in higher priority levels. As of 2019-05, only Gurobi and SCIP
-        support setting branching priority; all other solvers will simply ignore
-        this annotation.
-        """
-        return _pywraplp.Variable_branching_priority(self)
-
-    def SetBranchingPriority(self, priority: "int") -> "void":
-        return _pywraplp.Variable_SetBranchingPriority(self, priority)
-
-    def __str__(self) -> "std::string":
-        return _pywraplp.Variable___str__(self)
-
-    def __repr__(self) -> "std::string":
-        return _pywraplp.Variable___repr__(self)
-
-    def __getattr__(self, name):
-      return getattr(VariableExpr(self), name)
+solvers for multiple solutions. Other solvers return false unconditionally.

+ - def SolutionValue(self) -> "double": - return _pywraplp.Variable_SolutionValue(self) + +
+
#   - def Integer(self) -> "bool": - return _pywraplp.Variable_Integer(self) + + def + set_time_limit(self, time_limit_milliseconds: 'int64_t') -> 'void': +
- def Lb(self) -> "double": - return _pywraplp.Variable_Lb(self) +
+ View Source +
    def set_time_limit(self, time_limit_milliseconds: "int64_t") -> "void":
+        return _pywraplp.Solver_set_time_limit(self, time_limit_milliseconds)
+
- def Ub(self) -> "double": - return _pywraplp.Variable_Ub(self) +
- def SetLb(self, x: "double") -> "void": - return _pywraplp.Variable_SetLb(self, x) + - def SetUb(self, x: "double") -> "void": - return _pywraplp.Variable_SetUb(self, x) +
+
+
#   - def ReducedCost(self) -> "double": - return _pywraplp.Variable_ReducedCost(self) - __swig_destroy__ = _pywraplp.delete_Variable
-
-

Methods

-
-
-def Integer(self) ‑> bool -
-
-
-
- -Expand source code - -
def Integer(self) -> "bool":
-    return _pywraplp.Variable_Integer(self)
-
-
-
-def Lb(self) ‑> double -
-
-
-
- -Expand source code - -
def Lb(self) -> "double":
-    return _pywraplp.Variable_Lb(self)
-
-
-
-def ReducedCost(self) ‑> double -
-
-
-
- -Expand source code - -
def ReducedCost(self) -> "double":
-    return _pywraplp.Variable_ReducedCost(self)
-
-
-
-def SetBounds(self, lb: double, ub: double) ‑> void -
-
-

Sets both the lower and upper bounds.

-
- -Expand source code - -
def SetBounds(self, lb: "double", ub: "double") -> "void":
-    r""" Sets both the lower and upper bounds."""
-    return _pywraplp.Variable_SetBounds(self, lb, ub)
-
-
-
-def SetBranchingPriority(self, priority: int) ‑> void -
-
-
-
- -Expand source code - -
def SetBranchingPriority(self, priority: "int") -> "void":
-    return _pywraplp.Variable_SetBranchingPriority(self, priority)
-
-
-
-def SetInteger(self, integer: bool) ‑> void -
-
-

Sets the integrality requirement of the variable.

-
- -Expand source code - -
def SetInteger(self, integer: "bool") -> "void":
-    r""" Sets the integrality requirement of the variable."""
-    return _pywraplp.Variable_SetInteger(self, integer)
-
-
-
-def SetLb(self, x: double) ‑> void -
-
-
-
- -Expand source code - -
def SetLb(self, x: "double") -> "void":
-    return _pywraplp.Variable_SetLb(self, x)
-
-
-
-def SetUb(self, x: double) ‑> void -
-
-
-
- -Expand source code - -
def SetUb(self, x: "double") -> "void":
-    return _pywraplp.Variable_SetUb(self, x)
-
-
-
-def SolutionValue(self) ‑> double -
-
-
-
- -Expand source code - -
def SolutionValue(self) -> "double":
-    return _pywraplp.Variable_SolutionValue(self)
-
-
-
-def Ub(self) ‑> double -
-
-
-
- -Expand source code - -
def Ub(self) -> "double":
-    return _pywraplp.Variable_Ub(self)
-
-
-
-def basis_status(self) ‑> operations_research::MPSolver::BasisStatus -
-
-

Advanced usage: returns the basis status of the variable in the current + + def + wall_time(self) -> 'int64_t': +

+ +
+ View Source +
    def wall_time(self) -> "int64_t":
+        return _pywraplp.Solver_wall_time(self)
+
+ +
+ + + + +
+
#   + + + def + LoadModelFromProto( + self, + input_model: 'operations_research::MPModelProto const &' +) -> 'std::string': +
+ +
+ View Source +
    def LoadModelFromProto(self, input_model: "operations_research::MPModelProto const &") -> "std::string":
+        return _pywraplp.Solver_LoadModelFromProto(self, input_model)
+
+ +
+ + + +
+
+
#   + + + def + LoadSolutionFromProto(self, *args) -> bool: +
+ +
+ View Source +
    def LoadSolutionFromProto(self, *args) -> "bool":
+        return _pywraplp.Solver_LoadSolutionFromProto(self, *args)
+
+ +
+ + + +
+
+
#   + + + def + ExportModelAsLpFormat(self, obfuscated: bool) -> 'std::string': +
+ +
+ View Source +
    def ExportModelAsLpFormat(self, obfuscated: "bool") -> "std::string":
+        return _pywraplp.Solver_ExportModelAsLpFormat(self, obfuscated)
+
+ +
+ + + +
+
+
#   + + + def + ExportModelAsMpsFormat(self, fixed_format: bool, obfuscated: bool) -> 'std::string': +
+ +
+ View Source +
    def ExportModelAsMpsFormat(self, fixed_format: "bool", obfuscated: "bool") -> "std::string":
+        return _pywraplp.Solver_ExportModelAsMpsFormat(self, fixed_format, obfuscated)
+
+ +
+ + + +
+
+
#   + + + def + SetHint( + self, + variables: 'std::vector< operations_research::MPVariable * > const &', + values: 'std::vector< double > const &' +) -> 'void': +
+ +
+ View Source +
    def SetHint(self, variables: "std::vector< operations_research::MPVariable * > const &", values: "std::vector< double > const &") -> "void":
+        r""" Set a hint for solution. If a feasible or almost-feasible solution to the problem is already known, it may be helpful to pass it to the solver so that it can be used. A solver that supports this feature will try to use this information to create its initial feasible solution. Note that it may not always be faster to give a hint like this to the solver. There is also no guarantee that the solver will use this hint or try to return a solution "close" to this assignment in case of multiple optimal solutions."""
+        return _pywraplp.Solver_SetHint(self, variables, values)
+
+ +
+ +

Set a hint for solution. If a feasible or almost-feasible solution to the problem is already known, it may be helpful to pass it to the solver so that it can be used. A solver that supports this feature will try to use this information to create its initial feasible solution. Note that it may not always be faster to give a hint like this to the solver. There is also no guarantee that the solver will use this hint or try to return a solution "close" to this assignment in case of multiple optimal solutions.

+
+ + +
+
+
#   + + + def + SetNumThreads(self, num_theads: int) -> bool: +
+ +
+ View Source +
    def SetNumThreads(self, num_theads: "int") -> "bool":
+        r""" Sets the number of threads to be used by the solver."""
+        return _pywraplp.Solver_SetNumThreads(self, num_theads)
+
+ +
+ +

Sets the number of threads to be used by the solver.

+
+ + +
+
+
#   + + + def + Add(self, constraint, name=''): +
+ +
+ View Source +
    def Add(self, constraint, name=''):
+      if isinstance(constraint, bool):
+        if constraint:
+          return self.RowConstraint(0, 0, name)
+        else:
+          return self.RowConstraint(1, 1, name)
+      else:
+        return constraint.Extract(self, name)
+
+ +
+ + + +
+
+
#   + + + def + Sum(self, expr_array): +
+ +
+ View Source +
    def Sum(self, expr_array):
+      result = SumArray(expr_array)
+      return result
+
+ +
+ + + +
+
+
#   + + + def + RowConstraint(self, *args): +
+ +
+ View Source +
    def RowConstraint(self, *args):
+      return self.Constraint(*args)
+
+ +
+ + + +
+
+
#   + + + def + Minimize(self, expr): +
+ +
+ View Source +
    def Minimize(self, expr):
+      objective = self.Objective()
+      objective.Clear()
+      objective.SetMinimization()
+      if isinstance(expr, numbers.Number):
+          objective.SetOffset(expr)
+      else:
+          coeffs = expr.GetCoeffs()
+          objective.SetOffset(coeffs.pop(OFFSET_KEY, 0.0))
+          for v, c, in list(coeffs.items()):
+            objective.SetCoefficient(v, float(c))
+
+ +
+ + + +
+
+
#   + + + def + Maximize(self, expr): +
+ +
+ View Source +
    def Maximize(self, expr):
+      objective = self.Objective()
+      objective.Clear()
+      objective.SetMaximization()
+      if isinstance(expr, numbers.Number):
+          objective.SetOffset(expr)
+      else:
+          coeffs = expr.GetCoeffs()
+          objective.SetOffset(coeffs.pop(OFFSET_KEY, 0.0))
+          for v, c, in list(coeffs.items()):
+            objective.SetCoefficient(v, float(c))
+
+ +
+ + + +
+
+
#   + +
@staticmethod
+ + def + Infinity() -> 'double': +
+ +
+ View Source +
    @staticmethod
+    def Infinity() -> "double":
+        return _pywraplp.Solver_Infinity()
+
+ +
+ + + +
+
+
#   + + + def + SetTimeLimit(self, x: 'int64_t') -> 'void': +
+ +
+ View Source +
    def SetTimeLimit(self, x: "int64_t") -> "void":
+        return _pywraplp.Solver_SetTimeLimit(self, x)
+
+ +
+ + + +
+
+
#   + + + def + WallTime(self) -> 'int64_t': +
+ +
+ View Source +
    def WallTime(self) -> "int64_t":
+        return _pywraplp.Solver_WallTime(self)
+
+ +
+ + + +
+
+
#   + + + def + Iterations(self) -> 'int64_t': +
+ +
+ View Source +
    def Iterations(self) -> "int64_t":
+        return _pywraplp.Solver_Iterations(self)
+
+ +
+ + + +
+
+
+
#   + + + def + Solver_CreateSolver( + solver_id: 'std::string const &' +) -> 'operations_research::MPSolver *': +
+ +
+ View Source +
def Solver_CreateSolver(solver_id: "std::string const &") -> "operations_research::MPSolver *":
+    r"""
+    Recommended factory method to create a MPSolver instance, especially in
+    non C++ languages.
+
+    It returns a newly created solver instance if successful, or a nullptr
+    otherwise. This can occur if the relevant interface is not linked in, or if
+    a needed license is not accessible for commercial solvers.
+
+    Ownership of the solver is passed on to the caller of this method.
+    It will accept both string names of the OptimizationProblemType enum, as
+    well as a short version (i.e. "SCIP_MIXED_INTEGER_PROGRAMMING" or "SCIP").
+
+    solver_id is case insensitive, and the following names are supported:
+      - CLP_LINEAR_PROGRAMMING or CLP
+      - CBC_MIXED_INTEGER_PROGRAMMING or CBC
+      - GLOP_LINEAR_PROGRAMMING or GLOP
+      - BOP_INTEGER_PROGRAMMING or BOP
+      - SAT_INTEGER_PROGRAMMING or SAT or CP_SAT
+      - SCIP_MIXED_INTEGER_PROGRAMMING or SCIP
+      - GUROBI_LINEAR_PROGRAMMING or GUROBI_LP
+      - GUROBI_MIXED_INTEGER_PROGRAMMING or GUROBI or GUROBI_MIP
+      - CPLEX_LINEAR_PROGRAMMING or CPLEX_LP
+      - CPLEX_MIXED_INTEGER_PROGRAMMING or CPLEX or CPLEX_MIP
+      - XPRESS_LINEAR_PROGRAMMING or XPRESS_LP
+      - XPRESS_MIXED_INTEGER_PROGRAMMING or XPRESS or XPRESS_MIP
+      - GLPK_LINEAR_PROGRAMMING or GLPK_LP
+      - GLPK_MIXED_INTEGER_PROGRAMMING or GLPK or GLPK_MIP
+    """
+    return _pywraplp.Solver_CreateSolver(solver_id)
+
+ +
+ +

Recommended factory method to create a MPSolver instance, especially in +non C++ languages.

+ +

It returns a newly created solver instance if successful, or a nullptr +otherwise. This can occur if the relevant interface is not linked in, or if +a needed license is not accessible for commercial solvers.

+ +

Ownership of the solver is passed on to the caller of this method. +It will accept both string names of the OptimizationProblemType enum, as +well as a short version (i.e. "SCIP_MIXED_INTEGER_PROGRAMMING" or "SCIP").

+ +

solver_id is case insensitive, and the following names are supported:

+ +
    +
  • CLP_LINEAR_PROGRAMMING or CLP
  • +
  • CBC_MIXED_INTEGER_PROGRAMMING or CBC
  • +
  • GLOP_LINEAR_PROGRAMMING or GLOP
  • +
  • BOP_INTEGER_PROGRAMMING or BOP
  • +
  • SAT_INTEGER_PROGRAMMING or SAT or CP_SAT
  • +
  • SCIP_MIXED_INTEGER_PROGRAMMING or SCIP
  • +
  • GUROBI_LINEAR_PROGRAMMING or GUROBI_LP
  • +
  • GUROBI_MIXED_INTEGER_PROGRAMMING or GUROBI or GUROBI_MIP
  • +
  • CPLEX_LINEAR_PROGRAMMING or CPLEX_LP
  • +
  • CPLEX_MIXED_INTEGER_PROGRAMMING or CPLEX or CPLEX_MIP
  • +
  • XPRESS_LINEAR_PROGRAMMING or XPRESS_LP
  • +
  • XPRESS_MIXED_INTEGER_PROGRAMMING or XPRESS or XPRESS_MIP
  • +
  • GLPK_LINEAR_PROGRAMMING or GLPK_LP
  • +
  • GLPK_MIXED_INTEGER_PROGRAMMING or GLPK or GLPK_MIP
  • +
+
+ + +
+
+
#   + + + def + Solver_SupportsProblemType( + problem_type: 'operations_research::MPSolver::OptimizationProblemType' +) -> bool: +
+ +
+ View Source +
def Solver_SupportsProblemType(problem_type: "operations_research::MPSolver::OptimizationProblemType") -> "bool":
+    r"""
+    Whether the given problem type is supported (this will depend on the
+    targets that you linked).
+    """
+    return _pywraplp.Solver_SupportsProblemType(problem_type)
+
+ +
+ +

Whether the given problem type is supported (this will depend on the +targets that you linked).

+
+ + +
+
+
#   + + + def + Solver_SolveWithProto( + model_request: 'operations_research::MPModelRequest const &', + response: 'operations_research::MPSolutionResponse *', + interrupt: 'std::atomic< bool > const *' = None +) -> 'operations_research::MPSolutionResponse *': +
+ +
+ View Source +
def Solver_SolveWithProto(model_request: "operations_research::MPModelRequest const &", response: "operations_research::MPSolutionResponse *", interrupt: "std::atomic< bool > const *"=None) -> "operations_research::MPSolutionResponse *":
+    r"""
+    Solves the model encoded by a MPModelRequest protocol buffer and fills the
+    solution encoded as a MPSolutionResponse. The solve is stopped prematurely
+    if interrupt is non-null at set to true during (or before) solving.
+    Interruption is only supported if SolverTypeSupportsInterruption() returns
+    true for the requested solver. Passing a non-null interruption with any
+    other solver type immediately returns an MPSOLVER_INCOMPATIBLE_OPTIONS
+    error.
+
+    Note(user): This attempts to first use `DirectlySolveProto()` (if
+    implemented). Consequently, this most likely does *not* override any of
+    the default parameters of the underlying solver. This behavior *differs*
+    from `MPSolver::Solve()` which by default sets the feasibility tolerance
+    and the gap limit (as of 2020/02/11, to 1e-7 and 0.0001, respectively).
+    """
+    return _pywraplp.Solver_SolveWithProto(model_request, response, interrupt)
+
+ +
+ +

Solves the model encoded by a MPModelRequest protocol buffer and fills the +solution encoded as a MPSolutionResponse. The solve is stopped prematurely +if interrupt is non-null at set to true during (or before) solving. +Interruption is only supported if SolverTypeSupportsInterruption() returns +true for the requested solver. Passing a non-null interruption with any +other solver type immediately returns an MPSOLVER_INCOMPATIBLE_OPTIONS +error.

+ +

Note(user): This attempts to first use DirectlySolveProto() (if +implemented). Consequently, this most likely does not override any of +the default parameters of the underlying solver. This behavior differs +from MPSolver::Solve() which by default sets the feasibility tolerance +and the gap limit (as of 2020/02/11, to 1e-7 and 0.0001, respectively).

+
+ + +
+
+
#   + + + def + Solver_infinity() -> 'double': +
+ +
+ View Source +
def Solver_infinity() -> "double":
+    r"""
+    Infinity.
+
+    You can use -MPSolver::infinity() for negative infinity.
+    """
+    return _pywraplp.Solver_infinity()
+
+ +
+ +

Infinity.

+ +

You can use -MPSolver::infinity() for negative infinity.

+
+ + +
+
+
#   + + + def + Solver_Infinity() -> 'double': +
+ +
+ View Source +
def Solver_Infinity() -> "double":
+    return _pywraplp.Solver_Infinity()
+
+ +
+ + + +
+
+
+ #   + + + class + Objective: +
+ +
+ View Source +
class Objective(object):
+    r""" A class to express a linear objective."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+    __repr__ = _swig_repr
+
+    def Clear(self) -> "void":
+        r"""
+         Clears the offset, all variables and coefficients, and the optimization
+        direction.
+        """
+        return _pywraplp.Objective_Clear(self)
+
+    def SetCoefficient(self, var: "Variable", coeff: "double") -> "void":
+        r"""
+        Sets the coefficient of the variable in the objective.
+
+        If the variable does not belong to the solver, the function just returns,
+        or crashes in non-opt mode.
+        """
+        return _pywraplp.Objective_SetCoefficient(self, var, coeff)
+
+    def GetCoefficient(self, var: "Variable") -> "double":
+        r"""
+         Gets the coefficient of a given variable in the objective
+
+        It returns 0 if the variable does not appear in the objective).
+        """
+        return _pywraplp.Objective_GetCoefficient(self, var)
+
+    def SetOffset(self, value: "double") -> "void":
+        r""" Sets the constant term in the objective."""
+        return _pywraplp.Objective_SetOffset(self, value)
+
+    def offset(self) -> "double":
+        r""" Gets the constant term in the objective."""
+        return _pywraplp.Objective_offset(self)
+
+    def SetOptimizationDirection(self, maximize: "bool") -> "void":
+        r""" Sets the optimization direction (maximize: true or minimize: false)."""
+        return _pywraplp.Objective_SetOptimizationDirection(self, maximize)
+
+    def SetMinimization(self) -> "void":
+        r""" Sets the optimization direction to minimize."""
+        return _pywraplp.Objective_SetMinimization(self)
+
+    def SetMaximization(self) -> "void":
+        r""" Sets the optimization direction to maximize."""
+        return _pywraplp.Objective_SetMaximization(self)
+
+    def maximization(self) -> "bool":
+        r""" Is the optimization direction set to maximize?"""
+        return _pywraplp.Objective_maximization(self)
+
+    def minimization(self) -> "bool":
+        r""" Is the optimization direction set to minimize?"""
+        return _pywraplp.Objective_minimization(self)
+
+    def Value(self) -> "double":
+        r"""
+        Returns the objective value of the best solution found so far.
+
+        It is the optimal objective value if the problem has been solved to
+        optimality.
+
+        Note: the objective value may be slightly different than what you could
+        compute yourself using ``MPVariable::solution_value();`` please use the
+        --verify_solution flag to gain confidence about the numerical stability of
+        your solution.
+        """
+        return _pywraplp.Objective_Value(self)
+
+    def BestBound(self) -> "double":
+        r"""
+        Returns the best objective bound.
+
+        In case of minimization, it is a lower bound on the objective value of the
+        optimal integer solution. Only available for discrete problems.
+        """
+        return _pywraplp.Objective_BestBound(self)
+
+    def Offset(self) -> "double":
+        return _pywraplp.Objective_Offset(self)
+    __swig_destroy__ = _pywraplp.delete_Objective
+
+ +
+ +

A class to express a linear objective.

+
+ + +
+
#   + + + Objective(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + Clear(self) -> 'void': +
+ +
+ View Source +
    def Clear(self) -> "void":
+        r"""
+         Clears the offset, all variables and coefficients, and the optimization
+        direction.
+        """
+        return _pywraplp.Objective_Clear(self)
+
+ +
+ +

Clears the offset, all variables and coefficients, and the optimization +direction.

+
+ + +
+
+
#   + + + def + SetCoefficient(self, var: pywraplp.Variable, coeff: 'double') -> 'void': +
+ +
+ View Source +
    def SetCoefficient(self, var: "Variable", coeff: "double") -> "void":
+        r"""
+        Sets the coefficient of the variable in the objective.
+
+        If the variable does not belong to the solver, the function just returns,
+        or crashes in non-opt mode.
+        """
+        return _pywraplp.Objective_SetCoefficient(self, var, coeff)
+
+ +
+ +

Sets the coefficient of the variable in the objective.

+ +

If the variable does not belong to the solver, the function just returns, +or crashes in non-opt mode.

+
+ + +
+
+
#   + + + def + GetCoefficient(self, var: pywraplp.Variable) -> 'double': +
+ +
+ View Source +
    def GetCoefficient(self, var: "Variable") -> "double":
+        r"""
+         Gets the coefficient of a given variable in the objective
+
+        It returns 0 if the variable does not appear in the objective).
+        """
+        return _pywraplp.Objective_GetCoefficient(self, var)
+
+ +
+ +

Gets the coefficient of a given variable in the objective

+ +

It returns 0 if the variable does not appear in the objective).

+
+ + +
+
+
#   + + + def + SetOffset(self, value: 'double') -> 'void': +
+ +
+ View Source +
    def SetOffset(self, value: "double") -> "void":
+        r""" Sets the constant term in the objective."""
+        return _pywraplp.Objective_SetOffset(self, value)
+
+ +
+ +

Sets the constant term in the objective.

+
+ + +
+
+
#   + + + def + offset(self) -> 'double': +
+ +
+ View Source +
    def offset(self) -> "double":
+        r""" Gets the constant term in the objective."""
+        return _pywraplp.Objective_offset(self)
+
+ +
+ +

Gets the constant term in the objective.

+
+ + +
+
+
#   + + + def + SetOptimizationDirection(self, maximize: bool) -> 'void': +
+ +
+ View Source +
    def SetOptimizationDirection(self, maximize: "bool") -> "void":
+        r""" Sets the optimization direction (maximize: true or minimize: false)."""
+        return _pywraplp.Objective_SetOptimizationDirection(self, maximize)
+
+ +
+ +

Sets the optimization direction (maximize: true or minimize: false).

+
+ + +
+
+
#   + + + def + SetMinimization(self) -> 'void': +
+ +
+ View Source +
    def SetMinimization(self) -> "void":
+        r""" Sets the optimization direction to minimize."""
+        return _pywraplp.Objective_SetMinimization(self)
+
+ +
+ +

Sets the optimization direction to minimize.

+
+ + +
+
+
#   + + + def + SetMaximization(self) -> 'void': +
+ +
+ View Source +
    def SetMaximization(self) -> "void":
+        r""" Sets the optimization direction to maximize."""
+        return _pywraplp.Objective_SetMaximization(self)
+
+ +
+ +

Sets the optimization direction to maximize.

+
+ + +
+
+
#   + + + def + maximization(self) -> bool: +
+ +
+ View Source +
    def maximization(self) -> "bool":
+        r""" Is the optimization direction set to maximize?"""
+        return _pywraplp.Objective_maximization(self)
+
+ +
+ +

Is the optimization direction set to maximize?

+
+ + +
+
+
#   + + + def + minimization(self) -> bool: +
+ +
+ View Source +
    def minimization(self) -> "bool":
+        r""" Is the optimization direction set to minimize?"""
+        return _pywraplp.Objective_minimization(self)
+
+ +
+ +

Is the optimization direction set to minimize?

+
+ + +
+
+
#   + + + def + Value(self) -> 'double': +
+ +
+ View Source +
    def Value(self) -> "double":
+        r"""
+        Returns the objective value of the best solution found so far.
+
+        It is the optimal objective value if the problem has been solved to
+        optimality.
+
+        Note: the objective value may be slightly different than what you could
+        compute yourself using ``MPVariable::solution_value();`` please use the
+        --verify_solution flag to gain confidence about the numerical stability of
+        your solution.
+        """
+        return _pywraplp.Objective_Value(self)
+
+ +
+ +

Returns the objective value of the best solution found so far.

+ +

It is the optimal objective value if the problem has been solved to +optimality.

+ +

Note: the objective value may be slightly different than what you could +compute yourself using MPVariable::solution_value(); please use the +--verify_solution flag to gain confidence about the numerical stability of +your solution.

+
+ + +
+
+
#   + + + def + BestBound(self) -> 'double': +
+ +
+ View Source +
    def BestBound(self) -> "double":
+        r"""
+        Returns the best objective bound.
+
+        In case of minimization, it is a lower bound on the objective value of the
+        optimal integer solution. Only available for discrete problems.
+        """
+        return _pywraplp.Objective_BestBound(self)
+
+ +
+ +

Returns the best objective bound.

+ +

In case of minimization, it is a lower bound on the objective value of the +optimal integer solution. Only available for discrete problems.

+
+ + +
+
+
#   + + + def + Offset(self) -> 'double': +
+ +
+ View Source +
    def Offset(self) -> "double":
+        return _pywraplp.Objective_Offset(self)
+
+ +
+ + + +
+
+
+
+ #   + + + class + Variable: +
+ +
+ View Source +
class Variable(object):
+    r""" The class for variables of a Mathematical Programming (MP) model."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+
+    def name(self) -> "std::string const &":
+        r""" Returns the name of the variable."""
+        return _pywraplp.Variable_name(self)
+
+    def SetInteger(self, integer: "bool") -> "void":
+        r""" Sets the integrality requirement of the variable."""
+        return _pywraplp.Variable_SetInteger(self, integer)
+
+    def integer(self) -> "bool":
+        r""" Returns the integrality requirement of the variable."""
+        return _pywraplp.Variable_integer(self)
+
+    def solution_value(self) -> "double":
+        r"""
+        Returns the value of the variable in the current solution.
+
+        If the variable is integer, then the value will always be an integer (the
+        underlying solver handles floating-point values only, but this function
+        automatically rounds it to the nearest integer; see: man 3 round).
+        """
+        return _pywraplp.Variable_solution_value(self)
+
+    def index(self) -> "int":
+        r""" Returns the index of the variable in the MPSolver::variables_."""
+        return _pywraplp.Variable_index(self)
+
+    def lb(self) -> "double":
+        r""" Returns the lower bound."""
+        return _pywraplp.Variable_lb(self)
+
+    def ub(self) -> "double":
+        r""" Returns the upper bound."""
+        return _pywraplp.Variable_ub(self)
+
+    def SetBounds(self, lb: "double", ub: "double") -> "void":
+        r""" Sets both the lower and upper bounds."""
+        return _pywraplp.Variable_SetBounds(self, lb, ub)
+
+    def reduced_cost(self) -> "double":
+        r"""
+        Advanced usage: returns the reduced cost of the variable in the current
+        solution (only available for continuous problems).
+        """
+        return _pywraplp.Variable_reduced_cost(self)
+
+    def basis_status(self) -> "operations_research::MPSolver::BasisStatus":
+        r"""
+        Advanced usage: returns the basis status of the variable in the current
+        solution (only available for continuous problems).
+
+        See also: MPSolver::BasisStatus.
+        """
+        return _pywraplp.Variable_basis_status(self)
+
+    def branching_priority(self) -> "int":
+        r"""
+        Advanced usage: Certain MIP solvers (e.g. Gurobi or SCIP) allow you to set
+        a per-variable priority for determining which variable to branch on.
+
+        A value of 0 is treated as default, and is equivalent to not setting the
+        branching priority. The solver looks first to branch on fractional
+        variables in higher priority levels. As of 2019-05, only Gurobi and SCIP
+        support setting branching priority; all other solvers will simply ignore
+        this annotation.
+        """
+        return _pywraplp.Variable_branching_priority(self)
+
+    def SetBranchingPriority(self, priority: "int") -> "void":
+        return _pywraplp.Variable_SetBranchingPriority(self, priority)
+
+    def __str__(self) -> "std::string":
+        return _pywraplp.Variable___str__(self)
+
+    def __repr__(self) -> "std::string":
+        return _pywraplp.Variable___repr__(self)
+
+    def __getattr__(self, name):
+      return getattr(VariableExpr(self), name)
+
+
+    def SolutionValue(self) -> "double":
+        return _pywraplp.Variable_SolutionValue(self)
+
+    def Integer(self) -> "bool":
+        return _pywraplp.Variable_Integer(self)
+
+    def Lb(self) -> "double":
+        return _pywraplp.Variable_Lb(self)
+
+    def Ub(self) -> "double":
+        return _pywraplp.Variable_Ub(self)
+
+    def SetLb(self, x: "double") -> "void":
+        return _pywraplp.Variable_SetLb(self, x)
+
+    def SetUb(self, x: "double") -> "void":
+        return _pywraplp.Variable_SetUb(self, x)
+
+    def ReducedCost(self) -> "double":
+        return _pywraplp.Variable_ReducedCost(self)
+    __swig_destroy__ = _pywraplp.delete_Variable
+
+ +
+ +

The class for variables of a Mathematical Programming (MP) model.

+
+ + +
+
#   + + + Variable(*args, **kwargs) +
+ +
+ View Source +
    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + + def + name(self) -> 'std::string const &': +
+ +
+ View Source +
    def name(self) -> "std::string const &":
+        r""" Returns the name of the variable."""
+        return _pywraplp.Variable_name(self)
+
+ +
+ +

Returns the name of the variable.

+
+ + +
+
+
#   + + + def + SetInteger(self, integer: bool) -> 'void': +
+ +
+ View Source +
    def SetInteger(self, integer: "bool") -> "void":
+        r""" Sets the integrality requirement of the variable."""
+        return _pywraplp.Variable_SetInteger(self, integer)
+
+ +
+ +

Sets the integrality requirement of the variable.

+
+ + +
+
+
#   + + + def + integer(self) -> bool: +
+ +
+ View Source +
    def integer(self) -> "bool":
+        r""" Returns the integrality requirement of the variable."""
+        return _pywraplp.Variable_integer(self)
+
+ +
+ +

Returns the integrality requirement of the variable.

+
+ + +
+
+
#   + + + def + solution_value(self) -> 'double': +
+ +
+ View Source +
    def solution_value(self) -> "double":
+        r"""
+        Returns the value of the variable in the current solution.
+
+        If the variable is integer, then the value will always be an integer (the
+        underlying solver handles floating-point values only, but this function
+        automatically rounds it to the nearest integer; see: man 3 round).
+        """
+        return _pywraplp.Variable_solution_value(self)
+
+ +
+ +

Returns the value of the variable in the current solution.

+ +

If the variable is integer, then the value will always be an integer (the +underlying solver handles floating-point values only, but this function +automatically rounds it to the nearest integer; see: man 3 round).

+
+ + +
+
+
#   + + + def + index(self) -> int: +
+ +
+ View Source +
    def index(self) -> "int":
+        r""" Returns the index of the variable in the MPSolver::variables_."""
+        return _pywraplp.Variable_index(self)
+
+ +
+ +

Returns the index of the variable in the MPSolver::variables_.

+
+ + +
+
+
#   + + + def + lb(self) -> 'double': +
+ +
+ View Source +
    def lb(self) -> "double":
+        r""" Returns the lower bound."""
+        return _pywraplp.Variable_lb(self)
+
+ +
+ +

Returns the lower bound.

+
+ + +
+
+
#   + + + def + ub(self) -> 'double': +
+ +
+ View Source +
    def ub(self) -> "double":
+        r""" Returns the upper bound."""
+        return _pywraplp.Variable_ub(self)
+
+ +
+ +

Returns the upper bound.

+
+ + +
+
+
#   + + + def + SetBounds(self, lb: 'double', ub: 'double') -> 'void': +
+ +
+ View Source +
    def SetBounds(self, lb: "double", ub: "double") -> "void":
+        r""" Sets both the lower and upper bounds."""
+        return _pywraplp.Variable_SetBounds(self, lb, ub)
+
+ +
+ +

Sets both the lower and upper bounds.

+
+ + +
+
+
#   + + + def + reduced_cost(self) -> 'double': +
+ +
+ View Source +
    def reduced_cost(self) -> "double":
+        r"""
+        Advanced usage: returns the reduced cost of the variable in the current
+        solution (only available for continuous problems).
+        """
+        return _pywraplp.Variable_reduced_cost(self)
+
+ +
+ +

Advanced usage: returns the reduced cost of the variable in the current solution (only available for continuous problems).

-

See also: MPSolver::BasisStatus.

-
- -Expand source code - -
def basis_status(self) -> "operations_research::MPSolver::BasisStatus":
-    r"""
-    Advanced usage: returns the basis status of the variable in the current
-    solution (only available for continuous problems).
+
- See also: MPSolver::BasisStatus. - """ - return _pywraplp.Variable_basis_status(self) - - -
-def branching_priority(self) ‑> int -
-
-

Advanced usage: Certain MIP solvers (e.g. Gurobi or SCIP) allow you to set + +

+
+
#   + + + def + basis_status(self) -> 'operations_research::MPSolver::BasisStatus': +
+ +
+ View Source +
    def basis_status(self) -> "operations_research::MPSolver::BasisStatus":
+        r"""
+        Advanced usage: returns the basis status of the variable in the current
+        solution (only available for continuous problems).
+
+        See also: MPSolver::BasisStatus.
+        """
+        return _pywraplp.Variable_basis_status(self)
+
+ +
+ +

Advanced usage: returns the basis status of the variable in the current +solution (only available for continuous problems).

+ +

See also: MPSolver::BasisStatus.

+
+ + +
+
+
#   + + + def + branching_priority(self) -> int: +
+ +
+ View Source +
    def branching_priority(self) -> "int":
+        r"""
+        Advanced usage: Certain MIP solvers (e.g. Gurobi or SCIP) allow you to set
+        a per-variable priority for determining which variable to branch on.
+
+        A value of 0 is treated as default, and is equivalent to not setting the
+        branching priority. The solver looks first to branch on fractional
+        variables in higher priority levels. As of 2019-05, only Gurobi and SCIP
+        support setting branching priority; all other solvers will simply ignore
+        this annotation.
+        """
+        return _pywraplp.Variable_branching_priority(self)
+
+ +
+ +

Advanced usage: Certain MIP solvers (e.g. Gurobi or SCIP) allow you to set a per-variable priority for determining which variable to branch on.

+

A value of 0 is treated as default, and is equivalent to not setting the branching priority. The solver looks first to branch on fractional variables in higher priority levels. As of 2019-05, only Gurobi and SCIP support setting branching priority; all other solvers will simply ignore -this annotation.

-
- -Expand source code - -
def branching_priority(self) -> "int":
-    r"""
-    Advanced usage: Certain MIP solvers (e.g. Gurobi or SCIP) allow you to set
-    a per-variable priority for determining which variable to branch on.
-
-    A value of 0 is treated as default, and is equivalent to not setting the
-    branching priority. The solver looks first to branch on fractional
-    variables in higher priority levels. As of 2019-05, only Gurobi and SCIP
-    support setting branching priority; all other solvers will simply ignore
-    this annotation.
-    """
-    return _pywraplp.Variable_branching_priority(self)
-
-
-
-def index(self) ‑> int -
-
-

Returns the index of the variable in the MPSolver::variables_.

-
- -Expand source code - -
def index(self) -> "int":
-    r""" Returns the index of the variable in the MPSolver::variables_."""
-    return _pywraplp.Variable_index(self)
-
-
-
-def integer(self) ‑> bool -
-
-

Returns the integrality requirement of the variable.

-
- -Expand source code - -
def integer(self) -> "bool":
-    r""" Returns the integrality requirement of the variable."""
-    return _pywraplp.Variable_integer(self)
-
-
-
-def lb(self) ‑> double -
-
-

Returns the lower bound.

-
- -Expand source code - -
def lb(self) -> "double":
-    r""" Returns the lower bound."""
-    return _pywraplp.Variable_lb(self)
-
-
-
-def name(self) ‑> std::string const & -
-
-

Returns the name of the variable.

-
- -Expand source code - -
def name(self) -> "std::string const &":
-    r""" Returns the name of the variable."""
-    return _pywraplp.Variable_name(self)
-
-
-
-def reduced_cost(self) ‑> double -
-
-

Advanced usage: returns the reduced cost of the variable in the current -solution (only available for continuous problems).

-
- -Expand source code - -
def reduced_cost(self) -> "double":
-    r"""
-    Advanced usage: returns the reduced cost of the variable in the current
-    solution (only available for continuous problems).
-    """
-    return _pywraplp.Variable_reduced_cost(self)
-
-
-
-def solution_value(self) ‑> double -
-
-

Returns the value of the variable in the current solution.

-

If the variable is integer, then the value will always be an integer (the -underlying solver handles floating-point values only, but this function -automatically rounds it to the nearest integer; see: man 3 round).

-
- -Expand source code - -
def solution_value(self) -> "double":
-    r"""
-    Returns the value of the variable in the current solution.
-
-    If the variable is integer, then the value will always be an integer (the
-    underlying solver handles floating-point values only, but this function
-    automatically rounds it to the nearest integer; see: man 3 round).
-    """
-    return _pywraplp.Variable_solution_value(self)
-
-
-
-def ub(self) ‑> double -
-
-

Returns the upper bound.

-
- -Expand source code - -
def ub(self) -> "double":
-    r""" Returns the upper bound."""
-    return _pywraplp.Variable_ub(self)
-
-
- - - -
-
- -
- + +

TODO(user): store the parameter values in a protocol buffer +instead. We need to figure out how to deal with the subtleties of +the default values.

+ + + +
+
#   + + + MPSolverParameters() +
+ +
+ View Source +
    def __init__(self):
+        r""" The constructor sets all parameters to their default value."""
+        _pywraplp.MPSolverParameters_swiginit(self, _pywraplp.new_MPSolverParameters())
+
+ +
+ +

The constructor sets all parameters to their default value.

+
+ + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
#   + + RELATIVE_MIP_GAP = 0 +
+ +

Limit for relative MIP gap.

+
+ + +
+
+
#   + + PRIMAL_TOLERANCE = 1 +
+ +

Advanced usage: tolerance for primal feasibility of basic solutions.

+ +

This does not control the integer feasibility tolerance of integer +solutions for MIP or the tolerance used during presolve.

+
+ + +
+
+
#   + + DUAL_TOLERANCE = 2 +
+ +

Advanced usage: tolerance for dual feasibility of basic solutions.

+
+ + +
+
+
#   + + PRESOLVE = 1000 +
+ +

Advanced usage: presolve mode.

+
+ + +
+
+
#   + + LP_ALGORITHM = 1001 +
+ +

Algorithm to solve linear programs.

+
+ + +
+
+
#   + + INCREMENTALITY = 1002 +
+ +

Advanced usage: incrementality from one solve to the next.

+
+ + +
+
+
#   + + SCALING = 1003 +
+ +

Advanced usage: enable or disable matrix scaling.

+
+ + +
+
+
#   + + PRESOLVE_OFF = 0 +
+ +

Presolve is off.

+
+ + +
+
+
#   + + PRESOLVE_ON = 1 +
+ +

Presolve is on.

+
+ + +
+
+
#   + + DUAL = 10 +
+ +

Dual simplex.

+
+ + +
+
+
#   + + PRIMAL = 11 +
+ +

Primal simplex.

+
+ + +
+
+
#   + + BARRIER = 12 +
+ +

Barrier algorithm.

+
+ + +
+
+
#   + + INCREMENTALITY_OFF = 0 +
+ +

Start solve from scratch.

+
+ + +
+
+
#   + + INCREMENTALITY_ON = 1 +
+ +

Reuse results from previous solve as much as the underlying solver +allows.

+
+ + +
+
+
#   + + SCALING_OFF = 0 +
+ +

Scaling is off.

+
+ + +
+
+
#   + + SCALING_ON = 1 +
+ +

Scaling is on.

+
+ + +
+
+
#   + + + def + SetDoubleParam( + self, + param: 'operations_research::MPSolverParameters::DoubleParam', + value: 'double' +) -> 'void': +
+ +
+ View Source +
    def SetDoubleParam(self, param: "operations_research::MPSolverParameters::DoubleParam", value: "double") -> "void":
+        r""" Sets a double parameter to a specific value."""
+        return _pywraplp.MPSolverParameters_SetDoubleParam(self, param, value)
+
+ +
+ +

Sets a double parameter to a specific value.

+
+ + +
+
+
#   + + + def + SetIntegerParam( + self, + param: 'operations_research::MPSolverParameters::IntegerParam', + value: int +) -> 'void': +
+ +
+ View Source +
    def SetIntegerParam(self, param: "operations_research::MPSolverParameters::IntegerParam", value: "int") -> "void":
+        r""" Sets a integer parameter to a specific value."""
+        return _pywraplp.MPSolverParameters_SetIntegerParam(self, param, value)
+
+ +
+ +

Sets a integer parameter to a specific value.

+
+ + +
+
+
#   + + + def + GetDoubleParam( + self, + param: 'operations_research::MPSolverParameters::DoubleParam' +) -> 'double': +
+ +
+ View Source +
    def GetDoubleParam(self, param: "operations_research::MPSolverParameters::DoubleParam") -> "double":
+        r""" Returns the value of a double parameter."""
+        return _pywraplp.MPSolverParameters_GetDoubleParam(self, param)
+
+ +
+ +

Returns the value of a double parameter.

+
+ + +
+
+
#   + + + def + GetIntegerParam( + self, + param: 'operations_research::MPSolverParameters::IntegerParam' +) -> int: +
+ +
+ View Source +
    def GetIntegerParam(self, param: "operations_research::MPSolverParameters::IntegerParam") -> "int":
+        r""" Returns the value of an integer parameter."""
+        return _pywraplp.MPSolverParameters_GetIntegerParam(self, param)
+
+ +
+ +

Returns the value of an integer parameter.

+
+ + +
+
+
#   + + kDefaultRelativeMipGap = 0.0001 +
+ + + +
+
+
#   + + kDefaultPrimalTolerance = 1e-07 +
+ + + +
+
+
#   + + kDefaultDualTolerance = 1e-07 +
+ + + +
+
+
#   + + kDefaultPresolve = 1 +
+ + + +
+
+
#   + + kDefaultIncrementality = 1 +
+ + + +
+ +
+
+ #   + + + class + ModelExportOptions: +
+ +
+ View Source +
class ModelExportOptions(object):
+    r""" Export options."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self):
+        _pywraplp.ModelExportOptions_swiginit(self, _pywraplp.new_ModelExportOptions())
+    __swig_destroy__ = _pywraplp.delete_ModelExportOptions
+
+ +
+ +

Export options.

+
+ + +
+
#   + + + ModelExportOptions() +
+ +
+ View Source +
    def __init__(self):
+        _pywraplp.ModelExportOptions_swiginit(self, _pywraplp.new_ModelExportOptions())
+
+ +
+ + + +
+
+
#   + + thisown +
+ +

The membership flag

+
+ + +
+
+
+
#   + + + def + ExportModelAsLpFormat(*args) -> 'std::string': +
+ +
+ View Source +
def ExportModelAsLpFormat(*args) -> "std::string":
+    return _pywraplp.ExportModelAsLpFormat(*args)
+
+ +
+ + + +
+
+
#   + + + def + ExportModelAsMpsFormat(*args) -> 'std::string': +
+ +
+ View Source +
def ExportModelAsMpsFormat(*args) -> "std::string":
+    return _pywraplp.ExportModelAsMpsFormat(*args)
+
+ +
+ + + +
+
+
#   + + + def + FindErrorInModelProto( + input_model: 'operations_research::MPModelProto const &' +) -> 'std::string': +
+ +
+ View Source +
def FindErrorInModelProto(input_model: "operations_research::MPModelProto const &") -> "std::string":
+    return _pywraplp.FindErrorInModelProto(input_model)
+
+ +
+ + + +
+
+
#   + + + def + setup_variable_operator(opname): +
+ +
+ View Source +
def setup_variable_operator(opname):
+  setattr(Variable, opname,
+          lambda self, *args: getattr(VariableExpr(self), opname)(*args))
+
+ +
+ + + +
+ \ No newline at end of file diff --git a/docs/python/ortools/sat/python/cp_model.html b/docs/python/ortools/sat/python/cp_model.html index 5255809aa7..80bde6b5af 100644 --- a/docs/python/ortools/sat/python/cp_model.html +++ b/docs/python/ortools/sat/python/cp_model.html @@ -1,5711 +1,8815 @@ - - - -cp_model API documentation - - - - - - - - - - - + + + + ortools.sat.python.cp_model API documentation + + + + + + - -
-
-
-

Module cp_model

-
-
-

Methods for building and solving CP-SAT models.

+ +
+
+

+ortools.sat.python.cp_model

+ +

Methods for building and solving CP-SAT models.

+

The following two sections describe the main methods for building and solving CP-SAT models.

+
    -
  • CpModel: Methods for creating +
  • CpModel: Methods for creating models, including variables and constraints.
  • CPSolver: Methods for solving a model and evaluating solutions.
+

The following methods implement callbacks that the solver calls each time it finds a new solution.

+ +

Additional methods for solving CP-SAT models:

+
    -
  • Constraint: A few utility methods for modifying -constraints created by CpModel.
  • -
  • LinearExpr: Methods for creating constraints +
  • Constraint: A few utility methods for modifying +constraints created by CpModel.
  • +
  • LinearExpr: Methods for creating constraints and the objective from large arrays of coefficients.
+

Other methods and functions listed are primarily used for developing OR-Tools, rather than for solving specific optimization problems.

-
- -Expand source code - -
# Copyright 2010-2021 Google LLC
-# 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
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-"""Methods for building and solving CP-SAT models.
-
-The following two sections describe the main
-methods for building and solving CP-SAT models.
-
-* [`CpModel`](#cp_model.CpModel): Methods for creating
-models, including variables and constraints.
-* [`CPSolver`](#cp_model.CpSolver): Methods for solving
-a model and evaluating solutions.
-
-The following methods implement callbacks that the
-solver calls each time it finds a new solution.
-
-* [`CpSolverSolutionCallback`](#cp_model.CpSolverSolutionCallback):
-  A general method for implementing callbacks.
-* [`ObjectiveSolutionPrinter`](#cp_model.ObjectiveSolutionPrinter):
-  Print objective values and elapsed time for intermediate solutions.
-* [`VarArraySolutionPrinter`](#cp_model.VarArraySolutionPrinter):
-  Print intermediate solutions (variable values, time).
-* [`VarArrayAndObjectiveSolutionPrinter`]
-      (#cp_model.VarArrayAndObjectiveSolutionPrinter):
-  Print both intermediate solutions and objective values.
-
-Additional methods for solving CP-SAT models:
-
-* [`Constraint`](#cp_model.Constraint): A few utility methods for modifying
-  constraints created by `CpModel`.
-* [`LinearExpr`](#lineacp_model.LinearExpr): Methods for creating constraints
-  and the objective from large arrays of coefficients.
-
-Other methods and functions listed are primarily used for developing OR-Tools,
-rather than for solving specific optimization problems.
-"""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import collections
-import numbers
-import threading
-import time
-
-from ortools.sat import cp_model_pb2
-from ortools.sat import sat_parameters_pb2
-from ortools.sat.python import cp_model_helper
-from ortools.sat import pywrapsat
-from ortools.util import sorted_interval_list
-
-Domain = sorted_interval_list.Domain
-
-# Documentation cleaning.
-# Remove the documentation of some functions.
-# See https://pdoc3.github.io/pdoc/doc/pdoc/#overriding-docstrings-with-
-__pdoc__ = {}
-__pdoc__['DisplayBounds'] = False
-__pdoc__['EvaluateLinearExpr'] = False
-__pdoc__['EvaluateBooleanExpression'] = False
-__pdoc__['ShortName'] = False
-
-# The classes below allow linear expressions to be expressed naturally with the
-# usual arithmetic operators +-*/ and with constant numbers, which makes the
-# python API very intuitive. See ../samples/*.py for examples.
-
-INT_MIN = -9223372036854775808  # hardcoded to be platform independent.
-INT_MAX = 9223372036854775807
-INT32_MAX = 2147483647
-INT32_MIN = -2147483648
-
-# CpSolver status (exported to avoid importing cp_model_cp2).
-UNKNOWN = cp_model_pb2.UNKNOWN
-MODEL_INVALID = cp_model_pb2.MODEL_INVALID
-FEASIBLE = cp_model_pb2.FEASIBLE
-INFEASIBLE = cp_model_pb2.INFEASIBLE
-OPTIMAL = cp_model_pb2.OPTIMAL
-
-# Variable selection strategy
-CHOOSE_FIRST = cp_model_pb2.DecisionStrategyProto.CHOOSE_FIRST
-CHOOSE_LOWEST_MIN = cp_model_pb2.DecisionStrategyProto.CHOOSE_LOWEST_MIN
-CHOOSE_HIGHEST_MAX = cp_model_pb2.DecisionStrategyProto.CHOOSE_HIGHEST_MAX
-CHOOSE_MIN_DOMAIN_SIZE = (
-    cp_model_pb2.DecisionStrategyProto.CHOOSE_MIN_DOMAIN_SIZE)
-CHOOSE_MAX_DOMAIN_SIZE = (
-    cp_model_pb2.DecisionStrategyProto.CHOOSE_MAX_DOMAIN_SIZE)
-
-# Domain reduction strategy
-SELECT_MIN_VALUE = cp_model_pb2.DecisionStrategyProto.SELECT_MIN_VALUE
-SELECT_MAX_VALUE = cp_model_pb2.DecisionStrategyProto.SELECT_MAX_VALUE
-SELECT_LOWER_HALF = cp_model_pb2.DecisionStrategyProto.SELECT_LOWER_HALF
-SELECT_UPPER_HALF = cp_model_pb2.DecisionStrategyProto.SELECT_UPPER_HALF
-
-# Search branching
-AUTOMATIC_SEARCH = sat_parameters_pb2.SatParameters.AUTOMATIC_SEARCH
-FIXED_SEARCH = sat_parameters_pb2.SatParameters.FIXED_SEARCH
-PORTFOLIO_SEARCH = sat_parameters_pb2.SatParameters.PORTFOLIO_SEARCH
-LP_SEARCH = sat_parameters_pb2.SatParameters.LP_SEARCH
-
-
-def DisplayBounds(bounds):
-    """Displays a flattened list of intervals."""
-    out = ''
-    for i in range(0, len(bounds), 2):
-        if i != 0:
-            out += ', '
-        if bounds[i] == bounds[i + 1]:
-            out += str(bounds[i])
-        else:
-            out += str(bounds[i]) + '..' + str(bounds[i + 1])
-    return out
-
-
-def ShortName(model, i):
-    """Returns a short name of an integer variable, or its negation."""
-    if i < 0:
-        return 'Not(%s)' % ShortName(model, -i - 1)
-    v = model.variables[i]
-    if v.name:
-        return v.name
-    elif len(v.domain) == 2 and v.domain[0] == v.domain[1]:
-        return str(v.domain[0])
-    else:
-        return '[%s]' % DisplayBounds(v.domain)
-
-
-class LinearExpr(object):
-    """Holds an integer linear expression.
-
-  A linear expression is built from integer constants and variables.
-  For example, x + 2 * (y - z + 1).
-
-  Linear expressions are used in CP-SAT models in two ways:
-
-  * To define constraints. For example
-
-      model.Add(x + 2 * y <= 5)
-      model.Add(sum(array_of_vars) == 5)
-
-  * To define the objective function. For example
-
-      model.Minimize(x + 2 * y + z)
-
-  For large arrays, you can create constraints and the objective
-  from lists of linear expressions or coefficients as follows:
-
-      model.Minimize(cp_model.LinearExpr.Sum(expressions))
-      model.Add(cp_model.LinearExpr.ScalProd(expressions, coefficients) >= 0)
-  """
-
-    @classmethod
-    def Sum(cls, expressions):
-        """Creates the expression sum(expressions)."""
-        return _SumArray(expressions)
-
-    @classmethod
-    def ScalProd(cls, expressions, coefficients):
-        """Creates the expression sum(expressions[i] * coefficients[i])."""
-        return _ScalProd(expressions, coefficients)
-
-    @classmethod
-    def Term(cls, expression, coefficient):
-        """Creates `expression * coefficient`."""
-        return expression * coefficient
-
-    def GetVarValueMap(self):
-        """Scans the expression, and return a list of (var_coef_map, constant)."""
-        coeffs = collections.defaultdict(int)
-        constant = 0
-        to_process = [(self, 1)]
-        while to_process:  # Flatten to avoid recursion.
-            expr, coef = to_process.pop()
-            if isinstance(expr, _ProductCst):
-                to_process.append(
-                    (expr.Expression(), coef * expr.Coefficient()))
-            elif isinstance(expr, _SumArray):
-                for e in expr.Expressions():
-                    to_process.append((e, coef))
-                constant += expr.Constant() * coef
-            elif isinstance(expr, _ScalProd):
-                for e, c in zip(expr.Expressions(), expr.Coefficients()):
-                    to_process.append((e, coef * c))
-                constant += expr.Constant() * coef
-            elif isinstance(expr, IntVar):
-                coeffs[expr] += coef
-            elif isinstance(expr, _NotBooleanVariable):
-                constant += coef
-                coeffs[expr.Not()] -= coef
-            else:
-                raise TypeError('Unrecognized linear expression: ' + str(expr))
-
-        return coeffs, constant
-
-    def __hash__(self):
-        return object.__hash__(self)
-
-    def __abs__(self):
-        raise NotImplementedError(
-            'calling abs() on a linear expression is not supported, '
-            'please use CpModel.AddAbsEquality')
-
-    def __add__(self, expr):
-        return _SumArray([self, expr])
-
-    def __radd__(self, arg):
-        return _SumArray([self, arg])
-
-    def __sub__(self, expr):
-        return _SumArray([self, -expr])
-
-    def __rsub__(self, arg):
-        return _SumArray([-self, arg])
-
-    def __mul__(self, arg):
-        if isinstance(arg, numbers.Integral):
-            if arg == 1:
-                return self
-            elif arg == 0:
-                return 0
-            cp_model_helper.AssertIsInt64(arg)
-            return _ProductCst(self, arg)
-        else:
-            raise TypeError('Not an integer linear expression: ' + str(arg))
-
-    def __rmul__(self, arg):
-        cp_model_helper.AssertIsInt64(arg)
-        if arg == 1:
-            return self
-        return _ProductCst(self, arg)
-
-    def __div__(self, _):
-        raise NotImplementedError(
-            'calling / on a linear expression is not supported, '
-            'please use CpModel.AddDivisionEquality')
-
-    def __truediv__(self, _):
-        raise NotImplementedError(
-            'calling // on a linear expression is not supported, '
-            'please use CpModel.AddDivisionEquality')
-
-    def __mod__(self, _):
-        raise NotImplementedError(
-            'calling %% on a linear expression is not supported, '
-            'please use CpModel.AddModuloEquality')
-
-    def __pow__(self, _):
-        raise NotImplementedError(
-            'calling ** on a linear expression is not supported, '
-            'please use CpModel.AddMultiplicationEquality')
-
-    def __lshift__(self, _):
-        raise NotImplementedError(
-            'calling left shift on a linear expression is not supported')
-
-    def __rshift__(self, _):
-        raise NotImplementedError(
-            'calling right shift on a linear expression is not supported')
-
-    def __and__(self, _):
-        raise NotImplementedError(
-            'calling and on a linear expression is not supported, '
-            'please use CpModel.AddBoolAnd')
-
-    def __or__(self, _):
-        raise NotImplementedError(
-            'calling or on a linear expression is not supported, '
-            'please use CpModel.AddBoolOr')
-
-    def __xor__(self, _):
-        raise NotImplementedError(
-            'calling xor on a linear expression is not supported, '
-            'please use CpModel.AddBoolXor')
-
-    def __neg__(self):
-        return _ProductCst(self, -1)
-
-    def __bool__(self):
-        raise NotImplementedError(
-            'Evaluating a LinearExpr instance as a Boolean is not implemented.')
-
-    def __eq__(self, arg):
-        if arg is None:
-            return False
-        if isinstance(arg, numbers.Integral):
-            cp_model_helper.AssertIsInt64(arg)
-            return BoundedLinearExpression(self, [arg, arg])
-        else:
-            return BoundedLinearExpression(self - arg, [0, 0])
-
-    def __ge__(self, arg):
-        if isinstance(arg, numbers.Integral):
-            cp_model_helper.AssertIsInt64(arg)
-            return BoundedLinearExpression(self, [arg, INT_MAX])
-        else:
-            return BoundedLinearExpression(self - arg, [0, INT_MAX])
-
-    def __le__(self, arg):
-        if isinstance(arg, numbers.Integral):
-            cp_model_helper.AssertIsInt64(arg)
-            return BoundedLinearExpression(self, [INT_MIN, arg])
-        else:
-            return BoundedLinearExpression(self - arg, [INT_MIN, 0])
-
-    def __lt__(self, arg):
-        if isinstance(arg, numbers.Integral):
-            cp_model_helper.AssertIsInt64(arg)
-            if arg == INT_MIN:
-                raise ArithmeticError('< INT_MIN is not supported')
-            return BoundedLinearExpression(self, [INT_MIN, arg - 1])
-        else:
-            return BoundedLinearExpression(self - arg, [INT_MIN, -1])
-
-    def __gt__(self, arg):
-        if isinstance(arg, numbers.Integral):
-            cp_model_helper.AssertIsInt64(arg)
-            if arg == INT_MAX:
-                raise ArithmeticError('> INT_MAX is not supported')
-            return BoundedLinearExpression(self, [arg + 1, INT_MAX])
-        else:
-            return BoundedLinearExpression(self - arg, [1, INT_MAX])
-
-    def __ne__(self, arg):
-        if arg is None:
-            return True
-        if isinstance(arg, numbers.Integral):
-            cp_model_helper.AssertIsInt64(arg)
-            if arg == INT_MAX:
-                return BoundedLinearExpression(self, [INT_MIN, INT_MAX - 1])
-            elif arg == INT_MIN:
-                return BoundedLinearExpression(self, [INT_MIN + 1, INT_MAX])
-            else:
-                return BoundedLinearExpression(
-                    self, [INT_MIN, arg - 1, arg + 1, INT_MAX])
-        else:
-            return BoundedLinearExpression(self - arg,
-                                           [INT_MIN, -1, 1, INT_MAX])
-
-
-class _ProductCst(LinearExpr):
-    """Represents the product of a LinearExpr by a constant."""
-
-    def __init__(self, expr, coef):
-        cp_model_helper.AssertIsInt64(coef)
-        if isinstance(expr, _ProductCst):
-            self.__expr = expr.Expression()
-            self.__coef = expr.Coefficient() * coef
-        else:
-            self.__expr = expr
-            self.__coef = coef
-
-    def __str__(self):
-        if self.__coef == -1:
-            return '-' + str(self.__expr)
-        else:
-            return '(' + str(self.__coef) + ' * ' + str(self.__expr) + ')'
-
-    def __repr__(self):
-        return 'ProductCst(' + repr(self.__expr) + ', ' + repr(
-            self.__coef) + ')'
-
-    def Coefficient(self):
-        return self.__coef
-
-    def Expression(self):
-        return self.__expr
-
-
-class _SumArray(LinearExpr):
-    """Represents the sum of a list of LinearExpr and a constant."""
-
-    def __init__(self, expressions):
-        self.__expressions = []
-        self.__constant = 0
-        for x in expressions:
-            if isinstance(x, numbers.Integral):
-                cp_model_helper.AssertIsInt64(x)
-                self.__constant += x
-            elif isinstance(x, LinearExpr):
-                self.__expressions.append(x)
-            else:
-                raise TypeError('Not an linear expression: ' + str(x))
-
-    def __str__(self):
-        if self.__constant == 0:
-            return '({})'.format(' + '.join(map(str, self.__expressions)))
-        else:
-            return '({} + {})'.format(' + '.join(map(str, self.__expressions)),
-                                      self.__constant)
-
-    def __repr__(self):
-        return 'SumArray({}, {})'.format(
-            ', '.join(map(repr, self.__expressions)), self.__constant)
-
-    def Expressions(self):
-        return self.__expressions
-
-    def Constant(self):
-        return self.__constant
-
-
-class _ScalProd(LinearExpr):
-    """Represents the scalar product of expressions with constants and a constant."""
-
-    def __init__(self, expressions, coefficients):
-        self.__expressions = []
-        self.__coefficients = []
-        self.__constant = 0
-        if len(expressions) != len(coefficients):
-            raise TypeError(
-                'In the LinearExpr.ScalProd method, the expression array and the '
-                ' coefficient array must have the same length.')
-        for e, c in zip(expressions, coefficients):
-            cp_model_helper.AssertIsInt64(c)
-            if c == 0:
-                continue
-            if isinstance(e, numbers.Integral):
-                cp_model_helper.AssertIsInt64(e)
-                self.__constant += e * c
-            elif isinstance(e, LinearExpr):
-                self.__expressions.append(e)
-                self.__coefficients.append(c)
-            else:
-                raise TypeError('Not an linear expression: ' + str(e))
-
-    def __str__(self):
-        output = None
-        for expr, coeff in zip(self.__expressions, self.__coefficients):
-            if not output and coeff == 1:
-                output = str(expr)
-            elif not output and coeff == -1:
-                output = '-' + str(expr)
-            elif not output:
-                output = '{} * {}'.format(coeff, str(expr))
-            elif coeff == 1:
-                output += ' + {}'.format(str(expr))
-            elif coeff == -1:
-                output += ' - {}'.format(str(expr))
-            elif coeff > 1:
-                output += ' + {} * {}'.format(coeff, str(expr))
-            elif coeff < -1:
-                output += ' - {} * {}'.format(-coeff, str(expr))
-        if self.__constant > 0:
-            output += ' + {}'.format(self.__constant)
-        elif self.__constant < 0:
-            output += ' - {}'.format(-self.__constant)
-        return output
-
-    def __repr__(self):
-        return 'ScalProd([{}], [{}], {})'.format(
-            ', '.join(map(repr, self.__expressions)),
-            ', '.join(map(repr, self.__coefficients)), self.__constant)
-
-    def Expressions(self):
-        return self.__expressions
-
-    def Coefficients(self):
-        return self.__coefficients
-
-    def Constant(self):
-        return self.__constant
-
-
-class IntVar(LinearExpr):
-    """An integer variable.
-
-  An IntVar is an object that can take on any integer value within defined
-  ranges. Variables appear in constraint like:
-
-      x + y >= 5
-      AllDifferent([x, y, z])
-
-  Solving a model is equivalent to finding, for each variable, a single value
-  from the set of initial values (called the initial domain), such that the
-  model is feasible, or optimal if you provided an objective function.
-  """
-
-    def __init__(self, model, domain, name):
-        """See CpModel.NewIntVar below."""
-        self.__model = model
-        self.__negation = None
-        # Python do not support multiple __init__ methods.
-        # This method is only called from the CpModel class.
-        # We hack the parameter to support the two cases:
-        # case 1:
-        #     model is a CpModelProto, domain is a Domain, and name is a string.
-        # case 2:
-        #     model is a CpModelProto, domain is an index (int), and name is None.
-        if isinstance(domain, numbers.Integral) and name is None:
-            self.__index = domain
-            self.__var = model.variables[domain]
-        else:
-            self.__index = len(model.variables)
-            self.__var = model.variables.add()
-            self.__var.domain.extend(domain.FlattenedIntervals())
-            self.__var.name = name
-
-    def Index(self):
-        """Returns the index of the variable in the model."""
-        return self.__index
-
-    def Proto(self):
-        """Returns the variable protobuf."""
-        return self.__var
-
-    def IsEqualTo(self, other):
-        """Returns true if self == other in the python sense."""
-        if not isinstance(other, IntVar):
-            return False
-        return self.Index() == other.Index()
-
-    def __str__(self):
-        if not self.__var.name:
-            if len(self.__var.domain
-                  ) == 2 and self.__var.domain[0] == self.__var.domain[1]:
-                # Special case for constants.
-                return str(self.__var.domain[0])
-            else:
-                return 'unnamed_var_%i' % self.__index
-        return self.__var.name
-
-    def __repr__(self):
-        return '%s(%s)' % (self.__var.name, DisplayBounds(self.__var.domain))
-
-    def Name(self):
-        return self.__var.name
-
-    def Not(self):
-        """Returns the negation of a Boolean variable.
-
-    This method implements the logical negation of a Boolean variable.
-    It is only valid if the variable has a Boolean domain (0 or 1).
-
-    Note that this method is nilpotent: `x.Not().Not() == x`.
-    """
-
-        for bound in self.__var.domain:
-            if bound < 0 or bound > 1:
-                raise TypeError(
-                    'Cannot call Not on a non boolean variable: %s' % self)
-        if self.__negation is None:
-            self.__negation = _NotBooleanVariable(self)
-        return self.__negation
-
-
-class _NotBooleanVariable(LinearExpr):
-    """Negation of a boolean variable."""
-
-    def __init__(self, boolvar):
-        self.__boolvar = boolvar
-
-    def Index(self):
-        return -self.__boolvar.Index() - 1
-
-    def Not(self):
-        return self.__boolvar
-
-    def __str__(self):
-        return 'not(%s)' % str(self.__boolvar)
-
-    def __bool__(self):
-        raise NotImplementedError(
-            'Evaluating a literal as a Boolean value is not implemented.')
-
-
-class BoundedLinearExpression(object):
-    """Represents a linear constraint: `lb <= linear expression <= ub`.
-
-  The only use of this class is to be added to the CpModel through
-  `CpModel.Add(expression)`, as in:
-
-      model.Add(x + 2 * y -1 >= z)
-  """
-
-    def __init__(self, expr, bounds):
-        self.__expr = expr
-        self.__bounds = bounds
-
-    def __str__(self):
-        if len(self.__bounds) == 2:
-            lb = self.__bounds[0]
-            ub = self.__bounds[1]
-            if lb > INT_MIN and ub < INT_MAX:
-                if lb == ub:
-                    return str(self.__expr) + ' == ' + str(lb)
-                else:
-                    return str(lb) + ' <= ' + str(
-                        self.__expr) + ' <= ' + str(ub)
-            elif lb > INT_MIN:
-                return str(self.__expr) + ' >= ' + str(lb)
-            elif ub < INT_MAX:
-                return str(self.__expr) + ' <= ' + str(ub)
-            else:
-                return 'True (unbounded expr ' + str(self.__expr) + ')'
-        else:
-            return str(self.__expr) + ' in [' + DisplayBounds(
-                self.__bounds) + ']'
-
-    def Expression(self):
-        return self.__expr
-
-    def Bounds(self):
-        return self.__bounds
-
-    def __bool__(self):
-        # Check for x == y
-        if self.__bounds == [0, 0]:
-            coeffs_map, constant = self.__expr.GetVarValueMap()
-            if constant != 0:
-                return False
-            for coeff in coeffs_map.values():
-                if coeff != 0:
-                    return False
-            return True
-        elif self.__bounds == [INT_MIN, -1, 1, INT_MAX]:
-            # Check for x != y
-            coeffs_map, constant = self.__expr.GetVarValueMap()
-            if constant != 0:
-                return True
-            for coeff in coeffs_map.values():
-                if coeff != 0:
-                    return True
-            return False
-
-        raise NotImplementedError(
-            'Evaluating a BoundedLinearExpr as a Boolean value is not supported.'
-        )
-
-
-class Constraint(object):
-    """Base class for constraints.
-
-  Constraints are built by the CpModel through the Add<XXX> methods.
-  Once created by the CpModel class, they are automatically added to the model.
-  The purpose of this class is to allow specification of enforcement literals
-  for this constraint.
-
-      b = model.NewBoolVar('b')
-      x = model.NewIntVar(0, 10, 'x')
-      y = model.NewIntVar(0, 10, 'y')
-
-      model.Add(x + 2 * y == 5).OnlyEnforceIf(b.Not())
-  """
-
-    def __init__(self, constraints):
-        self.__index = len(constraints)
-        self.__constraint = constraints.add()
-
-    def OnlyEnforceIf(self, boolvar):
-        """Adds an enforcement literal to the constraint.
-
-    This method adds one or more literals (that is, a boolean variable or its
-    negation) as enforcement literals. The conjunction of all these literals
-    determines whether the constraint is active or not. It acts as an
-    implication, so if the conjunction is true, it implies that the constraint
-    must be enforced. If it is false, then the constraint is ignored.
-
-    BoolOr, BoolAnd, and linear constraints all support enforcement literals.
-
-    Args:
-      boolvar: A boolean literal or a list of boolean literals.
-
-    Returns:
-      self.
-    """
-
-        if isinstance(boolvar, numbers.Integral) and boolvar == 1:
-            # Always true. Do nothing.
-            pass
-        elif isinstance(boolvar, list):
-            for b in boolvar:
-                if isinstance(b, numbers.Integral) and b == 1:
-                    pass
-                else:
-                    self.__constraint.enforcement_literal.append(b.Index())
-        else:
-            self.__constraint.enforcement_literal.append(boolvar.Index())
-        return self
-
-    def Index(self):
-        """Returns the index of the constraint in the model."""
-        return self.__index
-
-    def Proto(self):
-        """Returns the constraint protobuf."""
-        return self.__constraint
-
-
-class IntervalVar(object):
-    """Represents an Interval variable.
-
-  An interval variable is both a constraint and a variable. It is defined by
-  three integer variables: start, size, and end.
-
-  It is a constraint because, internally, it enforces that start + size == end.
-
-  It is also a variable as it can appear in specific scheduling constraints:
-  NoOverlap, NoOverlap2D, Cumulative.
-
-  Optionally, an enforcement literal can be added to this constraint, in which
-  case these scheduling constraints will ignore interval variables with
-  enforcement literals assigned to false. Conversely, these constraints will
-  also set these enforcement literals to false if they cannot fit these
-  intervals into the schedule.
-  """
-
-    def __init__(self, model, start_index, size_index, end_index,
-                 is_present_index, name):
-        self.__model = model
-        # As with the IntVar::__init__ method, we hack the __init__ method to
-        # support two use cases:
-        #   case 1: called when creating a new interval variable.
-        #      {start|size|end}_index are indices of integer variables
-        #      is_present_index is either None or the index of a Boolean literal.
-        #      name is a string
-        #   case 2: called when querying an existing interval variable.
-        #      start_index is an int, all parameters after are None.
-        if (size_index is None and end_index is None and
-                is_present_index is None and name is None):
-            self.__index = start_index
-            self.__ct = model.constraints[start_index]
-        else:
-            self.__index = len(model.constraints)
-            self.__ct = self.__model.constraints.add()
-            self.__ct.interval.start = start_index
-            self.__ct.interval.size = size_index
-            self.__ct.interval.end = end_index
-            if is_present_index is not None:
-                self.__ct.enforcement_literal.append(is_present_index)
-            if name:
-                self.__ct.name = name
-
-    def Index(self):
-        """Returns the index of the interval constraint in the model."""
-        return self.__index
-
-    def Proto(self):
-        """Returns the interval protobuf."""
-        return self.__ct.interval
-
-    def __str__(self):
-        return self.__ct.name
-
-    def __repr__(self):
-        interval = self.__ct.interval
-        if self.__ct.enforcement_literal:
-            return '%s(start = %s, size = %s, end = %s, is_present = %s)' % (
-                self.__ct.name, ShortName(self.__model, interval.start),
-                ShortName(self.__model,
-                          interval.size), ShortName(self.__model, interval.end),
-                ShortName(self.__model, self.__ct.enforcement_literal[0]))
-        else:
-            return '%s(start = %s, size = %s, end = %s)' % (
-                self.__ct.name, ShortName(self.__model, interval.start),
-                ShortName(self.__model,
-                          interval.size), ShortName(self.__model, interval.end))
-
-    def Name(self):
-        return self.__ct.name
-
-
-def ObjectIsATrueLiteral(literal):
-    """Checks if literal is either True, or a Boolean literals fixed to True."""
-    if isinstance(literal, IntVar):
-        proto = literal.Proto()
-        return (len(proto.domain) == 2 and proto.domain[0] == 1 and
-                proto.domain[1] == 1)
-    if isinstance(literal, _NotBooleanVariable):
-        proto = literal.Not().Proto()
-        return (len(proto.domain) == 2 and proto.domain[0] == 0 and
-                proto.domain[1] == 0)
-    if isinstance(literal, numbers.Integral):
-        return literal == 1
-    return False
-
-
-def ObjectIsAFalseLiteral(literal):
-    """Checks if literal is either False, or a Boolean literals fixed to False."""
-    if isinstance(literal, IntVar):
-        proto = literal.Proto()
-        return (len(proto.domain) == 2 and proto.domain[0] == 0 and
-                proto.domain[1] == 0)
-    if isinstance(literal, _NotBooleanVariable):
-        proto = literal.Not().Proto()
-        return (len(proto.domain) == 2 and proto.domain[0] == 1 and
-                proto.domain[1] == 1)
-    if isinstance(literal, numbers.Integral):
-        return literal == 0
-    return False
-
-
-class CpModel(object):
-    """Methods for building a CP model.
-
-  Methods beginning with:
-
-  * ```New``` create integer, boolean, or interval variables.
-  * ```Add``` create new constraints and add them to the model.
-  """
-
-    def __init__(self):
-        self.__model = cp_model_pb2.CpModelProto()
-        self.__constant_map = {}
-
-    # Integer variable.
-
-    def NewIntVar(self, lb, ub, name):
-        """Create an integer variable with domain [lb, ub].
-
-    The CP-SAT solver is limited to integer variables. If you have fractional
-    values, scale them up so that they become integers; if you have strings,
-    encode them as integers.
-
-    Args:
-      lb: Lower bound for the variable.
-      ub: Upper bound for the variable.
-      name: The name of the variable.
-
-    Returns:
-      a variable whose domain is [lb, ub].
-    """
-
-        return IntVar(self.__model, Domain(lb, ub), name)
-
-    def NewIntVarFromDomain(self, domain, name):
-        """Create an integer variable from a domain.
-
-    A domain is a set of integers specified by a collection of intervals.
-    For example, `model.NewIntVarFromDomain(cp_model.
-         Domain.FromIntervals([[1, 2], [4, 6]]), 'x')`
-
-    Args:
-      domain: An instance of the Domain class.
-      name: The name of the variable.
-
-    Returns:
-        a variable whose domain is the given domain.
-    """
-        return IntVar(self.__model, domain, name)
-
-    def NewBoolVar(self, name):
-        """Creates a 0-1 variable with the given name."""
-        return IntVar(self.__model, Domain(0, 1), name)
-
-    def NewConstant(self, value):
-        """Declares a constant integer."""
-        return IntVar(self.__model, self.GetOrMakeIndexFromConstant(value),
-                      None)
-
-    # Linear constraints.
-
-    def AddLinearConstraint(self, linear_expr, lb, ub):
-        """Adds the constraint: `lb <= linear_expr <= ub`."""
-        return self.AddLinearExpressionInDomain(linear_expr, Domain(lb, ub))
-
-    def AddLinearExpressionInDomain(self, linear_expr, domain):
-        """Adds the constraint: `linear_expr` in `domain`."""
-        if isinstance(linear_expr, LinearExpr):
-            ct = Constraint(self.__model.constraints)
-            model_ct = self.__model.constraints[ct.Index()]
-            coeffs_map, constant = linear_expr.GetVarValueMap()
-            for t in coeffs_map.items():
-                if not isinstance(t[0], IntVar):
-                    raise TypeError('Wrong argument' + str(t))
-                cp_model_helper.AssertIsInt64(t[1])
-                model_ct.linear.vars.append(t[0].Index())
-                model_ct.linear.coeffs.append(t[1])
-            model_ct.linear.domain.extend([
-                cp_model_helper.CapSub(x, constant)
-                for x in domain.FlattenedIntervals()
-            ])
-            return ct
-        elif isinstance(linear_expr, numbers.Integral):
-            if not domain.Contains(linear_expr):
-                return self.AddBoolOr([])  # Evaluate to false.
-            # Nothing to do otherwise.
-        else:
-            raise TypeError(
-                'Not supported: CpModel.AddLinearExpressionInDomain(' +
-                str(linear_expr) + ' ' + str(domain) + ')')
-
-    def Add(self, ct):
-        """Adds a `BoundedLinearExpression` to the model.
-
-    Args:
-      ct: A [`BoundedLinearExpression`](#boundedlinearexpression).
-
-    Returns:
-      An instance of the `Constraint` class.
-    """
-        if isinstance(ct, BoundedLinearExpression):
-            return self.AddLinearExpressionInDomain(
-                ct.Expression(), Domain.FromFlatIntervals(ct.Bounds()))
-        elif ct and isinstance(ct, bool):
-            return self.AddBoolOr([True])
-        elif not ct and isinstance(ct, bool):
-            return self.AddBoolOr([])  # Evaluate to false.
-        else:
-            raise TypeError('Not supported: CpModel.Add(' + str(ct) + ')')
-
-    # General Integer Constraints.
-
-    def AddAllDifferent(self, variables):
-        """Adds AllDifferent(variables).
-
-    This constraint forces all variables to have different values.
-
-    Args:
-      variables: a list of integer variables.
-
-    Returns:
-      An instance of the `Constraint` class.
-    """
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.all_diff.vars.extend(
-            [self.GetOrMakeIndex(x) for x in variables])
-        return ct
-
-    def AddElement(self, index, variables, target):
-        """Adds the element constraint: `variables[index] == target`."""
-
-        if not variables:
-            raise ValueError('AddElement expects a non-empty variables array')
-
-        if isinstance(index, numbers.Integral):
-            return self.Add(list(variables)[index] == target)
-
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.element.index = self.GetOrMakeIndex(index)
-        model_ct.element.vars.extend(
-            [self.GetOrMakeIndex(x) for x in variables])
-        model_ct.element.target = self.GetOrMakeIndex(target)
-        return ct
-
-    def AddCircuit(self, arcs):
-        """Adds Circuit(arcs).
-
-    Adds a circuit constraint from a sparse list of arcs that encode the graph.
-
-    A circuit is a unique Hamiltonian path in a subgraph of the total
-    graph. In case a node 'i' is not in the path, then there must be a
-    loop arc 'i -> i' associated with a true literal. Otherwise
-    this constraint will fail.
-
-    Args:
-      arcs: a list of arcs. An arc is a tuple (source_node, destination_node,
-        literal). The arc is selected in the circuit if the literal is true.
-        Both source_node and destination_node must be integers between 0 and the
-        number of nodes - 1.
-
-    Returns:
-      An instance of the `Constraint` class.
-
-    Raises:
-      ValueError: If the list of arcs is empty.
-    """
-        if not arcs:
-            raise ValueError('AddCircuit expects a non-empty array of arcs')
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        for arc in arcs:
-            cp_model_helper.AssertIsInt32(arc[0])
-            cp_model_helper.AssertIsInt32(arc[1])
-            lit = self.GetOrMakeBooleanIndex(arc[2])
-            model_ct.circuit.tails.append(arc[0])
-            model_ct.circuit.heads.append(arc[1])
-            model_ct.circuit.literals.append(lit)
-        return ct
-
-    def AddAllowedAssignments(self, variables, tuples_list):
-        """Adds AllowedAssignments(variables, tuples_list).
-
-    An AllowedAssignments constraint is a constraint on an array of variables,
-    which requires that when all variables are assigned values, the resulting
-    array equals one of the  tuples in `tuple_list`.
-
-    Args:
-      variables: A list of variables.
-      tuples_list: A list of admissible tuples. Each tuple must have the same
-        length as the variables, and the ith value of a tuple corresponds to the
-        ith variable.
-
-    Returns:
-      An instance of the `Constraint` class.
-
-    Raises:
-      TypeError: If a tuple does not have the same size as the list of
-          variables.
-      ValueError: If the array of variables is empty.
-    """
-
-        if not variables:
-            raise ValueError(
-                'AddAllowedAssignments expects a non-empty variables '
-                'array')
-
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.table.vars.extend([self.GetOrMakeIndex(x) for x in variables])
-        arity = len(variables)
-        for t in tuples_list:
-            if len(t) != arity:
-                raise TypeError('Tuple ' + str(t) + ' has the wrong arity')
-            for v in t:
-                cp_model_helper.AssertIsInt64(v)
-            model_ct.table.values.extend(t)
-        return ct
-
-    def AddForbiddenAssignments(self, variables, tuples_list):
-        """Adds AddForbiddenAssignments(variables, [tuples_list]).
-
-    A ForbiddenAssignments constraint is a constraint on an array of variables
-    where the list of impossible combinations is provided in the tuples list.
-
-    Args:
-      variables: A list of variables.
-      tuples_list: A list of forbidden tuples. Each tuple must have the same
-        length as the variables, and the *i*th value of a tuple corresponds to
-        the *i*th variable.
-
-    Returns:
-      An instance of the `Constraint` class.
-
-    Raises:
-      TypeError: If a tuple does not have the same size as the list of
-                 variables.
-      ValueError: If the array of variables is empty.
-    """
-
-        if not variables:
-            raise ValueError(
-                'AddForbiddenAssignments expects a non-empty variables '
-                'array')
-
-        index = len(self.__model.constraints)
-        ct = self.AddAllowedAssignments(variables, tuples_list)
-        self.__model.constraints[index].table.negated = True
-        return ct
-
-    def AddAutomaton(self, transition_variables, starting_state, final_states,
-                     transition_triples):
-        """Adds an automaton constraint.
-
-    An automaton constraint takes a list of variables (of size *n*), an initial
-    state, a set of final states, and a set of transitions. A transition is a
-    triplet (*tail*, *transition*, *head*), where *tail* and *head* are states,
-    and *transition* is the label of an arc from *head* to *tail*,
-    corresponding to the value of one variable in the list of variables.
-
-    This automaton will be unrolled into a flow with *n* + 1 phases. Each phase
-    contains the possible states of the automaton. The first state contains the
-    initial state. The last phase contains the final states.
-
-    Between two consecutive phases *i* and *i* + 1, the automaton creates a set
-    of arcs. For each transition (*tail*, *transition*, *head*), it will add
-    an arc from the state *tail* of phase *i* and the state *head* of phase
-    *i* + 1. This arc is labeled by the value *transition* of the variables
-    `variables[i]`. That is, this arc can only be selected if `variables[i]`
-    is assigned the value *transition*.
-
-    A feasible solution of this constraint is an assignment of variables such
-    that, starting from the initial state in phase 0, there is a path labeled by
-    the values of the variables that ends in one of the final states in the
-    final phase.
-
-    Args:
-      transition_variables: A non-empty list of variables whose values
-        correspond to the labels of the arcs traversed by the automaton.
-      starting_state: The initial state of the automaton.
-      final_states: A non-empty list of admissible final states.
-      transition_triples: A list of transitions for the automaton, in the
-        following format (current_state, variable_value, next_state).
-
-    Returns:
-      An instance of the `Constraint` class.
-
-    Raises:
-      ValueError: if `transition_variables`, `final_states`, or
-        `transition_triples` are empty.
-    """
-
-        if not transition_variables:
-            raise ValueError(
-                'AddAutomaton expects a non-empty transition_variables '
-                'array')
-        if not final_states:
-            raise ValueError('AddAutomaton expects some final states')
-
-        if not transition_triples:
-            raise ValueError('AddAutomaton expects some transition triples')
-
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.automaton.vars.extend(
-            [self.GetOrMakeIndex(x) for x in transition_variables])
-        cp_model_helper.AssertIsInt64(starting_state)
-        model_ct.automaton.starting_state = starting_state
-        for v in final_states:
-            cp_model_helper.AssertIsInt64(v)
-            model_ct.automaton.final_states.append(v)
-        for t in transition_triples:
-            if len(t) != 3:
-                raise TypeError('Tuple ' + str(t) +
-                                ' has the wrong arity (!= 3)')
-            cp_model_helper.AssertIsInt64(t[0])
-            cp_model_helper.AssertIsInt64(t[1])
-            cp_model_helper.AssertIsInt64(t[2])
-            model_ct.automaton.transition_tail.append(t[0])
-            model_ct.automaton.transition_label.append(t[1])
-            model_ct.automaton.transition_head.append(t[2])
-        return ct
-
-    def AddInverse(self, variables, inverse_variables):
-        """Adds Inverse(variables, inverse_variables).
-
-    An inverse constraint enforces that if `variables[i]` is assigned a value
-    `j`, then `inverse_variables[j]` is assigned a value `i`. And vice versa.
-
-    Args:
-      variables: An array of integer variables.
-      inverse_variables: An array of integer variables.
-
-    Returns:
-      An instance of the `Constraint` class.
-
-    Raises:
-      TypeError: if variables and inverse_variables have different lengths, or
-          if they are empty.
-    """
-
-        if not variables or not inverse_variables:
-            raise TypeError(
-                'The Inverse constraint does not accept empty arrays')
-        if len(variables) != len(inverse_variables):
-            raise TypeError(
-                'In the inverse constraint, the two array variables and'
-                ' inverse_variables must have the same length.')
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.inverse.f_direct.extend(
-            [self.GetOrMakeIndex(x) for x in variables])
-        model_ct.inverse.f_inverse.extend(
-            [self.GetOrMakeIndex(x) for x in inverse_variables])
-        return ct
-
-    def AddReservoirConstraint(self, times, demands, min_level, max_level):
-        """Adds Reservoir(times, demands, min_level, max_level).
-
-    Maintains a reservoir level within bounds. The water level starts at 0, and
-    at any time, it must be between min_level and max_level.
-
-    If the variable `times[i]` is assigned a value t, then the current level
-    changes by `demands[i]`, which is constant, at time t.
-
-     Note that min level must be <= 0, and the max level must be >= 0. Please
-     use fixed demands to simulate initial state.
-
-     Therefore, at any time:
-         sum(demands[i] if times[i] <= t) in [min_level, max_level]
-
-    Args:
-      times: A list of integer variables which specify the time of the
-        filling or emptying the reservoir.
-      demands: A list of integer values that specifies the amount of the
-        emptying or filling.
-      min_level: At any time, the level of the reservoir must be greater or
-        equal than the min level.
-      max_level: At any time, the level of the reservoir must be less or equal
-        than the max level.
-
-    Returns:
-      An instance of the `Constraint` class.
-
-    Raises:
-      ValueError: if max_level < min_level.
-
-      ValueError: if max_level < 0.
-
-      ValueError: if min_level > 0
-    """
-
-        if max_level < min_level:
-            return ValueError(
-                'Reservoir constraint must have a max_level >= min_level')
-
-        if max_level < 0:
-            return ValueError('Reservoir constraint must have a max_level >= 0')
-
-        if min_level > 0:
-            return ValueError('Reservoir constraint must have a min_level <= 0')
-
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.reservoir.times.extend([self.GetOrMakeIndex(x) for x in times])
-        model_ct.reservoir.demands.extend(demands)
-        model_ct.reservoir.min_level = min_level
-        model_ct.reservoir.max_level = max_level
-        return ct
-
-    def AddReservoirConstraintWithActive(self, times, demands, actives,
-                                         min_level, max_level):
-        """Adds Reservoir(times, demands, actives, min_level, max_level).
-
-    Maintains a reservoir level within bounds. The water level starts at 0, and
-    at any time, it must be between min_level and max_level.
-
-    If the variable `times[i]` is assigned a value t, and `actives[i]` is
-    `True`, then the current level changes by `demands[i]`, which is constant,
-    at time t.
-
-     Note that min level must be <= 0, and the max level must be >= 0. Please
-     use fixed demands to simulate initial state.
-
-     Therefore, at any time:
-         sum(demands[i] * actives[i] if times[i] <= t) in [min_level, max_level]
-
-
-    The array of boolean variables 'actives', if defined, indicates which
-    actions are actually performed.
-
-    Args:
-      times: A list of integer variables which specify the time of the
-        filling or emptying the reservoir.
-      demands: A list of integer values that specifies the amount of the
-        emptying or filling.
-      actives: a list of boolean variables. They indicates if the
-        emptying/refilling events actually take place.
-      min_level: At any time, the level of the reservoir must be greater or
-        equal than the min level.
-      max_level: At any time, the level of the reservoir must be less or equal
-        than the max level.
-
-    Returns:
-      An instance of the `Constraint` class.
-
-    Raises:
-      ValueError: if max_level < min_level.
-
-      ValueError: if max_level < 0.
-
-      ValueError: if min_level > 0
-    """
-
-        if max_level < min_level:
-            return ValueError(
-                'Reservoir constraint must have a max_level >= min_level')
-
-        if max_level < 0:
-            return ValueError('Reservoir constraint must have a max_level >= 0')
-
-        if min_level > 0:
-            return ValueError('Reservoir constraint must have a min_level <= 0')
-
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.reservoir.times.extend([self.GetOrMakeIndex(x) for x in times])
-        model_ct.reservoir.demands.extend(demands)
-        model_ct.reservoir.actives.extend(
-            [self.GetOrMakeIndex(x) for x in actives])
-        model_ct.reservoir.min_level = min_level
-        model_ct.reservoir.max_level = max_level
-        return ct
-
-    def AddMapDomain(self, var, bool_var_array, offset=0):
-        """Adds `var == i + offset <=> bool_var_array[i] == true for all i`."""
-
-        for i, bool_var in enumerate(bool_var_array):
-            b_index = bool_var.Index()
-            var_index = var.Index()
-            model_ct = self.__model.constraints.add()
-            model_ct.linear.vars.append(var_index)
-            model_ct.linear.coeffs.append(1)
-            model_ct.linear.domain.extend([offset + i, offset + i])
-            model_ct.enforcement_literal.append(b_index)
-
-            model_ct = self.__model.constraints.add()
-            model_ct.linear.vars.append(var_index)
-            model_ct.linear.coeffs.append(1)
-            model_ct.enforcement_literal.append(-b_index - 1)
-            if offset + i - 1 >= INT_MIN:
-                model_ct.linear.domain.extend([INT_MIN, offset + i - 1])
-            if offset + i + 1 <= INT_MAX:
-                model_ct.linear.domain.extend([offset + i + 1, INT_MAX])
-
-    def AddImplication(self, a, b):
-        """Adds `a => b` (`a` implies `b`)."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.bool_or.literals.append(self.GetOrMakeBooleanIndex(b))
-        model_ct.enforcement_literal.append(self.GetOrMakeBooleanIndex(a))
-        return ct
-
-    def AddBoolOr(self, literals):
-        """Adds `Or(literals) == true`."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.bool_or.literals.extend(
-            [self.GetOrMakeBooleanIndex(x) for x in literals])
-        return ct
-
-    def AddBoolAnd(self, literals):
-        """Adds `And(literals) == true`."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.bool_and.literals.extend(
-            [self.GetOrMakeBooleanIndex(x) for x in literals])
-        return ct
-
-    def AddBoolXOr(self, literals):
-        """Adds `XOr(literals) == true`."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.bool_xor.literals.extend(
-            [self.GetOrMakeBooleanIndex(x) for x in literals])
-        return ct
-
-    def AddMinEquality(self, target, variables):
-        """Adds `target == Min(variables)`."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.int_min.vars.extend(
-            [self.GetOrMakeIndex(x) for x in variables])
-        model_ct.int_min.target = self.GetOrMakeIndex(target)
-        return ct
-
-    def AddMaxEquality(self, target, variables):
-        """Adds `target == Max(variables)`."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.int_max.vars.extend(
-            [self.GetOrMakeIndex(x) for x in variables])
-        model_ct.int_max.target = self.GetOrMakeIndex(target)
-        return ct
-
-    def AddDivisionEquality(self, target, num, denom):
-        """Adds `target == num // denom` (integer division rounded towards 0)."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.int_div.vars.extend(
-            [self.GetOrMakeIndex(num),
-             self.GetOrMakeIndex(denom)])
-        model_ct.int_div.target = self.GetOrMakeIndex(target)
-        return ct
-
-    def AddAbsEquality(self, target, var):
-        """Adds `target == Abs(var)`."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        index = self.GetOrMakeIndex(var)
-        model_ct.int_max.vars.extend([index, -index - 1])
-        model_ct.int_max.target = self.GetOrMakeIndex(target)
-        return ct
-
-    def AddModuloEquality(self, target, var, mod):
-        """Adds `target = var % mod`."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.int_mod.vars.extend(
-            [self.GetOrMakeIndex(var),
-             self.GetOrMakeIndex(mod)])
-        model_ct.int_mod.target = self.GetOrMakeIndex(target)
-        return ct
-
-    def AddMultiplicationEquality(self, target, variables):
-        """Adds `target == variables[0] * .. * variables[n]`."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.int_prod.vars.extend(
-            [self.GetOrMakeIndex(x) for x in variables])
-        model_ct.int_prod.target = self.GetOrMakeIndex(target)
-        return ct
-
-    def AddProdEquality(self, target, variables):
-        """Deprecated, use AddMultiplicationEquality."""
-        return self.AddMultiplicationEquality(target, variables)
-
-    # Scheduling support
-
-    def NewIntervalVar(self, start, size, end, name):
-        """Creates an interval variable from start, size, and end.
-
-    An interval variable is a constraint, that is itself used in other
-    constraints like NoOverlap.
-
-    Internally, it ensures that `start + size == end`.
-
-    Args:
-      start: The start of the interval. It can be an integer value, or an
-        integer variable.
-      size: The size of the interval. It can be an integer value, or an integer
-        variable.
-      end: The end of the interval. It can be an integer value, or an integer
-        variable.
-      name: The name of the interval variable.
-
-    Returns:
-      An `IntervalVar` object.
-    """
-
-        start_index = self.GetOrMakeIndex(start)
-        size_index = self.GetOrMakeIndex(size)
-        end_index = self.GetOrMakeIndex(end)
-        return IntervalVar(self.__model, start_index, size_index, end_index,
-                           None, name)
-
-    def NewOptionalIntervalVar(self, start, size, end, is_present, name):
-        """Creates an optional interval var from start, size, end, and is_present.
-
-    An optional interval variable is a constraint, that is itself used in other
-    constraints like NoOverlap. This constraint is protected by an is_present
-    literal that indicates if it is active or not.
-
-    Internally, it ensures that `is_present` implies `start + size == end`.
-
-    Args:
-      start: The start of the interval. It can be an integer value, or an
-        integer variable.
-      size: The size of the interval. It can be an integer value, or an integer
-        variable.
-      end: The end of the interval. It can be an integer value, or an integer
-        variable.
-      is_present: A literal that indicates if the interval is active or not. A
-        inactive interval is simply ignored by all constraints.
-      name: The name of the interval variable.
-
-    Returns:
-      An `IntervalVar` object.
-    """
-        is_present_index = self.GetOrMakeBooleanIndex(is_present)
-        start_index = self.GetOrMakeIndex(start)
-        size_index = self.GetOrMakeIndex(size)
-        end_index = self.GetOrMakeIndex(end)
-        return IntervalVar(self.__model, start_index, size_index, end_index,
-                           is_present_index, name)
-
-    def AddNoOverlap(self, interval_vars):
-        """Adds NoOverlap(interval_vars).
-
-    A NoOverlap constraint ensures that all present intervals do not overlap
-    in time.
-
-    Args:
-      interval_vars: The list of interval variables to constrain.
-
-    Returns:
-      An instance of the `Constraint` class.
-    """
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.no_overlap.intervals.extend(
-            [self.GetIntervalIndex(x) for x in interval_vars])
-        return ct
-
-    def AddNoOverlap2D(self, x_intervals, y_intervals):
-        """Adds NoOverlap2D(x_intervals, y_intervals).
-
-    A NoOverlap2D constraint ensures that all present rectangles do not overlap
-    on a plane. Each rectangle is aligned with the X and Y axis, and is defined
-    by two intervals which represent its projection onto the X and Y axis.
-
-    Args:
-      x_intervals: The X coordinates of the rectangles.
-      y_intervals: The Y coordinates of the rectangles.
-
-    Returns:
-      An instance of the `Constraint` class.
-    """
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.no_overlap_2d.x_intervals.extend(
-            [self.GetIntervalIndex(x) for x in x_intervals])
-        model_ct.no_overlap_2d.y_intervals.extend(
-            [self.GetIntervalIndex(x) for x in y_intervals])
-        return ct
-
-    def AddCumulative(self, intervals, demands, capacity):
-        """Adds Cumulative(intervals, demands, capacity).
-
-    This constraint enforces that:
-
-        for all t:
-          sum(demands[i]
-            if (start(intervals[t]) <= t < end(intervals[t])) and
-            (t is present)) <= capacity
-
-    Args:
-      intervals: The list of intervals.
-      demands: The list of demands for each interval. Each demand must be >= 0.
-        Each demand can be an integer value, or an integer variable.
-      capacity: The maximum capacity of the cumulative constraint. It must be a
-        positive integer value or variable.
-
-    Returns:
-      An instance of the `Constraint` class.
-    """
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.cumulative.intervals.extend(
-            [self.GetIntervalIndex(x) for x in intervals])
-        model_ct.cumulative.demands.extend(
-            [self.GetOrMakeIndex(x) for x in demands])
-        model_ct.cumulative.capacity = self.GetOrMakeIndex(capacity)
-        return ct
-
-    # Support for deep copy.
-    def CopyFrom(self, other_model):
-        """Reset the model, and creates a new one from a CpModelProto instance."""
-        self.__model.CopyFrom(other_model.Proto())
-
-        # Rebuild constant map.
-        self.__constant_map.clear()
-        for i, var in enumerate(self.__model.variables):
-            if len(var.domain) == 2 and var.domain[0] == var.domain[1]:
-                self.__constant_map[var.domain[0]] = i
-
-    def GetBoolVarFromProtoIndex(self, index):
-        """Returns an already created Boolean variable from its index."""
-        if index < 0 or index >= len(self.__model.variables):
-            raise ValueError(
-                f'GetBoolVarFromProtoIndex: out of bound index {index}')
-        var = self.__model.variables[index]
-        if len(var.domain) != 2 or var.domain[0] < 0 or var.domain[1] > 1:
-            raise ValueError(
-                f'GetBoolVarFromProtoIndex: index {index} does not reference' +
-                ' a Boolean variable')
-
-        return IntVar(self.__model, index, None)
-
-    def GetIntVarFromProtoIndex(self, index):
-        """Returns an already created integer variable from its index."""
-        if index < 0 or index >= len(self.__model.variables):
-            raise ValueError(
-                f'GetIntVarFromProtoIndex: out of bound index {index}')
-        return IntVar(self.__model, index, None)
-
-    def GetIntervalVarFromProtoIndex(self, index):
-        """Returns an already created interval variable from its index."""
-        if index < 0 or index >= len(self.__model.constraints):
-            raise ValueError(
-                f'GetIntervalVarFromProtoIndex: out of bound index {index}')
-        ct = self.__model.constraints[index]
-        if not ct.HasField('interval'):
-            raise ValueError(
-                f'GetIntervalVarFromProtoIndex: index {index} does not reference an'
-                + ' interval variable')
-
-        return IntervalVar(self.__model, index, None, None, None, None)
-
-    # Helpers.
-
-    def __str__(self):
-        return str(self.__model)
-
-    def Proto(self):
-        """Returns the underlying CpModelProto."""
-        return self.__model
-
-    def Negated(self, index):
-        return -index - 1
-
-    def GetOrMakeIndex(self, arg):
-        """Returns the index of a variable, its negation, or a number."""
-        if isinstance(arg, IntVar):
-            return arg.Index()
-        elif (isinstance(arg, _ProductCst) and
-              isinstance(arg.Expression(), IntVar) and arg.Coefficient() == -1):
-            return -arg.Expression().Index() - 1
-        elif isinstance(arg, numbers.Integral):
-            cp_model_helper.AssertIsInt64(arg)
-            return self.GetOrMakeIndexFromConstant(arg)
-        else:
-            raise TypeError('NotSupported: model.GetOrMakeIndex(' + str(arg) +
-                            ')')
-
-    def GetOrMakeBooleanIndex(self, arg):
-        """Returns an index from a boolean expression."""
-        if isinstance(arg, IntVar):
-            self.AssertIsBooleanVariable(arg)
-            return arg.Index()
-        elif isinstance(arg, _NotBooleanVariable):
-            self.AssertIsBooleanVariable(arg.Not())
-            return arg.Index()
-        elif isinstance(arg, numbers.Integral):
-            cp_model_helper.AssertIsBoolean(arg)
-            return self.GetOrMakeIndexFromConstant(arg)
-        else:
-            raise TypeError('NotSupported: model.GetOrMakeBooleanIndex(' +
-                            str(arg) + ')')
-
-    def GetIntervalIndex(self, arg):
-        if not isinstance(arg, IntervalVar):
-            raise TypeError('NotSupported: model.GetIntervalIndex(%s)' % arg)
-        return arg.Index()
-
-    def GetOrMakeIndexFromConstant(self, value):
-        if value in self.__constant_map:
-            return self.__constant_map[value]
-        index = len(self.__model.variables)
-        var = self.__model.variables.add()
-        var.domain.extend([value, value])
-        self.__constant_map[value] = index
-        return index
-
-    def VarIndexToVarProto(self, var_index):
-        if var_index >= 0:
-            return self.__model.variables[var_index]
-        else:
-            return self.__model.variables[-var_index - 1]
-
-    def _SetObjective(self, obj, minimize):
-        """Sets the objective of the model."""
-        if isinstance(obj, IntVar):
-            self.__model.ClearField('objective')
-            self.__model.objective.coeffs.append(1)
-            self.__model.objective.offset = 0
-            if minimize:
-                self.__model.objective.vars.append(obj.Index())
-                self.__model.objective.scaling_factor = 1
-            else:
-                self.__model.objective.vars.append(self.Negated(obj.Index()))
-                self.__model.objective.scaling_factor = -1
-        elif isinstance(obj, LinearExpr):
-            coeffs_map, constant = obj.GetVarValueMap()
-            self.__model.ClearField('objective')
-            if minimize:
-                self.__model.objective.scaling_factor = 1
-                self.__model.objective.offset = constant
-            else:
-                self.__model.objective.scaling_factor = -1
-                self.__model.objective.offset = -constant
-            for v, c, in coeffs_map.items():
-                self.__model.objective.coeffs.append(c)
-                if minimize:
-                    self.__model.objective.vars.append(v.Index())
-                else:
-                    self.__model.objective.vars.append(self.Negated(v.Index()))
-        elif isinstance(obj, numbers.Integral):
-            self.__model.objective.offset = obj
-            self.__model.objective.scaling_factor = 1
-        else:
-            raise TypeError('TypeError: ' + str(obj) +
-                            ' is not a valid objective')
-
-    def Minimize(self, obj):
-        """Sets the objective of the model to minimize(obj)."""
-        self._SetObjective(obj, minimize=True)
-
-    def Maximize(self, obj):
-        """Sets the objective of the model to maximize(obj)."""
-        self._SetObjective(obj, minimize=False)
-
-    def HasObjective(self):
-        return self.__model.HasField('objective')
-
-    def AddDecisionStrategy(self, variables, var_strategy, domain_strategy):
-        """Adds a search strategy to the model.
-
-    Args:
-      variables: a list of variables this strategy will assign.
-      var_strategy: heuristic to choose the next variable to assign.
-      domain_strategy: heuristic to reduce the domain of the selected variable.
-        Currently, this is advanced code: the union of all strategies added to
-          the model must be complete, i.e. instantiates all variables.
-          Otherwise, Solve() will fail.
-    """
-
-        strategy = self.__model.search_strategy.add()
-        for v in variables:
-            strategy.variables.append(v.Index())
-        strategy.variable_selection_strategy = var_strategy
-        strategy.domain_reduction_strategy = domain_strategy
-
-    def ModelStats(self):
-        """Returns a string containing some model statistics."""
-        return pywrapsat.CpSatHelper.ModelStats(self.__model)
-
-    def Validate(self):
-        """Returns a string indicating that the model is invalid."""
-        return pywrapsat.CpSatHelper.ValidateModel(self.__model)
-
-    def ExportToFile(self, file):
-        """Write the model as a protocol buffer to 'file'.
-
-    Args:
-      file: file to write the model to. If the filename ends with 'txt', the
-            model will be written as a text file, otherwise, the binary format
-            will be used.
-
-
-    Returns:
-      True if the model was correctly written.
-    """
-        return pywrapsat.CpSatHelper.WriteModelToFile(self.__model, file)
-
-    def AssertIsBooleanVariable(self, x):
-        if isinstance(x, IntVar):
-            var = self.__model.variables[x.Index()]
-            if len(var.domain) != 2 or var.domain[0] < 0 or var.domain[1] > 1:
-                raise TypeError('TypeError: ' + str(x) +
-                                ' is not a boolean variable')
-        elif not isinstance(x, _NotBooleanVariable):
-            raise TypeError('TypeError: ' + str(x) +
-                            ' is not a boolean variable')
-
-    def AddHint(self, var, value):
-        """Adds 'var == value' as a hint to the solver."""
-        self.__model.solution_hint.vars.append(self.GetOrMakeIndex(var))
-        self.__model.solution_hint.values.append(value)
-
-    def ClearHints(self):
-        """Remove any solution hint from the model."""
-        self.__model.ClearField('solution_hint')
-
-    def AddAssumption(self, lit):
-        """Add the literal 'lit' to the model as assumptions."""
-        self.__model.assumptions.append(self.GetOrMakeBooleanIndex(lit))
-
-    def AddAssumptions(self, literals):
-        """Add the literals to the model as assumptions."""
-        for lit in literals:
-            self.AddAssumption(lit)
-
-    def ClearAssumptions(self):
-        """Remove all assumptions from the model."""
-        self.__model.ClearField('assumptions')
-
-
-def EvaluateLinearExpr(expression, solution):
-    """Evaluate a linear expression against a solution."""
-    if isinstance(expression, numbers.Integral):
-        return expression
-    if not isinstance(expression, LinearExpr):
-        raise TypeError('Cannot interpret %s as a linear expression.' %
-                        expression)
-
-    value = 0
-    to_process = [(expression, 1)]
-    while to_process:
-        expr, coef = to_process.pop()
-        if isinstance(expr, _ProductCst):
-            to_process.append((expr.Expression(), coef * expr.Coefficient()))
-        elif isinstance(expr, _SumArray):
-            for e in expr.Expressions():
-                to_process.append((e, coef))
-            value += expr.Constant() * coef
-        elif isinstance(expr, _ScalProd):
-            for e, c in zip(expr.Expressions(), expr.Coefficients()):
-                to_process.append((e, coef * c))
-            value += expr.Constant() * coef
-        elif isinstance(expr, IntVar):
-            value += coef * solution.solution[expr.Index()]
-        elif isinstance(expr, _NotBooleanVariable):
-            value += coef * (1 - solution.solution[expr.Not().Index()])
-    return value
-
-
-def EvaluateBooleanExpression(literal, solution):
-    """Evaluate a boolean expression against a solution."""
-    if isinstance(literal, numbers.Integral):
-        return bool(literal)
-    elif isinstance(literal, IntVar) or isinstance(literal,
-                                                   _NotBooleanVariable):
-        index = literal.Index()
-        if index >= 0:
-            return bool(solution.solution[index])
-        else:
-            return not solution.solution[-index - 1]
-    else:
-        raise TypeError('Cannot interpret %s as a boolean expression.' %
-                        literal)
-
-
-class CpSolver(object):
-    """Main solver class.
-
-  The purpose of this class is to search for a solution to the model provided
-  to the Solve() method.
-
-  Once Solve() is called, this class allows inspecting the solution found
-  with the Value() and BooleanValue() methods, as well as general statistics
-  about the solve procedure.
-  """
-
-    def __init__(self):
-        self.__model = None
-        self.__solution: cp_model_pb2.CpSolverResponse = None
-        self.parameters = sat_parameters_pb2.SatParameters()
-        self.log_callback = None
-        self.__solve_wrapper: pywrapsat.SolveWrapper = None
-        self.__lock = threading.Lock()
-
-    def Solve(self, model, solution_callback=None):
-        """Solves a problem and passes each solution to the callback if not null."""
-        with self.__lock:
-            solve_wrapper = pywrapsat.SolveWrapper()
-
-        solve_wrapper.SetParameters(self.parameters)
-        if solution_callback is not None:
-            solve_wrapper.AddSolutionCallback(solution_callback)
-
-        if self.log_callback is not None:
-            solve_wrapper.AddLogCallback(self.log_callback)
-
-        self.__solution = solve_wrapper.Solve(model.Proto())
-
-        if solution_callback is not None:
-            solve_wrapper.ClearSolutionCallback(solution_callback)
-
-        with self.__lock:
-            self.__solve_wrapper = None
-
-        return self.__solution.status
-
-    # DEPRECATED, just use Solve() with the callback argument.
-    def SolveWithSolutionCallback(self, model, callback):
-        """DEPRECATED Use Solve() with the callback argument."""
-        return self.Solve(model, callback)
-
-    def SearchForAllSolutions(self, model, callback):
-        """Search for all solutions of a satisfiability problem.
-
-    This method searches for all feasible solutions of a given model.
-    Then it feeds the solution to the callback.
-
-    Note that the model cannot contain an objective.
-
-    Args:
-      model: The model to solve.
-      callback: The callback that will be called at each solution.
-
-    Returns:
-      The status of the solve:
-
-      * *FEASIBLE* if some solutions have been found
-      * *INFEASIBLE* if the solver has proved there are no solution
-      * *OPTIMAL* if all solutions have been found
-    """
-        if model.HasObjective():
-            raise TypeError('Search for all solutions is only defined on '
-                            'satisfiability problems')
-        # Store old parameter.
-        enumerate_all = self.parameters.enumerate_all_solutions
-        self.parameters.enumerate_all_solutions = True
-
-        self.Solve(model, callback)
-
-        # Restore parameter.
-        self.parameters.enumerate_all_solutions = enumerate_all
-        return self.__solution.status
-
-    def StopSearch(self):
-        """Stops the current search asynchronously."""
-        with self.__lock:
-            if self.__solve_wrapper:
-                self.__solve_wrapper.StopSearch()
-
-    def Value(self, expression):
-        """Returns the value of a linear expression after solve."""
-        if not self.__solution:
-            raise RuntimeError('Solve() has not be called.')
-        return EvaluateLinearExpr(expression, self.__solution)
-
-    def BooleanValue(self, literal):
-        """Returns the boolean value of a literal after solve."""
-        if not self.__solution:
-            raise RuntimeError('Solve() has not be called.')
-        return EvaluateBooleanExpression(literal, self.__solution)
-
-    def ObjectiveValue(self):
-        """Returns the value of the objective after solve."""
-        return self.__solution.objective_value
-
-    def BestObjectiveBound(self):
-        """Returns the best lower (upper) bound found when min(max)imizing."""
-        return self.__solution.best_objective_bound
-
-    def StatusName(self, status=None):
-        """Returns the name of the status returned by Solve()."""
-        if status is None:
-            status = self.__solution.status
-        return cp_model_pb2.CpSolverStatus.Name(status)
-
-    def NumBooleans(self):
-        """Returns the number of boolean variables managed by the SAT solver."""
-        return self.__solution.num_booleans
-
-    def NumConflicts(self):
-        """Returns the number of conflicts since the creation of the solver."""
-        return self.__solution.num_conflicts
-
-    def NumBranches(self):
-        """Returns the number of search branches explored by the solver."""
-        return self.__solution.num_branches
-
-    def WallTime(self):
-        """Returns the wall time in seconds since the creation of the solver."""
-        return self.__solution.wall_time
-
-    def UserTime(self):
-        """Returns the user time in seconds since the creation of the solver."""
-        return self.__solution.user_time
-
-    def ResponseStats(self):
-        """Returns some statistics on the solution found as a string."""
-        return pywrapsat.CpSatHelper.SolverResponseStats(self.__solution)
-
-    def ResponseProto(self):
-        """Returns the response object."""
-        return self.__solution
-
-    def SufficientAssumptionsForInfeasibility(self):
-        """Returns the indices of the infeasible assumptions."""
-        return self.__solution.sufficient_assumptions_for_infeasibility
-
-
-class CpSolverSolutionCallback(pywrapsat.SolutionCallback):
-    """Solution callback.
-
-  This class implements a callback that will be called at each new solution
-  found during search.
-
-  The method OnSolutionCallback() will be called by the solver, and must be
-  implemented. The current solution can be queried using the BooleanValue()
-  and Value() methods.
-
-  It inherits the following methods from its base class:
-
-  * `ObjectiveValue(self)`
-  * `BestObjectiveBound(self)`
-  * `NumBooleans(self)`
-  * `NumConflicts(self)`
-  * `NumBranches(self)`
-  * `WallTime(self)`
-  * `UserTime(self)`
-
-  These methods returns the same information as their counterpart in the
-  `CpSolver` class.
-  """
-
-    def __init__(self):
-        pywrapsat.SolutionCallback.__init__(self)
-
-    def OnSolutionCallback(self):
-        """Proxy for the same method in snake case."""
-        self.on_solution_callback()
-
-    def BooleanValue(self, lit):
-        """Returns the boolean value of a boolean literal.
-
-    Args:
-        lit: A boolean variable or its negation.
-
-    Returns:
-        The Boolean value of the literal in the solution.
-
-    Raises:
-        RuntimeError: if `lit` is not a boolean variable or its negation.
-    """
-        if not self.HasResponse():
-            raise RuntimeError('Solve() has not be called.')
-        if isinstance(lit, numbers.Integral):
-            return bool(lit)
-        elif isinstance(lit, IntVar) or isinstance(lit, _NotBooleanVariable):
-            index = lit.Index()
-            return self.SolutionBooleanValue(index)
-        else:
-            raise TypeError('Cannot interpret %s as a boolean expression.' %
-                            lit)
-
-    def Value(self, expression):
-        """Evaluates an linear expression in the current solution.
-
-    Args:
-        expression: a linear expression of the model.
-
-    Returns:
-        An integer value equal to the evaluation of the linear expression
-        against the current solution.
-
-    Raises:
-        RuntimeError: if 'expression' is not a LinearExpr.
-    """
-        if not self.HasResponse():
-            raise RuntimeError('Solve() has not be called.')
-        if isinstance(expression, numbers.Integral):
-            return expression
-        if not isinstance(expression, LinearExpr):
-            raise TypeError('Cannot interpret %s as a linear expression.' %
-                            expression)
-
-        value = 0
-        to_process = [(expression, 1)]
-        while to_process:
-            expr, coef = to_process.pop()
-            if isinstance(expr, _ProductCst):
-                to_process.append(
-                    (expr.Expression(), coef * expr.Coefficient()))
-            elif isinstance(expr, _SumArray):
-                for e in expr.Expressions():
-                    to_process.append((e, coef))
-                    value += expr.Constant() * coef
-            elif isinstance(expr, _ScalProd):
-                for e, c in zip(expr.Expressions(), expr.Coefficients()):
-                    to_process.append((e, coef * c))
-                value += expr.Constant() * coef
-            elif isinstance(expr, IntVar):
-                value += coef * self.SolutionIntegerValue(expr.Index())
-            elif isinstance(expr, _NotBooleanVariable):
-                value += coef * (1 -
-                                 self.SolutionIntegerValue(expr.Not().Index()))
-        return value
-
-
-class ObjectiveSolutionPrinter(CpSolverSolutionCallback):
-    """Display the objective value and time of intermediate solutions."""
-
-    def __init__(self):
-        CpSolverSolutionCallback.__init__(self)
-        self.__solution_count = 0
-        self.__start_time = time.time()
-
-    def on_solution_callback(self):
-        """Called on each new solution."""
-        current_time = time.time()
-        obj = self.ObjectiveValue()
-        print('Solution %i, time = %0.2f s, objective = %i' %
-              (self.__solution_count, current_time - self.__start_time, obj))
-        self.__solution_count += 1
-
-    def solution_count(self):
-        """Returns the number of solutions found."""
-        return self.__solution_count
-
-
-class VarArrayAndObjectiveSolutionPrinter(CpSolverSolutionCallback):
-    """Print intermediate solutions (objective, variable values, time)."""
-
-    def __init__(self, variables):
-        CpSolverSolutionCallback.__init__(self)
-        self.__variables = variables
-        self.__solution_count = 0
-        self.__start_time = time.time()
-
-    def on_solution_callback(self):
-        """Called on each new solution."""
-        current_time = time.time()
-        obj = self.ObjectiveValue()
-        print('Solution %i, time = %0.2f s, objective = %i' %
-              (self.__solution_count, current_time - self.__start_time, obj))
-        for v in self.__variables:
-            print('  %s = %i' % (v, self.Value(v)), end=' ')
-        print()
-        self.__solution_count += 1
-
-    def solution_count(self):
-        """Returns the number of solutions found."""
-        return self.__solution_count
-
-
-class VarArraySolutionPrinter(CpSolverSolutionCallback):
-    """Print intermediate solutions (variable values, time)."""
-
-    def __init__(self, variables):
-        CpSolverSolutionCallback.__init__(self)
-        self.__variables = variables
-        self.__solution_count = 0
-        self.__start_time = time.time()
-
-    def on_solution_callback(self):
-        """Called on each new solution."""
-        current_time = time.time()
-        print('Solution %i, time = %0.2f s' %
-              (self.__solution_count, current_time - self.__start_time))
-        for v in self.__variables:
-            print('  %s = %i' % (v, self.Value(v)), end=' ')
-        print()
-        self.__solution_count += 1
-
-    def solution_count(self):
-        """Returns the number of solutions found."""
-        return self.__solution_count
-
-
-
-
-
-
-
-

Functions

-
-
-def ObjectIsAFalseLiteral(literal) -
-
-

Checks if literal is either False, or a Boolean literals fixed to False.

-
- -Expand source code - -
def ObjectIsAFalseLiteral(literal):
-    """Checks if literal is either False, or a Boolean literals fixed to False."""
-    if isinstance(literal, IntVar):
-        proto = literal.Proto()
-        return (len(proto.domain) == 2 and proto.domain[0] == 0 and
-                proto.domain[1] == 0)
-    if isinstance(literal, _NotBooleanVariable):
-        proto = literal.Not().Proto()
-        return (len(proto.domain) == 2 and proto.domain[0] == 1 and
-                proto.domain[1] == 1)
-    if isinstance(literal, numbers.Integral):
-        return literal == 0
-    return False
-
-
-
-def ObjectIsATrueLiteral(literal) -
-
-

Checks if literal is either True, or a Boolean literals fixed to True.

-
- -Expand source code - -
def ObjectIsATrueLiteral(literal):
-    """Checks if literal is either True, or a Boolean literals fixed to True."""
-    if isinstance(literal, IntVar):
-        proto = literal.Proto()
-        return (len(proto.domain) == 2 and proto.domain[0] == 1 and
-                proto.domain[1] == 1)
-    if isinstance(literal, _NotBooleanVariable):
-        proto = literal.Not().Proto()
-        return (len(proto.domain) == 2 and proto.domain[0] == 0 and
-                proto.domain[1] == 0)
-    if isinstance(literal, numbers.Integral):
-        return literal == 1
-    return False
-
-
-
-
-
-

Classes

-
-
-class BoundedLinearExpression -(expr, bounds) -
-
-

Represents a linear constraint: lb <= linear expression <= ub.

+
+ +
+ View Source +
# Copyright 2010-2021 Google LLC
+# 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
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Methods for building and solving CP-SAT models.
+
+The following two sections describe the main
+methods for building and solving CP-SAT models.
+
+* [`CpModel`](#cp_model.CpModel): Methods for creating
+models, including variables and constraints.
+* [`CPSolver`](#cp_model.CpSolver): Methods for solving
+a model and evaluating solutions.
+
+The following methods implement callbacks that the
+solver calls each time it finds a new solution.
+
+* [`CpSolverSolutionCallback`](#cp_model.CpSolverSolutionCallback):
+  A general method for implementing callbacks.
+* [`ObjectiveSolutionPrinter`](#cp_model.ObjectiveSolutionPrinter):
+  Print objective values and elapsed time for intermediate solutions.
+* [`VarArraySolutionPrinter`](#cp_model.VarArraySolutionPrinter):
+  Print intermediate solutions (variable values, time).
+* [`VarArrayAndObjectiveSolutionPrinter`]
+      (#cp_model.VarArrayAndObjectiveSolutionPrinter):
+  Print both intermediate solutions and objective values.
+
+Additional methods for solving CP-SAT models:
+
+* [`Constraint`](#cp_model.Constraint): A few utility methods for modifying
+  constraints created by `CpModel`.
+* [`LinearExpr`](#lineacp_model.LinearExpr): Methods for creating constraints
+  and the objective from large arrays of coefficients.
+
+Other methods and functions listed are primarily used for developing OR-Tools,
+rather than for solving specific optimization problems.
+"""
+
+import collections
+import numbers
+import threading
+import time
+import warnings
+
+from ortools.sat import cp_model_pb2
+from ortools.sat import sat_parameters_pb2
+from ortools.sat.python import cp_model_helper
+from ortools.sat import pywrapsat
+from ortools.util import sorted_interval_list
+
+Domain = sorted_interval_list.Domain
+
+# The classes below allow linear expressions to be expressed naturally with the
+# usual arithmetic operators +-*/ and with constant numbers, which makes the
+# python API very intuitive. See ../samples/*.py for examples.
+
+INT_MIN = -9223372036854775808  # hardcoded to be platform independent.
+INT_MAX = 9223372036854775807
+INT32_MAX = 2147483647
+INT32_MIN = -2147483648
+
+# CpSolver status (exported to avoid importing cp_model_cp2).
+UNKNOWN = cp_model_pb2.UNKNOWN
+MODEL_INVALID = cp_model_pb2.MODEL_INVALID
+FEASIBLE = cp_model_pb2.FEASIBLE
+INFEASIBLE = cp_model_pb2.INFEASIBLE
+OPTIMAL = cp_model_pb2.OPTIMAL
+
+# Variable selection strategy
+CHOOSE_FIRST = cp_model_pb2.DecisionStrategyProto.CHOOSE_FIRST
+CHOOSE_LOWEST_MIN = cp_model_pb2.DecisionStrategyProto.CHOOSE_LOWEST_MIN
+CHOOSE_HIGHEST_MAX = cp_model_pb2.DecisionStrategyProto.CHOOSE_HIGHEST_MAX
+CHOOSE_MIN_DOMAIN_SIZE = (
+    cp_model_pb2.DecisionStrategyProto.CHOOSE_MIN_DOMAIN_SIZE)
+CHOOSE_MAX_DOMAIN_SIZE = (
+    cp_model_pb2.DecisionStrategyProto.CHOOSE_MAX_DOMAIN_SIZE)
+
+# Domain reduction strategy
+SELECT_MIN_VALUE = cp_model_pb2.DecisionStrategyProto.SELECT_MIN_VALUE
+SELECT_MAX_VALUE = cp_model_pb2.DecisionStrategyProto.SELECT_MAX_VALUE
+SELECT_LOWER_HALF = cp_model_pb2.DecisionStrategyProto.SELECT_LOWER_HALF
+SELECT_UPPER_HALF = cp_model_pb2.DecisionStrategyProto.SELECT_UPPER_HALF
+
+# Search branching
+AUTOMATIC_SEARCH = sat_parameters_pb2.SatParameters.AUTOMATIC_SEARCH
+FIXED_SEARCH = sat_parameters_pb2.SatParameters.FIXED_SEARCH
+PORTFOLIO_SEARCH = sat_parameters_pb2.SatParameters.PORTFOLIO_SEARCH
+LP_SEARCH = sat_parameters_pb2.SatParameters.LP_SEARCH
+
+
+def DisplayBounds(bounds):
+    """Displays a flattened list of intervals."""
+    out = ''
+    for i in range(0, len(bounds), 2):
+        if i != 0:
+            out += ', '
+        if bounds[i] == bounds[i + 1]:
+            out += str(bounds[i])
+        else:
+            out += str(bounds[i]) + '..' + str(bounds[i + 1])
+    return out
+
+
+def ShortName(model, i):
+    """Returns a short name of an integer variable, or its negation."""
+    if i < 0:
+        return 'Not(%s)' % ShortName(model, -i - 1)
+    v = model.variables[i]
+    if v.name:
+        return v.name
+    elif len(v.domain) == 2 and v.domain[0] == v.domain[1]:
+        return str(v.domain[0])
+    else:
+        return '[%s]' % DisplayBounds(v.domain)
+
+
+def ShortExprName(model, e):
+    """Pretty-print LinearExpressionProto instances."""
+    if not e.vars:
+        return str(e.offset)
+    if len(e.vars) == 1:
+        var_name = ShortName(model, e.vars[0])
+        coeff = e.coeffs[0]
+        result = ''
+        if coeff == 1:
+            result = var_name
+        elif coeff == -1:
+            result = f'-{var_name}'
+        elif coeff != 0:
+            result = f'{coeff} * {var_name}'
+        if e.offset > 0:
+            result = f'{result} + {e.offset}'
+        elif e.offset < 0:
+            result = f'{result} - {-e.offset}'
+        return result
+    # TODO(user): Support more than affine expressions.
+    return str(e)
+
+
+class LinearExpr(object):
+    """Holds an integer linear expression.
+
+  A linear expression is built from integer constants and variables.
+  For example, x + 2 * (y - z + 1).
+
+  Linear expressions are used in CP-SAT models in two ways:
+
+  * To define constraints. For example
+
+      model.Add(x + 2 * y <= 5)
+      model.Add(sum(array_of_vars) == 5)
+
+  * To define the objective function. For example
+
+      model.Minimize(x + 2 * y + z)
+
+  For large arrays, you can create constraints and the objective
+  from lists of linear expressions or coefficients as follows:
+
+      model.Minimize(cp_model.LinearExpr.Sum(expressions))
+      model.Add(cp_model.LinearExpr.ScalProd(expressions, coefficients) >= 0)
+  """
+
+    @classmethod
+    def Sum(cls, expressions):
+        """Creates the expression sum(expressions)."""
+        return _SumArray(expressions)
+
+    @classmethod
+    def ScalProd(cls, expressions, coefficients):
+        """Creates the expression sum(expressions[i] * coefficients[i])."""
+        if LinearExpr.IsEmptyOrAllNull(coefficients):
+            return 0
+        else:
+            return _ScalProd(expressions, coefficients)
+
+    @classmethod
+    def Term(cls, expression, coefficient):
+        """Creates `expression * coefficient`."""
+        if coefficient == 0:
+            return 0
+        else:
+            return expression * coefficient
+
+    @classmethod
+    def IsEmptyOrAllNull(cls, coefficients):
+        for c in coefficients:
+            if c != 0:
+                return False
+        return True
+
+    def GetVarValueMap(self):
+        """Scans the expression, and return a list of (var_coef_map, constant)."""
+        coeffs = collections.defaultdict(int)
+        constant = 0
+        to_process = [(self, 1)]
+        while to_process:  # Flatten to avoid recursion.
+            expr, coef = to_process.pop()
+            if isinstance(expr, _ProductCst):
+                to_process.append(
+                    (expr.Expression(), coef * expr.Coefficient()))
+            elif isinstance(expr, _SumArray):
+                for e in expr.Expressions():
+                    to_process.append((e, coef))
+                constant += expr.Constant() * coef
+            elif isinstance(expr, _ScalProd):
+                for e, c in zip(expr.Expressions(), expr.Coefficients()):
+                    to_process.append((e, coef * c))
+                constant += expr.Constant() * coef
+            elif isinstance(expr, IntVar):
+                coeffs[expr] += coef
+            elif isinstance(expr, _NotBooleanVariable):
+                constant += coef
+                coeffs[expr.Not()] -= coef
+            else:
+                raise TypeError('Unrecognized linear expression: ' + str(expr))
+
+        return coeffs, constant
+
+    def __hash__(self):
+        return object.__hash__(self)
+
+    def __abs__(self):
+        raise NotImplementedError(
+            'calling abs() on a linear expression is not supported, '
+            'please use CpModel.AddAbsEquality')
+
+    def __add__(self, expr):
+        return _SumArray([self, expr])
+
+    def __radd__(self, arg):
+        return _SumArray([self, arg])
+
+    def __sub__(self, expr):
+        return _SumArray([self, -expr])
+
+    def __rsub__(self, arg):
+        return _SumArray([-self, arg])
+
+    def __mul__(self, arg):
+        if isinstance(arg, numbers.Integral):
+            if arg == 1:
+                return self
+            elif arg == 0:
+                return 0
+            cp_model_helper.AssertIsInt64(arg)
+            return _ProductCst(self, arg)
+        else:
+            raise TypeError('Not an integer linear expression: ' + str(arg))
+
+    def __rmul__(self, arg):
+        cp_model_helper.AssertIsInt64(arg)
+        if arg == 1:
+            return self
+        return _ProductCst(self, arg)
+
+    def __div__(self, _):
+        raise NotImplementedError(
+            'calling / on a linear expression is not supported, '
+            'please use CpModel.AddDivisionEquality')
+
+    def __truediv__(self, _):
+        raise NotImplementedError(
+            'calling // on a linear expression is not supported, '
+            'please use CpModel.AddDivisionEquality')
+
+    def __mod__(self, _):
+        raise NotImplementedError(
+            'calling %% on a linear expression is not supported, '
+            'please use CpModel.AddModuloEquality')
+
+    def __pow__(self, _):
+        raise NotImplementedError(
+            'calling ** on a linear expression is not supported, '
+            'please use CpModel.AddMultiplicationEquality')
+
+    def __lshift__(self, _):
+        raise NotImplementedError(
+            'calling left shift on a linear expression is not supported')
+
+    def __rshift__(self, _):
+        raise NotImplementedError(
+            'calling right shift on a linear expression is not supported')
+
+    def __and__(self, _):
+        raise NotImplementedError(
+            'calling and on a linear expression is not supported, '
+            'please use CpModel.AddBoolAnd')
+
+    def __or__(self, _):
+        raise NotImplementedError(
+            'calling or on a linear expression is not supported, '
+            'please use CpModel.AddBoolOr')
+
+    def __xor__(self, _):
+        raise NotImplementedError(
+            'calling xor on a linear expression is not supported, '
+            'please use CpModel.AddBoolXor')
+
+    def __neg__(self):
+        return _ProductCst(self, -1)
+
+    def __bool__(self):
+        raise NotImplementedError(
+            'Evaluating a LinearExpr instance as a Boolean is not implemented.')
+
+    def __eq__(self, arg):
+        if arg is None:
+            return False
+        if isinstance(arg, numbers.Integral):
+            cp_model_helper.AssertIsInt64(arg)
+            return BoundedLinearExpression(self, [arg, arg])
+        else:
+            return BoundedLinearExpression(self - arg, [0, 0])
+
+    def __ge__(self, arg):
+        if isinstance(arg, numbers.Integral):
+            cp_model_helper.AssertIsInt64(arg)
+            return BoundedLinearExpression(self, [arg, INT_MAX])
+        else:
+            return BoundedLinearExpression(self - arg, [0, INT_MAX])
+
+    def __le__(self, arg):
+        if isinstance(arg, numbers.Integral):
+            cp_model_helper.AssertIsInt64(arg)
+            return BoundedLinearExpression(self, [INT_MIN, arg])
+        else:
+            return BoundedLinearExpression(self - arg, [INT_MIN, 0])
+
+    def __lt__(self, arg):
+        if isinstance(arg, numbers.Integral):
+            cp_model_helper.AssertIsInt64(arg)
+            if arg == INT_MIN:
+                raise ArithmeticError('< INT_MIN is not supported')
+            return BoundedLinearExpression(self, [INT_MIN, arg - 1])
+        else:
+            return BoundedLinearExpression(self - arg, [INT_MIN, -1])
+
+    def __gt__(self, arg):
+        if isinstance(arg, numbers.Integral):
+            cp_model_helper.AssertIsInt64(arg)
+            if arg == INT_MAX:
+                raise ArithmeticError('> INT_MAX is not supported')
+            return BoundedLinearExpression(self, [arg + 1, INT_MAX])
+        else:
+            return BoundedLinearExpression(self - arg, [1, INT_MAX])
+
+    def __ne__(self, arg):
+        if arg is None:
+            return True
+        if isinstance(arg, numbers.Integral):
+            cp_model_helper.AssertIsInt64(arg)
+            if arg == INT_MAX:
+                return BoundedLinearExpression(self, [INT_MIN, INT_MAX - 1])
+            elif arg == INT_MIN:
+                return BoundedLinearExpression(self, [INT_MIN + 1, INT_MAX])
+            else:
+                return BoundedLinearExpression(
+                    self, [INT_MIN, arg - 1, arg + 1, INT_MAX])
+        else:
+            return BoundedLinearExpression(self - arg,
+                                           [INT_MIN, -1, 1, INT_MAX])
+
+
+class _ProductCst(LinearExpr):
+    """Represents the product of a LinearExpr by a constant."""
+
+    def __init__(self, expr, coef):
+        cp_model_helper.AssertIsInt64(coef)
+        if isinstance(expr, _ProductCst):
+            self.__expr = expr.Expression()
+            self.__coef = expr.Coefficient() * coef
+        else:
+            self.__expr = expr
+            self.__coef = coef
+
+    def __str__(self):
+        if self.__coef == -1:
+            return '-' + str(self.__expr)
+        else:
+            return '(' + str(self.__coef) + ' * ' + str(self.__expr) + ')'
+
+    def __repr__(self):
+        return 'ProductCst(' + repr(self.__expr) + ', ' + repr(
+            self.__coef) + ')'
+
+    def Coefficient(self):
+        return self.__coef
+
+    def Expression(self):
+        return self.__expr
+
+
+class _SumArray(LinearExpr):
+    """Represents the sum of a list of LinearExpr and a constant."""
+
+    def __init__(self, expressions):
+        self.__expressions = []
+        self.__constant = 0
+        for x in expressions:
+            if isinstance(x, numbers.Integral):
+                cp_model_helper.AssertIsInt64(x)
+                self.__constant += x
+            elif isinstance(x, LinearExpr):
+                self.__expressions.append(x)
+            else:
+                raise TypeError('Not an linear expression: ' + str(x))
+
+    def __str__(self):
+        if self.__constant == 0:
+            return '({})'.format(' + '.join(map(str, self.__expressions)))
+        else:
+            return '({} + {})'.format(' + '.join(map(str, self.__expressions)),
+                                      self.__constant)
+
+    def __repr__(self):
+        return 'SumArray({}, {})'.format(
+            ', '.join(map(repr, self.__expressions)), self.__constant)
+
+    def Expressions(self):
+        return self.__expressions
+
+    def Constant(self):
+        return self.__constant
+
+
+class _ScalProd(LinearExpr):
+    """Represents the scalar product of expressions with constants and a constant."""
+
+    def __init__(self, expressions, coefficients):
+        self.__expressions = []
+        self.__coefficients = []
+        self.__constant = 0
+        if len(expressions) != len(coefficients):
+            raise TypeError(
+                'In the LinearExpr.ScalProd method, the expression array and the '
+                ' coefficient array must have the same length.')
+        for e, c in zip(expressions, coefficients):
+            cp_model_helper.AssertIsInt64(c)
+            if c == 0:
+                continue
+            if isinstance(e, numbers.Integral):
+                cp_model_helper.AssertIsInt64(e)
+                self.__constant += e * c
+            elif isinstance(e, LinearExpr):
+                self.__expressions.append(e)
+                self.__coefficients.append(c)
+            else:
+                raise TypeError('Not an linear expression: ' + str(e))
+
+    def __str__(self):
+        output = None
+        for expr, coeff in zip(self.__expressions, self.__coefficients):
+            if not output and coeff == 1:
+                output = str(expr)
+            elif not output and coeff == -1:
+                output = '-' + str(expr)
+            elif not output:
+                output = '{} * {}'.format(coeff, str(expr))
+            elif coeff == 1:
+                output += ' + {}'.format(str(expr))
+            elif coeff == -1:
+                output += ' - {}'.format(str(expr))
+            elif coeff > 1:
+                output += ' + {} * {}'.format(coeff, str(expr))
+            elif coeff < -1:
+                output += ' - {} * {}'.format(-coeff, str(expr))
+        if self.__constant > 0:
+            output += ' + {}'.format(self.__constant)
+        elif self.__constant < 0:
+            output += ' - {}'.format(-self.__constant)
+        if output is None:
+            output = '0'
+        return output
+
+    def __repr__(self):
+        return 'ScalProd([{}], [{}], {})'.format(
+            ', '.join(map(repr, self.__expressions)),
+            ', '.join(map(repr, self.__coefficients)), self.__constant)
+
+    def Expressions(self):
+        return self.__expressions
+
+    def Coefficients(self):
+        return self.__coefficients
+
+    def Constant(self):
+        return self.__constant
+
+
+class IntVar(LinearExpr):
+    """An integer variable.
+
+  An IntVar is an object that can take on any integer value within defined
+  ranges. Variables appear in constraint like:
+
+      x + y >= 5
+      AllDifferent([x, y, z])
+
+  Solving a model is equivalent to finding, for each variable, a single value
+  from the set of initial values (called the initial domain), such that the
+  model is feasible, or optimal if you provided an objective function.
+  """
+
+    def __init__(self, model, domain, name):
+        """See CpModel.NewIntVar below."""
+        self.__model = model
+        self.__negation = None
+        # Python do not support multiple __init__ methods.
+        # This method is only called from the CpModel class.
+        # We hack the parameter to support the two cases:
+        # case 1:
+        #     model is a CpModelProto, domain is a Domain, and name is a string.
+        # case 2:
+        #     model is a CpModelProto, domain is an index (int), and name is None.
+        if isinstance(domain, numbers.Integral) and name is None:
+            self.__index = domain
+            self.__var = model.variables[domain]
+        else:
+            self.__index = len(model.variables)
+            self.__var = model.variables.add()
+            self.__var.domain.extend(domain.FlattenedIntervals())
+            self.__var.name = name
+
+    def Index(self):
+        """Returns the index of the variable in the model."""
+        return self.__index
+
+    def Proto(self):
+        """Returns the variable protobuf."""
+        return self.__var
+
+    def IsEqualTo(self, other):
+        """Returns true if self == other in the python sense."""
+        if not isinstance(other, IntVar):
+            return False
+        return self.Index() == other.Index()
+
+    def __str__(self):
+        if not self.__var.name:
+            if len(self.__var.domain
+                  ) == 2 and self.__var.domain[0] == self.__var.domain[1]:
+                # Special case for constants.
+                return str(self.__var.domain[0])
+            else:
+                return 'unnamed_var_%i' % self.__index
+        return self.__var.name
+
+    def __repr__(self):
+        return '%s(%s)' % (self.__var.name, DisplayBounds(self.__var.domain))
+
+    def Name(self):
+        return self.__var.name
+
+    def Not(self):
+        """Returns the negation of a Boolean variable.
+
+    This method implements the logical negation of a Boolean variable.
+    It is only valid if the variable has a Boolean domain (0 or 1).
+
+    Note that this method is nilpotent: `x.Not().Not() == x`.
+    """
+
+        for bound in self.__var.domain:
+            if bound < 0 or bound > 1:
+                raise TypeError(
+                    'Cannot call Not on a non boolean variable: %s' % self)
+        if self.__negation is None:
+            self.__negation = _NotBooleanVariable(self)
+        return self.__negation
+
+
+class _NotBooleanVariable(LinearExpr):
+    """Negation of a boolean variable."""
+
+    def __init__(self, boolvar):
+        self.__boolvar = boolvar
+
+    def Index(self):
+        return -self.__boolvar.Index() - 1
+
+    def Not(self):
+        return self.__boolvar
+
+    def __str__(self):
+        return 'not(%s)' % str(self.__boolvar)
+
+    def __bool__(self):
+        raise NotImplementedError(
+            'Evaluating a literal as a Boolean value is not implemented.')
+
+
+class BoundedLinearExpression(object):
+    """Represents a linear constraint: `lb <= linear expression <= ub`.
+
+  The only use of this class is to be added to the CpModel through
+  `CpModel.Add(expression)`, as in:
+
+      model.Add(x + 2 * y -1 >= z)
+  """
+
+    def __init__(self, expr, bounds):
+        self.__expr = expr
+        self.__bounds = bounds
+
+    def __str__(self):
+        if len(self.__bounds) == 2:
+            lb = self.__bounds[0]
+            ub = self.__bounds[1]
+            if lb > INT_MIN and ub < INT_MAX:
+                if lb == ub:
+                    return str(self.__expr) + ' == ' + str(lb)
+                else:
+                    return str(lb) + ' <= ' + str(
+                        self.__expr) + ' <= ' + str(ub)
+            elif lb > INT_MIN:
+                return str(self.__expr) + ' >= ' + str(lb)
+            elif ub < INT_MAX:
+                return str(self.__expr) + ' <= ' + str(ub)
+            else:
+                return 'True (unbounded expr ' + str(self.__expr) + ')'
+        elif (len(self.__bounds) == 4 and self.__bounds[0] == INT_MIN and
+              self.__bounds[1] + 2 == self.__bounds[2] and
+              self.__bounds[3] == INT_MAX):
+            return str(self.__expr) + ' != ' + str(self.__bounds[1] + 1)
+        else:
+            return str(self.__expr) + ' in [' + DisplayBounds(
+                self.__bounds) + ']'
+
+    def Expression(self):
+        return self.__expr
+
+    def Bounds(self):
+        return self.__bounds
+
+    def __bool__(self):
+        coeffs_map, constant = self.__expr.GetVarValueMap()
+        all_coeffs = set(coeffs_map.values())
+        same_var = set([0])
+        eq_bounds = [0, 0]
+        different_vars = set([-1, 1])
+        ne_bounds = [INT_MIN, -1, 1, INT_MAX]
+        if (len(coeffs_map) == 1 and all_coeffs == same_var and
+                constant == 0 and
+            (self.__bounds == eq_bounds or self.__bounds == ne_bounds)):
+            return self.__bounds == eq_bounds
+        if (len(coeffs_map) == 2 and all_coeffs == different_vars and
+                constant == 0 and
+            (self.__bounds == eq_bounds or self.__bounds == ne_bounds)):
+            return self.__bounds == ne_bounds
+
+        raise NotImplementedError(
+            f'Evaluating a BoundedLinearExpression \'{self}\' as a Boolean value'
+            + ' is not supported.')
+
+
+class Constraint(object):
+    """Base class for constraints.
+
+  Constraints are built by the CpModel through the Add<XXX> methods.
+  Once created by the CpModel class, they are automatically added to the model.
+  The purpose of this class is to allow specification of enforcement literals
+  for this constraint.
+
+      b = model.NewBoolVar('b')
+      x = model.NewIntVar(0, 10, 'x')
+      y = model.NewIntVar(0, 10, 'y')
+
+      model.Add(x + 2 * y == 5).OnlyEnforceIf(b.Not())
+  """
+
+    def __init__(self, constraints):
+        self.__index = len(constraints)
+        self.__constraint = constraints.add()
+
+    def OnlyEnforceIf(self, boolvar):
+        """Adds an enforcement literal to the constraint.
+
+    This method adds one or more literals (that is, a boolean variable or its
+    negation) as enforcement literals. The conjunction of all these literals
+    determines whether the constraint is active or not. It acts as an
+    implication, so if the conjunction is true, it implies that the constraint
+    must be enforced. If it is false, then the constraint is ignored.
+
+    BoolOr, BoolAnd, and linear constraints all support enforcement literals.
+
+    Args:
+      boolvar: A boolean literal or a list of boolean literals.
+
+    Returns:
+      self.
+    """
+
+        if isinstance(boolvar, numbers.Integral) and boolvar == 1:
+            # Always true. Do nothing.
+            pass
+        elif isinstance(boolvar, list):
+            for b in boolvar:
+                if isinstance(b, numbers.Integral) and b == 1:
+                    pass
+                else:
+                    self.__constraint.enforcement_literal.append(b.Index())
+        else:
+            self.__constraint.enforcement_literal.append(boolvar.Index())
+        return self
+
+    def Index(self):
+        """Returns the index of the constraint in the model."""
+        return self.__index
+
+    def Proto(self):
+        """Returns the constraint protobuf."""
+        return self.__constraint
+
+
+class IntervalVar(object):
+    """Represents an Interval variable.
+
+  An interval variable is both a constraint and a variable. It is defined by
+  three integer variables: start, size, and end.
+
+  It is a constraint because, internally, it enforces that start + size == end.
+
+  It is also a variable as it can appear in specific scheduling constraints:
+  NoOverlap, NoOverlap2D, Cumulative.
+
+  Optionally, an enforcement literal can be added to this constraint, in which
+  case these scheduling constraints will ignore interval variables with
+  enforcement literals assigned to false. Conversely, these constraints will
+  also set these enforcement literals to false if they cannot fit these
+  intervals into the schedule.
+  """
+
+    def __init__(self, model, start_view, size_view, end_view, is_present_index,
+                 name):
+        self.__model = model
+        # As with the IntVar::__init__ method, we hack the __init__ method to
+        # support two use cases:
+        #   case 1: called when creating a new interval variable.
+        #      {start|size|end}_index are indices of integer variables
+        #      is_present_index is either None or the index of a Boolean literal.
+        #      name is a string
+        #   case 2: called when querying an existing interval variable.
+        #      start_index is an int, all parameters after are None.
+        if (size_view is None and end_view is None and
+                is_present_index is None and name is None):
+            self.__index = start_view
+            self.__ct = model.constraints[start_view]
+        else:
+            self.__index = len(model.constraints)
+            self.__ct = self.__model.constraints.add()
+            self.__ct.interval.start_view.CopyFrom(start_view)
+            self.__ct.interval.size_view.CopyFrom(size_view)
+            self.__ct.interval.end_view.CopyFrom(end_view)
+            if is_present_index is not None:
+                self.__ct.enforcement_literal.append(is_present_index)
+            if name:
+                self.__ct.name = name
+
+    def Index(self):
+        """Returns the index of the interval constraint in the model."""
+        return self.__index
+
+    def Proto(self):
+        """Returns the interval protobuf."""
+        return self.__ct.interval
+
+    def __str__(self):
+        return self.__ct.name
+
+    def __repr__(self):
+        interval = self.__ct.interval
+        if self.__ct.enforcement_literal:
+            return '%s(start = %s, size = %s, end = %s, is_present = %s)' % (
+                self.__ct.name, ShortExprName(self.__model,
+                                              interval.start_view),
+                ShortExprName(self.__model, interval.size_view),
+                ShortExprName(self.__model, interval.end_view),
+                ShortName(self.__model, self.__ct.enforcement_literal[0]))
+        else:
+            return '%s(start = %s, size = %s, end = %s)' % (
+                self.__ct.name, ShortExprName(self.__model,
+                                              interval.start_view),
+                ShortExprName(self.__model, interval.size_view),
+                ShortExprName(self.__model, interval.end_view))
+
+    def Name(self):
+        return self.__ct.name
+
+
+def ObjectIsATrueLiteral(literal):
+    """Checks if literal is either True, or a Boolean literals fixed to True."""
+    if isinstance(literal, IntVar):
+        proto = literal.Proto()
+        return (len(proto.domain) == 2 and proto.domain[0] == 1 and
+                proto.domain[1] == 1)
+    if isinstance(literal, _NotBooleanVariable):
+        proto = literal.Not().Proto()
+        return (len(proto.domain) == 2 and proto.domain[0] == 0 and
+                proto.domain[1] == 0)
+    if isinstance(literal, numbers.Integral):
+        return literal == 1
+    return False
+
+
+def ObjectIsAFalseLiteral(literal):
+    """Checks if literal is either False, or a Boolean literals fixed to False."""
+    if isinstance(literal, IntVar):
+        proto = literal.Proto()
+        return (len(proto.domain) == 2 and proto.domain[0] == 0 and
+                proto.domain[1] == 0)
+    if isinstance(literal, _NotBooleanVariable):
+        proto = literal.Not().Proto()
+        return (len(proto.domain) == 2 and proto.domain[0] == 1 and
+                proto.domain[1] == 1)
+    if isinstance(literal, numbers.Integral):
+        return literal == 0
+    return False
+
+
+class CpModel(object):
+    """Methods for building a CP model.
+
+  Methods beginning with:
+
+  * ```New``` create integer, boolean, or interval variables.
+  * ```Add``` create new constraints and add them to the model.
+  """
+
+    def __init__(self):
+        self.__model = cp_model_pb2.CpModelProto()
+        self.__constant_map = {}
+
+    # Integer variable.
+
+    def NewIntVar(self, lb, ub, name):
+        """Create an integer variable with domain [lb, ub].
+
+    The CP-SAT solver is limited to integer variables. If you have fractional
+    values, scale them up so that they become integers; if you have strings,
+    encode them as integers.
+
+    Args:
+      lb: Lower bound for the variable.
+      ub: Upper bound for the variable.
+      name: The name of the variable.
+
+    Returns:
+      a variable whose domain is [lb, ub].
+    """
+
+        return IntVar(self.__model, Domain(lb, ub), name)
+
+    def NewIntVarFromDomain(self, domain, name):
+        """Create an integer variable from a domain.
+
+    A domain is a set of integers specified by a collection of intervals.
+    For example, `model.NewIntVarFromDomain(cp_model.
+         Domain.FromIntervals([[1, 2], [4, 6]]), 'x')`
+
+    Args:
+      domain: An instance of the Domain class.
+      name: The name of the variable.
+
+    Returns:
+        a variable whose domain is the given domain.
+    """
+        return IntVar(self.__model, domain, name)
+
+    def NewBoolVar(self, name):
+        """Creates a 0-1 variable with the given name."""
+        return IntVar(self.__model, Domain(0, 1), name)
+
+    def NewConstant(self, value):
+        """Declares a constant integer."""
+        return IntVar(self.__model, self.GetOrMakeIndexFromConstant(value),
+                      None)
+
+    # Linear constraints.
+
+    def AddLinearConstraint(self, linear_expr, lb, ub):
+        """Adds the constraint: `lb <= linear_expr <= ub`."""
+        return self.AddLinearExpressionInDomain(linear_expr, Domain(lb, ub))
+
+    def AddLinearExpressionInDomain(self, linear_expr, domain):
+        """Adds the constraint: `linear_expr` in `domain`."""
+        if isinstance(linear_expr, LinearExpr):
+            ct = Constraint(self.__model.constraints)
+            model_ct = self.__model.constraints[ct.Index()]
+            coeffs_map, constant = linear_expr.GetVarValueMap()
+            for t in coeffs_map.items():
+                if not isinstance(t[0], IntVar):
+                    raise TypeError('Wrong argument' + str(t))
+                cp_model_helper.AssertIsInt64(t[1])
+                model_ct.linear.vars.append(t[0].Index())
+                model_ct.linear.coeffs.append(t[1])
+            model_ct.linear.domain.extend([
+                cp_model_helper.CapSub(x, constant)
+                for x in domain.FlattenedIntervals()
+            ])
+            return ct
+        elif isinstance(linear_expr, numbers.Integral):
+            if not domain.Contains(linear_expr):
+                return self.AddBoolOr([])  # Evaluate to false.
+            # Nothing to do otherwise.
+        else:
+            raise TypeError(
+                'Not supported: CpModel.AddLinearExpressionInDomain(' +
+                str(linear_expr) + ' ' + str(domain) + ')')
+
+    def Add(self, ct):
+        """Adds a `BoundedLinearExpression` to the model.
+
+    Args:
+      ct: A [`BoundedLinearExpression`](#boundedlinearexpression).
+
+    Returns:
+      An instance of the `Constraint` class.
+    """
+        if isinstance(ct, BoundedLinearExpression):
+            return self.AddLinearExpressionInDomain(
+                ct.Expression(), Domain.FromFlatIntervals(ct.Bounds()))
+        elif ct and isinstance(ct, bool):
+            return self.AddBoolOr([True])
+        elif not ct and isinstance(ct, bool):
+            return self.AddBoolOr([])  # Evaluate to false.
+        else:
+            raise TypeError('Not supported: CpModel.Add(' + str(ct) + ')')
+
+    # General Integer Constraints.
+
+    def AddAllDifferent(self, variables):
+        """Adds AllDifferent(variables).
+
+    This constraint forces all variables to have different values.
+
+    Args:
+      variables: a list of integer variables.
+
+    Returns:
+      An instance of the `Constraint` class.
+    """
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.all_diff.vars.extend(
+            [self.GetOrMakeIndex(x) for x in variables])
+        return ct
+
+    def AddElement(self, index, variables, target):
+        """Adds the element constraint: `variables[index] == target`."""
+
+        if not variables:
+            raise ValueError('AddElement expects a non-empty variables array')
+
+        if isinstance(index, numbers.Integral):
+            return self.Add(list(variables)[index] == target)
+
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.element.index = self.GetOrMakeIndex(index)
+        model_ct.element.vars.extend(
+            [self.GetOrMakeIndex(x) for x in variables])
+        model_ct.element.target = self.GetOrMakeIndex(target)
+        return ct
+
+    def AddCircuit(self, arcs):
+        """Adds Circuit(arcs).
+
+    Adds a circuit constraint from a sparse list of arcs that encode the graph.
+
+    A circuit is a unique Hamiltonian path in a subgraph of the total
+    graph. In case a node 'i' is not in the path, then there must be a
+    loop arc 'i -> i' associated with a true literal. Otherwise
+    this constraint will fail.
+
+    Args:
+      arcs: a list of arcs. An arc is a tuple (source_node, destination_node,
+        literal). The arc is selected in the circuit if the literal is true.
+        Both source_node and destination_node must be integers between 0 and the
+        number of nodes - 1.
+
+    Returns:
+      An instance of the `Constraint` class.
+
+    Raises:
+      ValueError: If the list of arcs is empty.
+    """
+        if not arcs:
+            raise ValueError('AddCircuit expects a non-empty array of arcs')
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        for arc in arcs:
+            cp_model_helper.AssertIsInt32(arc[0])
+            cp_model_helper.AssertIsInt32(arc[1])
+            lit = self.GetOrMakeBooleanIndex(arc[2])
+            model_ct.circuit.tails.append(arc[0])
+            model_ct.circuit.heads.append(arc[1])
+            model_ct.circuit.literals.append(lit)
+        return ct
+
+    def AddAllowedAssignments(self, variables, tuples_list):
+        """Adds AllowedAssignments(variables, tuples_list).
+
+    An AllowedAssignments constraint is a constraint on an array of variables,
+    which requires that when all variables are assigned values, the resulting
+    array equals one of the  tuples in `tuple_list`.
+
+    Args:
+      variables: A list of variables.
+      tuples_list: A list of admissible tuples. Each tuple must have the same
+        length as the variables, and the ith value of a tuple corresponds to the
+        ith variable.
+
+    Returns:
+      An instance of the `Constraint` class.
+
+    Raises:
+      TypeError: If a tuple does not have the same size as the list of
+          variables.
+      ValueError: If the array of variables is empty.
+    """
+
+        if not variables:
+            raise ValueError(
+                'AddAllowedAssignments expects a non-empty variables '
+                'array')
+
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.table.vars.extend([self.GetOrMakeIndex(x) for x in variables])
+        arity = len(variables)
+        for t in tuples_list:
+            if len(t) != arity:
+                raise TypeError('Tuple ' + str(t) + ' has the wrong arity')
+            for v in t:
+                cp_model_helper.AssertIsInt64(v)
+            model_ct.table.values.extend(t)
+        return ct
+
+    def AddForbiddenAssignments(self, variables, tuples_list):
+        """Adds AddForbiddenAssignments(variables, [tuples_list]).
+
+    A ForbiddenAssignments constraint is a constraint on an array of variables
+    where the list of impossible combinations is provided in the tuples list.
+
+    Args:
+      variables: A list of variables.
+      tuples_list: A list of forbidden tuples. Each tuple must have the same
+        length as the variables, and the *i*th value of a tuple corresponds to
+        the *i*th variable.
+
+    Returns:
+      An instance of the `Constraint` class.
+
+    Raises:
+      TypeError: If a tuple does not have the same size as the list of
+                 variables.
+      ValueError: If the array of variables is empty.
+    """
+
+        if not variables:
+            raise ValueError(
+                'AddForbiddenAssignments expects a non-empty variables '
+                'array')
+
+        index = len(self.__model.constraints)
+        ct = self.AddAllowedAssignments(variables, tuples_list)
+        self.__model.constraints[index].table.negated = True
+        return ct
+
+    def AddAutomaton(self, transition_variables, starting_state, final_states,
+                     transition_triples):
+        """Adds an automaton constraint.
+
+    An automaton constraint takes a list of variables (of size *n*), an initial
+    state, a set of final states, and a set of transitions. A transition is a
+    triplet (*tail*, *transition*, *head*), where *tail* and *head* are states,
+    and *transition* is the label of an arc from *head* to *tail*,
+    corresponding to the value of one variable in the list of variables.
+
+    This automaton will be unrolled into a flow with *n* + 1 phases. Each phase
+    contains the possible states of the automaton. The first state contains the
+    initial state. The last phase contains the final states.
+
+    Between two consecutive phases *i* and *i* + 1, the automaton creates a set
+    of arcs. For each transition (*tail*, *transition*, *head*), it will add
+    an arc from the state *tail* of phase *i* and the state *head* of phase
+    *i* + 1. This arc is labeled by the value *transition* of the variables
+    `variables[i]`. That is, this arc can only be selected if `variables[i]`
+    is assigned the value *transition*.
+
+    A feasible solution of this constraint is an assignment of variables such
+    that, starting from the initial state in phase 0, there is a path labeled by
+    the values of the variables that ends in one of the final states in the
+    final phase.
+
+    Args:
+      transition_variables: A non-empty list of variables whose values
+        correspond to the labels of the arcs traversed by the automaton.
+      starting_state: The initial state of the automaton.
+      final_states: A non-empty list of admissible final states.
+      transition_triples: A list of transitions for the automaton, in the
+        following format (current_state, variable_value, next_state).
+
+    Returns:
+      An instance of the `Constraint` class.
+
+    Raises:
+      ValueError: if `transition_variables`, `final_states`, or
+        `transition_triples` are empty.
+    """
+
+        if not transition_variables:
+            raise ValueError(
+                'AddAutomaton expects a non-empty transition_variables '
+                'array')
+        if not final_states:
+            raise ValueError('AddAutomaton expects some final states')
+
+        if not transition_triples:
+            raise ValueError('AddAutomaton expects some transition triples')
+
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.automaton.vars.extend(
+            [self.GetOrMakeIndex(x) for x in transition_variables])
+        cp_model_helper.AssertIsInt64(starting_state)
+        model_ct.automaton.starting_state = starting_state
+        for v in final_states:
+            cp_model_helper.AssertIsInt64(v)
+            model_ct.automaton.final_states.append(v)
+        for t in transition_triples:
+            if len(t) != 3:
+                raise TypeError('Tuple ' + str(t) +
+                                ' has the wrong arity (!= 3)')
+            cp_model_helper.AssertIsInt64(t[0])
+            cp_model_helper.AssertIsInt64(t[1])
+            cp_model_helper.AssertIsInt64(t[2])
+            model_ct.automaton.transition_tail.append(t[0])
+            model_ct.automaton.transition_label.append(t[1])
+            model_ct.automaton.transition_head.append(t[2])
+        return ct
+
+    def AddInverse(self, variables, inverse_variables):
+        """Adds Inverse(variables, inverse_variables).
+
+    An inverse constraint enforces that if `variables[i]` is assigned a value
+    `j`, then `inverse_variables[j]` is assigned a value `i`. And vice versa.
+
+    Args:
+      variables: An array of integer variables.
+      inverse_variables: An array of integer variables.
+
+    Returns:
+      An instance of the `Constraint` class.
+
+    Raises:
+      TypeError: if variables and inverse_variables have different lengths, or
+          if they are empty.
+    """
+
+        if not variables or not inverse_variables:
+            raise TypeError(
+                'The Inverse constraint does not accept empty arrays')
+        if len(variables) != len(inverse_variables):
+            raise TypeError(
+                'In the inverse constraint, the two array variables and'
+                ' inverse_variables must have the same length.')
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.inverse.f_direct.extend(
+            [self.GetOrMakeIndex(x) for x in variables])
+        model_ct.inverse.f_inverse.extend(
+            [self.GetOrMakeIndex(x) for x in inverse_variables])
+        return ct
+
+    def AddReservoirConstraint(self, times, demands, min_level, max_level):
+        """Adds Reservoir(times, demands, min_level, max_level).
+
+    Maintains a reservoir level within bounds. The water level starts at 0, and
+    at any time, it must be between min_level and max_level.
+
+    If the variable `times[i]` is assigned a value t, then the current level
+    changes by `demands[i]`, which is constant, at time t.
+
+     Note that min level must be <= 0, and the max level must be >= 0. Please
+     use fixed demands to simulate initial state.
+
+     Therefore, at any time:
+         sum(demands[i] if times[i] <= t) in [min_level, max_level]
+
+    Args:
+      times: A list of integer variables which specify the time of the filling
+        or emptying the reservoir.
+      demands: A list of integer values that specifies the amount of the
+        emptying or filling.
+      min_level: At any time, the level of the reservoir must be greater or
+        equal than the min level.
+      max_level: At any time, the level of the reservoir must be less or equal
+        than the max level.
+
+    Returns:
+      An instance of the `Constraint` class.
+
+    Raises:
+      ValueError: if max_level < min_level.
+
+      ValueError: if max_level < 0.
+
+      ValueError: if min_level > 0
+    """
+
+        if max_level < min_level:
+            return ValueError(
+                'Reservoir constraint must have a max_level >= min_level')
+
+        if max_level < 0:
+            return ValueError('Reservoir constraint must have a max_level >= 0')
+
+        if min_level > 0:
+            return ValueError('Reservoir constraint must have a min_level <= 0')
+
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.reservoir.times.extend([self.GetOrMakeIndex(x) for x in times])
+        model_ct.reservoir.demands.extend(demands)
+        model_ct.reservoir.min_level = min_level
+        model_ct.reservoir.max_level = max_level
+        return ct
+
+    def AddReservoirConstraintWithActive(self, times, demands, actives,
+                                         min_level, max_level):
+        """Adds Reservoir(times, demands, actives, min_level, max_level).
+
+    Maintains a reservoir level within bounds. The water level starts at 0, and
+    at any time, it must be between min_level and max_level.
+
+    If the variable `times[i]` is assigned a value t, and `actives[i]` is
+    `True`, then the current level changes by `demands[i]`, which is constant,
+    at time t.
+
+     Note that min level must be <= 0, and the max level must be >= 0. Please
+     use fixed demands to simulate initial state.
+
+     Therefore, at any time:
+         sum(demands[i] * actives[i] if times[i] <= t) in [min_level, max_level]
+
+
+    The array of boolean variables 'actives', if defined, indicates which
+    actions are actually performed.
+
+    Args:
+      times: A list of integer variables which specify the time of the filling
+        or emptying the reservoir.
+      demands: A list of integer values that specifies the amount of the
+        emptying or filling.
+      actives: a list of boolean variables. They indicates if the
+        emptying/refilling events actually take place.
+      min_level: At any time, the level of the reservoir must be greater or
+        equal than the min level.
+      max_level: At any time, the level of the reservoir must be less or equal
+        than the max level.
+
+    Returns:
+      An instance of the `Constraint` class.
+
+    Raises:
+      ValueError: if max_level < min_level.
+
+      ValueError: if max_level < 0.
+
+      ValueError: if min_level > 0
+    """
+
+        if max_level < min_level:
+            return ValueError(
+                'Reservoir constraint must have a max_level >= min_level')
+
+        if max_level < 0:
+            return ValueError('Reservoir constraint must have a max_level >= 0')
+
+        if min_level > 0:
+            return ValueError('Reservoir constraint must have a min_level <= 0')
+
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.reservoir.times.extend([self.GetOrMakeIndex(x) for x in times])
+        model_ct.reservoir.demands.extend(demands)
+        model_ct.reservoir.actives.extend(
+            [self.GetOrMakeIndex(x) for x in actives])
+        model_ct.reservoir.min_level = min_level
+        model_ct.reservoir.max_level = max_level
+        return ct
+
+    def AddMapDomain(self, var, bool_var_array, offset=0):
+        """Adds `var == i + offset <=> bool_var_array[i] == true for all i`."""
+
+        for i, bool_var in enumerate(bool_var_array):
+            b_index = bool_var.Index()
+            var_index = var.Index()
+            model_ct = self.__model.constraints.add()
+            model_ct.linear.vars.append(var_index)
+            model_ct.linear.coeffs.append(1)
+            model_ct.linear.domain.extend([offset + i, offset + i])
+            model_ct.enforcement_literal.append(b_index)
+
+            model_ct = self.__model.constraints.add()
+            model_ct.linear.vars.append(var_index)
+            model_ct.linear.coeffs.append(1)
+            model_ct.enforcement_literal.append(-b_index - 1)
+            if offset + i - 1 >= INT_MIN:
+                model_ct.linear.domain.extend([INT_MIN, offset + i - 1])
+            if offset + i + 1 <= INT_MAX:
+                model_ct.linear.domain.extend([offset + i + 1, INT_MAX])
+
+    def AddImplication(self, a, b):
+        """Adds `a => b` (`a` implies `b`)."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.bool_or.literals.append(self.GetOrMakeBooleanIndex(b))
+        model_ct.enforcement_literal.append(self.GetOrMakeBooleanIndex(a))
+        return ct
+
+    def AddBoolOr(self, literals):
+        """Adds `Or(literals) == true`."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.bool_or.literals.extend(
+            [self.GetOrMakeBooleanIndex(x) for x in literals])
+        return ct
+
+    def AddBoolAnd(self, literals):
+        """Adds `And(literals) == true`."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.bool_and.literals.extend(
+            [self.GetOrMakeBooleanIndex(x) for x in literals])
+        return ct
+
+    def AddBoolXOr(self, literals):
+        """Adds `XOr(literals) == true`."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.bool_xor.literals.extend(
+            [self.GetOrMakeBooleanIndex(x) for x in literals])
+        return ct
+
+    def AddMinEquality(self, target, variables):
+        """Adds `target == Min(variables)`."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.int_min.vars.extend(
+            [self.GetOrMakeIndex(x) for x in variables])
+        model_ct.int_min.target = self.GetOrMakeIndex(target)
+        return ct
+
+    def AddMaxEquality(self, target, variables):
+        """Adds `target == Max(variables)`."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.int_max.vars.extend(
+            [self.GetOrMakeIndex(x) for x in variables])
+        model_ct.int_max.target = self.GetOrMakeIndex(target)
+        return ct
+
+    def AddDivisionEquality(self, target, num, denom):
+        """Adds `target == num // denom` (integer division rounded towards 0)."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.int_div.vars.extend(
+            [self.GetOrMakeIndex(num),
+             self.GetOrMakeIndex(denom)])
+        model_ct.int_div.target = self.GetOrMakeIndex(target)
+        return ct
+
+    def AddAbsEquality(self, target, var):
+        """Adds `target == Abs(var)`."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        index = self.GetOrMakeIndex(var)
+        model_ct.int_max.vars.extend([index, -index - 1])
+        model_ct.int_max.target = self.GetOrMakeIndex(target)
+        return ct
+
+    def AddModuloEquality(self, target, var, mod):
+        """Adds `target = var % mod`."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.int_mod.vars.extend(
+            [self.GetOrMakeIndex(var),
+             self.GetOrMakeIndex(mod)])
+        model_ct.int_mod.target = self.GetOrMakeIndex(target)
+        return ct
+
+    def AddMultiplicationEquality(self, target, variables):
+        """Adds `target == variables[0] * .. * variables[n]`."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.int_prod.vars.extend(
+            [self.GetOrMakeIndex(x) for x in variables])
+        model_ct.int_prod.target = self.GetOrMakeIndex(target)
+        return ct
+
+    def AddProdEquality(self, target, variables):
+        """Deprecated, use AddMultiplicationEquality."""
+        warnings.warn(
+            'AddProdEquality is deprecated; use' + 'AddMultiplicationEquality.',
+            DeprecationWarning)
+        return self.AddMultiplicationEquality(target, variables)
+
+    # Scheduling support
+
+    def NewIntervalVar(self, start, size, end, name):
+        """Creates an interval variable from start, size, and end.
+
+    An interval variable is a constraint, that is itself used in other
+    constraints like NoOverlap.
+
+    Internally, it ensures that `start + size == end`.
+
+    Args:
+      start: The start of the interval. It can be an affine or constant
+        expression.
+      size: The size of the interval. It can be an affine or constant
+        expression.
+      end: The end of the interval. It can be an affine or constant expression.
+      name: The name of the interval variable.
+
+    Returns:
+      An `IntervalVar` object.
+    """
+
+        self.Add(start + size == end)
+
+        start_view = self.ParseLinearExpression(start)
+        size_view = self.ParseLinearExpression(size)
+        end_view = self.ParseLinearExpression(end)
+        if len(start_view.vars) > 1:
+            raise TypeError(
+                'cp_model.NewIntervalVar: start must be affine or constant.')
+        if len(size_view.vars) > 1:
+            raise TypeError(
+                'cp_model.NewIntervalVar: size must be affine or constant.')
+        if len(end_view.vars) > 1:
+            raise TypeError(
+                'cp_model.NewIntervalVar: end must be affine or constant.')
+        return IntervalVar(self.__model, start_view, size_view, end_view, None,
+                           name)
+
+    def NewFixedSizeIntervalVar(self, start, size, name):
+        """Creates an interval variable from start, and a fixed size.
+
+    An interval variable is a constraint, that is itself used in other
+    constraints like NoOverlap.
+
+    Args:
+      start: The start of the interval. It can be an affine or constant
+        expression.
+      size: The size of the interval. It must be an integer value.
+      name: The name of the interval variable.
+
+    Returns:
+      An `IntervalVar` object.
+    """
+        cp_model_helper.AssertIsInt64(size)
+        start_view = self.ParseLinearExpression(start)
+        size_view = self.ParseLinearExpression(size)
+        end_view = self.ParseLinearExpression(start + size)
+        if len(start_view.vars) > 1:
+            raise TypeError(
+                'cp_model.NewIntervalVar: start must be affine or constant.')
+        return IntervalVar(self.__model, start_view, size_view, end_view, None,
+                           name)
+
+    def NewOptionalIntervalVar(self, start, size, end, is_present, name):
+        """Creates an optional interval var from start, size, end, and is_present.
+
+    An optional interval variable is a constraint, that is itself used in other
+    constraints like NoOverlap. This constraint is protected by an is_present
+    literal that indicates if it is active or not.
+
+    Internally, it ensures that `is_present` implies `start + size == end`.
+
+    Args:
+      start: The start of the interval. It can be an integer value, or an
+        integer variable.
+      size: The size of the interval. It can be an integer value, or an integer
+        variable.
+      end: The end of the interval. It can be an integer value, or an integer
+        variable.
+      is_present: A literal that indicates if the interval is active or not. A
+        inactive interval is simply ignored by all constraints.
+      name: The name of the interval variable.
+
+    Returns:
+      An `IntervalVar` object.
+    """
+
+        # Add the linear constraint.
+        self.Add(start + size == end).OnlyEnforceIf(is_present)
+
+        # Creates the IntervalConstraintProto object.
+        is_present_index = self.GetOrMakeBooleanIndex(is_present)
+        start_view = self.ParseLinearExpression(start)
+        size_view = self.ParseLinearExpression(size)
+        end_view = self.ParseLinearExpression(end)
+        if len(start_view.vars) > 1:
+            raise TypeError(
+                'cp_model.NewIntervalVar: start must be affine or constant.')
+        if len(size_view.vars) > 1:
+            raise TypeError(
+                'cp_model.NewIntervalVar: size must be affine or constant.')
+        if len(end_view.vars) > 1:
+            raise TypeError(
+                'cp_model.NewIntervalVar: end must be affine or constant.')
+        return IntervalVar(self.__model, start_view, size_view, end_view,
+                           is_present_index, name)
+
+    def NewOptionalFixedSizeIntervalVar(self, start, size, is_present, name):
+        """Creates an interval variable from start, and a fixed size.
+
+    An interval variable is a constraint, that is itself used in other
+    constraints like NoOverlap.
+
+    Args:
+      start: The start of the interval. It can be an affine or constant
+        expression.
+      size: The size of the interval. It must be an integer value.
+      is_present: A literal that indicates if the interval is active or not. A
+        inactive interval is simply ignored by all constraints.
+      name: The name of the interval variable.
+
+    Returns:
+      An `IntervalVar` object.
+    """
+        cp_model_helper.AssertIsInt64(size)
+        start_view = self.ParseLinearExpression(start)
+        size_view = self.ParseLinearExpression(size)
+        end_view = self.ParseLinearExpression(start + size)
+        if len(start_view.vars) > 1:
+            raise TypeError(
+                'cp_model.NewIntervalVar: start must be affine or constant.')
+        is_present_index = self.GetOrMakeBooleanIndex(is_present)
+        return IntervalVar(self.__model, start_view, size_view, end_view,
+                           is_present_index, name)
+
+    def AddNoOverlap(self, interval_vars):
+        """Adds NoOverlap(interval_vars).
+
+    A NoOverlap constraint ensures that all present intervals do not overlap
+    in time.
+
+    Args:
+      interval_vars: The list of interval variables to constrain.
+
+    Returns:
+      An instance of the `Constraint` class.
+    """
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.no_overlap.intervals.extend(
+            [self.GetIntervalIndex(x) for x in interval_vars])
+        return ct
+
+    def AddNoOverlap2D(self, x_intervals, y_intervals):
+        """Adds NoOverlap2D(x_intervals, y_intervals).
+
+    A NoOverlap2D constraint ensures that all present rectangles do not overlap
+    on a plane. Each rectangle is aligned with the X and Y axis, and is defined
+    by two intervals which represent its projection onto the X and Y axis.
+
+    Args:
+      x_intervals: The X coordinates of the rectangles.
+      y_intervals: The Y coordinates of the rectangles.
+
+    Returns:
+      An instance of the `Constraint` class.
+    """
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.no_overlap_2d.x_intervals.extend(
+            [self.GetIntervalIndex(x) for x in x_intervals])
+        model_ct.no_overlap_2d.y_intervals.extend(
+            [self.GetIntervalIndex(x) for x in y_intervals])
+        return ct
+
+    def AddCumulative(self, intervals, demands, capacity):
+        """Adds Cumulative(intervals, demands, capacity).
+
+    This constraint enforces that:
+
+        for all t:
+          sum(demands[i]
+            if (start(intervals[t]) <= t < end(intervals[t])) and
+            (t is present)) <= capacity
+
+    Args:
+      intervals: The list of intervals.
+      demands: The list of demands for each interval. Each demand must be >= 0.
+        Each demand can be an integer value, or an integer variable.
+      capacity: The maximum capacity of the cumulative constraint. It must be a
+        positive integer value or variable.
+
+    Returns:
+      An instance of the `Constraint` class.
+    """
+        return self.AddCumulativeWithEnergy(intervals, demands, [], capacity)
+
+    def AddCumulativeWithEnergy(self, intervals, demands, energies, capacity):
+        """Adds Cumulative(intervals, demands, energies, capacity).
+
+    This constraint enforces that:
+
+        for all t:
+          sum(demands[i]
+            if (start(intervals[t]) <= t < end(intervals[t])) and
+            (t is present)) <= capacity
+
+    The constraint assumes that:
+
+        for all t:
+          energies[t] == size(intervals[t]) * demands[t]
+
+    Args:
+      intervals: The list of intervals.
+      demands: The list of demands for each interval. Each demand must be >= 0.
+        Each demand can be an integer value, or an integer variable.
+      energies: The list of linear expressions representing the energy of each
+        task. This information is optional, and if given must be compatible with
+        the demand and the size of each task (energy = size * demand).
+      capacity: The maximum capacity of the cumulative constraint. It must be a
+        positive integer value or variable.
+
+    Returns:
+      An instance of the `Constraint` class.
+    """
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.cumulative.intervals.extend(
+            [self.GetIntervalIndex(x) for x in intervals])
+        model_ct.cumulative.demands.extend(
+            [self.GetOrMakeIndex(x) for x in demands])
+        for e in energies:
+            model_ct.cumulative.energies.append(self.ParseLinearExpression(e))
+        model_ct.cumulative.capacity = self.GetOrMakeIndex(capacity)
+        return ct
+
+    # Support for deep copy.
+    def CopyFrom(self, other_model):
+        """Reset the model, and creates a new one from a CpModelProto instance."""
+        self.__model.CopyFrom(other_model.Proto())
+
+        # Rebuild constant map.
+        self.__constant_map.clear()
+        for i, var in enumerate(self.__model.variables):
+            if len(var.domain) == 2 and var.domain[0] == var.domain[1]:
+                self.__constant_map[var.domain[0]] = i
+
+    def GetBoolVarFromProtoIndex(self, index):
+        """Returns an already created Boolean variable from its index."""
+        if index < 0 or index >= len(self.__model.variables):
+            raise ValueError(
+                f'GetBoolVarFromProtoIndex: out of bound index {index}')
+        var = self.__model.variables[index]
+        if len(var.domain) != 2 or var.domain[0] < 0 or var.domain[1] > 1:
+            raise ValueError(
+                f'GetBoolVarFromProtoIndex: index {index} does not reference' +
+                ' a Boolean variable')
+
+        return IntVar(self.__model, index, None)
+
+    def GetIntVarFromProtoIndex(self, index):
+        """Returns an already created integer variable from its index."""
+        if index < 0 or index >= len(self.__model.variables):
+            raise ValueError(
+                f'GetIntVarFromProtoIndex: out of bound index {index}')
+        return IntVar(self.__model, index, None)
+
+    def GetIntervalVarFromProtoIndex(self, index):
+        """Returns an already created interval variable from its index."""
+        if index < 0 or index >= len(self.__model.constraints):
+            raise ValueError(
+                f'GetIntervalVarFromProtoIndex: out of bound index {index}')
+        ct = self.__model.constraints[index]
+        if not ct.HasField('interval'):
+            raise ValueError(
+                f'GetIntervalVarFromProtoIndex: index {index} does not reference an'
+                + ' interval variable')
+
+        return IntervalVar(self.__model, index, None, None, None, None)
+
+    # Helpers.
+
+    def __str__(self):
+        return str(self.__model)
+
+    def Proto(self):
+        """Returns the underlying CpModelProto."""
+        return self.__model
+
+    def Negated(self, index):
+        return -index - 1
+
+    def GetOrMakeIndex(self, arg):
+        """Returns the index of a variable, its negation, or a number."""
+        if isinstance(arg, IntVar):
+            return arg.Index()
+        elif (isinstance(arg, _ProductCst) and
+              isinstance(arg.Expression(), IntVar) and arg.Coefficient() == -1):
+            return -arg.Expression().Index() - 1
+        elif isinstance(arg, numbers.Integral):
+            cp_model_helper.AssertIsInt64(arg)
+            return self.GetOrMakeIndexFromConstant(arg)
+        else:
+            raise TypeError('NotSupported: model.GetOrMakeIndex(' + str(arg) +
+                            ')')
+
+    def GetOrMakeBooleanIndex(self, arg):
+        """Returns an index from a boolean expression."""
+        if isinstance(arg, IntVar):
+            self.AssertIsBooleanVariable(arg)
+            return arg.Index()
+        elif isinstance(arg, _NotBooleanVariable):
+            self.AssertIsBooleanVariable(arg.Not())
+            return arg.Index()
+        elif isinstance(arg, numbers.Integral):
+            cp_model_helper.AssertIsBoolean(arg)
+            return self.GetOrMakeIndexFromConstant(arg)
+        else:
+            raise TypeError('NotSupported: model.GetOrMakeBooleanIndex(' +
+                            str(arg) + ')')
+
+    def GetIntervalIndex(self, arg):
+        if not isinstance(arg, IntervalVar):
+            raise TypeError('NotSupported: model.GetIntervalIndex(%s)' % arg)
+        return arg.Index()
+
+    def GetOrMakeIndexFromConstant(self, value):
+        if value in self.__constant_map:
+            return self.__constant_map[value]
+        index = len(self.__model.variables)
+        var = self.__model.variables.add()
+        var.domain.extend([value, value])
+        self.__constant_map[value] = index
+        return index
+
+    def VarIndexToVarProto(self, var_index):
+        if var_index >= 0:
+            return self.__model.variables[var_index]
+        else:
+            return self.__model.variables[-var_index - 1]
+
+    def ParseLinearExpression(self, linear_expr):
+        """Returns a LinearExpressionProto built from a LinearExpr instance."""
+        result = cp_model_pb2.LinearExpressionProto()
+        if isinstance(linear_expr, numbers.Integral):
+            result.offset = linear_expr
+            return result
+
+        if isinstance(linear_expr, IntVar):
+            result.vars.append(self.GetOrMakeIndex(linear_expr))
+            result.coeffs.append(1)
+            return result
+
+        coeffs_map, constant = linear_expr.GetVarValueMap()
+        result.offset = constant
+        for t in coeffs_map.items():
+            if not isinstance(t[0], IntVar):
+                raise TypeError('Wrong argument' + str(t))
+            cp_model_helper.AssertIsInt64(t[1])
+            result.vars.append(t[0].Index())
+            result.coeffs.append(t[1])
+        return result
+
+    def _SetObjective(self, obj, minimize):
+        """Sets the objective of the model."""
+        if isinstance(obj, IntVar):
+            self.__model.ClearField('objective')
+            self.__model.objective.coeffs.append(1)
+            self.__model.objective.offset = 0
+            if minimize:
+                self.__model.objective.vars.append(obj.Index())
+                self.__model.objective.scaling_factor = 1
+            else:
+                self.__model.objective.vars.append(self.Negated(obj.Index()))
+                self.__model.objective.scaling_factor = -1
+        elif isinstance(obj, LinearExpr):
+            coeffs_map, constant = obj.GetVarValueMap()
+            self.__model.ClearField('objective')
+            if minimize:
+                self.__model.objective.scaling_factor = 1
+                self.__model.objective.offset = constant
+            else:
+                self.__model.objective.scaling_factor = -1
+                self.__model.objective.offset = -constant
+            for v, c, in coeffs_map.items():
+                self.__model.objective.coeffs.append(c)
+                if minimize:
+                    self.__model.objective.vars.append(v.Index())
+                else:
+                    self.__model.objective.vars.append(self.Negated(v.Index()))
+        elif isinstance(obj, numbers.Integral):
+            self.__model.objective.offset = obj
+            self.__model.objective.scaling_factor = 1
+        else:
+            raise TypeError('TypeError: ' + str(obj) +
+                            ' is not a valid objective')
+
+    def Minimize(self, obj):
+        """Sets the objective of the model to minimize(obj)."""
+        self._SetObjective(obj, minimize=True)
+
+    def Maximize(self, obj):
+        """Sets the objective of the model to maximize(obj)."""
+        self._SetObjective(obj, minimize=False)
+
+    def HasObjective(self):
+        return self.__model.HasField('objective')
+
+    def AddDecisionStrategy(self, variables, var_strategy, domain_strategy):
+        """Adds a search strategy to the model.
+
+    Args:
+      variables: a list of variables this strategy will assign.
+      var_strategy: heuristic to choose the next variable to assign.
+      domain_strategy: heuristic to reduce the domain of the selected variable.
+        Currently, this is advanced code: the union of all strategies added to
+          the model must be complete, i.e. instantiates all variables.
+          Otherwise, Solve() will fail.
+    """
+
+        strategy = self.__model.search_strategy.add()
+        for v in variables:
+            strategy.variables.append(v.Index())
+        strategy.variable_selection_strategy = var_strategy
+        strategy.domain_reduction_strategy = domain_strategy
+
+    def ModelStats(self):
+        """Returns a string containing some model statistics."""
+        return pywrapsat.CpSatHelper.ModelStats(self.__model)
+
+    def Validate(self):
+        """Returns a string indicating that the model is invalid."""
+        return pywrapsat.CpSatHelper.ValidateModel(self.__model)
+
+    def ExportToFile(self, file):
+        """Write the model as a protocol buffer to 'file'.
+
+    Args:
+      file: file to write the model to. If the filename ends with 'txt', the
+            model will be written as a text file, otherwise, the binary format
+            will be used.
+
+
+    Returns:
+      True if the model was correctly written.
+    """
+        return pywrapsat.CpSatHelper.WriteModelToFile(self.__model, file)
+
+    def AssertIsBooleanVariable(self, x):
+        if isinstance(x, IntVar):
+            var = self.__model.variables[x.Index()]
+            if len(var.domain) != 2 or var.domain[0] < 0 or var.domain[1] > 1:
+                raise TypeError('TypeError: ' + str(x) +
+                                ' is not a boolean variable')
+        elif not isinstance(x, _NotBooleanVariable):
+            raise TypeError('TypeError: ' + str(x) +
+                            ' is not a boolean variable')
+
+    def AddHint(self, var, value):
+        """Adds 'var == value' as a hint to the solver."""
+        self.__model.solution_hint.vars.append(self.GetOrMakeIndex(var))
+        self.__model.solution_hint.values.append(value)
+
+    def ClearHints(self):
+        """Remove any solution hint from the model."""
+        self.__model.ClearField('solution_hint')
+
+    def AddAssumption(self, lit):
+        """Add the literal 'lit' to the model as assumptions."""
+        self.__model.assumptions.append(self.GetOrMakeBooleanIndex(lit))
+
+    def AddAssumptions(self, literals):
+        """Add the literals to the model as assumptions."""
+        for lit in literals:
+            self.AddAssumption(lit)
+
+    def ClearAssumptions(self):
+        """Remove all assumptions from the model."""
+        self.__model.ClearField('assumptions')
+
+
+def EvaluateLinearExpr(expression, solution):
+    """Evaluate a linear expression against a solution."""
+    if isinstance(expression, numbers.Integral):
+        return expression
+    if not isinstance(expression, LinearExpr):
+        raise TypeError('Cannot interpret %s as a linear expression.' %
+                        expression)
+
+    value = 0
+    to_process = [(expression, 1)]
+    while to_process:
+        expr, coef = to_process.pop()
+        if isinstance(expr, _ProductCst):
+            to_process.append((expr.Expression(), coef * expr.Coefficient()))
+        elif isinstance(expr, _SumArray):
+            for e in expr.Expressions():
+                to_process.append((e, coef))
+            value += expr.Constant() * coef
+        elif isinstance(expr, _ScalProd):
+            for e, c in zip(expr.Expressions(), expr.Coefficients()):
+                to_process.append((e, coef * c))
+            value += expr.Constant() * coef
+        elif isinstance(expr, IntVar):
+            value += coef * solution.solution[expr.Index()]
+        elif isinstance(expr, _NotBooleanVariable):
+            value += coef * (1 - solution.solution[expr.Not().Index()])
+    return value
+
+
+def EvaluateBooleanExpression(literal, solution):
+    """Evaluate a boolean expression against a solution."""
+    if isinstance(literal, numbers.Integral):
+        return bool(literal)
+    elif isinstance(literal, IntVar) or isinstance(literal,
+                                                   _NotBooleanVariable):
+        index = literal.Index()
+        if index >= 0:
+            return bool(solution.solution[index])
+        else:
+            return not solution.solution[-index - 1]
+    else:
+        raise TypeError('Cannot interpret %s as a boolean expression.' %
+                        literal)
+
+
+class CpSolver(object):
+    """Main solver class.
+
+  The purpose of this class is to search for a solution to the model provided
+  to the Solve() method.
+
+  Once Solve() is called, this class allows inspecting the solution found
+  with the Value() and BooleanValue() methods, as well as general statistics
+  about the solve procedure.
+  """
+
+    def __init__(self):
+        self.__model = None
+        self.__solution: cp_model_pb2.CpSolverResponse = None
+        self.parameters = sat_parameters_pb2.SatParameters()
+        self.log_callback = None
+        self.__solve_wrapper: pywrapsat.SolveWrapper = None
+        self.__lock = threading.Lock()
+
+    def Solve(self, model, solution_callback=None):
+        """Solves a problem and passes each solution to the callback if not null."""
+        with self.__lock:
+            solve_wrapper = pywrapsat.SolveWrapper()
+
+        solve_wrapper.SetParameters(self.parameters)
+        if solution_callback is not None:
+            solve_wrapper.AddSolutionCallback(solution_callback)
+
+        if self.log_callback is not None:
+            solve_wrapper.AddLogCallback(self.log_callback)
+
+        self.__solution = solve_wrapper.Solve(model.Proto())
+
+        if solution_callback is not None:
+            solve_wrapper.ClearSolutionCallback(solution_callback)
+
+        with self.__lock:
+            self.__solve_wrapper = None
+
+        return self.__solution.status
+
+    # DEPRECATED, just use Solve() with the callback argument.
+    def SolveWithSolutionCallback(self, model, callback):
+        """DEPRECATED Use Solve() with the callback argument."""
+        warnings.warn("SolveWithSolutionCallback is deprecated; use Solve() with the callback argument.",
+                      DeprecationWarning)
+        return self.Solve(model, callback)
+
+    def SearchForAllSolutions(self, model, callback):
+        """DEPRECATED Use Solve() with the right parameter.
+
+    Search for all solutions of a satisfiability problem.
+
+    This method searches for all feasible solutions of a given model.
+    Then it feeds the solution to the callback.
+
+    Note that the model cannot contain an objective.
+
+    Args:
+      model: The model to solve.
+      callback: The callback that will be called at each solution.
+
+    Returns:
+      The status of the solve:
+
+      * *FEASIBLE* if some solutions have been found
+      * *INFEASIBLE* if the solver has proved there are no solution
+      * *OPTIMAL* if all solutions have been found
+    """
+        warnings.warn("SearchForAllSolutions is deprecated; use Solve() with enumerate_all_solutions = True.",
+                      DeprecationWarning)
+        if model.HasObjective():
+            raise TypeError('Search for all solutions is only defined on '
+                            'satisfiability problems')
+        # Store old parameter.
+        enumerate_all = self.parameters.enumerate_all_solutions
+        self.parameters.enumerate_all_solutions = True
+
+        self.Solve(model, callback)
+
+        # Restore parameter.
+        self.parameters.enumerate_all_solutions = enumerate_all
+        return self.__solution.status
+
+    def StopSearch(self):
+        """Stops the current search asynchronously."""
+        with self.__lock:
+            if self.__solve_wrapper:
+                self.__solve_wrapper.StopSearch()
+
+    def Value(self, expression):
+        """Returns the value of a linear expression after solve."""
+        if not self.__solution:
+            raise RuntimeError('Solve() has not be called.')
+        return EvaluateLinearExpr(expression, self.__solution)
+
+    def BooleanValue(self, literal):
+        """Returns the boolean value of a literal after solve."""
+        if not self.__solution:
+            raise RuntimeError('Solve() has not be called.')
+        return EvaluateBooleanExpression(literal, self.__solution)
+
+    def ObjectiveValue(self):
+        """Returns the value of the objective after solve."""
+        return self.__solution.objective_value
+
+    def BestObjectiveBound(self):
+        """Returns the best lower (upper) bound found when min(max)imizing."""
+        return self.__solution.best_objective_bound
+
+    def StatusName(self, status=None):
+        """Returns the name of the status returned by Solve()."""
+        if status is None:
+            status = self.__solution.status
+        return cp_model_pb2.CpSolverStatus.Name(status)
+
+    def NumBooleans(self):
+        """Returns the number of boolean variables managed by the SAT solver."""
+        return self.__solution.num_booleans
+
+    def NumConflicts(self):
+        """Returns the number of conflicts since the creation of the solver."""
+        return self.__solution.num_conflicts
+
+    def NumBranches(self):
+        """Returns the number of search branches explored by the solver."""
+        return self.__solution.num_branches
+
+    def WallTime(self):
+        """Returns the wall time in seconds since the creation of the solver."""
+        return self.__solution.wall_time
+
+    def UserTime(self):
+        """Returns the user time in seconds since the creation of the solver."""
+        return self.__solution.user_time
+
+    def ResponseStats(self):
+        """Returns some statistics on the solution found as a string."""
+        return pywrapsat.CpSatHelper.SolverResponseStats(self.__solution)
+
+    def ResponseProto(self):
+        """Returns the response object."""
+        return self.__solution
+
+    def SufficientAssumptionsForInfeasibility(self):
+        """Returns the indices of the infeasible assumptions."""
+        return self.__solution.sufficient_assumptions_for_infeasibility
+
+
+class CpSolverSolutionCallback(pywrapsat.SolutionCallback):
+    """Solution callback.
+
+  This class implements a callback that will be called at each new solution
+  found during search.
+
+  The method OnSolutionCallback() will be called by the solver, and must be
+  implemented. The current solution can be queried using the BooleanValue()
+  and Value() methods.
+
+  It inherits the following methods from its base class:
+
+  * `ObjectiveValue(self)`
+  * `BestObjectiveBound(self)`
+  * `NumBooleans(self)`
+  * `NumConflicts(self)`
+  * `NumBranches(self)`
+  * `WallTime(self)`
+  * `UserTime(self)`
+
+  These methods returns the same information as their counterpart in the
+  `CpSolver` class.
+  """
+
+    def __init__(self):
+        pywrapsat.SolutionCallback.__init__(self)
+
+    def OnSolutionCallback(self):
+        """Proxy for the same method in snake case."""
+        self.on_solution_callback()
+
+    def BooleanValue(self, lit):
+        """Returns the boolean value of a boolean literal.
+
+    Args:
+        lit: A boolean variable or its negation.
+
+    Returns:
+        The Boolean value of the literal in the solution.
+
+    Raises:
+        RuntimeError: if `lit` is not a boolean variable or its negation.
+    """
+        if not self.HasResponse():
+            raise RuntimeError('Solve() has not be called.')
+        if isinstance(lit, numbers.Integral):
+            return bool(lit)
+        elif isinstance(lit, IntVar) or isinstance(lit, _NotBooleanVariable):
+            index = lit.Index()
+            return self.SolutionBooleanValue(index)
+        else:
+            raise TypeError('Cannot interpret %s as a boolean expression.' %
+                            lit)
+
+    def Value(self, expression):
+        """Evaluates an linear expression in the current solution.
+
+    Args:
+        expression: a linear expression of the model.
+
+    Returns:
+        An integer value equal to the evaluation of the linear expression
+        against the current solution.
+
+    Raises:
+        RuntimeError: if 'expression' is not a LinearExpr.
+    """
+        if not self.HasResponse():
+            raise RuntimeError('Solve() has not be called.')
+        if isinstance(expression, numbers.Integral):
+            return expression
+        if not isinstance(expression, LinearExpr):
+            raise TypeError('Cannot interpret %s as a linear expression.' %
+                            expression)
+
+        value = 0
+        to_process = [(expression, 1)]
+        while to_process:
+            expr, coef = to_process.pop()
+            if isinstance(expr, _ProductCst):
+                to_process.append(
+                    (expr.Expression(), coef * expr.Coefficient()))
+            elif isinstance(expr, _SumArray):
+                for e in expr.Expressions():
+                    to_process.append((e, coef))
+                    value += expr.Constant() * coef
+            elif isinstance(expr, _ScalProd):
+                for e, c in zip(expr.Expressions(), expr.Coefficients()):
+                    to_process.append((e, coef * c))
+                value += expr.Constant() * coef
+            elif isinstance(expr, IntVar):
+                value += coef * self.SolutionIntegerValue(expr.Index())
+            elif isinstance(expr, _NotBooleanVariable):
+                value += coef * (1 -
+                                 self.SolutionIntegerValue(expr.Not().Index()))
+        return value
+
+
+class ObjectiveSolutionPrinter(CpSolverSolutionCallback):
+    """Display the objective value and time of intermediate solutions."""
+
+    def __init__(self):
+        CpSolverSolutionCallback.__init__(self)
+        self.__solution_count = 0
+        self.__start_time = time.time()
+
+    def on_solution_callback(self):
+        """Called on each new solution."""
+        current_time = time.time()
+        obj = self.ObjectiveValue()
+        print('Solution %i, time = %0.2f s, objective = %i' %
+              (self.__solution_count, current_time - self.__start_time, obj))
+        self.__solution_count += 1
+
+    def solution_count(self):
+        """Returns the number of solutions found."""
+        return self.__solution_count
+
+
+class VarArrayAndObjectiveSolutionPrinter(CpSolverSolutionCallback):
+    """Print intermediate solutions (objective, variable values, time)."""
+
+    def __init__(self, variables):
+        CpSolverSolutionCallback.__init__(self)
+        self.__variables = variables
+        self.__solution_count = 0
+        self.__start_time = time.time()
+
+    def on_solution_callback(self):
+        """Called on each new solution."""
+        current_time = time.time()
+        obj = self.ObjectiveValue()
+        print('Solution %i, time = %0.2f s, objective = %i' %
+              (self.__solution_count, current_time - self.__start_time, obj))
+        for v in self.__variables:
+            print('  %s = %i' % (v, self.Value(v)), end=' ')
+        print()
+        self.__solution_count += 1
+
+    def solution_count(self):
+        """Returns the number of solutions found."""
+        return self.__solution_count
+
+
+class VarArraySolutionPrinter(CpSolverSolutionCallback):
+    """Print intermediate solutions (variable values, time)."""
+
+    def __init__(self, variables):
+        CpSolverSolutionCallback.__init__(self)
+        self.__variables = variables
+        self.__solution_count = 0
+        self.__start_time = time.time()
+
+    def on_solution_callback(self):
+        """Called on each new solution."""
+        current_time = time.time()
+        print('Solution %i, time = %0.2f s' %
+              (self.__solution_count, current_time - self.__start_time))
+        for v in self.__variables:
+            print('  %s = %i' % (v, self.Value(v)), end=' ')
+        print()
+        self.__solution_count += 1
+
+    def solution_count(self):
+        """Returns the number of solutions found."""
+        return self.__solution_count
+
+ +
+ +
+
+
#   + + + def + DisplayBounds(bounds): +
+ +
+ View Source +
def DisplayBounds(bounds):
+    """Displays a flattened list of intervals."""
+    out = ''
+    for i in range(0, len(bounds), 2):
+        if i != 0:
+            out += ', '
+        if bounds[i] == bounds[i + 1]:
+            out += str(bounds[i])
+        else:
+            out += str(bounds[i]) + '..' + str(bounds[i + 1])
+    return out
+
+ +
+ +

Displays a flattened list of intervals.

+
+ + +
+
+
#   + + + def + ShortName(model, i): +
+ +
+ View Source +
def ShortName(model, i):
+    """Returns a short name of an integer variable, or its negation."""
+    if i < 0:
+        return 'Not(%s)' % ShortName(model, -i - 1)
+    v = model.variables[i]
+    if v.name:
+        return v.name
+    elif len(v.domain) == 2 and v.domain[0] == v.domain[1]:
+        return str(v.domain[0])
+    else:
+        return '[%s]' % DisplayBounds(v.domain)
+
+ +
+ +

Returns a short name of an integer variable, or its negation.

+
+ + +
+
+
#   + + + def + ShortExprName(model, e): +
+ +
+ View Source +
def ShortExprName(model, e):
+    """Pretty-print LinearExpressionProto instances."""
+    if not e.vars:
+        return str(e.offset)
+    if len(e.vars) == 1:
+        var_name = ShortName(model, e.vars[0])
+        coeff = e.coeffs[0]
+        result = ''
+        if coeff == 1:
+            result = var_name
+        elif coeff == -1:
+            result = f'-{var_name}'
+        elif coeff != 0:
+            result = f'{coeff} * {var_name}'
+        if e.offset > 0:
+            result = f'{result} + {e.offset}'
+        elif e.offset < 0:
+            result = f'{result} - {-e.offset}'
+        return result
+    # TODO(user): Support more than affine expressions.
+    return str(e)
+
+ +
+ +

Pretty-print LinearExpressionProto instances.

+
+ + +
+
+
+ #   + + + class + LinearExpr: +
+ +
+ View Source +
class LinearExpr(object):
+    """Holds an integer linear expression.
+
+  A linear expression is built from integer constants and variables.
+  For example, x + 2 * (y - z + 1).
+
+  Linear expressions are used in CP-SAT models in two ways:
+
+  * To define constraints. For example
+
+      model.Add(x + 2 * y <= 5)
+      model.Add(sum(array_of_vars) == 5)
+
+  * To define the objective function. For example
+
+      model.Minimize(x + 2 * y + z)
+
+  For large arrays, you can create constraints and the objective
+  from lists of linear expressions or coefficients as follows:
+
+      model.Minimize(cp_model.LinearExpr.Sum(expressions))
+      model.Add(cp_model.LinearExpr.ScalProd(expressions, coefficients) >= 0)
+  """
+
+    @classmethod
+    def Sum(cls, expressions):
+        """Creates the expression sum(expressions)."""
+        return _SumArray(expressions)
+
+    @classmethod
+    def ScalProd(cls, expressions, coefficients):
+        """Creates the expression sum(expressions[i] * coefficients[i])."""
+        if LinearExpr.IsEmptyOrAllNull(coefficients):
+            return 0
+        else:
+            return _ScalProd(expressions, coefficients)
+
+    @classmethod
+    def Term(cls, expression, coefficient):
+        """Creates `expression * coefficient`."""
+        if coefficient == 0:
+            return 0
+        else:
+            return expression * coefficient
+
+    @classmethod
+    def IsEmptyOrAllNull(cls, coefficients):
+        for c in coefficients:
+            if c != 0:
+                return False
+        return True
+
+    def GetVarValueMap(self):
+        """Scans the expression, and return a list of (var_coef_map, constant)."""
+        coeffs = collections.defaultdict(int)
+        constant = 0
+        to_process = [(self, 1)]
+        while to_process:  # Flatten to avoid recursion.
+            expr, coef = to_process.pop()
+            if isinstance(expr, _ProductCst):
+                to_process.append(
+                    (expr.Expression(), coef * expr.Coefficient()))
+            elif isinstance(expr, _SumArray):
+                for e in expr.Expressions():
+                    to_process.append((e, coef))
+                constant += expr.Constant() * coef
+            elif isinstance(expr, _ScalProd):
+                for e, c in zip(expr.Expressions(), expr.Coefficients()):
+                    to_process.append((e, coef * c))
+                constant += expr.Constant() * coef
+            elif isinstance(expr, IntVar):
+                coeffs[expr] += coef
+            elif isinstance(expr, _NotBooleanVariable):
+                constant += coef
+                coeffs[expr.Not()] -= coef
+            else:
+                raise TypeError('Unrecognized linear expression: ' + str(expr))
+
+        return coeffs, constant
+
+    def __hash__(self):
+        return object.__hash__(self)
+
+    def __abs__(self):
+        raise NotImplementedError(
+            'calling abs() on a linear expression is not supported, '
+            'please use CpModel.AddAbsEquality')
+
+    def __add__(self, expr):
+        return _SumArray([self, expr])
+
+    def __radd__(self, arg):
+        return _SumArray([self, arg])
+
+    def __sub__(self, expr):
+        return _SumArray([self, -expr])
+
+    def __rsub__(self, arg):
+        return _SumArray([-self, arg])
+
+    def __mul__(self, arg):
+        if isinstance(arg, numbers.Integral):
+            if arg == 1:
+                return self
+            elif arg == 0:
+                return 0
+            cp_model_helper.AssertIsInt64(arg)
+            return _ProductCst(self, arg)
+        else:
+            raise TypeError('Not an integer linear expression: ' + str(arg))
+
+    def __rmul__(self, arg):
+        cp_model_helper.AssertIsInt64(arg)
+        if arg == 1:
+            return self
+        return _ProductCst(self, arg)
+
+    def __div__(self, _):
+        raise NotImplementedError(
+            'calling / on a linear expression is not supported, '
+            'please use CpModel.AddDivisionEquality')
+
+    def __truediv__(self, _):
+        raise NotImplementedError(
+            'calling // on a linear expression is not supported, '
+            'please use CpModel.AddDivisionEquality')
+
+    def __mod__(self, _):
+        raise NotImplementedError(
+            'calling %% on a linear expression is not supported, '
+            'please use CpModel.AddModuloEquality')
+
+    def __pow__(self, _):
+        raise NotImplementedError(
+            'calling ** on a linear expression is not supported, '
+            'please use CpModel.AddMultiplicationEquality')
+
+    def __lshift__(self, _):
+        raise NotImplementedError(
+            'calling left shift on a linear expression is not supported')
+
+    def __rshift__(self, _):
+        raise NotImplementedError(
+            'calling right shift on a linear expression is not supported')
+
+    def __and__(self, _):
+        raise NotImplementedError(
+            'calling and on a linear expression is not supported, '
+            'please use CpModel.AddBoolAnd')
+
+    def __or__(self, _):
+        raise NotImplementedError(
+            'calling or on a linear expression is not supported, '
+            'please use CpModel.AddBoolOr')
+
+    def __xor__(self, _):
+        raise NotImplementedError(
+            'calling xor on a linear expression is not supported, '
+            'please use CpModel.AddBoolXor')
+
+    def __neg__(self):
+        return _ProductCst(self, -1)
+
+    def __bool__(self):
+        raise NotImplementedError(
+            'Evaluating a LinearExpr instance as a Boolean is not implemented.')
+
+    def __eq__(self, arg):
+        if arg is None:
+            return False
+        if isinstance(arg, numbers.Integral):
+            cp_model_helper.AssertIsInt64(arg)
+            return BoundedLinearExpression(self, [arg, arg])
+        else:
+            return BoundedLinearExpression(self - arg, [0, 0])
+
+    def __ge__(self, arg):
+        if isinstance(arg, numbers.Integral):
+            cp_model_helper.AssertIsInt64(arg)
+            return BoundedLinearExpression(self, [arg, INT_MAX])
+        else:
+            return BoundedLinearExpression(self - arg, [0, INT_MAX])
+
+    def __le__(self, arg):
+        if isinstance(arg, numbers.Integral):
+            cp_model_helper.AssertIsInt64(arg)
+            return BoundedLinearExpression(self, [INT_MIN, arg])
+        else:
+            return BoundedLinearExpression(self - arg, [INT_MIN, 0])
+
+    def __lt__(self, arg):
+        if isinstance(arg, numbers.Integral):
+            cp_model_helper.AssertIsInt64(arg)
+            if arg == INT_MIN:
+                raise ArithmeticError('< INT_MIN is not supported')
+            return BoundedLinearExpression(self, [INT_MIN, arg - 1])
+        else:
+            return BoundedLinearExpression(self - arg, [INT_MIN, -1])
+
+    def __gt__(self, arg):
+        if isinstance(arg, numbers.Integral):
+            cp_model_helper.AssertIsInt64(arg)
+            if arg == INT_MAX:
+                raise ArithmeticError('> INT_MAX is not supported')
+            return BoundedLinearExpression(self, [arg + 1, INT_MAX])
+        else:
+            return BoundedLinearExpression(self - arg, [1, INT_MAX])
+
+    def __ne__(self, arg):
+        if arg is None:
+            return True
+        if isinstance(arg, numbers.Integral):
+            cp_model_helper.AssertIsInt64(arg)
+            if arg == INT_MAX:
+                return BoundedLinearExpression(self, [INT_MIN, INT_MAX - 1])
+            elif arg == INT_MIN:
+                return BoundedLinearExpression(self, [INT_MIN + 1, INT_MAX])
+            else:
+                return BoundedLinearExpression(
+                    self, [INT_MIN, arg - 1, arg + 1, INT_MAX])
+        else:
+            return BoundedLinearExpression(self - arg,
+                                           [INT_MIN, -1, 1, INT_MAX])
+
+ +
+ +

Holds an integer linear expression.

+ +

A linear expression is built from integer constants and variables. +For example, x + 2 * (y - z + 1).

+ +

Linear expressions are used in CP-SAT models in two ways:

+ +
    +
  • To define constraints. For example

    + +

    model.Add(x + 2 * y <= 5) +model.Add(sum(array_of_vars) == 5)

  • +
  • To define the objective function. For example

    + +

    model.Minimize(x + 2 * y + z)

  • +
+ +

For large arrays, you can create constraints and the objective +from lists of linear expressions or coefficients as follows:

+ +
model.Minimize(cp_model.LinearExpr.Sum(expressions))
+model.Add(cp_model.LinearExpr.ScalProd(expressions, coefficients) >= 0)
+
+
+ + +
+
#   + + + LinearExpr() +
+ + + + +
+
+
#   + +
@classmethod
+ + def + Sum(cls, expressions): +
+ +
+ View Source +
    @classmethod
+    def Sum(cls, expressions):
+        """Creates the expression sum(expressions)."""
+        return _SumArray(expressions)
+
+ +
+ +

Creates the expression sum(expressions).

+
+ + +
+
+
#   + +
@classmethod
+ + def + ScalProd(cls, expressions, coefficients): +
+ +
+ View Source +
    @classmethod
+    def ScalProd(cls, expressions, coefficients):
+        """Creates the expression sum(expressions[i] * coefficients[i])."""
+        if LinearExpr.IsEmptyOrAllNull(coefficients):
+            return 0
+        else:
+            return _ScalProd(expressions, coefficients)
+
+ +
+ +

Creates the expression sum(expressions[i] * coefficients[i]).

+
+ + +
+
+
#   + +
@classmethod
+ + def + Term(cls, expression, coefficient): +
+ +
+ View Source +
    @classmethod
+    def Term(cls, expression, coefficient):
+        """Creates `expression * coefficient`."""
+        if coefficient == 0:
+            return 0
+        else:
+            return expression * coefficient
+
+ +
+ +

Creates expression * coefficient.

+
+ + +
+
+
#   + +
@classmethod
+ + def + IsEmptyOrAllNull(cls, coefficients): +
+ +
+ View Source +
    @classmethod
+    def IsEmptyOrAllNull(cls, coefficients):
+        for c in coefficients:
+            if c != 0:
+                return False
+        return True
+
+ +
+ + + +
+
+
#   + + + def + GetVarValueMap(self): +
+ +
+ View Source +
    def GetVarValueMap(self):
+        """Scans the expression, and return a list of (var_coef_map, constant)."""
+        coeffs = collections.defaultdict(int)
+        constant = 0
+        to_process = [(self, 1)]
+        while to_process:  # Flatten to avoid recursion.
+            expr, coef = to_process.pop()
+            if isinstance(expr, _ProductCst):
+                to_process.append(
+                    (expr.Expression(), coef * expr.Coefficient()))
+            elif isinstance(expr, _SumArray):
+                for e in expr.Expressions():
+                    to_process.append((e, coef))
+                constant += expr.Constant() * coef
+            elif isinstance(expr, _ScalProd):
+                for e, c in zip(expr.Expressions(), expr.Coefficients()):
+                    to_process.append((e, coef * c))
+                constant += expr.Constant() * coef
+            elif isinstance(expr, IntVar):
+                coeffs[expr] += coef
+            elif isinstance(expr, _NotBooleanVariable):
+                constant += coef
+                coeffs[expr.Not()] -= coef
+            else:
+                raise TypeError('Unrecognized linear expression: ' + str(expr))
+
+        return coeffs, constant
+
+ +
+ +

Scans the expression, and return a list of (var_coef_map, constant).

+
+ + +
+
+
+
+ #   + + + class + IntVar(LinearExpr): +
+ +
+ View Source +
class IntVar(LinearExpr):
+    """An integer variable.
+
+  An IntVar is an object that can take on any integer value within defined
+  ranges. Variables appear in constraint like:
+
+      x + y >= 5
+      AllDifferent([x, y, z])
+
+  Solving a model is equivalent to finding, for each variable, a single value
+  from the set of initial values (called the initial domain), such that the
+  model is feasible, or optimal if you provided an objective function.
+  """
+
+    def __init__(self, model, domain, name):
+        """See CpModel.NewIntVar below."""
+        self.__model = model
+        self.__negation = None
+        # Python do not support multiple __init__ methods.
+        # This method is only called from the CpModel class.
+        # We hack the parameter to support the two cases:
+        # case 1:
+        #     model is a CpModelProto, domain is a Domain, and name is a string.
+        # case 2:
+        #     model is a CpModelProto, domain is an index (int), and name is None.
+        if isinstance(domain, numbers.Integral) and name is None:
+            self.__index = domain
+            self.__var = model.variables[domain]
+        else:
+            self.__index = len(model.variables)
+            self.__var = model.variables.add()
+            self.__var.domain.extend(domain.FlattenedIntervals())
+            self.__var.name = name
+
+    def Index(self):
+        """Returns the index of the variable in the model."""
+        return self.__index
+
+    def Proto(self):
+        """Returns the variable protobuf."""
+        return self.__var
+
+    def IsEqualTo(self, other):
+        """Returns true if self == other in the python sense."""
+        if not isinstance(other, IntVar):
+            return False
+        return self.Index() == other.Index()
+
+    def __str__(self):
+        if not self.__var.name:
+            if len(self.__var.domain
+                  ) == 2 and self.__var.domain[0] == self.__var.domain[1]:
+                # Special case for constants.
+                return str(self.__var.domain[0])
+            else:
+                return 'unnamed_var_%i' % self.__index
+        return self.__var.name
+
+    def __repr__(self):
+        return '%s(%s)' % (self.__var.name, DisplayBounds(self.__var.domain))
+
+    def Name(self):
+        return self.__var.name
+
+    def Not(self):
+        """Returns the negation of a Boolean variable.
+
+    This method implements the logical negation of a Boolean variable.
+    It is only valid if the variable has a Boolean domain (0 or 1).
+
+    Note that this method is nilpotent: `x.Not().Not() == x`.
+    """
+
+        for bound in self.__var.domain:
+            if bound < 0 or bound > 1:
+                raise TypeError(
+                    'Cannot call Not on a non boolean variable: %s' % self)
+        if self.__negation is None:
+            self.__negation = _NotBooleanVariable(self)
+        return self.__negation
+
+ +
+ +

An integer variable.

+ +

An IntVar is an object that can take on any integer value within defined +ranges. Variables appear in constraint like:

+ +
x + y >= 5
+AllDifferent([x, y, z])
+
+ +

Solving a model is equivalent to finding, for each variable, a single value +from the set of initial values (called the initial domain), such that the +model is feasible, or optimal if you provided an objective function.

+
+ + +
+
#   + + + IntVar(model, domain, name) +
+ +
+ View Source +
    def __init__(self, model, domain, name):
+        """See CpModel.NewIntVar below."""
+        self.__model = model
+        self.__negation = None
+        # Python do not support multiple __init__ methods.
+        # This method is only called from the CpModel class.
+        # We hack the parameter to support the two cases:
+        # case 1:
+        #     model is a CpModelProto, domain is a Domain, and name is a string.
+        # case 2:
+        #     model is a CpModelProto, domain is an index (int), and name is None.
+        if isinstance(domain, numbers.Integral) and name is None:
+            self.__index = domain
+            self.__var = model.variables[domain]
+        else:
+            self.__index = len(model.variables)
+            self.__var = model.variables.add()
+            self.__var.domain.extend(domain.FlattenedIntervals())
+            self.__var.name = name
+
+ +
+ +

See CpModel.NewIntVar below.

+
+ + +
+
+
#   + + + def + Index(self): +
+ +
+ View Source +
    def Index(self):
+        """Returns the index of the variable in the model."""
+        return self.__index
+
+ +
+ +

Returns the index of the variable in the model.

+
+ + +
+
+
#   + + + def + Proto(self): +
+ +
+ View Source +
    def Proto(self):
+        """Returns the variable protobuf."""
+        return self.__var
+
+ +
+ +

Returns the variable protobuf.

+
+ + +
+
+
#   + + + def + IsEqualTo(self, other): +
+ +
+ View Source +
    def IsEqualTo(self, other):
+        """Returns true if self == other in the python sense."""
+        if not isinstance(other, IntVar):
+            return False
+        return self.Index() == other.Index()
+
+ +
+ +

Returns true if self == other in the python sense.

+
+ + +
+
+
#   + + + def + Name(self): +
+ +
+ View Source +
    def Name(self):
+        return self.__var.name
+
+ +
+ + + +
+
+
#   + + + def + Not(self): +
+ +
+ View Source +
    def Not(self):
+        """Returns the negation of a Boolean variable.
+
+    This method implements the logical negation of a Boolean variable.
+    It is only valid if the variable has a Boolean domain (0 or 1).
+
+    Note that this method is nilpotent: `x.Not().Not() == x`.
+    """
+
+        for bound in self.__var.domain:
+            if bound < 0 or bound > 1:
+                raise TypeError(
+                    'Cannot call Not on a non boolean variable: %s' % self)
+        if self.__negation is None:
+            self.__negation = _NotBooleanVariable(self)
+        return self.__negation
+
+ +
+ +

Returns the negation of a Boolean variable.

+ +

This method implements the logical negation of a Boolean variable. +It is only valid if the variable has a Boolean domain (0 or 1).

+ +

Note that this method is nilpotent: x.Not().Not() == x.

+
+ + +
+
+
Inherited Members
+
+ +
+
+
+
+
+ #   + + + class + BoundedLinearExpression: +
+ +
+ View Source +
class BoundedLinearExpression(object):
+    """Represents a linear constraint: `lb <= linear expression <= ub`.
+
+  The only use of this class is to be added to the CpModel through
+  `CpModel.Add(expression)`, as in:
+
+      model.Add(x + 2 * y -1 >= z)
+  """
+
+    def __init__(self, expr, bounds):
+        self.__expr = expr
+        self.__bounds = bounds
+
+    def __str__(self):
+        if len(self.__bounds) == 2:
+            lb = self.__bounds[0]
+            ub = self.__bounds[1]
+            if lb > INT_MIN and ub < INT_MAX:
+                if lb == ub:
+                    return str(self.__expr) + ' == ' + str(lb)
+                else:
+                    return str(lb) + ' <= ' + str(
+                        self.__expr) + ' <= ' + str(ub)
+            elif lb > INT_MIN:
+                return str(self.__expr) + ' >= ' + str(lb)
+            elif ub < INT_MAX:
+                return str(self.__expr) + ' <= ' + str(ub)
+            else:
+                return 'True (unbounded expr ' + str(self.__expr) + ')'
+        elif (len(self.__bounds) == 4 and self.__bounds[0] == INT_MIN and
+              self.__bounds[1] + 2 == self.__bounds[2] and
+              self.__bounds[3] == INT_MAX):
+            return str(self.__expr) + ' != ' + str(self.__bounds[1] + 1)
+        else:
+            return str(self.__expr) + ' in [' + DisplayBounds(
+                self.__bounds) + ']'
+
+    def Expression(self):
+        return self.__expr
+
+    def Bounds(self):
+        return self.__bounds
+
+    def __bool__(self):
+        coeffs_map, constant = self.__expr.GetVarValueMap()
+        all_coeffs = set(coeffs_map.values())
+        same_var = set([0])
+        eq_bounds = [0, 0]
+        different_vars = set([-1, 1])
+        ne_bounds = [INT_MIN, -1, 1, INT_MAX]
+        if (len(coeffs_map) == 1 and all_coeffs == same_var and
+                constant == 0 and
+            (self.__bounds == eq_bounds or self.__bounds == ne_bounds)):
+            return self.__bounds == eq_bounds
+        if (len(coeffs_map) == 2 and all_coeffs == different_vars and
+                constant == 0 and
+            (self.__bounds == eq_bounds or self.__bounds == ne_bounds)):
+            return self.__bounds == ne_bounds
+
+        raise NotImplementedError(
+            f'Evaluating a BoundedLinearExpression \'{self}\' as a Boolean value'
+            + ' is not supported.')
+
+ +
+ +

Represents a linear constraint: lb <= linear expression <= ub.

+

The only use of this class is to be added to the CpModel through -CpModel.Add()(expression), as in:

+CpModel.Add(expression), as in:

+
model.Add(x + 2 * y -1 >= z)
-
-
- -Expand source code - -
class BoundedLinearExpression(object):
-    """Represents a linear constraint: `lb <= linear expression <= ub`.
+
+ - The only use of this class is to be added to the CpModel through - `CpModel.Add(expression)`, as in: - model.Add(x + 2 * y -1 >= z) - """ +
+
#   - def __init__(self, expr, bounds): - self.__expr = expr - self.__bounds = bounds + + BoundedLinearExpression(expr, bounds) +
- def __str__(self): - if len(self.__bounds) == 2: - lb = self.__bounds[0] - ub = self.__bounds[1] - if lb > INT_MIN and ub < INT_MAX: - if lb == ub: - return str(self.__expr) + ' == ' + str(lb) - else: - return str(lb) + ' <= ' + str( - self.__expr) + ' <= ' + str(ub) - elif lb > INT_MIN: - return str(self.__expr) + ' >= ' + str(lb) - elif ub < INT_MAX: - return str(self.__expr) + ' <= ' + str(ub) - else: - return 'True (unbounded expr ' + str(self.__expr) + ')' - else: - return str(self.__expr) + ' in [' + DisplayBounds( - self.__bounds) + ']' +
+ View Source +
    def __init__(self, expr, bounds):
+        self.__expr = expr
+        self.__bounds = bounds
+
- def Expression(self): - return self.__expr +
- def Bounds(self): - return self.__bounds + - def __bool__(self): - # Check for x == y - if self.__bounds == [0, 0]: - coeffs_map, constant = self.__expr.GetVarValueMap() - if constant != 0: - return False - for coeff in coeffs_map.values(): - if coeff != 0: - return False - return True - elif self.__bounds == [INT_MIN, -1, 1, INT_MAX]: - # Check for x != y - coeffs_map, constant = self.__expr.GetVarValueMap() - if constant != 0: - return True - for coeff in coeffs_map.values(): - if coeff != 0: - return True - return False +
+
+
#   + + + def + Expression(self): +
+ +
+ View Source +
    def Expression(self):
+        return self.__expr
+
+ +
+ + + +
+
+
#   + + + def + Bounds(self): +
+ +
+ View Source +
    def Bounds(self):
+        return self.__bounds
+
+ +
+ + + +
+
+
+
+ #   + + + class + Constraint: +
+ +
+ View Source +
class Constraint(object):
+    """Base class for constraints.
+
+  Constraints are built by the CpModel through the Add<XXX> methods.
+  Once created by the CpModel class, they are automatically added to the model.
+  The purpose of this class is to allow specification of enforcement literals
+  for this constraint.
+
+      b = model.NewBoolVar('b')
+      x = model.NewIntVar(0, 10, 'x')
+      y = model.NewIntVar(0, 10, 'y')
+
+      model.Add(x + 2 * y == 5).OnlyEnforceIf(b.Not())
+  """
+
+    def __init__(self, constraints):
+        self.__index = len(constraints)
+        self.__constraint = constraints.add()
+
+    def OnlyEnforceIf(self, boolvar):
+        """Adds an enforcement literal to the constraint.
+
+    This method adds one or more literals (that is, a boolean variable or its
+    negation) as enforcement literals. The conjunction of all these literals
+    determines whether the constraint is active or not. It acts as an
+    implication, so if the conjunction is true, it implies that the constraint
+    must be enforced. If it is false, then the constraint is ignored.
+
+    BoolOr, BoolAnd, and linear constraints all support enforcement literals.
+
+    Args:
+      boolvar: A boolean literal or a list of boolean literals.
+
+    Returns:
+      self.
+    """
+
+        if isinstance(boolvar, numbers.Integral) and boolvar == 1:
+            # Always true. Do nothing.
+            pass
+        elif isinstance(boolvar, list):
+            for b in boolvar:
+                if isinstance(b, numbers.Integral) and b == 1:
+                    pass
+                else:
+                    self.__constraint.enforcement_literal.append(b.Index())
+        else:
+            self.__constraint.enforcement_literal.append(boolvar.Index())
+        return self
+
+    def Index(self):
+        """Returns the index of the constraint in the model."""
+        return self.__index
+
+    def Proto(self):
+        """Returns the constraint protobuf."""
+        return self.__constraint
+
+ +
+ +

Base class for constraints.

- raise NotImplementedError( - 'Evaluating a BoundedLinearExpr as a Boolean value is not supported.' - )
- -

Methods

-
-
-def Bounds(self) -
-
-
-
- -Expand source code - -
def Bounds(self):
-    return self.__bounds
-
-
-
-def Expression(self) -
-
-
-
- -Expand source code - -
def Expression(self):
-    return self.__expr
-
-
-
- -
-class Constraint -(constraints) -
-
-

Base class for constraints.

Constraints are built by the CpModel through the Add methods. Once created by the CpModel class, they are automatically added to the model. The purpose of this class is to allow specification of enforcement literals for this constraint.

+
b = model.NewBoolVar('b')
 x = model.NewIntVar(0, 10, 'x')
 y = model.NewIntVar(0, 10, 'y')
 
 model.Add(x + 2 * y == 5).OnlyEnforceIf(b.Not())
-
-
- -Expand source code - -
class Constraint(object):
-    """Base class for constraints.
+
+
- Constraints are built by the CpModel through the Add<XXX> methods. - Once created by the CpModel class, they are automatically added to the model. - The purpose of this class is to allow specification of enforcement literals - for this constraint. - b = model.NewBoolVar('b') - x = model.NewIntVar(0, 10, 'x') - y = model.NewIntVar(0, 10, 'y') +
+
#   - model.Add(x + 2 * y == 5).OnlyEnforceIf(b.Not()) - """ + + Constraint(constraints) +
- def __init__(self, constraints): - self.__index = len(constraints) - self.__constraint = constraints.add() +
+ View Source +
    def __init__(self, constraints):
+        self.__index = len(constraints)
+        self.__constraint = constraints.add()
+
- def OnlyEnforceIf(self, boolvar): - """Adds an enforcement literal to the constraint. +
- This method adds one or more literals (that is, a boolean variable or its - negation) as enforcement literals. The conjunction of all these literals - determines whether the constraint is active or not. It acts as an - implication, so if the conjunction is true, it implies that the constraint - must be enforced. If it is false, then the constraint is ignored. + - BoolOr, BoolAnd, and linear constraints all support enforcement literals. +
+
+
#   - Args: - boolvar: A boolean literal or a list of boolean literals. + + def + OnlyEnforceIf(self, boolvar): +
- Returns: - self. - """ +
+ View Source +
    def OnlyEnforceIf(self, boolvar):
+        """Adds an enforcement literal to the constraint.
 
-        if isinstance(boolvar, numbers.Integral) and boolvar == 1:
-            # Always true. Do nothing.
-            pass
-        elif isinstance(boolvar, list):
-            for b in boolvar:
-                if isinstance(b, numbers.Integral) and b == 1:
-                    pass
-                else:
-                    self.__constraint.enforcement_literal.append(b.Index())
-        else:
-            self.__constraint.enforcement_literal.append(boolvar.Index())
-        return self
+    This method adds one or more literals (that is, a boolean variable or its
+    negation) as enforcement literals. The conjunction of all these literals
+    determines whether the constraint is active or not. It acts as an
+    implication, so if the conjunction is true, it implies that the constraint
+    must be enforced. If it is false, then the constraint is ignored.
 
-    def Index(self):
-        """Returns the index of the constraint in the model."""
-        return self.__index
+    BoolOr, BoolAnd, and linear constraints all support enforcement literals.
+
+    Args:
+      boolvar: A boolean literal or a list of boolean literals.
+
+    Returns:
+      self.
+    """
+
+        if isinstance(boolvar, numbers.Integral) and boolvar == 1:
+            # Always true. Do nothing.
+            pass
+        elif isinstance(boolvar, list):
+            for b in boolvar:
+                if isinstance(b, numbers.Integral) and b == 1:
+                    pass
+                else:
+                    self.__constraint.enforcement_literal.append(b.Index())
+        else:
+            self.__constraint.enforcement_literal.append(boolvar.Index())
+        return self
+
+ +
+ +

Adds an enforcement literal to the constraint.

- def Proto(self): - """Returns the constraint protobuf.""" - return self.__constraint
- -

Methods

-
-
-def Index(self) -
-
-

Returns the index of the constraint in the model.

-
- -Expand source code - -
def Index(self):
-    """Returns the index of the constraint in the model."""
-    return self.__index
-
-
-
-def OnlyEnforceIf(self, boolvar) -
-
-

Adds an enforcement literal to the constraint.

This method adds one or more literals (that is, a boolean variable or its negation) as enforcement literals. The conjunction of all these literals determines whether the constraint is active or not. It acts as an implication, so if the conjunction is true, it implies that the constraint must be enforced. If it is false, then the constraint is ignored.

+

BoolOr, BoolAnd, and linear constraints all support enforcement literals.

-

Args

-
-
boolvar
-
A boolean literal or a list of boolean literals.
-
-

Returns

-

self.

-
- -Expand source code - -
def OnlyEnforceIf(self, boolvar):
-    """Adds an enforcement literal to the constraint.
 
-This method adds one or more literals (that is, a boolean variable or its
-negation) as enforcement literals. The conjunction of all these literals
-determines whether the constraint is active or not. It acts as an
-implication, so if the conjunction is true, it implies that the constraint
-must be enforced. If it is false, then the constraint is ignored.
+
Args
-BoolOr, BoolAnd, and linear constraints all support enforcement literals. +
    +
  • boolvar: A boolean literal or a list of boolean literals.
  • +
-Args: - boolvar: A boolean literal or a list of boolean literals. +
Returns
-Returns: - self. -""" +
+

self.

+
+
+ + +
+
+
#   + + + def + Index(self): +
+ +
+ View Source +
    def Index(self):
+        """Returns the index of the constraint in the model."""
+        return self.__index
+
+ +
+ +

Returns the index of the constraint in the model.

+
+ + +
+
+
#   + + + def + Proto(self): +
+ +
+ View Source +
    def Proto(self):
+        """Returns the constraint protobuf."""
+        return self.__constraint
+
+ +
+ +

Returns the constraint protobuf.

+
+ + +
+
+
+
+ #   + + + class + IntervalVar: +
+ +
+ View Source +
class IntervalVar(object):
+    """Represents an Interval variable.
+
+  An interval variable is both a constraint and a variable. It is defined by
+  three integer variables: start, size, and end.
+
+  It is a constraint because, internally, it enforces that start + size == end.
+
+  It is also a variable as it can appear in specific scheduling constraints:
+  NoOverlap, NoOverlap2D, Cumulative.
+
+  Optionally, an enforcement literal can be added to this constraint, in which
+  case these scheduling constraints will ignore interval variables with
+  enforcement literals assigned to false. Conversely, these constraints will
+  also set these enforcement literals to false if they cannot fit these
+  intervals into the schedule.
+  """
+
+    def __init__(self, model, start_view, size_view, end_view, is_present_index,
+                 name):
+        self.__model = model
+        # As with the IntVar::__init__ method, we hack the __init__ method to
+        # support two use cases:
+        #   case 1: called when creating a new interval variable.
+        #      {start|size|end}_index are indices of integer variables
+        #      is_present_index is either None or the index of a Boolean literal.
+        #      name is a string
+        #   case 2: called when querying an existing interval variable.
+        #      start_index is an int, all parameters after are None.
+        if (size_view is None and end_view is None and
+                is_present_index is None and name is None):
+            self.__index = start_view
+            self.__ct = model.constraints[start_view]
+        else:
+            self.__index = len(model.constraints)
+            self.__ct = self.__model.constraints.add()
+            self.__ct.interval.start_view.CopyFrom(start_view)
+            self.__ct.interval.size_view.CopyFrom(size_view)
+            self.__ct.interval.end_view.CopyFrom(end_view)
+            if is_present_index is not None:
+                self.__ct.enforcement_literal.append(is_present_index)
+            if name:
+                self.__ct.name = name
+
+    def Index(self):
+        """Returns the index of the interval constraint in the model."""
+        return self.__index
+
+    def Proto(self):
+        """Returns the interval protobuf."""
+        return self.__ct.interval
+
+    def __str__(self):
+        return self.__ct.name
+
+    def __repr__(self):
+        interval = self.__ct.interval
+        if self.__ct.enforcement_literal:
+            return '%s(start = %s, size = %s, end = %s, is_present = %s)' % (
+                self.__ct.name, ShortExprName(self.__model,
+                                              interval.start_view),
+                ShortExprName(self.__model, interval.size_view),
+                ShortExprName(self.__model, interval.end_view),
+                ShortName(self.__model, self.__ct.enforcement_literal[0]))
+        else:
+            return '%s(start = %s, size = %s, end = %s)' % (
+                self.__ct.name, ShortExprName(self.__model,
+                                              interval.start_view),
+                ShortExprName(self.__model, interval.size_view),
+                ShortExprName(self.__model, interval.end_view))
+
+    def Name(self):
+        return self.__ct.name
+
+ +
+ +

Represents an Interval variable.

+ +

An interval variable is both a constraint and a variable. It is defined by +three integer variables: start, size, and end.

+ +

It is a constraint because, internally, it enforces that start + size == end.

+ +

It is also a variable as it can appear in specific scheduling constraints: +NoOverlap, NoOverlap2D, Cumulative.

+ +

Optionally, an enforcement literal can be added to this constraint, in which +case these scheduling constraints will ignore interval variables with +enforcement literals assigned to false. Conversely, these constraints will +also set these enforcement literals to false if they cannot fit these +intervals into the schedule.

+
+ + +
+
#   + + + IntervalVar(model, start_view, size_view, end_view, is_present_index, name) +
+ +
+ View Source +
    def __init__(self, model, start_view, size_view, end_view, is_present_index,
+                 name):
+        self.__model = model
+        # As with the IntVar::__init__ method, we hack the __init__ method to
+        # support two use cases:
+        #   case 1: called when creating a new interval variable.
+        #      {start|size|end}_index are indices of integer variables
+        #      is_present_index is either None or the index of a Boolean literal.
+        #      name is a string
+        #   case 2: called when querying an existing interval variable.
+        #      start_index is an int, all parameters after are None.
+        if (size_view is None and end_view is None and
+                is_present_index is None and name is None):
+            self.__index = start_view
+            self.__ct = model.constraints[start_view]
+        else:
+            self.__index = len(model.constraints)
+            self.__ct = self.__model.constraints.add()
+            self.__ct.interval.start_view.CopyFrom(start_view)
+            self.__ct.interval.size_view.CopyFrom(size_view)
+            self.__ct.interval.end_view.CopyFrom(end_view)
+            if is_present_index is not None:
+                self.__ct.enforcement_literal.append(is_present_index)
+            if name:
+                self.__ct.name = name
+
+ +
+ + + +
+
+
#   + + + def + Index(self): +
+ +
+ View Source +
    def Index(self):
+        """Returns the index of the interval constraint in the model."""
+        return self.__index
+
+ +
+ +

Returns the index of the interval constraint in the model.

+
+ + +
+
+
#   + + + def + Proto(self): +
+ +
+ View Source +
    def Proto(self):
+        """Returns the interval protobuf."""
+        return self.__ct.interval
+
+ +
+ +

Returns the interval protobuf.

+
+ + +
+
+
#   + + + def + Name(self): +
+ +
+ View Source +
    def Name(self):
+        return self.__ct.name
+
+ +
+ + + +
+
+
+
#   + + + def + ObjectIsATrueLiteral(literal): +
+ +
+ View Source +
def ObjectIsATrueLiteral(literal):
+    """Checks if literal is either True, or a Boolean literals fixed to True."""
+    if isinstance(literal, IntVar):
+        proto = literal.Proto()
+        return (len(proto.domain) == 2 and proto.domain[0] == 1 and
+                proto.domain[1] == 1)
+    if isinstance(literal, _NotBooleanVariable):
+        proto = literal.Not().Proto()
+        return (len(proto.domain) == 2 and proto.domain[0] == 0 and
+                proto.domain[1] == 0)
+    if isinstance(literal, numbers.Integral):
+        return literal == 1
+    return False
+
+ +
+ +

Checks if literal is either True, or a Boolean literals fixed to True.

+
+ + +
+
+
#   + + + def + ObjectIsAFalseLiteral(literal): +
+ +
+ View Source +
def ObjectIsAFalseLiteral(literal):
+    """Checks if literal is either False, or a Boolean literals fixed to False."""
+    if isinstance(literal, IntVar):
+        proto = literal.Proto()
+        return (len(proto.domain) == 2 and proto.domain[0] == 0 and
+                proto.domain[1] == 0)
+    if isinstance(literal, _NotBooleanVariable):
+        proto = literal.Not().Proto()
+        return (len(proto.domain) == 2 and proto.domain[0] == 1 and
+                proto.domain[1] == 1)
+    if isinstance(literal, numbers.Integral):
+        return literal == 0
+    return False
+
+ +
+ +

Checks if literal is either False, or a Boolean literals fixed to False.

+
+ + +
+
+
+ #   + + + class + CpModel: +
+ +
+ View Source +
class CpModel(object):
+    """Methods for building a CP model.
+
+  Methods beginning with:
+
+  * ```New``` create integer, boolean, or interval variables.
+  * ```Add``` create new constraints and add them to the model.
+  """
+
+    def __init__(self):
+        self.__model = cp_model_pb2.CpModelProto()
+        self.__constant_map = {}
+
+    # Integer variable.
+
+    def NewIntVar(self, lb, ub, name):
+        """Create an integer variable with domain [lb, ub].
+
+    The CP-SAT solver is limited to integer variables. If you have fractional
+    values, scale them up so that they become integers; if you have strings,
+    encode them as integers.
+
+    Args:
+      lb: Lower bound for the variable.
+      ub: Upper bound for the variable.
+      name: The name of the variable.
+
+    Returns:
+      a variable whose domain is [lb, ub].
+    """
+
+        return IntVar(self.__model, Domain(lb, ub), name)
+
+    def NewIntVarFromDomain(self, domain, name):
+        """Create an integer variable from a domain.
+
+    A domain is a set of integers specified by a collection of intervals.
+    For example, `model.NewIntVarFromDomain(cp_model.
+         Domain.FromIntervals([[1, 2], [4, 6]]), 'x')`
+
+    Args:
+      domain: An instance of the Domain class.
+      name: The name of the variable.
+
+    Returns:
+        a variable whose domain is the given domain.
+    """
+        return IntVar(self.__model, domain, name)
+
+    def NewBoolVar(self, name):
+        """Creates a 0-1 variable with the given name."""
+        return IntVar(self.__model, Domain(0, 1), name)
+
+    def NewConstant(self, value):
+        """Declares a constant integer."""
+        return IntVar(self.__model, self.GetOrMakeIndexFromConstant(value),
+                      None)
+
+    # Linear constraints.
+
+    def AddLinearConstraint(self, linear_expr, lb, ub):
+        """Adds the constraint: `lb <= linear_expr <= ub`."""
+        return self.AddLinearExpressionInDomain(linear_expr, Domain(lb, ub))
+
+    def AddLinearExpressionInDomain(self, linear_expr, domain):
+        """Adds the constraint: `linear_expr` in `domain`."""
+        if isinstance(linear_expr, LinearExpr):
+            ct = Constraint(self.__model.constraints)
+            model_ct = self.__model.constraints[ct.Index()]
+            coeffs_map, constant = linear_expr.GetVarValueMap()
+            for t in coeffs_map.items():
+                if not isinstance(t[0], IntVar):
+                    raise TypeError('Wrong argument' + str(t))
+                cp_model_helper.AssertIsInt64(t[1])
+                model_ct.linear.vars.append(t[0].Index())
+                model_ct.linear.coeffs.append(t[1])
+            model_ct.linear.domain.extend([
+                cp_model_helper.CapSub(x, constant)
+                for x in domain.FlattenedIntervals()
+            ])
+            return ct
+        elif isinstance(linear_expr, numbers.Integral):
+            if not domain.Contains(linear_expr):
+                return self.AddBoolOr([])  # Evaluate to false.
+            # Nothing to do otherwise.
+        else:
+            raise TypeError(
+                'Not supported: CpModel.AddLinearExpressionInDomain(' +
+                str(linear_expr) + ' ' + str(domain) + ')')
+
+    def Add(self, ct):
+        """Adds a `BoundedLinearExpression` to the model.
+
+    Args:
+      ct: A [`BoundedLinearExpression`](#boundedlinearexpression).
+
+    Returns:
+      An instance of the `Constraint` class.
+    """
+        if isinstance(ct, BoundedLinearExpression):
+            return self.AddLinearExpressionInDomain(
+                ct.Expression(), Domain.FromFlatIntervals(ct.Bounds()))
+        elif ct and isinstance(ct, bool):
+            return self.AddBoolOr([True])
+        elif not ct and isinstance(ct, bool):
+            return self.AddBoolOr([])  # Evaluate to false.
+        else:
+            raise TypeError('Not supported: CpModel.Add(' + str(ct) + ')')
+
+    # General Integer Constraints.
+
+    def AddAllDifferent(self, variables):
+        """Adds AllDifferent(variables).
+
+    This constraint forces all variables to have different values.
+
+    Args:
+      variables: a list of integer variables.
+
+    Returns:
+      An instance of the `Constraint` class.
+    """
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.all_diff.vars.extend(
+            [self.GetOrMakeIndex(x) for x in variables])
+        return ct
+
+    def AddElement(self, index, variables, target):
+        """Adds the element constraint: `variables[index] == target`."""
+
+        if not variables:
+            raise ValueError('AddElement expects a non-empty variables array')
+
+        if isinstance(index, numbers.Integral):
+            return self.Add(list(variables)[index] == target)
+
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.element.index = self.GetOrMakeIndex(index)
+        model_ct.element.vars.extend(
+            [self.GetOrMakeIndex(x) for x in variables])
+        model_ct.element.target = self.GetOrMakeIndex(target)
+        return ct
+
+    def AddCircuit(self, arcs):
+        """Adds Circuit(arcs).
+
+    Adds a circuit constraint from a sparse list of arcs that encode the graph.
+
+    A circuit is a unique Hamiltonian path in a subgraph of the total
+    graph. In case a node 'i' is not in the path, then there must be a
+    loop arc 'i -> i' associated with a true literal. Otherwise
+    this constraint will fail.
+
+    Args:
+      arcs: a list of arcs. An arc is a tuple (source_node, destination_node,
+        literal). The arc is selected in the circuit if the literal is true.
+        Both source_node and destination_node must be integers between 0 and the
+        number of nodes - 1.
+
+    Returns:
+      An instance of the `Constraint` class.
+
+    Raises:
+      ValueError: If the list of arcs is empty.
+    """
+        if not arcs:
+            raise ValueError('AddCircuit expects a non-empty array of arcs')
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        for arc in arcs:
+            cp_model_helper.AssertIsInt32(arc[0])
+            cp_model_helper.AssertIsInt32(arc[1])
+            lit = self.GetOrMakeBooleanIndex(arc[2])
+            model_ct.circuit.tails.append(arc[0])
+            model_ct.circuit.heads.append(arc[1])
+            model_ct.circuit.literals.append(lit)
+        return ct
+
+    def AddAllowedAssignments(self, variables, tuples_list):
+        """Adds AllowedAssignments(variables, tuples_list).
+
+    An AllowedAssignments constraint is a constraint on an array of variables,
+    which requires that when all variables are assigned values, the resulting
+    array equals one of the  tuples in `tuple_list`.
+
+    Args:
+      variables: A list of variables.
+      tuples_list: A list of admissible tuples. Each tuple must have the same
+        length as the variables, and the ith value of a tuple corresponds to the
+        ith variable.
+
+    Returns:
+      An instance of the `Constraint` class.
+
+    Raises:
+      TypeError: If a tuple does not have the same size as the list of
+          variables.
+      ValueError: If the array of variables is empty.
+    """
+
+        if not variables:
+            raise ValueError(
+                'AddAllowedAssignments expects a non-empty variables '
+                'array')
+
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.table.vars.extend([self.GetOrMakeIndex(x) for x in variables])
+        arity = len(variables)
+        for t in tuples_list:
+            if len(t) != arity:
+                raise TypeError('Tuple ' + str(t) + ' has the wrong arity')
+            for v in t:
+                cp_model_helper.AssertIsInt64(v)
+            model_ct.table.values.extend(t)
+        return ct
+
+    def AddForbiddenAssignments(self, variables, tuples_list):
+        """Adds AddForbiddenAssignments(variables, [tuples_list]).
+
+    A ForbiddenAssignments constraint is a constraint on an array of variables
+    where the list of impossible combinations is provided in the tuples list.
+
+    Args:
+      variables: A list of variables.
+      tuples_list: A list of forbidden tuples. Each tuple must have the same
+        length as the variables, and the *i*th value of a tuple corresponds to
+        the *i*th variable.
+
+    Returns:
+      An instance of the `Constraint` class.
+
+    Raises:
+      TypeError: If a tuple does not have the same size as the list of
+                 variables.
+      ValueError: If the array of variables is empty.
+    """
+
+        if not variables:
+            raise ValueError(
+                'AddForbiddenAssignments expects a non-empty variables '
+                'array')
+
+        index = len(self.__model.constraints)
+        ct = self.AddAllowedAssignments(variables, tuples_list)
+        self.__model.constraints[index].table.negated = True
+        return ct
+
+    def AddAutomaton(self, transition_variables, starting_state, final_states,
+                     transition_triples):
+        """Adds an automaton constraint.
+
+    An automaton constraint takes a list of variables (of size *n*), an initial
+    state, a set of final states, and a set of transitions. A transition is a
+    triplet (*tail*, *transition*, *head*), where *tail* and *head* are states,
+    and *transition* is the label of an arc from *head* to *tail*,
+    corresponding to the value of one variable in the list of variables.
+
+    This automaton will be unrolled into a flow with *n* + 1 phases. Each phase
+    contains the possible states of the automaton. The first state contains the
+    initial state. The last phase contains the final states.
+
+    Between two consecutive phases *i* and *i* + 1, the automaton creates a set
+    of arcs. For each transition (*tail*, *transition*, *head*), it will add
+    an arc from the state *tail* of phase *i* and the state *head* of phase
+    *i* + 1. This arc is labeled by the value *transition* of the variables
+    `variables[i]`. That is, this arc can only be selected if `variables[i]`
+    is assigned the value *transition*.
+
+    A feasible solution of this constraint is an assignment of variables such
+    that, starting from the initial state in phase 0, there is a path labeled by
+    the values of the variables that ends in one of the final states in the
+    final phase.
+
+    Args:
+      transition_variables: A non-empty list of variables whose values
+        correspond to the labels of the arcs traversed by the automaton.
+      starting_state: The initial state of the automaton.
+      final_states: A non-empty list of admissible final states.
+      transition_triples: A list of transitions for the automaton, in the
+        following format (current_state, variable_value, next_state).
+
+    Returns:
+      An instance of the `Constraint` class.
+
+    Raises:
+      ValueError: if `transition_variables`, `final_states`, or
+        `transition_triples` are empty.
+    """
+
+        if not transition_variables:
+            raise ValueError(
+                'AddAutomaton expects a non-empty transition_variables '
+                'array')
+        if not final_states:
+            raise ValueError('AddAutomaton expects some final states')
+
+        if not transition_triples:
+            raise ValueError('AddAutomaton expects some transition triples')
+
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.automaton.vars.extend(
+            [self.GetOrMakeIndex(x) for x in transition_variables])
+        cp_model_helper.AssertIsInt64(starting_state)
+        model_ct.automaton.starting_state = starting_state
+        for v in final_states:
+            cp_model_helper.AssertIsInt64(v)
+            model_ct.automaton.final_states.append(v)
+        for t in transition_triples:
+            if len(t) != 3:
+                raise TypeError('Tuple ' + str(t) +
+                                ' has the wrong arity (!= 3)')
+            cp_model_helper.AssertIsInt64(t[0])
+            cp_model_helper.AssertIsInt64(t[1])
+            cp_model_helper.AssertIsInt64(t[2])
+            model_ct.automaton.transition_tail.append(t[0])
+            model_ct.automaton.transition_label.append(t[1])
+            model_ct.automaton.transition_head.append(t[2])
+        return ct
+
+    def AddInverse(self, variables, inverse_variables):
+        """Adds Inverse(variables, inverse_variables).
+
+    An inverse constraint enforces that if `variables[i]` is assigned a value
+    `j`, then `inverse_variables[j]` is assigned a value `i`. And vice versa.
+
+    Args:
+      variables: An array of integer variables.
+      inverse_variables: An array of integer variables.
+
+    Returns:
+      An instance of the `Constraint` class.
+
+    Raises:
+      TypeError: if variables and inverse_variables have different lengths, or
+          if they are empty.
+    """
+
+        if not variables or not inverse_variables:
+            raise TypeError(
+                'The Inverse constraint does not accept empty arrays')
+        if len(variables) != len(inverse_variables):
+            raise TypeError(
+                'In the inverse constraint, the two array variables and'
+                ' inverse_variables must have the same length.')
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.inverse.f_direct.extend(
+            [self.GetOrMakeIndex(x) for x in variables])
+        model_ct.inverse.f_inverse.extend(
+            [self.GetOrMakeIndex(x) for x in inverse_variables])
+        return ct
+
+    def AddReservoirConstraint(self, times, demands, min_level, max_level):
+        """Adds Reservoir(times, demands, min_level, max_level).
+
+    Maintains a reservoir level within bounds. The water level starts at 0, and
+    at any time, it must be between min_level and max_level.
+
+    If the variable `times[i]` is assigned a value t, then the current level
+    changes by `demands[i]`, which is constant, at time t.
+
+     Note that min level must be <= 0, and the max level must be >= 0. Please
+     use fixed demands to simulate initial state.
+
+     Therefore, at any time:
+         sum(demands[i] if times[i] <= t) in [min_level, max_level]
+
+    Args:
+      times: A list of integer variables which specify the time of the filling
+        or emptying the reservoir.
+      demands: A list of integer values that specifies the amount of the
+        emptying or filling.
+      min_level: At any time, the level of the reservoir must be greater or
+        equal than the min level.
+      max_level: At any time, the level of the reservoir must be less or equal
+        than the max level.
+
+    Returns:
+      An instance of the `Constraint` class.
+
+    Raises:
+      ValueError: if max_level < min_level.
+
+      ValueError: if max_level < 0.
+
+      ValueError: if min_level > 0
+    """
+
+        if max_level < min_level:
+            return ValueError(
+                'Reservoir constraint must have a max_level >= min_level')
+
+        if max_level < 0:
+            return ValueError('Reservoir constraint must have a max_level >= 0')
+
+        if min_level > 0:
+            return ValueError('Reservoir constraint must have a min_level <= 0')
+
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.reservoir.times.extend([self.GetOrMakeIndex(x) for x in times])
+        model_ct.reservoir.demands.extend(demands)
+        model_ct.reservoir.min_level = min_level
+        model_ct.reservoir.max_level = max_level
+        return ct
+
+    def AddReservoirConstraintWithActive(self, times, demands, actives,
+                                         min_level, max_level):
+        """Adds Reservoir(times, demands, actives, min_level, max_level).
+
+    Maintains a reservoir level within bounds. The water level starts at 0, and
+    at any time, it must be between min_level and max_level.
+
+    If the variable `times[i]` is assigned a value t, and `actives[i]` is
+    `True`, then the current level changes by `demands[i]`, which is constant,
+    at time t.
+
+     Note that min level must be <= 0, and the max level must be >= 0. Please
+     use fixed demands to simulate initial state.
+
+     Therefore, at any time:
+         sum(demands[i] * actives[i] if times[i] <= t) in [min_level, max_level]
+
+
+    The array of boolean variables 'actives', if defined, indicates which
+    actions are actually performed.
+
+    Args:
+      times: A list of integer variables which specify the time of the filling
+        or emptying the reservoir.
+      demands: A list of integer values that specifies the amount of the
+        emptying or filling.
+      actives: a list of boolean variables. They indicates if the
+        emptying/refilling events actually take place.
+      min_level: At any time, the level of the reservoir must be greater or
+        equal than the min level.
+      max_level: At any time, the level of the reservoir must be less or equal
+        than the max level.
+
+    Returns:
+      An instance of the `Constraint` class.
+
+    Raises:
+      ValueError: if max_level < min_level.
+
+      ValueError: if max_level < 0.
+
+      ValueError: if min_level > 0
+    """
+
+        if max_level < min_level:
+            return ValueError(
+                'Reservoir constraint must have a max_level >= min_level')
+
+        if max_level < 0:
+            return ValueError('Reservoir constraint must have a max_level >= 0')
+
+        if min_level > 0:
+            return ValueError('Reservoir constraint must have a min_level <= 0')
+
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.reservoir.times.extend([self.GetOrMakeIndex(x) for x in times])
+        model_ct.reservoir.demands.extend(demands)
+        model_ct.reservoir.actives.extend(
+            [self.GetOrMakeIndex(x) for x in actives])
+        model_ct.reservoir.min_level = min_level
+        model_ct.reservoir.max_level = max_level
+        return ct
+
+    def AddMapDomain(self, var, bool_var_array, offset=0):
+        """Adds `var == i + offset <=> bool_var_array[i] == true for all i`."""
+
+        for i, bool_var in enumerate(bool_var_array):
+            b_index = bool_var.Index()
+            var_index = var.Index()
+            model_ct = self.__model.constraints.add()
+            model_ct.linear.vars.append(var_index)
+            model_ct.linear.coeffs.append(1)
+            model_ct.linear.domain.extend([offset + i, offset + i])
+            model_ct.enforcement_literal.append(b_index)
+
+            model_ct = self.__model.constraints.add()
+            model_ct.linear.vars.append(var_index)
+            model_ct.linear.coeffs.append(1)
+            model_ct.enforcement_literal.append(-b_index - 1)
+            if offset + i - 1 >= INT_MIN:
+                model_ct.linear.domain.extend([INT_MIN, offset + i - 1])
+            if offset + i + 1 <= INT_MAX:
+                model_ct.linear.domain.extend([offset + i + 1, INT_MAX])
+
+    def AddImplication(self, a, b):
+        """Adds `a => b` (`a` implies `b`)."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.bool_or.literals.append(self.GetOrMakeBooleanIndex(b))
+        model_ct.enforcement_literal.append(self.GetOrMakeBooleanIndex(a))
+        return ct
+
+    def AddBoolOr(self, literals):
+        """Adds `Or(literals) == true`."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.bool_or.literals.extend(
+            [self.GetOrMakeBooleanIndex(x) for x in literals])
+        return ct
+
+    def AddBoolAnd(self, literals):
+        """Adds `And(literals) == true`."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.bool_and.literals.extend(
+            [self.GetOrMakeBooleanIndex(x) for x in literals])
+        return ct
+
+    def AddBoolXOr(self, literals):
+        """Adds `XOr(literals) == true`."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.bool_xor.literals.extend(
+            [self.GetOrMakeBooleanIndex(x) for x in literals])
+        return ct
+
+    def AddMinEquality(self, target, variables):
+        """Adds `target == Min(variables)`."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.int_min.vars.extend(
+            [self.GetOrMakeIndex(x) for x in variables])
+        model_ct.int_min.target = self.GetOrMakeIndex(target)
+        return ct
+
+    def AddMaxEquality(self, target, variables):
+        """Adds `target == Max(variables)`."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.int_max.vars.extend(
+            [self.GetOrMakeIndex(x) for x in variables])
+        model_ct.int_max.target = self.GetOrMakeIndex(target)
+        return ct
+
+    def AddDivisionEquality(self, target, num, denom):
+        """Adds `target == num // denom` (integer division rounded towards 0)."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.int_div.vars.extend(
+            [self.GetOrMakeIndex(num),
+             self.GetOrMakeIndex(denom)])
+        model_ct.int_div.target = self.GetOrMakeIndex(target)
+        return ct
+
+    def AddAbsEquality(self, target, var):
+        """Adds `target == Abs(var)`."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        index = self.GetOrMakeIndex(var)
+        model_ct.int_max.vars.extend([index, -index - 1])
+        model_ct.int_max.target = self.GetOrMakeIndex(target)
+        return ct
+
+    def AddModuloEquality(self, target, var, mod):
+        """Adds `target = var % mod`."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.int_mod.vars.extend(
+            [self.GetOrMakeIndex(var),
+             self.GetOrMakeIndex(mod)])
+        model_ct.int_mod.target = self.GetOrMakeIndex(target)
+        return ct
+
+    def AddMultiplicationEquality(self, target, variables):
+        """Adds `target == variables[0] * .. * variables[n]`."""
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.int_prod.vars.extend(
+            [self.GetOrMakeIndex(x) for x in variables])
+        model_ct.int_prod.target = self.GetOrMakeIndex(target)
+        return ct
+
+    def AddProdEquality(self, target, variables):
+        """Deprecated, use AddMultiplicationEquality."""
+        warnings.warn(
+            'AddProdEquality is deprecated; use' + 'AddMultiplicationEquality.',
+            DeprecationWarning)
+        return self.AddMultiplicationEquality(target, variables)
+
+    # Scheduling support
+
+    def NewIntervalVar(self, start, size, end, name):
+        """Creates an interval variable from start, size, and end.
+
+    An interval variable is a constraint, that is itself used in other
+    constraints like NoOverlap.
+
+    Internally, it ensures that `start + size == end`.
+
+    Args:
+      start: The start of the interval. It can be an affine or constant
+        expression.
+      size: The size of the interval. It can be an affine or constant
+        expression.
+      end: The end of the interval. It can be an affine or constant expression.
+      name: The name of the interval variable.
+
+    Returns:
+      An `IntervalVar` object.
+    """
+
+        self.Add(start + size == end)
+
+        start_view = self.ParseLinearExpression(start)
+        size_view = self.ParseLinearExpression(size)
+        end_view = self.ParseLinearExpression(end)
+        if len(start_view.vars) > 1:
+            raise TypeError(
+                'cp_model.NewIntervalVar: start must be affine or constant.')
+        if len(size_view.vars) > 1:
+            raise TypeError(
+                'cp_model.NewIntervalVar: size must be affine or constant.')
+        if len(end_view.vars) > 1:
+            raise TypeError(
+                'cp_model.NewIntervalVar: end must be affine or constant.')
+        return IntervalVar(self.__model, start_view, size_view, end_view, None,
+                           name)
+
+    def NewFixedSizeIntervalVar(self, start, size, name):
+        """Creates an interval variable from start, and a fixed size.
+
+    An interval variable is a constraint, that is itself used in other
+    constraints like NoOverlap.
+
+    Args:
+      start: The start of the interval. It can be an affine or constant
+        expression.
+      size: The size of the interval. It must be an integer value.
+      name: The name of the interval variable.
+
+    Returns:
+      An `IntervalVar` object.
+    """
+        cp_model_helper.AssertIsInt64(size)
+        start_view = self.ParseLinearExpression(start)
+        size_view = self.ParseLinearExpression(size)
+        end_view = self.ParseLinearExpression(start + size)
+        if len(start_view.vars) > 1:
+            raise TypeError(
+                'cp_model.NewIntervalVar: start must be affine or constant.')
+        return IntervalVar(self.__model, start_view, size_view, end_view, None,
+                           name)
+
+    def NewOptionalIntervalVar(self, start, size, end, is_present, name):
+        """Creates an optional interval var from start, size, end, and is_present.
+
+    An optional interval variable is a constraint, that is itself used in other
+    constraints like NoOverlap. This constraint is protected by an is_present
+    literal that indicates if it is active or not.
+
+    Internally, it ensures that `is_present` implies `start + size == end`.
+
+    Args:
+      start: The start of the interval. It can be an integer value, or an
+        integer variable.
+      size: The size of the interval. It can be an integer value, or an integer
+        variable.
+      end: The end of the interval. It can be an integer value, or an integer
+        variable.
+      is_present: A literal that indicates if the interval is active or not. A
+        inactive interval is simply ignored by all constraints.
+      name: The name of the interval variable.
+
+    Returns:
+      An `IntervalVar` object.
+    """
+
+        # Add the linear constraint.
+        self.Add(start + size == end).OnlyEnforceIf(is_present)
+
+        # Creates the IntervalConstraintProto object.
+        is_present_index = self.GetOrMakeBooleanIndex(is_present)
+        start_view = self.ParseLinearExpression(start)
+        size_view = self.ParseLinearExpression(size)
+        end_view = self.ParseLinearExpression(end)
+        if len(start_view.vars) > 1:
+            raise TypeError(
+                'cp_model.NewIntervalVar: start must be affine or constant.')
+        if len(size_view.vars) > 1:
+            raise TypeError(
+                'cp_model.NewIntervalVar: size must be affine or constant.')
+        if len(end_view.vars) > 1:
+            raise TypeError(
+                'cp_model.NewIntervalVar: end must be affine or constant.')
+        return IntervalVar(self.__model, start_view, size_view, end_view,
+                           is_present_index, name)
+
+    def NewOptionalFixedSizeIntervalVar(self, start, size, is_present, name):
+        """Creates an interval variable from start, and a fixed size.
+
+    An interval variable is a constraint, that is itself used in other
+    constraints like NoOverlap.
+
+    Args:
+      start: The start of the interval. It can be an affine or constant
+        expression.
+      size: The size of the interval. It must be an integer value.
+      is_present: A literal that indicates if the interval is active or not. A
+        inactive interval is simply ignored by all constraints.
+      name: The name of the interval variable.
+
+    Returns:
+      An `IntervalVar` object.
+    """
+        cp_model_helper.AssertIsInt64(size)
+        start_view = self.ParseLinearExpression(start)
+        size_view = self.ParseLinearExpression(size)
+        end_view = self.ParseLinearExpression(start + size)
+        if len(start_view.vars) > 1:
+            raise TypeError(
+                'cp_model.NewIntervalVar: start must be affine or constant.')
+        is_present_index = self.GetOrMakeBooleanIndex(is_present)
+        return IntervalVar(self.__model, start_view, size_view, end_view,
+                           is_present_index, name)
+
+    def AddNoOverlap(self, interval_vars):
+        """Adds NoOverlap(interval_vars).
+
+    A NoOverlap constraint ensures that all present intervals do not overlap
+    in time.
+
+    Args:
+      interval_vars: The list of interval variables to constrain.
+
+    Returns:
+      An instance of the `Constraint` class.
+    """
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.no_overlap.intervals.extend(
+            [self.GetIntervalIndex(x) for x in interval_vars])
+        return ct
+
+    def AddNoOverlap2D(self, x_intervals, y_intervals):
+        """Adds NoOverlap2D(x_intervals, y_intervals).
+
+    A NoOverlap2D constraint ensures that all present rectangles do not overlap
+    on a plane. Each rectangle is aligned with the X and Y axis, and is defined
+    by two intervals which represent its projection onto the X and Y axis.
+
+    Args:
+      x_intervals: The X coordinates of the rectangles.
+      y_intervals: The Y coordinates of the rectangles.
+
+    Returns:
+      An instance of the `Constraint` class.
+    """
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.no_overlap_2d.x_intervals.extend(
+            [self.GetIntervalIndex(x) for x in x_intervals])
+        model_ct.no_overlap_2d.y_intervals.extend(
+            [self.GetIntervalIndex(x) for x in y_intervals])
+        return ct
+
+    def AddCumulative(self, intervals, demands, capacity):
+        """Adds Cumulative(intervals, demands, capacity).
+
+    This constraint enforces that:
+
+        for all t:
+          sum(demands[i]
+            if (start(intervals[t]) <= t < end(intervals[t])) and
+            (t is present)) <= capacity
+
+    Args:
+      intervals: The list of intervals.
+      demands: The list of demands for each interval. Each demand must be >= 0.
+        Each demand can be an integer value, or an integer variable.
+      capacity: The maximum capacity of the cumulative constraint. It must be a
+        positive integer value or variable.
+
+    Returns:
+      An instance of the `Constraint` class.
+    """
+        return self.AddCumulativeWithEnergy(intervals, demands, [], capacity)
+
+    def AddCumulativeWithEnergy(self, intervals, demands, energies, capacity):
+        """Adds Cumulative(intervals, demands, energies, capacity).
+
+    This constraint enforces that:
+
+        for all t:
+          sum(demands[i]
+            if (start(intervals[t]) <= t < end(intervals[t])) and
+            (t is present)) <= capacity
+
+    The constraint assumes that:
+
+        for all t:
+          energies[t] == size(intervals[t]) * demands[t]
+
+    Args:
+      intervals: The list of intervals.
+      demands: The list of demands for each interval. Each demand must be >= 0.
+        Each demand can be an integer value, or an integer variable.
+      energies: The list of linear expressions representing the energy of each
+        task. This information is optional, and if given must be compatible with
+        the demand and the size of each task (energy = size * demand).
+      capacity: The maximum capacity of the cumulative constraint. It must be a
+        positive integer value or variable.
+
+    Returns:
+      An instance of the `Constraint` class.
+    """
+        ct = Constraint(self.__model.constraints)
+        model_ct = self.__model.constraints[ct.Index()]
+        model_ct.cumulative.intervals.extend(
+            [self.GetIntervalIndex(x) for x in intervals])
+        model_ct.cumulative.demands.extend(
+            [self.GetOrMakeIndex(x) for x in demands])
+        for e in energies:
+            model_ct.cumulative.energies.append(self.ParseLinearExpression(e))
+        model_ct.cumulative.capacity = self.GetOrMakeIndex(capacity)
+        return ct
+
+    # Support for deep copy.
+    def CopyFrom(self, other_model):
+        """Reset the model, and creates a new one from a CpModelProto instance."""
+        self.__model.CopyFrom(other_model.Proto())
+
+        # Rebuild constant map.
+        self.__constant_map.clear()
+        for i, var in enumerate(self.__model.variables):
+            if len(var.domain) == 2 and var.domain[0] == var.domain[1]:
+                self.__constant_map[var.domain[0]] = i
+
+    def GetBoolVarFromProtoIndex(self, index):
+        """Returns an already created Boolean variable from its index."""
+        if index < 0 or index >= len(self.__model.variables):
+            raise ValueError(
+                f'GetBoolVarFromProtoIndex: out of bound index {index}')
+        var = self.__model.variables[index]
+        if len(var.domain) != 2 or var.domain[0] < 0 or var.domain[1] > 1:
+            raise ValueError(
+                f'GetBoolVarFromProtoIndex: index {index} does not reference' +
+                ' a Boolean variable')
+
+        return IntVar(self.__model, index, None)
+
+    def GetIntVarFromProtoIndex(self, index):
+        """Returns an already created integer variable from its index."""
+        if index < 0 or index >= len(self.__model.variables):
+            raise ValueError(
+                f'GetIntVarFromProtoIndex: out of bound index {index}')
+        return IntVar(self.__model, index, None)
+
+    def GetIntervalVarFromProtoIndex(self, index):
+        """Returns an already created interval variable from its index."""
+        if index < 0 or index >= len(self.__model.constraints):
+            raise ValueError(
+                f'GetIntervalVarFromProtoIndex: out of bound index {index}')
+        ct = self.__model.constraints[index]
+        if not ct.HasField('interval'):
+            raise ValueError(
+                f'GetIntervalVarFromProtoIndex: index {index} does not reference an'
+                + ' interval variable')
+
+        return IntervalVar(self.__model, index, None, None, None, None)
+
+    # Helpers.
+
+    def __str__(self):
+        return str(self.__model)
+
+    def Proto(self):
+        """Returns the underlying CpModelProto."""
+        return self.__model
+
+    def Negated(self, index):
+        return -index - 1
+
+    def GetOrMakeIndex(self, arg):
+        """Returns the index of a variable, its negation, or a number."""
+        if isinstance(arg, IntVar):
+            return arg.Index()
+        elif (isinstance(arg, _ProductCst) and
+              isinstance(arg.Expression(), IntVar) and arg.Coefficient() == -1):
+            return -arg.Expression().Index() - 1
+        elif isinstance(arg, numbers.Integral):
+            cp_model_helper.AssertIsInt64(arg)
+            return self.GetOrMakeIndexFromConstant(arg)
+        else:
+            raise TypeError('NotSupported: model.GetOrMakeIndex(' + str(arg) +
+                            ')')
+
+    def GetOrMakeBooleanIndex(self, arg):
+        """Returns an index from a boolean expression."""
+        if isinstance(arg, IntVar):
+            self.AssertIsBooleanVariable(arg)
+            return arg.Index()
+        elif isinstance(arg, _NotBooleanVariable):
+            self.AssertIsBooleanVariable(arg.Not())
+            return arg.Index()
+        elif isinstance(arg, numbers.Integral):
+            cp_model_helper.AssertIsBoolean(arg)
+            return self.GetOrMakeIndexFromConstant(arg)
+        else:
+            raise TypeError('NotSupported: model.GetOrMakeBooleanIndex(' +
+                            str(arg) + ')')
+
+    def GetIntervalIndex(self, arg):
+        if not isinstance(arg, IntervalVar):
+            raise TypeError('NotSupported: model.GetIntervalIndex(%s)' % arg)
+        return arg.Index()
+
+    def GetOrMakeIndexFromConstant(self, value):
+        if value in self.__constant_map:
+            return self.__constant_map[value]
+        index = len(self.__model.variables)
+        var = self.__model.variables.add()
+        var.domain.extend([value, value])
+        self.__constant_map[value] = index
+        return index
+
+    def VarIndexToVarProto(self, var_index):
+        if var_index >= 0:
+            return self.__model.variables[var_index]
+        else:
+            return self.__model.variables[-var_index - 1]
+
+    def ParseLinearExpression(self, linear_expr):
+        """Returns a LinearExpressionProto built from a LinearExpr instance."""
+        result = cp_model_pb2.LinearExpressionProto()
+        if isinstance(linear_expr, numbers.Integral):
+            result.offset = linear_expr
+            return result
+
+        if isinstance(linear_expr, IntVar):
+            result.vars.append(self.GetOrMakeIndex(linear_expr))
+            result.coeffs.append(1)
+            return result
+
+        coeffs_map, constant = linear_expr.GetVarValueMap()
+        result.offset = constant
+        for t in coeffs_map.items():
+            if not isinstance(t[0], IntVar):
+                raise TypeError('Wrong argument' + str(t))
+            cp_model_helper.AssertIsInt64(t[1])
+            result.vars.append(t[0].Index())
+            result.coeffs.append(t[1])
+        return result
+
+    def _SetObjective(self, obj, minimize):
+        """Sets the objective of the model."""
+        if isinstance(obj, IntVar):
+            self.__model.ClearField('objective')
+            self.__model.objective.coeffs.append(1)
+            self.__model.objective.offset = 0
+            if minimize:
+                self.__model.objective.vars.append(obj.Index())
+                self.__model.objective.scaling_factor = 1
+            else:
+                self.__model.objective.vars.append(self.Negated(obj.Index()))
+                self.__model.objective.scaling_factor = -1
+        elif isinstance(obj, LinearExpr):
+            coeffs_map, constant = obj.GetVarValueMap()
+            self.__model.ClearField('objective')
+            if minimize:
+                self.__model.objective.scaling_factor = 1
+                self.__model.objective.offset = constant
+            else:
+                self.__model.objective.scaling_factor = -1
+                self.__model.objective.offset = -constant
+            for v, c, in coeffs_map.items():
+                self.__model.objective.coeffs.append(c)
+                if minimize:
+                    self.__model.objective.vars.append(v.Index())
+                else:
+                    self.__model.objective.vars.append(self.Negated(v.Index()))
+        elif isinstance(obj, numbers.Integral):
+            self.__model.objective.offset = obj
+            self.__model.objective.scaling_factor = 1
+        else:
+            raise TypeError('TypeError: ' + str(obj) +
+                            ' is not a valid objective')
+
+    def Minimize(self, obj):
+        """Sets the objective of the model to minimize(obj)."""
+        self._SetObjective(obj, minimize=True)
+
+    def Maximize(self, obj):
+        """Sets the objective of the model to maximize(obj)."""
+        self._SetObjective(obj, minimize=False)
+
+    def HasObjective(self):
+        return self.__model.HasField('objective')
+
+    def AddDecisionStrategy(self, variables, var_strategy, domain_strategy):
+        """Adds a search strategy to the model.
+
+    Args:
+      variables: a list of variables this strategy will assign.
+      var_strategy: heuristic to choose the next variable to assign.
+      domain_strategy: heuristic to reduce the domain of the selected variable.
+        Currently, this is advanced code: the union of all strategies added to
+          the model must be complete, i.e. instantiates all variables.
+          Otherwise, Solve() will fail.
+    """
+
+        strategy = self.__model.search_strategy.add()
+        for v in variables:
+            strategy.variables.append(v.Index())
+        strategy.variable_selection_strategy = var_strategy
+        strategy.domain_reduction_strategy = domain_strategy
+
+    def ModelStats(self):
+        """Returns a string containing some model statistics."""
+        return pywrapsat.CpSatHelper.ModelStats(self.__model)
+
+    def Validate(self):
+        """Returns a string indicating that the model is invalid."""
+        return pywrapsat.CpSatHelper.ValidateModel(self.__model)
+
+    def ExportToFile(self, file):
+        """Write the model as a protocol buffer to 'file'.
+
+    Args:
+      file: file to write the model to. If the filename ends with 'txt', the
+            model will be written as a text file, otherwise, the binary format
+            will be used.
+
+
+    Returns:
+      True if the model was correctly written.
+    """
+        return pywrapsat.CpSatHelper.WriteModelToFile(self.__model, file)
+
+    def AssertIsBooleanVariable(self, x):
+        if isinstance(x, IntVar):
+            var = self.__model.variables[x.Index()]
+            if len(var.domain) != 2 or var.domain[0] < 0 or var.domain[1] > 1:
+                raise TypeError('TypeError: ' + str(x) +
+                                ' is not a boolean variable')
+        elif not isinstance(x, _NotBooleanVariable):
+            raise TypeError('TypeError: ' + str(x) +
+                            ' is not a boolean variable')
+
+    def AddHint(self, var, value):
+        """Adds 'var == value' as a hint to the solver."""
+        self.__model.solution_hint.vars.append(self.GetOrMakeIndex(var))
+        self.__model.solution_hint.values.append(value)
+
+    def ClearHints(self):
+        """Remove any solution hint from the model."""
+        self.__model.ClearField('solution_hint')
+
+    def AddAssumption(self, lit):
+        """Add the literal 'lit' to the model as assumptions."""
+        self.__model.assumptions.append(self.GetOrMakeBooleanIndex(lit))
+
+    def AddAssumptions(self, literals):
+        """Add the literals to the model as assumptions."""
+        for lit in literals:
+            self.AddAssumption(lit)
+
+    def ClearAssumptions(self):
+        """Remove all assumptions from the model."""
+        self.__model.ClearField('assumptions')
+
+ +
+ +

Methods for building a CP model.

- if isinstance(boolvar, numbers.Integral) and boolvar == 1: - # Always true. Do nothing. - pass - elif isinstance(boolvar, list): - for b in boolvar: - if isinstance(b, numbers.Integral) and b == 1: - pass - else: - self.__constraint.enforcement_literal.append(b.Index()) - else: - self.__constraint.enforcement_literal.append(boolvar.Index()) - return self
- - -
-def Proto(self) -
-
-

Returns the constraint protobuf.

-
- -Expand source code - -
def Proto(self):
-    """Returns the constraint protobuf."""
-    return self.__constraint
-
-
- - -
-class CpModel -
-
-

Methods for building a CP model.

Methods beginning with:

+
  • New create integer, boolean, or interval variables.
  • -
  • Add create new constraints and add them to the model.
  • -
-
- -Expand source code - -
class CpModel(object):
-    """Methods for building a CP model.
-
-  Methods beginning with:
-
-  * ```New``` create integer, boolean, or interval variables.
-  * ```Add``` create new constraints and add them to the model.
-  """
-
-    def __init__(self):
-        self.__model = cp_model_pb2.CpModelProto()
-        self.__constant_map = {}
-
-    # Integer variable.
-
-    def NewIntVar(self, lb, ub, name):
-        """Create an integer variable with domain [lb, ub].
-
-    The CP-SAT solver is limited to integer variables. If you have fractional
-    values, scale them up so that they become integers; if you have strings,
-    encode them as integers.
-
-    Args:
-      lb: Lower bound for the variable.
-      ub: Upper bound for the variable.
-      name: The name of the variable.
-
-    Returns:
-      a variable whose domain is [lb, ub].
-    """
-
-        return IntVar(self.__model, Domain(lb, ub), name)
-
-    def NewIntVarFromDomain(self, domain, name):
-        """Create an integer variable from a domain.
-
-    A domain is a set of integers specified by a collection of intervals.
-    For example, `model.NewIntVarFromDomain(cp_model.
-         Domain.FromIntervals([[1, 2], [4, 6]]), 'x')`
-
-    Args:
-      domain: An instance of the Domain class.
-      name: The name of the variable.
-
-    Returns:
-        a variable whose domain is the given domain.
-    """
-        return IntVar(self.__model, domain, name)
-
-    def NewBoolVar(self, name):
-        """Creates a 0-1 variable with the given name."""
-        return IntVar(self.__model, Domain(0, 1), name)
-
-    def NewConstant(self, value):
-        """Declares a constant integer."""
-        return IntVar(self.__model, self.GetOrMakeIndexFromConstant(value),
-                      None)
-
-    # Linear constraints.
-
-    def AddLinearConstraint(self, linear_expr, lb, ub):
-        """Adds the constraint: `lb <= linear_expr <= ub`."""
-        return self.AddLinearExpressionInDomain(linear_expr, Domain(lb, ub))
-
-    def AddLinearExpressionInDomain(self, linear_expr, domain):
-        """Adds the constraint: `linear_expr` in `domain`."""
-        if isinstance(linear_expr, LinearExpr):
-            ct = Constraint(self.__model.constraints)
-            model_ct = self.__model.constraints[ct.Index()]
-            coeffs_map, constant = linear_expr.GetVarValueMap()
-            for t in coeffs_map.items():
-                if not isinstance(t[0], IntVar):
-                    raise TypeError('Wrong argument' + str(t))
-                cp_model_helper.AssertIsInt64(t[1])
-                model_ct.linear.vars.append(t[0].Index())
-                model_ct.linear.coeffs.append(t[1])
-            model_ct.linear.domain.extend([
-                cp_model_helper.CapSub(x, constant)
-                for x in domain.FlattenedIntervals()
-            ])
-            return ct
-        elif isinstance(linear_expr, numbers.Integral):
-            if not domain.Contains(linear_expr):
-                return self.AddBoolOr([])  # Evaluate to false.
-            # Nothing to do otherwise.
-        else:
-            raise TypeError(
-                'Not supported: CpModel.AddLinearExpressionInDomain(' +
-                str(linear_expr) + ' ' + str(domain) + ')')
-
-    def Add(self, ct):
-        """Adds a `BoundedLinearExpression` to the model.
-
-    Args:
-      ct: A [`BoundedLinearExpression`](#boundedlinearexpression).
-
-    Returns:
-      An instance of the `Constraint` class.
-    """
-        if isinstance(ct, BoundedLinearExpression):
-            return self.AddLinearExpressionInDomain(
-                ct.Expression(), Domain.FromFlatIntervals(ct.Bounds()))
-        elif ct and isinstance(ct, bool):
-            return self.AddBoolOr([True])
-        elif not ct and isinstance(ct, bool):
-            return self.AddBoolOr([])  # Evaluate to false.
-        else:
-            raise TypeError('Not supported: CpModel.Add(' + str(ct) + ')')
-
-    # General Integer Constraints.
-
-    def AddAllDifferent(self, variables):
-        """Adds AllDifferent(variables).
-
-    This constraint forces all variables to have different values.
-
-    Args:
-      variables: a list of integer variables.
-
-    Returns:
-      An instance of the `Constraint` class.
-    """
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.all_diff.vars.extend(
-            [self.GetOrMakeIndex(x) for x in variables])
-        return ct
-
-    def AddElement(self, index, variables, target):
-        """Adds the element constraint: `variables[index] == target`."""
-
-        if not variables:
-            raise ValueError('AddElement expects a non-empty variables array')
-
-        if isinstance(index, numbers.Integral):
-            return self.Add(list(variables)[index] == target)
-
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.element.index = self.GetOrMakeIndex(index)
-        model_ct.element.vars.extend(
-            [self.GetOrMakeIndex(x) for x in variables])
-        model_ct.element.target = self.GetOrMakeIndex(target)
-        return ct
-
-    def AddCircuit(self, arcs):
-        """Adds Circuit(arcs).
-
-    Adds a circuit constraint from a sparse list of arcs that encode the graph.
-
-    A circuit is a unique Hamiltonian path in a subgraph of the total
-    graph. In case a node 'i' is not in the path, then there must be a
-    loop arc 'i -> i' associated with a true literal. Otherwise
-    this constraint will fail.
-
-    Args:
-      arcs: a list of arcs. An arc is a tuple (source_node, destination_node,
-        literal). The arc is selected in the circuit if the literal is true.
-        Both source_node and destination_node must be integers between 0 and the
-        number of nodes - 1.
-
-    Returns:
-      An instance of the `Constraint` class.
-
-    Raises:
-      ValueError: If the list of arcs is empty.
-    """
-        if not arcs:
-            raise ValueError('AddCircuit expects a non-empty array of arcs')
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        for arc in arcs:
-            cp_model_helper.AssertIsInt32(arc[0])
-            cp_model_helper.AssertIsInt32(arc[1])
-            lit = self.GetOrMakeBooleanIndex(arc[2])
-            model_ct.circuit.tails.append(arc[0])
-            model_ct.circuit.heads.append(arc[1])
-            model_ct.circuit.literals.append(lit)
-        return ct
-
-    def AddAllowedAssignments(self, variables, tuples_list):
-        """Adds AllowedAssignments(variables, tuples_list).
-
-    An AllowedAssignments constraint is a constraint on an array of variables,
-    which requires that when all variables are assigned values, the resulting
-    array equals one of the  tuples in `tuple_list`.
-
-    Args:
-      variables: A list of variables.
-      tuples_list: A list of admissible tuples. Each tuple must have the same
-        length as the variables, and the ith value of a tuple corresponds to the
-        ith variable.
-
-    Returns:
-      An instance of the `Constraint` class.
-
-    Raises:
-      TypeError: If a tuple does not have the same size as the list of
-          variables.
-      ValueError: If the array of variables is empty.
-    """
-
-        if not variables:
-            raise ValueError(
-                'AddAllowedAssignments expects a non-empty variables '
-                'array')
-
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.table.vars.extend([self.GetOrMakeIndex(x) for x in variables])
-        arity = len(variables)
-        for t in tuples_list:
-            if len(t) != arity:
-                raise TypeError('Tuple ' + str(t) + ' has the wrong arity')
-            for v in t:
-                cp_model_helper.AssertIsInt64(v)
-            model_ct.table.values.extend(t)
-        return ct
-
-    def AddForbiddenAssignments(self, variables, tuples_list):
-        """Adds AddForbiddenAssignments(variables, [tuples_list]).
-
-    A ForbiddenAssignments constraint is a constraint on an array of variables
-    where the list of impossible combinations is provided in the tuples list.
-
-    Args:
-      variables: A list of variables.
-      tuples_list: A list of forbidden tuples. Each tuple must have the same
-        length as the variables, and the *i*th value of a tuple corresponds to
-        the *i*th variable.
-
-    Returns:
-      An instance of the `Constraint` class.
-
-    Raises:
-      TypeError: If a tuple does not have the same size as the list of
-                 variables.
-      ValueError: If the array of variables is empty.
-    """
-
-        if not variables:
-            raise ValueError(
-                'AddForbiddenAssignments expects a non-empty variables '
-                'array')
-
-        index = len(self.__model.constraints)
-        ct = self.AddAllowedAssignments(variables, tuples_list)
-        self.__model.constraints[index].table.negated = True
-        return ct
-
-    def AddAutomaton(self, transition_variables, starting_state, final_states,
-                     transition_triples):
-        """Adds an automaton constraint.
-
-    An automaton constraint takes a list of variables (of size *n*), an initial
-    state, a set of final states, and a set of transitions. A transition is a
-    triplet (*tail*, *transition*, *head*), where *tail* and *head* are states,
-    and *transition* is the label of an arc from *head* to *tail*,
-    corresponding to the value of one variable in the list of variables.
-
-    This automaton will be unrolled into a flow with *n* + 1 phases. Each phase
-    contains the possible states of the automaton. The first state contains the
-    initial state. The last phase contains the final states.
-
-    Between two consecutive phases *i* and *i* + 1, the automaton creates a set
-    of arcs. For each transition (*tail*, *transition*, *head*), it will add
-    an arc from the state *tail* of phase *i* and the state *head* of phase
-    *i* + 1. This arc is labeled by the value *transition* of the variables
-    `variables[i]`. That is, this arc can only be selected if `variables[i]`
-    is assigned the value *transition*.
-
-    A feasible solution of this constraint is an assignment of variables such
-    that, starting from the initial state in phase 0, there is a path labeled by
-    the values of the variables that ends in one of the final states in the
-    final phase.
-
-    Args:
-      transition_variables: A non-empty list of variables whose values
-        correspond to the labels of the arcs traversed by the automaton.
-      starting_state: The initial state of the automaton.
-      final_states: A non-empty list of admissible final states.
-      transition_triples: A list of transitions for the automaton, in the
-        following format (current_state, variable_value, next_state).
-
-    Returns:
-      An instance of the `Constraint` class.
-
-    Raises:
-      ValueError: if `transition_variables`, `final_states`, or
-        `transition_triples` are empty.
-    """
-
-        if not transition_variables:
-            raise ValueError(
-                'AddAutomaton expects a non-empty transition_variables '
-                'array')
-        if not final_states:
-            raise ValueError('AddAutomaton expects some final states')
-
-        if not transition_triples:
-            raise ValueError('AddAutomaton expects some transition triples')
-
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.automaton.vars.extend(
-            [self.GetOrMakeIndex(x) for x in transition_variables])
-        cp_model_helper.AssertIsInt64(starting_state)
-        model_ct.automaton.starting_state = starting_state
-        for v in final_states:
-            cp_model_helper.AssertIsInt64(v)
-            model_ct.automaton.final_states.append(v)
-        for t in transition_triples:
-            if len(t) != 3:
-                raise TypeError('Tuple ' + str(t) +
-                                ' has the wrong arity (!= 3)')
-            cp_model_helper.AssertIsInt64(t[0])
-            cp_model_helper.AssertIsInt64(t[1])
-            cp_model_helper.AssertIsInt64(t[2])
-            model_ct.automaton.transition_tail.append(t[0])
-            model_ct.automaton.transition_label.append(t[1])
-            model_ct.automaton.transition_head.append(t[2])
-        return ct
-
-    def AddInverse(self, variables, inverse_variables):
-        """Adds Inverse(variables, inverse_variables).
-
-    An inverse constraint enforces that if `variables[i]` is assigned a value
-    `j`, then `inverse_variables[j]` is assigned a value `i`. And vice versa.
-
-    Args:
-      variables: An array of integer variables.
-      inverse_variables: An array of integer variables.
-
-    Returns:
-      An instance of the `Constraint` class.
-
-    Raises:
-      TypeError: if variables and inverse_variables have different lengths, or
-          if they are empty.
-    """
-
-        if not variables or not inverse_variables:
-            raise TypeError(
-                'The Inverse constraint does not accept empty arrays')
-        if len(variables) != len(inverse_variables):
-            raise TypeError(
-                'In the inverse constraint, the two array variables and'
-                ' inverse_variables must have the same length.')
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.inverse.f_direct.extend(
-            [self.GetOrMakeIndex(x) for x in variables])
-        model_ct.inverse.f_inverse.extend(
-            [self.GetOrMakeIndex(x) for x in inverse_variables])
-        return ct
-
-    def AddReservoirConstraint(self, times, demands, min_level, max_level):
-        """Adds Reservoir(times, demands, min_level, max_level).
-
-    Maintains a reservoir level within bounds. The water level starts at 0, and
-    at any time, it must be between min_level and max_level.
-
-    If the variable `times[i]` is assigned a value t, then the current level
-    changes by `demands[i]`, which is constant, at time t.
-
-     Note that min level must be <= 0, and the max level must be >= 0. Please
-     use fixed demands to simulate initial state.
-
-     Therefore, at any time:
-         sum(demands[i] if times[i] <= t) in [min_level, max_level]
-
-    Args:
-      times: A list of integer variables which specify the time of the
-        filling or emptying the reservoir.
-      demands: A list of integer values that specifies the amount of the
-        emptying or filling.
-      min_level: At any time, the level of the reservoir must be greater or
-        equal than the min level.
-      max_level: At any time, the level of the reservoir must be less or equal
-        than the max level.
-
-    Returns:
-      An instance of the `Constraint` class.
-
-    Raises:
-      ValueError: if max_level < min_level.
-
-      ValueError: if max_level < 0.
-
-      ValueError: if min_level > 0
-    """
-
-        if max_level < min_level:
-            return ValueError(
-                'Reservoir constraint must have a max_level >= min_level')
-
-        if max_level < 0:
-            return ValueError('Reservoir constraint must have a max_level >= 0')
-
-        if min_level > 0:
-            return ValueError('Reservoir constraint must have a min_level <= 0')
-
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.reservoir.times.extend([self.GetOrMakeIndex(x) for x in times])
-        model_ct.reservoir.demands.extend(demands)
-        model_ct.reservoir.min_level = min_level
-        model_ct.reservoir.max_level = max_level
-        return ct
-
-    def AddReservoirConstraintWithActive(self, times, demands, actives,
-                                         min_level, max_level):
-        """Adds Reservoir(times, demands, actives, min_level, max_level).
-
-    Maintains a reservoir level within bounds. The water level starts at 0, and
-    at any time, it must be between min_level and max_level.
-
-    If the variable `times[i]` is assigned a value t, and `actives[i]` is
-    `True`, then the current level changes by `demands[i]`, which is constant,
-    at time t.
-
-     Note that min level must be <= 0, and the max level must be >= 0. Please
-     use fixed demands to simulate initial state.
-
-     Therefore, at any time:
-         sum(demands[i] * actives[i] if times[i] <= t) in [min_level, max_level]
-
-
-    The array of boolean variables 'actives', if defined, indicates which
-    actions are actually performed.
-
-    Args:
-      times: A list of integer variables which specify the time of the
-        filling or emptying the reservoir.
-      demands: A list of integer values that specifies the amount of the
-        emptying or filling.
-      actives: a list of boolean variables. They indicates if the
-        emptying/refilling events actually take place.
-      min_level: At any time, the level of the reservoir must be greater or
-        equal than the min level.
-      max_level: At any time, the level of the reservoir must be less or equal
-        than the max level.
-
-    Returns:
-      An instance of the `Constraint` class.
-
-    Raises:
-      ValueError: if max_level < min_level.
-
-      ValueError: if max_level < 0.
-
-      ValueError: if min_level > 0
-    """
-
-        if max_level < min_level:
-            return ValueError(
-                'Reservoir constraint must have a max_level >= min_level')
-
-        if max_level < 0:
-            return ValueError('Reservoir constraint must have a max_level >= 0')
-
-        if min_level > 0:
-            return ValueError('Reservoir constraint must have a min_level <= 0')
-
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.reservoir.times.extend([self.GetOrMakeIndex(x) for x in times])
-        model_ct.reservoir.demands.extend(demands)
-        model_ct.reservoir.actives.extend(
-            [self.GetOrMakeIndex(x) for x in actives])
-        model_ct.reservoir.min_level = min_level
-        model_ct.reservoir.max_level = max_level
-        return ct
-
-    def AddMapDomain(self, var, bool_var_array, offset=0):
-        """Adds `var == i + offset <=> bool_var_array[i] == true for all i`."""
-
-        for i, bool_var in enumerate(bool_var_array):
-            b_index = bool_var.Index()
-            var_index = var.Index()
-            model_ct = self.__model.constraints.add()
-            model_ct.linear.vars.append(var_index)
-            model_ct.linear.coeffs.append(1)
-            model_ct.linear.domain.extend([offset + i, offset + i])
-            model_ct.enforcement_literal.append(b_index)
-
-            model_ct = self.__model.constraints.add()
-            model_ct.linear.vars.append(var_index)
-            model_ct.linear.coeffs.append(1)
-            model_ct.enforcement_literal.append(-b_index - 1)
-            if offset + i - 1 >= INT_MIN:
-                model_ct.linear.domain.extend([INT_MIN, offset + i - 1])
-            if offset + i + 1 <= INT_MAX:
-                model_ct.linear.domain.extend([offset + i + 1, INT_MAX])
-
-    def AddImplication(self, a, b):
-        """Adds `a => b` (`a` implies `b`)."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.bool_or.literals.append(self.GetOrMakeBooleanIndex(b))
-        model_ct.enforcement_literal.append(self.GetOrMakeBooleanIndex(a))
-        return ct
-
-    def AddBoolOr(self, literals):
-        """Adds `Or(literals) == true`."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.bool_or.literals.extend(
-            [self.GetOrMakeBooleanIndex(x) for x in literals])
-        return ct
-
-    def AddBoolAnd(self, literals):
-        """Adds `And(literals) == true`."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.bool_and.literals.extend(
-            [self.GetOrMakeBooleanIndex(x) for x in literals])
-        return ct
-
-    def AddBoolXOr(self, literals):
-        """Adds `XOr(literals) == true`."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.bool_xor.literals.extend(
-            [self.GetOrMakeBooleanIndex(x) for x in literals])
-        return ct
-
-    def AddMinEquality(self, target, variables):
-        """Adds `target == Min(variables)`."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.int_min.vars.extend(
-            [self.GetOrMakeIndex(x) for x in variables])
-        model_ct.int_min.target = self.GetOrMakeIndex(target)
-        return ct
-
-    def AddMaxEquality(self, target, variables):
-        """Adds `target == Max(variables)`."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.int_max.vars.extend(
-            [self.GetOrMakeIndex(x) for x in variables])
-        model_ct.int_max.target = self.GetOrMakeIndex(target)
-        return ct
-
-    def AddDivisionEquality(self, target, num, denom):
-        """Adds `target == num // denom` (integer division rounded towards 0)."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.int_div.vars.extend(
-            [self.GetOrMakeIndex(num),
-             self.GetOrMakeIndex(denom)])
-        model_ct.int_div.target = self.GetOrMakeIndex(target)
-        return ct
-
-    def AddAbsEquality(self, target, var):
-        """Adds `target == Abs(var)`."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        index = self.GetOrMakeIndex(var)
-        model_ct.int_max.vars.extend([index, -index - 1])
-        model_ct.int_max.target = self.GetOrMakeIndex(target)
-        return ct
-
-    def AddModuloEquality(self, target, var, mod):
-        """Adds `target = var % mod`."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.int_mod.vars.extend(
-            [self.GetOrMakeIndex(var),
-             self.GetOrMakeIndex(mod)])
-        model_ct.int_mod.target = self.GetOrMakeIndex(target)
-        return ct
-
-    def AddMultiplicationEquality(self, target, variables):
-        """Adds `target == variables[0] * .. * variables[n]`."""
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.int_prod.vars.extend(
-            [self.GetOrMakeIndex(x) for x in variables])
-        model_ct.int_prod.target = self.GetOrMakeIndex(target)
-        return ct
-
-    def AddProdEquality(self, target, variables):
-        """Deprecated, use AddMultiplicationEquality."""
-        return self.AddMultiplicationEquality(target, variables)
-
-    # Scheduling support
-
-    def NewIntervalVar(self, start, size, end, name):
-        """Creates an interval variable from start, size, and end.
-
-    An interval variable is a constraint, that is itself used in other
-    constraints like NoOverlap.
-
-    Internally, it ensures that `start + size == end`.
-
-    Args:
-      start: The start of the interval. It can be an integer value, or an
-        integer variable.
-      size: The size of the interval. It can be an integer value, or an integer
-        variable.
-      end: The end of the interval. It can be an integer value, or an integer
-        variable.
-      name: The name of the interval variable.
-
-    Returns:
-      An `IntervalVar` object.
-    """
-
-        start_index = self.GetOrMakeIndex(start)
-        size_index = self.GetOrMakeIndex(size)
-        end_index = self.GetOrMakeIndex(end)
-        return IntervalVar(self.__model, start_index, size_index, end_index,
-                           None, name)
-
-    def NewOptionalIntervalVar(self, start, size, end, is_present, name):
-        """Creates an optional interval var from start, size, end, and is_present.
-
-    An optional interval variable is a constraint, that is itself used in other
-    constraints like NoOverlap. This constraint is protected by an is_present
-    literal that indicates if it is active or not.
-
-    Internally, it ensures that `is_present` implies `start + size == end`.
-
-    Args:
-      start: The start of the interval. It can be an integer value, or an
-        integer variable.
-      size: The size of the interval. It can be an integer value, or an integer
-        variable.
-      end: The end of the interval. It can be an integer value, or an integer
-        variable.
-      is_present: A literal that indicates if the interval is active or not. A
-        inactive interval is simply ignored by all constraints.
-      name: The name of the interval variable.
-
-    Returns:
-      An `IntervalVar` object.
-    """
-        is_present_index = self.GetOrMakeBooleanIndex(is_present)
-        start_index = self.GetOrMakeIndex(start)
-        size_index = self.GetOrMakeIndex(size)
-        end_index = self.GetOrMakeIndex(end)
-        return IntervalVar(self.__model, start_index, size_index, end_index,
-                           is_present_index, name)
-
-    def AddNoOverlap(self, interval_vars):
-        """Adds NoOverlap(interval_vars).
-
-    A NoOverlap constraint ensures that all present intervals do not overlap
-    in time.
-
-    Args:
-      interval_vars: The list of interval variables to constrain.
-
-    Returns:
-      An instance of the `Constraint` class.
-    """
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.no_overlap.intervals.extend(
-            [self.GetIntervalIndex(x) for x in interval_vars])
-        return ct
-
-    def AddNoOverlap2D(self, x_intervals, y_intervals):
-        """Adds NoOverlap2D(x_intervals, y_intervals).
-
-    A NoOverlap2D constraint ensures that all present rectangles do not overlap
-    on a plane. Each rectangle is aligned with the X and Y axis, and is defined
-    by two intervals which represent its projection onto the X and Y axis.
-
-    Args:
-      x_intervals: The X coordinates of the rectangles.
-      y_intervals: The Y coordinates of the rectangles.
-
-    Returns:
-      An instance of the `Constraint` class.
-    """
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.no_overlap_2d.x_intervals.extend(
-            [self.GetIntervalIndex(x) for x in x_intervals])
-        model_ct.no_overlap_2d.y_intervals.extend(
-            [self.GetIntervalIndex(x) for x in y_intervals])
-        return ct
-
-    def AddCumulative(self, intervals, demands, capacity):
-        """Adds Cumulative(intervals, demands, capacity).
-
-    This constraint enforces that:
-
-        for all t:
-          sum(demands[i]
-            if (start(intervals[t]) <= t < end(intervals[t])) and
-            (t is present)) <= capacity
-
-    Args:
-      intervals: The list of intervals.
-      demands: The list of demands for each interval. Each demand must be >= 0.
-        Each demand can be an integer value, or an integer variable.
-      capacity: The maximum capacity of the cumulative constraint. It must be a
-        positive integer value or variable.
-
-    Returns:
-      An instance of the `Constraint` class.
-    """
-        ct = Constraint(self.__model.constraints)
-        model_ct = self.__model.constraints[ct.Index()]
-        model_ct.cumulative.intervals.extend(
-            [self.GetIntervalIndex(x) for x in intervals])
-        model_ct.cumulative.demands.extend(
-            [self.GetOrMakeIndex(x) for x in demands])
-        model_ct.cumulative.capacity = self.GetOrMakeIndex(capacity)
-        return ct
-
-    # Support for deep copy.
-    def CopyFrom(self, other_model):
-        """Reset the model, and creates a new one from a CpModelProto instance."""
-        self.__model.CopyFrom(other_model.Proto())
-
-        # Rebuild constant map.
-        self.__constant_map.clear()
-        for i, var in enumerate(self.__model.variables):
-            if len(var.domain) == 2 and var.domain[0] == var.domain[1]:
-                self.__constant_map[var.domain[0]] = i
-
-    def GetBoolVarFromProtoIndex(self, index):
-        """Returns an already created Boolean variable from its index."""
-        if index < 0 or index >= len(self.__model.variables):
-            raise ValueError(
-                f'GetBoolVarFromProtoIndex: out of bound index {index}')
-        var = self.__model.variables[index]
-        if len(var.domain) != 2 or var.domain[0] < 0 or var.domain[1] > 1:
-            raise ValueError(
-                f'GetBoolVarFromProtoIndex: index {index} does not reference' +
-                ' a Boolean variable')
-
-        return IntVar(self.__model, index, None)
-
-    def GetIntVarFromProtoIndex(self, index):
-        """Returns an already created integer variable from its index."""
-        if index < 0 or index >= len(self.__model.variables):
-            raise ValueError(
-                f'GetIntVarFromProtoIndex: out of bound index {index}')
-        return IntVar(self.__model, index, None)
-
-    def GetIntervalVarFromProtoIndex(self, index):
-        """Returns an already created interval variable from its index."""
-        if index < 0 or index >= len(self.__model.constraints):
-            raise ValueError(
-                f'GetIntervalVarFromProtoIndex: out of bound index {index}')
-        ct = self.__model.constraints[index]
-        if not ct.HasField('interval'):
-            raise ValueError(
-                f'GetIntervalVarFromProtoIndex: index {index} does not reference an'
-                + ' interval variable')
-
-        return IntervalVar(self.__model, index, None, None, None, None)
-
-    # Helpers.
-
-    def __str__(self):
-        return str(self.__model)
-
-    def Proto(self):
-        """Returns the underlying CpModelProto."""
-        return self.__model
-
-    def Negated(self, index):
-        return -index - 1
-
-    def GetOrMakeIndex(self, arg):
-        """Returns the index of a variable, its negation, or a number."""
-        if isinstance(arg, IntVar):
-            return arg.Index()
-        elif (isinstance(arg, _ProductCst) and
-              isinstance(arg.Expression(), IntVar) and arg.Coefficient() == -1):
-            return -arg.Expression().Index() - 1
-        elif isinstance(arg, numbers.Integral):
-            cp_model_helper.AssertIsInt64(arg)
-            return self.GetOrMakeIndexFromConstant(arg)
-        else:
-            raise TypeError('NotSupported: model.GetOrMakeIndex(' + str(arg) +
-                            ')')
-
-    def GetOrMakeBooleanIndex(self, arg):
-        """Returns an index from a boolean expression."""
-        if isinstance(arg, IntVar):
-            self.AssertIsBooleanVariable(arg)
-            return arg.Index()
-        elif isinstance(arg, _NotBooleanVariable):
-            self.AssertIsBooleanVariable(arg.Not())
-            return arg.Index()
-        elif isinstance(arg, numbers.Integral):
-            cp_model_helper.AssertIsBoolean(arg)
-            return self.GetOrMakeIndexFromConstant(arg)
-        else:
-            raise TypeError('NotSupported: model.GetOrMakeBooleanIndex(' +
-                            str(arg) + ')')
-
-    def GetIntervalIndex(self, arg):
-        if not isinstance(arg, IntervalVar):
-            raise TypeError('NotSupported: model.GetIntervalIndex(%s)' % arg)
-        return arg.Index()
-
-    def GetOrMakeIndexFromConstant(self, value):
-        if value in self.__constant_map:
-            return self.__constant_map[value]
-        index = len(self.__model.variables)
-        var = self.__model.variables.add()
-        var.domain.extend([value, value])
-        self.__constant_map[value] = index
-        return index
-
-    def VarIndexToVarProto(self, var_index):
-        if var_index >= 0:
-            return self.__model.variables[var_index]
-        else:
-            return self.__model.variables[-var_index - 1]
-
-    def _SetObjective(self, obj, minimize):
-        """Sets the objective of the model."""
-        if isinstance(obj, IntVar):
-            self.__model.ClearField('objective')
-            self.__model.objective.coeffs.append(1)
-            self.__model.objective.offset = 0
-            if minimize:
-                self.__model.objective.vars.append(obj.Index())
-                self.__model.objective.scaling_factor = 1
-            else:
-                self.__model.objective.vars.append(self.Negated(obj.Index()))
-                self.__model.objective.scaling_factor = -1
-        elif isinstance(obj, LinearExpr):
-            coeffs_map, constant = obj.GetVarValueMap()
-            self.__model.ClearField('objective')
-            if minimize:
-                self.__model.objective.scaling_factor = 1
-                self.__model.objective.offset = constant
-            else:
-                self.__model.objective.scaling_factor = -1
-                self.__model.objective.offset = -constant
-            for v, c, in coeffs_map.items():
-                self.__model.objective.coeffs.append(c)
-                if minimize:
-                    self.__model.objective.vars.append(v.Index())
-                else:
-                    self.__model.objective.vars.append(self.Negated(v.Index()))
-        elif isinstance(obj, numbers.Integral):
-            self.__model.objective.offset = obj
-            self.__model.objective.scaling_factor = 1
-        else:
-            raise TypeError('TypeError: ' + str(obj) +
-                            ' is not a valid objective')
-
-    def Minimize(self, obj):
-        """Sets the objective of the model to minimize(obj)."""
-        self._SetObjective(obj, minimize=True)
-
-    def Maximize(self, obj):
-        """Sets the objective of the model to maximize(obj)."""
-        self._SetObjective(obj, minimize=False)
-
-    def HasObjective(self):
-        return self.__model.HasField('objective')
-
-    def AddDecisionStrategy(self, variables, var_strategy, domain_strategy):
-        """Adds a search strategy to the model.
-
-    Args:
-      variables: a list of variables this strategy will assign.
-      var_strategy: heuristic to choose the next variable to assign.
-      domain_strategy: heuristic to reduce the domain of the selected variable.
-        Currently, this is advanced code: the union of all strategies added to
-          the model must be complete, i.e. instantiates all variables.
-          Otherwise, Solve() will fail.
-    """
-
-        strategy = self.__model.search_strategy.add()
-        for v in variables:
-            strategy.variables.append(v.Index())
-        strategy.variable_selection_strategy = var_strategy
-        strategy.domain_reduction_strategy = domain_strategy
-
-    def ModelStats(self):
-        """Returns a string containing some model statistics."""
-        return pywrapsat.CpSatHelper.ModelStats(self.__model)
-
-    def Validate(self):
-        """Returns a string indicating that the model is invalid."""
-        return pywrapsat.CpSatHelper.ValidateModel(self.__model)
-
-    def ExportToFile(self, file):
-        """Write the model as a protocol buffer to 'file'.
-
-    Args:
-      file: file to write the model to. If the filename ends with 'txt', the
-            model will be written as a text file, otherwise, the binary format
-            will be used.
-
-
-    Returns:
-      True if the model was correctly written.
-    """
-        return pywrapsat.CpSatHelper.WriteModelToFile(self.__model, file)
-
-    def AssertIsBooleanVariable(self, x):
-        if isinstance(x, IntVar):
-            var = self.__model.variables[x.Index()]
-            if len(var.domain) != 2 or var.domain[0] < 0 or var.domain[1] > 1:
-                raise TypeError('TypeError: ' + str(x) +
-                                ' is not a boolean variable')
-        elif not isinstance(x, _NotBooleanVariable):
-            raise TypeError('TypeError: ' + str(x) +
-                            ' is not a boolean variable')
-
-    def AddHint(self, var, value):
-        """Adds 'var == value' as a hint to the solver."""
-        self.__model.solution_hint.vars.append(self.GetOrMakeIndex(var))
-        self.__model.solution_hint.values.append(value)
-
-    def ClearHints(self):
-        """Remove any solution hint from the model."""
-        self.__model.ClearField('solution_hint')
-
-    def AddAssumption(self, lit):
-        """Add the literal 'lit' to the model as assumptions."""
-        self.__model.assumptions.append(self.GetOrMakeBooleanIndex(lit))
-
-    def AddAssumptions(self, literals):
-        """Add the literals to the model as assumptions."""
-        for lit in literals:
-            self.AddAssumption(lit)
-
-    def ClearAssumptions(self):
-        """Remove all assumptions from the model."""
-        self.__model.ClearField('assumptions')
-
-

Methods

-
-
-def Add(self, ct) -
-
-

Adds a BoundedLinearExpression to the model.

-

Args

-
-
ct
-
A BoundedLinearExpression.
-
-

Returns

-

An instance of the Constraint class.

-
- -Expand source code - -
def Add(self, ct):
-    """Adds a `BoundedLinearExpression` to the model.
-
-Args:
-  ct: A [`BoundedLinearExpression`](#boundedlinearexpression).
-
-Returns:
-  An instance of the `Constraint` class.
-"""
-    if isinstance(ct, BoundedLinearExpression):
-        return self.AddLinearExpressionInDomain(
-            ct.Expression(), Domain.FromFlatIntervals(ct.Bounds()))
-    elif ct and isinstance(ct, bool):
-        return self.AddBoolOr([True])
-    elif not ct and isinstance(ct, bool):
-        return self.AddBoolOr([])  # Evaluate to false.
-    else:
-        raise TypeError('Not supported: CpModel.Add(' + str(ct) + ')')
-
-
-
-def AddAbsEquality(self, target, var) -
-
-

Adds target == Abs(var).

-
- -Expand source code - -
def AddAbsEquality(self, target, var):
-    """Adds `target == Abs(var)`."""
-    ct = Constraint(self.__model.constraints)
-    model_ct = self.__model.constraints[ct.Index()]
-    index = self.GetOrMakeIndex(var)
-    model_ct.int_max.vars.extend([index, -index - 1])
-    model_ct.int_max.target = self.GetOrMakeIndex(target)
-    return ct
-
-
-
-def AddAllDifferent(self, variables) -
-
-

Adds AllDifferent(variables).

+
  • Add create new constraints and add them to the model.
  • + +
    + + +
    +
    #   + + + CpModel() +
    + +
    + View Source +
        def __init__(self):
    +        self.__model = cp_model_pb2.CpModelProto()
    +        self.__constant_map = {}
    +
    + +
    + + + +
    +
    +
    #   + + + def + NewIntVar(self, lb, ub, name): +
    + +
    + View Source +
        def NewIntVar(self, lb, ub, name):
    +        """Create an integer variable with domain [lb, ub].
    +
    +    The CP-SAT solver is limited to integer variables. If you have fractional
    +    values, scale them up so that they become integers; if you have strings,
    +    encode them as integers.
    +
    +    Args:
    +      lb: Lower bound for the variable.
    +      ub: Upper bound for the variable.
    +      name: The name of the variable.
    +
    +    Returns:
    +      a variable whose domain is [lb, ub].
    +    """
    +
    +        return IntVar(self.__model, Domain(lb, ub), name)
    +
    + +
    + +

    Create an integer variable with domain [lb, ub].

    + +

    The CP-SAT solver is limited to integer variables. If you have fractional +values, scale them up so that they become integers; if you have strings, +encode them as integers.

    + +
    Args
    + +
      +
    • lb: Lower bound for the variable.
    • +
    • ub: Upper bound for the variable.
    • +
    • name: The name of the variable.
    • +
    + +
    Returns
    + +
    +

    a variable whose domain is [lb, ub].

    +
    +
    + + +
    +
    +
    #   + + + def + NewIntVarFromDomain(self, domain, name): +
    + +
    + View Source +
        def NewIntVarFromDomain(self, domain, name):
    +        """Create an integer variable from a domain.
    +
    +    A domain is a set of integers specified by a collection of intervals.
    +    For example, `model.NewIntVarFromDomain(cp_model.
    +         Domain.FromIntervals([[1, 2], [4, 6]]), 'x')`
    +
    +    Args:
    +      domain: An instance of the Domain class.
    +      name: The name of the variable.
    +
    +    Returns:
    +        a variable whose domain is the given domain.
    +    """
    +        return IntVar(self.__model, domain, name)
    +
    + +
    + +

    Create an integer variable from a domain.

    + +

    A domain is a set of integers specified by a collection of intervals. +For example, model.NewIntVarFromDomain(cp_model. + Domain.FromIntervals([[1, 2], [4, 6]]), 'x')

    + +
    Args
    + +
      +
    • domain: An instance of the Domain class.
    • +
    • name: The name of the variable.
    • +
    + +
    Returns
    + +
    +

    a variable whose domain is the given domain.

    +
    +
    + + +
    +
    +
    #   + + + def + NewBoolVar(self, name): +
    + +
    + View Source +
        def NewBoolVar(self, name):
    +        """Creates a 0-1 variable with the given name."""
    +        return IntVar(self.__model, Domain(0, 1), name)
    +
    + +
    + +

    Creates a 0-1 variable with the given name.

    +
    + + +
    +
    +
    #   + + + def + NewConstant(self, value): +
    + +
    + View Source +
        def NewConstant(self, value):
    +        """Declares a constant integer."""
    +        return IntVar(self.__model, self.GetOrMakeIndexFromConstant(value),
    +                      None)
    +
    + +
    + +

    Declares a constant integer.

    +
    + + +
    +
    +
    #   + + + def + AddLinearConstraint(self, linear_expr, lb, ub): +
    + +
    + View Source +
        def AddLinearConstraint(self, linear_expr, lb, ub):
    +        """Adds the constraint: `lb <= linear_expr <= ub`."""
    +        return self.AddLinearExpressionInDomain(linear_expr, Domain(lb, ub))
    +
    + +
    + +

    Adds the constraint: lb <= linear_expr <= ub.

    +
    + + +
    +
    +
    #   + + + def + AddLinearExpressionInDomain(self, linear_expr, domain): +
    + +
    + View Source +
        def AddLinearExpressionInDomain(self, linear_expr, domain):
    +        """Adds the constraint: `linear_expr` in `domain`."""
    +        if isinstance(linear_expr, LinearExpr):
    +            ct = Constraint(self.__model.constraints)
    +            model_ct = self.__model.constraints[ct.Index()]
    +            coeffs_map, constant = linear_expr.GetVarValueMap()
    +            for t in coeffs_map.items():
    +                if not isinstance(t[0], IntVar):
    +                    raise TypeError('Wrong argument' + str(t))
    +                cp_model_helper.AssertIsInt64(t[1])
    +                model_ct.linear.vars.append(t[0].Index())
    +                model_ct.linear.coeffs.append(t[1])
    +            model_ct.linear.domain.extend([
    +                cp_model_helper.CapSub(x, constant)
    +                for x in domain.FlattenedIntervals()
    +            ])
    +            return ct
    +        elif isinstance(linear_expr, numbers.Integral):
    +            if not domain.Contains(linear_expr):
    +                return self.AddBoolOr([])  # Evaluate to false.
    +            # Nothing to do otherwise.
    +        else:
    +            raise TypeError(
    +                'Not supported: CpModel.AddLinearExpressionInDomain(' +
    +                str(linear_expr) + ' ' + str(domain) + ')')
    +
    + +
    + +

    Adds the constraint: linear_expr in domain.

    +
    + + +
    +
    +
    #   + + + def + Add(self, ct): +
    + +
    + View Source +
        def Add(self, ct):
    +        """Adds a `BoundedLinearExpression` to the model.
    +
    +    Args:
    +      ct: A [`BoundedLinearExpression`](#boundedlinearexpression).
    +
    +    Returns:
    +      An instance of the `Constraint` class.
    +    """
    +        if isinstance(ct, BoundedLinearExpression):
    +            return self.AddLinearExpressionInDomain(
    +                ct.Expression(), Domain.FromFlatIntervals(ct.Bounds()))
    +        elif ct and isinstance(ct, bool):
    +            return self.AddBoolOr([True])
    +        elif not ct and isinstance(ct, bool):
    +            return self.AddBoolOr([])  # Evaluate to false.
    +        else:
    +            raise TypeError('Not supported: CpModel.Add(' + str(ct) + ')')
    +
    + +
    + +

    Adds a BoundedLinearExpression to the model.

    + +
    Args
    + + + +
    Returns
    + +
    +

    An instance of the Constraint class.

    +
    +
    + + +
    +
    +
    #   + + + def + AddAllDifferent(self, variables): +
    + +
    + View Source +
        def AddAllDifferent(self, variables):
    +        """Adds AllDifferent(variables).
    +
    +    This constraint forces all variables to have different values.
    +
    +    Args:
    +      variables: a list of integer variables.
    +
    +    Returns:
    +      An instance of the `Constraint` class.
    +    """
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        model_ct.all_diff.vars.extend(
    +            [self.GetOrMakeIndex(x) for x in variables])
    +        return ct
    +
    + +
    + +

    Adds AllDifferent(variables).

    +

    This constraint forces all variables to have different values.

    -

    Args

    -
    -
    variables
    -
    a list of integer variables.
    -
    -

    Returns

    -

    An instance of the Constraint class.

    -
    - -Expand source code - -
    def AddAllDifferent(self, variables):
    -    """Adds AllDifferent(variables).
     
    -This constraint forces all variables to have different values.
    +
    Args
    -Args: - variables: a list of integer variables. +
      +
    • variables: a list of integer variables.
    • +
    + +
    Returns
    + +
    +

    An instance of the Constraint class.

    +
    +
    + + +
    +
    +
    #   + + + def + AddElement(self, index, variables, target): +
    + +
    + View Source +
        def AddElement(self, index, variables, target):
    +        """Adds the element constraint: `variables[index] == target`."""
    +
    +        if not variables:
    +            raise ValueError('AddElement expects a non-empty variables array')
    +
    +        if isinstance(index, numbers.Integral):
    +            return self.Add(list(variables)[index] == target)
    +
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        model_ct.element.index = self.GetOrMakeIndex(index)
    +        model_ct.element.vars.extend(
    +            [self.GetOrMakeIndex(x) for x in variables])
    +        model_ct.element.target = self.GetOrMakeIndex(target)
    +        return ct
    +
    + +
    + +

    Adds the element constraint: variables[index] == target.

    +
    + + +
    +
    +
    #   + + + def + AddCircuit(self, arcs): +
    + +
    + View Source +
        def AddCircuit(self, arcs):
    +        """Adds Circuit(arcs).
    +
    +    Adds a circuit constraint from a sparse list of arcs that encode the graph.
    +
    +    A circuit is a unique Hamiltonian path in a subgraph of the total
    +    graph. In case a node 'i' is not in the path, then there must be a
    +    loop arc 'i -> i' associated with a true literal. Otherwise
    +    this constraint will fail.
    +
    +    Args:
    +      arcs: a list of arcs. An arc is a tuple (source_node, destination_node,
    +        literal). The arc is selected in the circuit if the literal is true.
    +        Both source_node and destination_node must be integers between 0 and the
    +        number of nodes - 1.
    +
    +    Returns:
    +      An instance of the `Constraint` class.
    +
    +    Raises:
    +      ValueError: If the list of arcs is empty.
    +    """
    +        if not arcs:
    +            raise ValueError('AddCircuit expects a non-empty array of arcs')
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        for arc in arcs:
    +            cp_model_helper.AssertIsInt32(arc[0])
    +            cp_model_helper.AssertIsInt32(arc[1])
    +            lit = self.GetOrMakeBooleanIndex(arc[2])
    +            model_ct.circuit.tails.append(arc[0])
    +            model_ct.circuit.heads.append(arc[1])
    +            model_ct.circuit.literals.append(lit)
    +        return ct
    +
    + +
    + +

    Adds Circuit(arcs).

    + +

    Adds a circuit constraint from a sparse list of arcs that encode the graph.

    + +

    A circuit is a unique Hamiltonian path in a subgraph of the total +graph. In case a node 'i' is not in the path, then there must be a +loop arc 'i -> i' associated with a true literal. Otherwise +this constraint will fail.

    + +
    Args
    + +
      +
    • arcs: a list of arcs. An arc is a tuple (source_node, destination_node, +literal). The arc is selected in the circuit if the literal is true. +Both source_node and destination_node must be integers between 0 and the +number of nodes - 1.
    • +
    + +
    Returns
    + +
    +

    An instance of the Constraint class.

    +
    + +
    Raises
    + +
      +
    • ValueError: If the list of arcs is empty.
    • +
    +
    + + +
    +
    +
    #   + + + def + AddAllowedAssignments(self, variables, tuples_list): +
    + +
    + View Source +
        def AddAllowedAssignments(self, variables, tuples_list):
    +        """Adds AllowedAssignments(variables, tuples_list).
    +
    +    An AllowedAssignments constraint is a constraint on an array of variables,
    +    which requires that when all variables are assigned values, the resulting
    +    array equals one of the  tuples in `tuple_list`.
    +
    +    Args:
    +      variables: A list of variables.
    +      tuples_list: A list of admissible tuples. Each tuple must have the same
    +        length as the variables, and the ith value of a tuple corresponds to the
    +        ith variable.
    +
    +    Returns:
    +      An instance of the `Constraint` class.
    +
    +    Raises:
    +      TypeError: If a tuple does not have the same size as the list of
    +          variables.
    +      ValueError: If the array of variables is empty.
    +    """
    +
    +        if not variables:
    +            raise ValueError(
    +                'AddAllowedAssignments expects a non-empty variables '
    +                'array')
    +
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        model_ct.table.vars.extend([self.GetOrMakeIndex(x) for x in variables])
    +        arity = len(variables)
    +        for t in tuples_list:
    +            if len(t) != arity:
    +                raise TypeError('Tuple ' + str(t) + ' has the wrong arity')
    +            for v in t:
    +                cp_model_helper.AssertIsInt64(v)
    +            model_ct.table.values.extend(t)
    +        return ct
    +
    + +
    + +

    Adds AllowedAssignments(variables, tuples_list).

    -Returns: - An instance of the `Constraint` class. -""" - ct = Constraint(self.__model.constraints) - model_ct = self.__model.constraints[ct.Index()] - model_ct.all_diff.vars.extend( - [self.GetOrMakeIndex(x) for x in variables]) - return ct
    - - -
    -def AddAllowedAssignments(self, variables, tuples_list) -
    -
    -

    Adds AllowedAssignments(variables, tuples_list).

    An AllowedAssignments constraint is a constraint on an array of variables, which requires that when all variables are assigned values, the resulting -array equals one of the -tuples in tuple_list.

    -

    Args

    -
    -
    variables
    -
    A list of variables.
    -
    tuples_list
    -
    A list of admissible tuples. Each tuple must have the same +array equals one of the tuples in tuple_list.

    + +
    Args
    + +
      +
    • variables: A list of variables.
    • +
    • tuples_list: A list of admissible tuples. Each tuple must have the same length as the variables, and the ith value of a tuple corresponds to the -ith variable.
    -
    -

    Returns

    -

    An instance of the Constraint class.

    -

    Raises

    -
    -
    TypeError
    -
    If a tuple does not have the same size as the list of -variables.
    -
    ValueError
    -
    If the array of variables is empty.
    -
    -
    - -Expand source code - -
    def AddAllowedAssignments(self, variables, tuples_list):
    -    """Adds AllowedAssignments(variables, tuples_list).
    +ith variable.
    +
     
    -An AllowedAssignments constraint is a constraint on an array of variables,
    -which requires that when all variables are assigned values, the resulting
    -array equals one of the  tuples in `tuple_list`.
    +
    Returns
    -Args: - variables: A list of variables. - tuples_list: A list of admissible tuples. Each tuple must have the same - length as the variables, and the ith value of a tuple corresponds to the - ith variable. +
    +

    An instance of the Constraint class.

    +
    -Returns: - An instance of the `Constraint` class. +
    Raises
    -Raises: - TypeError: If a tuple does not have the same size as the list of - variables. - ValueError: If the array of variables is empty. -""" +
      +
    • TypeError: If a tuple does not have the same size as the list of +variables.
    • +
    • ValueError: If the array of variables is empty.
    • +
    +
    - if not variables: - raise ValueError( - 'AddAllowedAssignments expects a non-empty variables ' - 'array') - ct = Constraint(self.__model.constraints) - model_ct = self.__model.constraints[ct.Index()] - model_ct.table.vars.extend([self.GetOrMakeIndex(x) for x in variables]) - arity = len(variables) - for t in tuples_list: - if len(t) != arity: - raise TypeError('Tuple ' + str(t) + ' has the wrong arity') - for v in t: - cp_model_helper.AssertIsInt64(v) - model_ct.table.values.extend(t) - return ct - - -
    -def AddAssumption(self, lit) -
    -
    -

    Add the literal 'lit' to the model as assumptions.

    -
    - -Expand source code - -
    def AddAssumption(self, lit):
    -    """Add the literal 'lit' to the model as assumptions."""
    -    self.__model.assumptions.append(self.GetOrMakeBooleanIndex(lit))
    -
    -
    -
    -def AddAssumptions(self, literals) -
    -
    -

    Add the literals to the model as assumptions.

    -
    - -Expand source code - -
    def AddAssumptions(self, literals):
    -    """Add the literals to the model as assumptions."""
    -    for lit in literals:
    -        self.AddAssumption(lit)
    -
    -
    -
    -def AddAutomaton(self, transition_variables, starting_state, final_states, transition_triples) -
    -
    -

    Adds an automaton constraint.

    +
    +
    +
    #   + + + def + AddForbiddenAssignments(self, variables, tuples_list): +
    + +
    + View Source +
        def AddForbiddenAssignments(self, variables, tuples_list):
    +        """Adds AddForbiddenAssignments(variables, [tuples_list]).
    +
    +    A ForbiddenAssignments constraint is a constraint on an array of variables
    +    where the list of impossible combinations is provided in the tuples list.
    +
    +    Args:
    +      variables: A list of variables.
    +      tuples_list: A list of forbidden tuples. Each tuple must have the same
    +        length as the variables, and the *i*th value of a tuple corresponds to
    +        the *i*th variable.
    +
    +    Returns:
    +      An instance of the `Constraint` class.
    +
    +    Raises:
    +      TypeError: If a tuple does not have the same size as the list of
    +                 variables.
    +      ValueError: If the array of variables is empty.
    +    """
    +
    +        if not variables:
    +            raise ValueError(
    +                'AddForbiddenAssignments expects a non-empty variables '
    +                'array')
    +
    +        index = len(self.__model.constraints)
    +        ct = self.AddAllowedAssignments(variables, tuples_list)
    +        self.__model.constraints[index].table.negated = True
    +        return ct
    +
    + +
    + +

    Adds AddForbiddenAssignments(variables, [tuples_list]).

    + +

    A ForbiddenAssignments constraint is a constraint on an array of variables +where the list of impossible combinations is provided in the tuples list.

    + +
    Args
    + +
      +
    • variables: A list of variables.
    • +
    • tuples_list: A list of forbidden tuples. Each tuple must have the same +length as the variables, and the ith value of a tuple corresponds to +the ith variable.
    • +
    + +
    Returns
    + +
    +

    An instance of the Constraint class.

    +
    + +
    Raises
    + +
      +
    • TypeError: If a tuple does not have the same size as the list of +variables.
    • +
    • ValueError: If the array of variables is empty.
    • +
    +
    + + +
    +
    +
    #   + + + def + AddAutomaton( + self, + transition_variables, + starting_state, + final_states, + transition_triples +): +
    + +
    + View Source +
        def AddAutomaton(self, transition_variables, starting_state, final_states,
    +                     transition_triples):
    +        """Adds an automaton constraint.
    +
    +    An automaton constraint takes a list of variables (of size *n*), an initial
    +    state, a set of final states, and a set of transitions. A transition is a
    +    triplet (*tail*, *transition*, *head*), where *tail* and *head* are states,
    +    and *transition* is the label of an arc from *head* to *tail*,
    +    corresponding to the value of one variable in the list of variables.
    +
    +    This automaton will be unrolled into a flow with *n* + 1 phases. Each phase
    +    contains the possible states of the automaton. The first state contains the
    +    initial state. The last phase contains the final states.
    +
    +    Between two consecutive phases *i* and *i* + 1, the automaton creates a set
    +    of arcs. For each transition (*tail*, *transition*, *head*), it will add
    +    an arc from the state *tail* of phase *i* and the state *head* of phase
    +    *i* + 1. This arc is labeled by the value *transition* of the variables
    +    `variables[i]`. That is, this arc can only be selected if `variables[i]`
    +    is assigned the value *transition*.
    +
    +    A feasible solution of this constraint is an assignment of variables such
    +    that, starting from the initial state in phase 0, there is a path labeled by
    +    the values of the variables that ends in one of the final states in the
    +    final phase.
    +
    +    Args:
    +      transition_variables: A non-empty list of variables whose values
    +        correspond to the labels of the arcs traversed by the automaton.
    +      starting_state: The initial state of the automaton.
    +      final_states: A non-empty list of admissible final states.
    +      transition_triples: A list of transitions for the automaton, in the
    +        following format (current_state, variable_value, next_state).
    +
    +    Returns:
    +      An instance of the `Constraint` class.
    +
    +    Raises:
    +      ValueError: if `transition_variables`, `final_states`, or
    +        `transition_triples` are empty.
    +    """
    +
    +        if not transition_variables:
    +            raise ValueError(
    +                'AddAutomaton expects a non-empty transition_variables '
    +                'array')
    +        if not final_states:
    +            raise ValueError('AddAutomaton expects some final states')
    +
    +        if not transition_triples:
    +            raise ValueError('AddAutomaton expects some transition triples')
    +
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        model_ct.automaton.vars.extend(
    +            [self.GetOrMakeIndex(x) for x in transition_variables])
    +        cp_model_helper.AssertIsInt64(starting_state)
    +        model_ct.automaton.starting_state = starting_state
    +        for v in final_states:
    +            cp_model_helper.AssertIsInt64(v)
    +            model_ct.automaton.final_states.append(v)
    +        for t in transition_triples:
    +            if len(t) != 3:
    +                raise TypeError('Tuple ' + str(t) +
    +                                ' has the wrong arity (!= 3)')
    +            cp_model_helper.AssertIsInt64(t[0])
    +            cp_model_helper.AssertIsInt64(t[1])
    +            cp_model_helper.AssertIsInt64(t[2])
    +            model_ct.automaton.transition_tail.append(t[0])
    +            model_ct.automaton.transition_label.append(t[1])
    +            model_ct.automaton.transition_head.append(t[2])
    +        return ct
    +
    + +
    + +

    Adds an automaton constraint.

    +

    An automaton constraint takes a list of variables (of size n), an initial state, a set of final states, and a set of transitions. A transition is a triplet (tail, transition, head), where tail and head are states, and transition is the label of an arc from head to tail, corresponding to the value of one variable in the list of variables.

    +

    This automaton will be unrolled into a flow with n + 1 phases. Each phase contains the possible states of the automaton. The first state contains the initial state. The last phase contains the final states.

    +

    Between two consecutive phases i and i + 1, the automaton creates a set of arcs. For each transition (tail, transition, head), it will add an arc from the state tail of phase i and the state head of phase i + 1. This arc is labeled by the value transition of the variables variables[i]. That is, this arc can only be selected if variables[i] is assigned the value transition.

    +

    A feasible solution of this constraint is an assignment of variables such that, starting from the initial state in phase 0, there is a path labeled by the values of the variables that ends in one of the final states in the final phase.

    -

    Args

    -
    -
    transition_variables
    -
    A non-empty list of variables whose values -correspond to the labels of the arcs traversed by the automaton.
    -
    starting_state
    -
    The initial state of the automaton.
    -
    final_states
    -
    A non-empty list of admissible final states.
    -
    transition_triples
    -
    A list of transitions for the automaton, in the -following format (current_state, variable_value, next_state).
    -
    -

    Returns

    -

    An instance of the Constraint class.

    -

    Raises

    -
    -
    ValueError
    -
    if transition_variables, final_states, or -transition_triples are empty.
    -
    -
    - -Expand source code - -
    def AddAutomaton(self, transition_variables, starting_state, final_states,
    -                 transition_triples):
    -    """Adds an automaton constraint.
     
    -An automaton constraint takes a list of variables (of size *n*), an initial
    -state, a set of final states, and a set of transitions. A transition is a
    -triplet (*tail*, *transition*, *head*), where *tail* and *head* are states,
    -and *transition* is the label of an arc from *head* to *tail*,
    -corresponding to the value of one variable in the list of variables.
    +
    Args
    -This automaton will be unrolled into a flow with *n* + 1 phases. Each phase -contains the possible states of the automaton. The first state contains the -initial state. The last phase contains the final states. +
      +
    • transition_variables: A non-empty list of variables whose values +correspond to the labels of the arcs traversed by the automaton.
    • +
    • starting_state: The initial state of the automaton.
    • +
    • final_states: A non-empty list of admissible final states.
    • +
    • transition_triples: A list of transitions for the automaton, in the +following format (current_state, variable_value, next_state).
    • +
    -Between two consecutive phases *i* and *i* + 1, the automaton creates a set -of arcs. For each transition (*tail*, *transition*, *head*), it will add -an arc from the state *tail* of phase *i* and the state *head* of phase -*i* + 1. This arc is labeled by the value *transition* of the variables -`variables[i]`. That is, this arc can only be selected if `variables[i]` -is assigned the value *transition*. +
    Returns
    -A feasible solution of this constraint is an assignment of variables such -that, starting from the initial state in phase 0, there is a path labeled by -the values of the variables that ends in one of the final states in the -final phase. +
    +

    An instance of the Constraint class.

    +
    -Args: - transition_variables: A non-empty list of variables whose values - correspond to the labels of the arcs traversed by the automaton. - starting_state: The initial state of the automaton. - final_states: A non-empty list of admissible final states. - transition_triples: A list of transitions for the automaton, in the - following format (current_state, variable_value, next_state). +
    Raises
    -Returns: - An instance of the `Constraint` class. +
      +
    • ValueError: if transition_variables, final_states, or +transition_triples are empty.
    • +
    +
    -Raises: - ValueError: if `transition_variables`, `final_states`, or - `transition_triples` are empty. -""" - if not transition_variables: - raise ValueError( - 'AddAutomaton expects a non-empty transition_variables ' - 'array') - if not final_states: - raise ValueError('AddAutomaton expects some final states') +
    +
    +
    #   - if not transition_triples: - raise ValueError('AddAutomaton expects some transition triples') + + def + AddInverse(self, variables, inverse_variables): +
    - ct = Constraint(self.__model.constraints) - model_ct = self.__model.constraints[ct.Index()] - model_ct.automaton.vars.extend( - [self.GetOrMakeIndex(x) for x in transition_variables]) - cp_model_helper.AssertIsInt64(starting_state) - model_ct.automaton.starting_state = starting_state - for v in final_states: - cp_model_helper.AssertIsInt64(v) - model_ct.automaton.final_states.append(v) - for t in transition_triples: - if len(t) != 3: - raise TypeError('Tuple ' + str(t) + - ' has the wrong arity (!= 3)') - cp_model_helper.AssertIsInt64(t[0]) - cp_model_helper.AssertIsInt64(t[1]) - cp_model_helper.AssertIsInt64(t[2]) - model_ct.automaton.transition_tail.append(t[0]) - model_ct.automaton.transition_label.append(t[1]) - model_ct.automaton.transition_head.append(t[2]) - return ct
    - - -
    -def AddBoolAnd(self, literals) -
    -
    -

    Adds And(literals) == true.

    -
    - -Expand source code - -
    def AddBoolAnd(self, literals):
    -    """Adds `And(literals) == true`."""
    -    ct = Constraint(self.__model.constraints)
    -    model_ct = self.__model.constraints[ct.Index()]
    -    model_ct.bool_and.literals.extend(
    -        [self.GetOrMakeBooleanIndex(x) for x in literals])
    -    return ct
    -
    -
    -
    -def AddBoolOr(self, literals) -
    -
    -

    Adds Or(literals) == true.

    -
    - -Expand source code - -
    def AddBoolOr(self, literals):
    -    """Adds `Or(literals) == true`."""
    -    ct = Constraint(self.__model.constraints)
    -    model_ct = self.__model.constraints[ct.Index()]
    -    model_ct.bool_or.literals.extend(
    -        [self.GetOrMakeBooleanIndex(x) for x in literals])
    -    return ct
    -
    -
    -
    -def AddBoolXOr(self, literals) -
    -
    -

    Adds XOr(literals) == true.

    -
    - -Expand source code - -
    def AddBoolXOr(self, literals):
    -    """Adds `XOr(literals) == true`."""
    -    ct = Constraint(self.__model.constraints)
    -    model_ct = self.__model.constraints[ct.Index()]
    -    model_ct.bool_xor.literals.extend(
    -        [self.GetOrMakeBooleanIndex(x) for x in literals])
    -    return ct
    -
    -
    -
    -def AddCircuit(self, arcs) -
    -
    -

    Adds Circuit(arcs).

    -

    Adds a circuit constraint from a sparse list of arcs that encode the graph.

    -

    A circuit is a unique Hamiltonian path in a subgraph of the total -graph. In case a node 'i' is not in the path, then there must be a -loop arc 'i -> i' associated with a true literal. Otherwise -this constraint will fail.

    -

    Args

    -
    -
    arcs
    -
    a list of arcs. An arc is a tuple (source_node, destination_node, -literal). The arc is selected in the circuit if the literal is true. -Both source_node and destination_node must be integers between 0 and the -number of nodes - 1.
    -
    -

    Returns

    -

    An instance of the Constraint class.

    -

    Raises

    -
    -
    ValueError
    -
    If the list of arcs is empty.
    -
    -
    - -Expand source code - -
    def AddCircuit(self, arcs):
    -    """Adds Circuit(arcs).
    +                
    + View Source +
        def AddInverse(self, variables, inverse_variables):
    +        """Adds Inverse(variables, inverse_variables).
     
    -Adds a circuit constraint from a sparse list of arcs that encode the graph.
    +    An inverse constraint enforces that if `variables[i]` is assigned a value
    +    `j`, then `inverse_variables[j]` is assigned a value `i`. And vice versa.
     
    -A circuit is a unique Hamiltonian path in a subgraph of the total
    -graph. In case a node 'i' is not in the path, then there must be a
    -loop arc 'i -> i' associated with a true literal. Otherwise
    -this constraint will fail.
    +    Args:
    +      variables: An array of integer variables.
    +      inverse_variables: An array of integer variables.
     
    -Args:
    -  arcs: a list of arcs. An arc is a tuple (source_node, destination_node,
    -    literal). The arc is selected in the circuit if the literal is true.
    -    Both source_node and destination_node must be integers between 0 and the
    -    number of nodes - 1.
    +    Returns:
    +      An instance of the `Constraint` class.
     
    -Returns:
    -  An instance of the `Constraint` class.
    +    Raises:
    +      TypeError: if variables and inverse_variables have different lengths, or
    +          if they are empty.
    +    """
     
    -Raises:
    -  ValueError: If the list of arcs is empty.
    -"""
    -    if not arcs:
    -        raise ValueError('AddCircuit expects a non-empty array of arcs')
    -    ct = Constraint(self.__model.constraints)
    -    model_ct = self.__model.constraints[ct.Index()]
    -    for arc in arcs:
    -        cp_model_helper.AssertIsInt32(arc[0])
    -        cp_model_helper.AssertIsInt32(arc[1])
    -        lit = self.GetOrMakeBooleanIndex(arc[2])
    -        model_ct.circuit.tails.append(arc[0])
    -        model_ct.circuit.heads.append(arc[1])
    -        model_ct.circuit.literals.append(lit)
    -    return ct
    -
    -
    -
    -def AddCumulative(self, intervals, demands, capacity) -
    -
    -

    Adds Cumulative(intervals, demands, capacity).

    -

    This constraint enforces that:

    -
    for all t:
    -  sum(demands[i]
    -    if (start(intervals[t]) <= t < end(intervals[t])) and
    -    (t is present)) <= capacity
    -
    -

    Args

    -
    -
    intervals
    -
    The list of intervals.
    -
    demands
    -
    The list of demands for each interval. Each demand must be >= 0. -Each demand can be an integer value, or an integer variable.
    -
    capacity
    -
    The maximum capacity of the cumulative constraint. It must be a -positive integer value or variable.
    -
    -

    Returns

    -

    An instance of the Constraint class.

    -
    - -Expand source code - -
    def AddCumulative(self, intervals, demands, capacity):
    -    """Adds Cumulative(intervals, demands, capacity).
    +        if not variables or not inverse_variables:
    +            raise TypeError(
    +                'The Inverse constraint does not accept empty arrays')
    +        if len(variables) != len(inverse_variables):
    +            raise TypeError(
    +                'In the inverse constraint, the two array variables and'
    +                ' inverse_variables must have the same length.')
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        model_ct.inverse.f_direct.extend(
    +            [self.GetOrMakeIndex(x) for x in variables])
    +        model_ct.inverse.f_inverse.extend(
    +            [self.GetOrMakeIndex(x) for x in inverse_variables])
    +        return ct
    +
    -This constraint enforces that: + - for all t: - sum(demands[i] - if (start(intervals[t]) <= t < end(intervals[t])) and - (t is present)) <= capacity +

    Adds Inverse(variables, inverse_variables).

    -Args: - intervals: The list of intervals. - demands: The list of demands for each interval. Each demand must be >= 0. - Each demand can be an integer value, or an integer variable. - capacity: The maximum capacity of the cumulative constraint. It must be a - positive integer value or variable. - -Returns: - An instance of the `Constraint` class. -""" - ct = Constraint(self.__model.constraints) - model_ct = self.__model.constraints[ct.Index()] - model_ct.cumulative.intervals.extend( - [self.GetIntervalIndex(x) for x in intervals]) - model_ct.cumulative.demands.extend( - [self.GetOrMakeIndex(x) for x in demands]) - model_ct.cumulative.capacity = self.GetOrMakeIndex(capacity) - return ct
    - - -
    -def AddDecisionStrategy(self, variables, var_strategy, domain_strategy) -
    -
    -

    Adds a search strategy to the model.

    -

    Args

    -
    -
    variables
    -
    a list of variables this strategy will assign.
    -
    var_strategy
    -
    heuristic to choose the next variable to assign.
    -
    domain_strategy
    -
    heuristic to reduce the domain of the selected variable. -Currently, this is advanced code: the union of all strategies added to -the model must be complete, i.e. instantiates all variables. -Otherwise, Solve() will fail.
    -
    -
    - -Expand source code - -
    def AddDecisionStrategy(self, variables, var_strategy, domain_strategy):
    -    """Adds a search strategy to the model.
    -
    -Args:
    -  variables: a list of variables this strategy will assign.
    -  var_strategy: heuristic to choose the next variable to assign.
    -  domain_strategy: heuristic to reduce the domain of the selected variable.
    -    Currently, this is advanced code: the union of all strategies added to
    -      the model must be complete, i.e. instantiates all variables.
    -      Otherwise, Solve() will fail.
    -"""
    -
    -    strategy = self.__model.search_strategy.add()
    -    for v in variables:
    -        strategy.variables.append(v.Index())
    -    strategy.variable_selection_strategy = var_strategy
    -    strategy.domain_reduction_strategy = domain_strategy
    -
    -
    -
    -def AddDivisionEquality(self, target, num, denom) -
    -
    -

    Adds target == num // denom (integer division rounded towards 0).

    -
    - -Expand source code - -
    def AddDivisionEquality(self, target, num, denom):
    -    """Adds `target == num // denom` (integer division rounded towards 0)."""
    -    ct = Constraint(self.__model.constraints)
    -    model_ct = self.__model.constraints[ct.Index()]
    -    model_ct.int_div.vars.extend(
    -        [self.GetOrMakeIndex(num),
    -         self.GetOrMakeIndex(denom)])
    -    model_ct.int_div.target = self.GetOrMakeIndex(target)
    -    return ct
    -
    -
    -
    -def AddElement(self, index, variables, target) -
    -
    -

    Adds the element constraint: variables[index] == target.

    -
    - -Expand source code - -
    def AddElement(self, index, variables, target):
    -    """Adds the element constraint: `variables[index] == target`."""
    -
    -    if not variables:
    -        raise ValueError('AddElement expects a non-empty variables array')
    -
    -    if isinstance(index, numbers.Integral):
    -        return self.Add(list(variables)[index] == target)
    -
    -    ct = Constraint(self.__model.constraints)
    -    model_ct = self.__model.constraints[ct.Index()]
    -    model_ct.element.index = self.GetOrMakeIndex(index)
    -    model_ct.element.vars.extend(
    -        [self.GetOrMakeIndex(x) for x in variables])
    -    model_ct.element.target = self.GetOrMakeIndex(target)
    -    return ct
    -
    -
    -
    -def AddForbiddenAssignments(self, variables, tuples_list) -
    -
    -

    Adds AddForbiddenAssignments(variables, [tuples_list]).

    -

    A ForbiddenAssignments constraint is a constraint on an array of variables -where the list of impossible combinations is provided in the tuples list.

    -

    Args

    -
    -
    variables
    -
    A list of variables.
    -
    tuples_list
    -
    A list of forbidden tuples. Each tuple must have the same -length as the variables, and the ith value of a tuple corresponds to -the ith variable.
    -
    -

    Returns

    -

    An instance of the Constraint class.

    -

    Raises

    -
    -
    TypeError
    -
    If a tuple does not have the same size as the list of -variables.
    -
    ValueError
    -
    If the array of variables is empty.
    -
    -
    - -Expand source code - -
    def AddForbiddenAssignments(self, variables, tuples_list):
    -    """Adds AddForbiddenAssignments(variables, [tuples_list]).
    -
    -A ForbiddenAssignments constraint is a constraint on an array of variables
    -where the list of impossible combinations is provided in the tuples list.
    -
    -Args:
    -  variables: A list of variables.
    -  tuples_list: A list of forbidden tuples. Each tuple must have the same
    -    length as the variables, and the *i*th value of a tuple corresponds to
    -    the *i*th variable.
    -
    -Returns:
    -  An instance of the `Constraint` class.
    -
    -Raises:
    -  TypeError: If a tuple does not have the same size as the list of
    -             variables.
    -  ValueError: If the array of variables is empty.
    -"""
    -
    -    if not variables:
    -        raise ValueError(
    -            'AddForbiddenAssignments expects a non-empty variables '
    -            'array')
    -
    -    index = len(self.__model.constraints)
    -    ct = self.AddAllowedAssignments(variables, tuples_list)
    -    self.__model.constraints[index].table.negated = True
    -    return ct
    -
    -
    -
    -def AddHint(self, var, value) -
    -
    -

    Adds 'var == value' as a hint to the solver.

    -
    - -Expand source code - -
    def AddHint(self, var, value):
    -    """Adds 'var == value' as a hint to the solver."""
    -    self.__model.solution_hint.vars.append(self.GetOrMakeIndex(var))
    -    self.__model.solution_hint.values.append(value)
    -
    -
    -
    -def AddImplication(self, a, b) -
    -
    -

    Adds a => b (a implies b).

    -
    - -Expand source code - -
    def AddImplication(self, a, b):
    -    """Adds `a => b` (`a` implies `b`)."""
    -    ct = Constraint(self.__model.constraints)
    -    model_ct = self.__model.constraints[ct.Index()]
    -    model_ct.bool_or.literals.append(self.GetOrMakeBooleanIndex(b))
    -    model_ct.enforcement_literal.append(self.GetOrMakeBooleanIndex(a))
    -    return ct
    -
    -
    -
    -def AddInverse(self, variables, inverse_variables) -
    -
    -

    Adds Inverse(variables, inverse_variables).

    An inverse constraint enforces that if variables[i] is assigned a value j, then inverse_variables[j] is assigned a value i. And vice versa.

    -

    Args

    -
    -
    variables
    -
    An array of integer variables.
    -
    inverse_variables
    -
    An array of integer variables.
    -
    -

    Returns

    -

    An instance of the Constraint class.

    -

    Raises

    -
    -
    TypeError
    -
    if variables and inverse_variables have different lengths, or -if they are empty.
    -
    -
    - -Expand source code - -
    def AddInverse(self, variables, inverse_variables):
    -    """Adds Inverse(variables, inverse_variables).
     
    -An inverse constraint enforces that if `variables[i]` is assigned a value
    -`j`, then `inverse_variables[j]` is assigned a value `i`. And vice versa.
    +
    Args
    -Args: - variables: An array of integer variables. - inverse_variables: An array of integer variables. +
      +
    • variables: An array of integer variables.
    • +
    • inverse_variables: An array of integer variables.
    • +
    -Returns: - An instance of the `Constraint` class. +
    Returns
    -Raises: - TypeError: if variables and inverse_variables have different lengths, or - if they are empty. -""" +
    +

    An instance of the Constraint class.

    +
    - if not variables or not inverse_variables: - raise TypeError( - 'The Inverse constraint does not accept empty arrays') - if len(variables) != len(inverse_variables): - raise TypeError( - 'In the inverse constraint, the two array variables and' - ' inverse_variables must have the same length.') - ct = Constraint(self.__model.constraints) - model_ct = self.__model.constraints[ct.Index()] - model_ct.inverse.f_direct.extend( - [self.GetOrMakeIndex(x) for x in variables]) - model_ct.inverse.f_inverse.extend( - [self.GetOrMakeIndex(x) for x in inverse_variables]) - return ct
    -
    -
    -
    -def AddLinearConstraint(self, linear_expr, lb, ub) -
    -
    -

    Adds the constraint: lb <= linear_expr <= ub.

    -
    - -Expand source code - -
    def AddLinearConstraint(self, linear_expr, lb, ub):
    -    """Adds the constraint: `lb <= linear_expr <= ub`."""
    -    return self.AddLinearExpressionInDomain(linear_expr, Domain(lb, ub))
    -
    -
    -
    -def AddLinearExpressionInDomain(self, linear_expr, domain) -
    -
    -

    Adds the constraint: linear_expr in domain.

    -
    - -Expand source code - -
    def AddLinearExpressionInDomain(self, linear_expr, domain):
    -    """Adds the constraint: `linear_expr` in `domain`."""
    -    if isinstance(linear_expr, LinearExpr):
    -        ct = Constraint(self.__model.constraints)
    -        model_ct = self.__model.constraints[ct.Index()]
    -        coeffs_map, constant = linear_expr.GetVarValueMap()
    -        for t in coeffs_map.items():
    -            if not isinstance(t[0], IntVar):
    -                raise TypeError('Wrong argument' + str(t))
    -            cp_model_helper.AssertIsInt64(t[1])
    -            model_ct.linear.vars.append(t[0].Index())
    -            model_ct.linear.coeffs.append(t[1])
    -        model_ct.linear.domain.extend([
    -            cp_model_helper.CapSub(x, constant)
    -            for x in domain.FlattenedIntervals()
    -        ])
    -        return ct
    -    elif isinstance(linear_expr, numbers.Integral):
    -        if not domain.Contains(linear_expr):
    -            return self.AddBoolOr([])  # Evaluate to false.
    -        # Nothing to do otherwise.
    -    else:
    -        raise TypeError(
    -            'Not supported: CpModel.AddLinearExpressionInDomain(' +
    -            str(linear_expr) + ' ' + str(domain) + ')')
    -
    -
    -
    -def AddMapDomain(self, var, bool_var_array, offset=0) -
    -
    -

    Adds var == i + offset <=> bool_var_array[i] == true for all i.

    -
    - -Expand source code - -
    def AddMapDomain(self, var, bool_var_array, offset=0):
    -    """Adds `var == i + offset <=> bool_var_array[i] == true for all i`."""
    +
    Raises
    - for i, bool_var in enumerate(bool_var_array): - b_index = bool_var.Index() - var_index = var.Index() - model_ct = self.__model.constraints.add() - model_ct.linear.vars.append(var_index) - model_ct.linear.coeffs.append(1) - model_ct.linear.domain.extend([offset + i, offset + i]) - model_ct.enforcement_literal.append(b_index) +
      +
    • TypeError: if variables and inverse_variables have different lengths, or +if they are empty.
    • +
    +
    - model_ct = self.__model.constraints.add() - model_ct.linear.vars.append(var_index) - model_ct.linear.coeffs.append(1) - model_ct.enforcement_literal.append(-b_index - 1) - if offset + i - 1 >= INT_MIN: - model_ct.linear.domain.extend([INT_MIN, offset + i - 1]) - if offset + i + 1 <= INT_MAX: - model_ct.linear.domain.extend([offset + i + 1, INT_MAX]) - - -
    -def AddMaxEquality(self, target, variables) -
    -
    -

    Adds target == Max(variables).

    -
    - -Expand source code - -
    def AddMaxEquality(self, target, variables):
    -    """Adds `target == Max(variables)`."""
    -    ct = Constraint(self.__model.constraints)
    -    model_ct = self.__model.constraints[ct.Index()]
    -    model_ct.int_max.vars.extend(
    -        [self.GetOrMakeIndex(x) for x in variables])
    -    model_ct.int_max.target = self.GetOrMakeIndex(target)
    -    return ct
    -
    -
    -
    -def AddMinEquality(self, target, variables) -
    -
    -

    Adds target == Min(variables).

    -
    - -Expand source code - -
    def AddMinEquality(self, target, variables):
    -    """Adds `target == Min(variables)`."""
    -    ct = Constraint(self.__model.constraints)
    -    model_ct = self.__model.constraints[ct.Index()]
    -    model_ct.int_min.vars.extend(
    -        [self.GetOrMakeIndex(x) for x in variables])
    -    model_ct.int_min.target = self.GetOrMakeIndex(target)
    -    return ct
    -
    -
    -
    -def AddModuloEquality(self, target, var, mod) -
    -
    -

    Adds target = var % mod.

    -
    - -Expand source code - -
    def AddModuloEquality(self, target, var, mod):
    -    """Adds `target = var % mod`."""
    -    ct = Constraint(self.__model.constraints)
    -    model_ct = self.__model.constraints[ct.Index()]
    -    model_ct.int_mod.vars.extend(
    -        [self.GetOrMakeIndex(var),
    -         self.GetOrMakeIndex(mod)])
    -    model_ct.int_mod.target = self.GetOrMakeIndex(target)
    -    return ct
    -
    -
    -
    -def AddMultiplicationEquality(self, target, variables) -
    -
    -

    Adds target == variables[0] * .. * variables[n].

    -
    - -Expand source code - -
    def AddMultiplicationEquality(self, target, variables):
    -    """Adds `target == variables[0] * .. * variables[n]`."""
    -    ct = Constraint(self.__model.constraints)
    -    model_ct = self.__model.constraints[ct.Index()]
    -    model_ct.int_prod.vars.extend(
    -        [self.GetOrMakeIndex(x) for x in variables])
    -    model_ct.int_prod.target = self.GetOrMakeIndex(target)
    -    return ct
    -
    -
    -
    -def AddNoOverlap(self, interval_vars) -
    -
    -

    Adds NoOverlap(interval_vars).

    -

    A NoOverlap constraint ensures that all present intervals do not overlap -in time.

    -

    Args

    -
    -
    interval_vars
    -
    The list of interval variables to constrain.
    -
    -

    Returns

    -

    An instance of the Constraint class.

    -
    - -Expand source code - -
    def AddNoOverlap(self, interval_vars):
    -    """Adds NoOverlap(interval_vars).
     
    -A NoOverlap constraint ensures that all present intervals do not overlap
    -in time.
    +                            
    +                            
    +
    #   -Args: - interval_vars: The list of interval variables to constrain. + + def + AddReservoirConstraint(self, times, demands, min_level, max_level): +
    -Returns: - An instance of the `Constraint` class. -""" - ct = Constraint(self.__model.constraints) - model_ct = self.__model.constraints[ct.Index()] - model_ct.no_overlap.intervals.extend( - [self.GetIntervalIndex(x) for x in interval_vars]) - return ct
    -
    -
    -
    -def AddNoOverlap2D(self, x_intervals, y_intervals) -
    -
    -

    Adds NoOverlap2D(x_intervals, y_intervals).

    -

    A NoOverlap2D constraint ensures that all present rectangles do not overlap -on a plane. Each rectangle is aligned with the X and Y axis, and is defined -by two intervals which represent its projection onto the X and Y axis.

    -

    Args

    -
    -
    x_intervals
    -
    The X coordinates of the rectangles.
    -
    y_intervals
    -
    The Y coordinates of the rectangles.
    -
    -

    Returns

    -

    An instance of the Constraint class.

    -
    - -Expand source code - -
    def AddNoOverlap2D(self, x_intervals, y_intervals):
    -    """Adds NoOverlap2D(x_intervals, y_intervals).
    +                
    + View Source +
        def AddReservoirConstraint(self, times, demands, min_level, max_level):
    +        """Adds Reservoir(times, demands, min_level, max_level).
     
    -A NoOverlap2D constraint ensures that all present rectangles do not overlap
    -on a plane. Each rectangle is aligned with the X and Y axis, and is defined
    -by two intervals which represent its projection onto the X and Y axis.
    +    Maintains a reservoir level within bounds. The water level starts at 0, and
    +    at any time, it must be between min_level and max_level.
     
    -Args:
    -  x_intervals: The X coordinates of the rectangles.
    -  y_intervals: The Y coordinates of the rectangles.
    +    If the variable `times[i]` is assigned a value t, then the current level
    +    changes by `demands[i]`, which is constant, at time t.
    +
    +     Note that min level must be <= 0, and the max level must be >= 0. Please
    +     use fixed demands to simulate initial state.
    +
    +     Therefore, at any time:
    +         sum(demands[i] if times[i] <= t) in [min_level, max_level]
    +
    +    Args:
    +      times: A list of integer variables which specify the time of the filling
    +        or emptying the reservoir.
    +      demands: A list of integer values that specifies the amount of the
    +        emptying or filling.
    +      min_level: At any time, the level of the reservoir must be greater or
    +        equal than the min level.
    +      max_level: At any time, the level of the reservoir must be less or equal
    +        than the max level.
    +
    +    Returns:
    +      An instance of the `Constraint` class.
    +
    +    Raises:
    +      ValueError: if max_level < min_level.
    +
    +      ValueError: if max_level < 0.
    +
    +      ValueError: if min_level > 0
    +    """
    +
    +        if max_level < min_level:
    +            return ValueError(
    +                'Reservoir constraint must have a max_level >= min_level')
    +
    +        if max_level < 0:
    +            return ValueError('Reservoir constraint must have a max_level >= 0')
    +
    +        if min_level > 0:
    +            return ValueError('Reservoir constraint must have a min_level <= 0')
    +
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        model_ct.reservoir.times.extend([self.GetOrMakeIndex(x) for x in times])
    +        model_ct.reservoir.demands.extend(demands)
    +        model_ct.reservoir.min_level = min_level
    +        model_ct.reservoir.max_level = max_level
    +        return ct
    +
    + +
    + +

    Adds Reservoir(times, demands, min_level, max_level).

    -Returns: - An instance of the `Constraint` class. -""" - ct = Constraint(self.__model.constraints) - model_ct = self.__model.constraints[ct.Index()] - model_ct.no_overlap_2d.x_intervals.extend( - [self.GetIntervalIndex(x) for x in x_intervals]) - model_ct.no_overlap_2d.y_intervals.extend( - [self.GetIntervalIndex(x) for x in y_intervals]) - return ct
    -
    -
    -
    -def AddProdEquality(self, target, variables) -
    -
    -

    Deprecated, use AddMultiplicationEquality.

    -
    - -Expand source code - -
    def AddProdEquality(self, target, variables):
    -    """Deprecated, use AddMultiplicationEquality."""
    -    return self.AddMultiplicationEquality(target, variables)
    -
    -
    -
    -def AddReservoirConstraint(self, times, demands, min_level, max_level) -
    -
    -

    Adds Reservoir(times, demands, min_level, max_level).

    Maintains a reservoir level within bounds. The water level starts at 0, and at any time, it must be between min_level and max_level.

    +

    If the variable times[i] is assigned a value t, then the current level changes by demands[i], which is constant, at time t.

    +

    Note that min level must be <= 0, and the max level must be >= 0. Please -use fixed demands to simulate initial state.

    + use fixed demands to simulate initial state.

    +

    Therefore, at any time: -sum(demands[i] if times[i] <= t) in [min_level, max_level]

    -

    Args

    -
    -
    times
    -
    A list of integer variables which specify the time of the -filling or emptying the reservoir.
    -
    demands
    -
    A list of integer values that specifies the amount of the -emptying or filling.
    -
    min_level
    -
    At any time, the level of the reservoir must be greater or -equal than the min level.
    -
    max_level
    -
    At any time, the level of the reservoir must be less or equal -than the max level.
    -
    -

    Returns

    -

    An instance of the Constraint class.

    -

    Raises

    -
    -
    ValueError
    -
    if max_level < min_level.
    -
    ValueError
    -
    if max_level < 0.
    -
    ValueError
    -
    if min_level > 0
    -
    -
    - -Expand source code - -
    def AddReservoirConstraint(self, times, demands, min_level, max_level):
    -    """Adds Reservoir(times, demands, min_level, max_level).
    +     sum(demands[i] if times[i] <= t) in [min_level, max_level]

    -Maintains a reservoir level within bounds. The water level starts at 0, and -at any time, it must be between min_level and max_level. +
    Args
    -If the variable `times[i]` is assigned a value t, then the current level -changes by `demands[i]`, which is constant, at time t. +
      +
    • times: A list of integer variables which specify the time of the filling +or emptying the reservoir.
    • +
    • demands: A list of integer values that specifies the amount of the +emptying or filling.
    • +
    • min_level: At any time, the level of the reservoir must be greater or +equal than the min level.
    • +
    • max_level: At any time, the level of the reservoir must be less or equal +than the max level.
    • +
    - Note that min level must be <= 0, and the max level must be >= 0. Please - use fixed demands to simulate initial state. +
    Returns
    - Therefore, at any time: - sum(demands[i] if times[i] <= t) in [min_level, max_level] +
    +

    An instance of the Constraint class.

    +
    -Args: - times: A list of integer variables which specify the time of the - filling or emptying the reservoir. - demands: A list of integer values that specifies the amount of the - emptying or filling. - min_level: At any time, the level of the reservoir must be greater or - equal than the min level. - max_level: At any time, the level of the reservoir must be less or equal - than the max level. +
    Raises
    -Returns: - An instance of the `Constraint` class. +
      +
    • ValueError: if max_level < min_level.
    • +
    • ValueError: if max_level < 0.
    • +
    • ValueError: if min_level > 0
    • +
    + -Raises: - ValueError: if max_level < min_level. - ValueError: if max_level < 0. + +
    +
    #   - ValueError: if min_level > 0 -""" + + def + AddReservoirConstraintWithActive(self, times, demands, actives, min_level, max_level): +
    - if max_level < min_level: - return ValueError( - 'Reservoir constraint must have a max_level >= min_level') +
    + View Source +
        def AddReservoirConstraintWithActive(self, times, demands, actives,
    +                                         min_level, max_level):
    +        """Adds Reservoir(times, demands, actives, min_level, max_level).
     
    -    if max_level < 0:
    -        return ValueError('Reservoir constraint must have a max_level >= 0')
    +    Maintains a reservoir level within bounds. The water level starts at 0, and
    +    at any time, it must be between min_level and max_level.
     
    -    if min_level > 0:
    -        return ValueError('Reservoir constraint must have a min_level <= 0')
    +    If the variable `times[i]` is assigned a value t, and `actives[i]` is
    +    `True`, then the current level changes by `demands[i]`, which is constant,
    +    at time t.
    +
    +     Note that min level must be <= 0, and the max level must be >= 0. Please
    +     use fixed demands to simulate initial state.
    +
    +     Therefore, at any time:
    +         sum(demands[i] * actives[i] if times[i] <= t) in [min_level, max_level]
    +
    +
    +    The array of boolean variables 'actives', if defined, indicates which
    +    actions are actually performed.
    +
    +    Args:
    +      times: A list of integer variables which specify the time of the filling
    +        or emptying the reservoir.
    +      demands: A list of integer values that specifies the amount of the
    +        emptying or filling.
    +      actives: a list of boolean variables. They indicates if the
    +        emptying/refilling events actually take place.
    +      min_level: At any time, the level of the reservoir must be greater or
    +        equal than the min level.
    +      max_level: At any time, the level of the reservoir must be less or equal
    +        than the max level.
    +
    +    Returns:
    +      An instance of the `Constraint` class.
    +
    +    Raises:
    +      ValueError: if max_level < min_level.
    +
    +      ValueError: if max_level < 0.
    +
    +      ValueError: if min_level > 0
    +    """
    +
    +        if max_level < min_level:
    +            return ValueError(
    +                'Reservoir constraint must have a max_level >= min_level')
    +
    +        if max_level < 0:
    +            return ValueError('Reservoir constraint must have a max_level >= 0')
    +
    +        if min_level > 0:
    +            return ValueError('Reservoir constraint must have a min_level <= 0')
    +
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        model_ct.reservoir.times.extend([self.GetOrMakeIndex(x) for x in times])
    +        model_ct.reservoir.demands.extend(demands)
    +        model_ct.reservoir.actives.extend(
    +            [self.GetOrMakeIndex(x) for x in actives])
    +        model_ct.reservoir.min_level = min_level
    +        model_ct.reservoir.max_level = max_level
    +        return ct
    +
    + +
    + +

    Adds Reservoir(times, demands, actives, min_level, max_level).

    - ct = Constraint(self.__model.constraints) - model_ct = self.__model.constraints[ct.Index()] - model_ct.reservoir.times.extend([self.GetOrMakeIndex(x) for x in times]) - model_ct.reservoir.demands.extend(demands) - model_ct.reservoir.min_level = min_level - model_ct.reservoir.max_level = max_level - return ct
    -
    -
    -
    -def AddReservoirConstraintWithActive(self, times, demands, actives, min_level, max_level) -
    -
    -

    Adds Reservoir(times, demands, actives, min_level, max_level).

    Maintains a reservoir level within bounds. The water level starts at 0, and at any time, it must be between min_level and max_level.

    +

    If the variable times[i] is assigned a value t, and actives[i] is True, then the current level changes by demands[i], which is constant, at time t.

    +

    Note that min level must be <= 0, and the max level must be >= 0. Please -use fixed demands to simulate initial state.

    + use fixed demands to simulate initial state.

    +

    Therefore, at any time: -sum(demands[i] * actives[i] if times[i] <= t) in [min_level, max_level]

    + sum(demands[i] * actives[i] if times[i] <= t) in [min_level, max_level]

    +

    The array of boolean variables 'actives', if defined, indicates which actions are actually performed.

    -

    Args

    -
    -
    times
    -
    A list of integer variables which specify the time of the -filling or emptying the reservoir.
    -
    demands
    -
    A list of integer values that specifies the amount of the -emptying or filling.
    -
    actives
    -
    a list of boolean variables. They indicates if the -emptying/refilling events actually take place.
    -
    min_level
    -
    At any time, the level of the reservoir must be greater or -equal than the min level.
    -
    max_level
    -
    At any time, the level of the reservoir must be less or equal -than the max level.
    -
    -

    Returns

    -

    An instance of the Constraint class.

    -

    Raises

    -
    -
    ValueError
    -
    if max_level < min_level.
    -
    ValueError
    -
    if max_level < 0.
    -
    ValueError
    -
    if min_level > 0
    -
    -
    - -Expand source code - -
    def AddReservoirConstraintWithActive(self, times, demands, actives,
    -                                     min_level, max_level):
    -    """Adds Reservoir(times, demands, actives, min_level, max_level).
     
    -Maintains a reservoir level within bounds. The water level starts at 0, and
    -at any time, it must be between min_level and max_level.
    +
    Args
    -If the variable `times[i]` is assigned a value t, and `actives[i]` is -`True`, then the current level changes by `demands[i]`, which is constant, -at time t. +
      +
    • times: A list of integer variables which specify the time of the filling +or emptying the reservoir.
    • +
    • demands: A list of integer values that specifies the amount of the +emptying or filling.
    • +
    • actives: a list of boolean variables. They indicates if the +emptying/refilling events actually take place.
    • +
    • min_level: At any time, the level of the reservoir must be greater or +equal than the min level.
    • +
    • max_level: At any time, the level of the reservoir must be less or equal +than the max level.
    • +
    - Note that min level must be <= 0, and the max level must be >= 0. Please - use fixed demands to simulate initial state. +
    Returns
    - Therefore, at any time: - sum(demands[i] * actives[i] if times[i] <= t) in [min_level, max_level] +
    +

    An instance of the Constraint class.

    +
    + +
    Raises
    + +
      +
    • ValueError: if max_level < min_level.
    • +
    • ValueError: if max_level < 0.
    • +
    • ValueError: if min_level > 0
    • +
    + -The array of boolean variables 'actives', if defined, indicates which -actions are actually performed. + +
    +
    #   -Args: - times: A list of integer variables which specify the time of the - filling or emptying the reservoir. - demands: A list of integer values that specifies the amount of the - emptying or filling. - actives: a list of boolean variables. They indicates if the - emptying/refilling events actually take place. - min_level: At any time, the level of the reservoir must be greater or - equal than the min level. - max_level: At any time, the level of the reservoir must be less or equal - than the max level. + + def + AddMapDomain(self, var, bool_var_array, offset=0): +
    -Returns: - An instance of the `Constraint` class. +
    + View Source +
        def AddMapDomain(self, var, bool_var_array, offset=0):
    +        """Adds `var == i + offset <=> bool_var_array[i] == true for all i`."""
     
    -Raises:
    -  ValueError: if max_level < min_level.
    +        for i, bool_var in enumerate(bool_var_array):
    +            b_index = bool_var.Index()
    +            var_index = var.Index()
    +            model_ct = self.__model.constraints.add()
    +            model_ct.linear.vars.append(var_index)
    +            model_ct.linear.coeffs.append(1)
    +            model_ct.linear.domain.extend([offset + i, offset + i])
    +            model_ct.enforcement_literal.append(b_index)
     
    -  ValueError: if max_level < 0.
    +            model_ct = self.__model.constraints.add()
    +            model_ct.linear.vars.append(var_index)
    +            model_ct.linear.coeffs.append(1)
    +            model_ct.enforcement_literal.append(-b_index - 1)
    +            if offset + i - 1 >= INT_MIN:
    +                model_ct.linear.domain.extend([INT_MIN, offset + i - 1])
    +            if offset + i + 1 <= INT_MAX:
    +                model_ct.linear.domain.extend([offset + i + 1, INT_MAX])
    +
    - ValueError: if min_level > 0 -""" +
    - if max_level < min_level: - return ValueError( - 'Reservoir constraint must have a max_level >= min_level') - - if max_level < 0: - return ValueError('Reservoir constraint must have a max_level >= 0') - - if min_level > 0: - return ValueError('Reservoir constraint must have a min_level <= 0') - - ct = Constraint(self.__model.constraints) - model_ct = self.__model.constraints[ct.Index()] - model_ct.reservoir.times.extend([self.GetOrMakeIndex(x) for x in times]) - model_ct.reservoir.demands.extend(demands) - model_ct.reservoir.actives.extend( - [self.GetOrMakeIndex(x) for x in actives]) - model_ct.reservoir.min_level = min_level - model_ct.reservoir.max_level = max_level - return ct
    -
    -
    -
    -def AssertIsBooleanVariable(self, x) -
    -
    -
    -
    - -Expand source code - -
    def AssertIsBooleanVariable(self, x):
    -    if isinstance(x, IntVar):
    -        var = self.__model.variables[x.Index()]
    -        if len(var.domain) != 2 or var.domain[0] < 0 or var.domain[1] > 1:
    -            raise TypeError('TypeError: ' + str(x) +
    -                            ' is not a boolean variable')
    -    elif not isinstance(x, _NotBooleanVariable):
    -        raise TypeError('TypeError: ' + str(x) +
    -                        ' is not a boolean variable')
    -
    -
    -
    -def ClearAssumptions(self) -
    -
    -

    Remove all assumptions from the model.

    -
    - -Expand source code - -
    def ClearAssumptions(self):
    -    """Remove all assumptions from the model."""
    -    self.__model.ClearField('assumptions')
    -
    -
    -
    -def ClearHints(self) -
    -
    -

    Remove any solution hint from the model.

    -
    - -Expand source code - -
    def ClearHints(self):
    -    """Remove any solution hint from the model."""
    -    self.__model.ClearField('solution_hint')
    -
    -
    -
    -def CopyFrom(self, other_model) -
    -
    -

    Reset the model, and creates a new one from a CpModelProto instance.

    -
    - -Expand source code - -
    def CopyFrom(self, other_model):
    -    """Reset the model, and creates a new one from a CpModelProto instance."""
    -    self.__model.CopyFrom(other_model.Proto())
    -
    -    # Rebuild constant map.
    -    self.__constant_map.clear()
    -    for i, var in enumerate(self.__model.variables):
    -        if len(var.domain) == 2 and var.domain[0] == var.domain[1]:
    -            self.__constant_map[var.domain[0]] = i
    -
    -
    -
    -def ExportToFile(self, file) -
    -
    -

    Write the model as a protocol buffer to 'file'.

    -

    Args

    -
    -
    file
    -
    file to write the model to. If the filename ends with 'txt', the -model will be written as a text file, otherwise, the binary format -will be used.
    -
    -

    Returns

    -

    True if the model was correctly written.

    -
    - -Expand source code - -
    def ExportToFile(self, file):
    -    """Write the model as a protocol buffer to 'file'.
    -
    -Args:
    -  file: file to write the model to. If the filename ends with 'txt', the
    -        model will be written as a text file, otherwise, the binary format
    -        will be used.
    +            

    Adds var == i + offset <=> bool_var_array[i] == true for all i.

    +
    -Returns: - True if the model was correctly written. -""" - return pywrapsat.CpSatHelper.WriteModelToFile(self.__model, file)
    -
    -
    -
    -def GetBoolVarFromProtoIndex(self, index) -
    -
    -

    Returns an already created Boolean variable from its index.

    -
    - -Expand source code - -
    def GetBoolVarFromProtoIndex(self, index):
    -    """Returns an already created Boolean variable from its index."""
    -    if index < 0 or index >= len(self.__model.variables):
    -        raise ValueError(
    -            f'GetBoolVarFromProtoIndex: out of bound index {index}')
    -    var = self.__model.variables[index]
    -    if len(var.domain) != 2 or var.domain[0] < 0 or var.domain[1] > 1:
    -        raise ValueError(
    -            f'GetBoolVarFromProtoIndex: index {index} does not reference' +
    -            ' a Boolean variable')
    +                            
    +                            
    +
    #   - return IntVar(self.__model, index, None)
    -
    -
    -
    -def GetIntVarFromProtoIndex(self, index) -
    -
    -

    Returns an already created integer variable from its index.

    -
    - -Expand source code - -
    def GetIntVarFromProtoIndex(self, index):
    -    """Returns an already created integer variable from its index."""
    -    if index < 0 or index >= len(self.__model.variables):
    -        raise ValueError(
    -            f'GetIntVarFromProtoIndex: out of bound index {index}')
    -    return IntVar(self.__model, index, None)
    -
    -
    -
    -def GetIntervalIndex(self, arg) -
    -
    -
    -
    - -Expand source code - -
    def GetIntervalIndex(self, arg):
    -    if not isinstance(arg, IntervalVar):
    -        raise TypeError('NotSupported: model.GetIntervalIndex(%s)' % arg)
    -    return arg.Index()
    -
    -
    -
    -def GetIntervalVarFromProtoIndex(self, index) -
    -
    -

    Returns an already created interval variable from its index.

    -
    - -Expand source code - -
    def GetIntervalVarFromProtoIndex(self, index):
    -    """Returns an already created interval variable from its index."""
    -    if index < 0 or index >= len(self.__model.constraints):
    -        raise ValueError(
    -            f'GetIntervalVarFromProtoIndex: out of bound index {index}')
    -    ct = self.__model.constraints[index]
    -    if not ct.HasField('interval'):
    -        raise ValueError(
    -            f'GetIntervalVarFromProtoIndex: index {index} does not reference an'
    -            + ' interval variable')
    +        
    +            def
    +            AddImplication(self, a, b):
    +    
     
    -    return IntervalVar(self.__model, index, None, None, None, None)
    -
    -
    -
    -def GetOrMakeBooleanIndex(self, arg) -
    -
    -

    Returns an index from a boolean expression.

    -
    - -Expand source code - -
    def GetOrMakeBooleanIndex(self, arg):
    -    """Returns an index from a boolean expression."""
    -    if isinstance(arg, IntVar):
    -        self.AssertIsBooleanVariable(arg)
    -        return arg.Index()
    -    elif isinstance(arg, _NotBooleanVariable):
    -        self.AssertIsBooleanVariable(arg.Not())
    -        return arg.Index()
    -    elif isinstance(arg, numbers.Integral):
    -        cp_model_helper.AssertIsBoolean(arg)
    -        return self.GetOrMakeIndexFromConstant(arg)
    -    else:
    -        raise TypeError('NotSupported: model.GetOrMakeBooleanIndex(' +
    -                        str(arg) + ')')
    -
    -
    -
    -def GetOrMakeIndex(self, arg) -
    -
    -

    Returns the index of a variable, its negation, or a number.

    -
    - -Expand source code - -
    def GetOrMakeIndex(self, arg):
    -    """Returns the index of a variable, its negation, or a number."""
    -    if isinstance(arg, IntVar):
    -        return arg.Index()
    -    elif (isinstance(arg, _ProductCst) and
    -          isinstance(arg.Expression(), IntVar) and arg.Coefficient() == -1):
    -        return -arg.Expression().Index() - 1
    -    elif isinstance(arg, numbers.Integral):
    -        cp_model_helper.AssertIsInt64(arg)
    -        return self.GetOrMakeIndexFromConstant(arg)
    -    else:
    -        raise TypeError('NotSupported: model.GetOrMakeIndex(' + str(arg) +
    -                        ')')
    -
    -
    -
    -def GetOrMakeIndexFromConstant(self, value) -
    -
    -
    -
    - -Expand source code - -
    def GetOrMakeIndexFromConstant(self, value):
    -    if value in self.__constant_map:
    -        return self.__constant_map[value]
    -    index = len(self.__model.variables)
    -    var = self.__model.variables.add()
    -    var.domain.extend([value, value])
    -    self.__constant_map[value] = index
    -    return index
    -
    -
    -
    -def HasObjective(self) -
    -
    -
    -
    - -Expand source code - -
    def HasObjective(self):
    -    return self.__model.HasField('objective')
    -
    -
    -
    -def Maximize(self, obj) -
    -
    -

    Sets the objective of the model to maximize(obj).

    -
    - -Expand source code - -
    def Maximize(self, obj):
    -    """Sets the objective of the model to maximize(obj)."""
    -    self._SetObjective(obj, minimize=False)
    -
    -
    -
    -def Minimize(self, obj) -
    -
    -

    Sets the objective of the model to minimize(obj).

    -
    - -Expand source code - -
    def Minimize(self, obj):
    -    """Sets the objective of the model to minimize(obj)."""
    -    self._SetObjective(obj, minimize=True)
    -
    -
    -
    -def ModelStats(self) -
    -
    -

    Returns a string containing some model statistics.

    -
    - -Expand source code - -
    def ModelStats(self):
    -    """Returns a string containing some model statistics."""
    -    return pywrapsat.CpSatHelper.ModelStats(self.__model)
    -
    -
    -
    -def Negated(self, index) -
    -
    -
    -
    - -Expand source code - -
    def Negated(self, index):
    -    return -index - 1
    -
    -
    -
    -def NewBoolVar(self, name) -
    -
    -

    Creates a 0-1 variable with the given name.

    -
    - -Expand source code - -
    def NewBoolVar(self, name):
    -    """Creates a 0-1 variable with the given name."""
    -    return IntVar(self.__model, Domain(0, 1), name)
    -
    -
    -
    -def NewConstant(self, value) -
    -
    -

    Declares a constant integer.

    -
    - -Expand source code - -
    def NewConstant(self, value):
    -    """Declares a constant integer."""
    -    return IntVar(self.__model, self.GetOrMakeIndexFromConstant(value),
    -                  None)
    -
    -
    -
    -def NewIntVar(self, lb, ub, name) -
    -
    -

    Create an integer variable with domain [lb, ub].

    -

    The CP-SAT solver is limited to integer variables. If you have fractional -values, scale them up so that they become integers; if you have strings, -encode them as integers.

    -

    Args

    -
    -
    lb
    -
    Lower bound for the variable.
    -
    ub
    -
    Upper bound for the variable.
    -
    name
    -
    The name of the variable.
    -
    -

    Returns

    -

    a variable whose domain is [lb, ub].

    -
    - -Expand source code - -
    def NewIntVar(self, lb, ub, name):
    -    """Create an integer variable with domain [lb, ub].
    +                
    + View Source +
        def AddImplication(self, a, b):
    +        """Adds `a => b` (`a` implies `b`)."""
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        model_ct.bool_or.literals.append(self.GetOrMakeBooleanIndex(b))
    +        model_ct.enforcement_literal.append(self.GetOrMakeBooleanIndex(a))
    +        return ct
    +
    -The CP-SAT solver is limited to integer variables. If you have fractional -values, scale them up so that they become integers; if you have strings, -encode them as integers. +
    -Args: - lb: Lower bound for the variable. - ub: Upper bound for the variable. - name: The name of the variable. +

    Adds a => b (a implies b).

    +
    -Returns: - a variable whose domain is [lb, ub]. -""" - return IntVar(self.__model, Domain(lb, ub), name)
    -
    -
    -
    -def NewIntVarFromDomain(self, domain, name) -
    -
    -

    Create an integer variable from a domain.

    -

    A domain is a set of integers specified by a collection of intervals. -For example, model.NewIntVarFromDomain(cp_model. -Domain.FromIntervals([[1, 2], [4, 6]]), 'x')

    -

    Args

    -
    -
    domain
    -
    An instance of the Domain class.
    -
    name
    -
    The name of the variable.
    -
    -

    Returns

    -

    a variable whose domain is the given domain.

    -
    - -Expand source code - -
    def NewIntVarFromDomain(self, domain, name):
    -    """Create an integer variable from a domain.
    +                            
    +                            
    +
    #   -A domain is a set of integers specified by a collection of intervals. -For example, `model.NewIntVarFromDomain(cp_model. - Domain.FromIntervals([[1, 2], [4, 6]]), 'x')` + + def + AddBoolOr(self, literals): +
    -Args: - domain: An instance of the Domain class. - name: The name of the variable. +
    + View Source +
        def AddBoolOr(self, literals):
    +        """Adds `Or(literals) == true`."""
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        model_ct.bool_or.literals.extend(
    +            [self.GetOrMakeBooleanIndex(x) for x in literals])
    +        return ct
    +
    + +
    + +

    Adds Or(literals) == true.

    +
    + + +
    +
    +
    #   + + + def + AddBoolAnd(self, literals): +
    + +
    + View Source +
        def AddBoolAnd(self, literals):
    +        """Adds `And(literals) == true`."""
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        model_ct.bool_and.literals.extend(
    +            [self.GetOrMakeBooleanIndex(x) for x in literals])
    +        return ct
    +
    + +
    + +

    Adds And(literals) == true.

    +
    + + +
    +
    +
    #   + + + def + AddBoolXOr(self, literals): +
    + +
    + View Source +
        def AddBoolXOr(self, literals):
    +        """Adds `XOr(literals) == true`."""
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        model_ct.bool_xor.literals.extend(
    +            [self.GetOrMakeBooleanIndex(x) for x in literals])
    +        return ct
    +
    + +
    + +

    Adds XOr(literals) == true.

    +
    + + +
    +
    +
    #   + + + def + AddMinEquality(self, target, variables): +
    + +
    + View Source +
        def AddMinEquality(self, target, variables):
    +        """Adds `target == Min(variables)`."""
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        model_ct.int_min.vars.extend(
    +            [self.GetOrMakeIndex(x) for x in variables])
    +        model_ct.int_min.target = self.GetOrMakeIndex(target)
    +        return ct
    +
    + +
    + +

    Adds target == Min(variables).

    +
    + + +
    +
    +
    #   + + + def + AddMaxEquality(self, target, variables): +
    + +
    + View Source +
        def AddMaxEquality(self, target, variables):
    +        """Adds `target == Max(variables)`."""
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        model_ct.int_max.vars.extend(
    +            [self.GetOrMakeIndex(x) for x in variables])
    +        model_ct.int_max.target = self.GetOrMakeIndex(target)
    +        return ct
    +
    + +
    + +

    Adds target == Max(variables).

    +
    + + +
    +
    +
    #   + + + def + AddDivisionEquality(self, target, num, denom): +
    + +
    + View Source +
        def AddDivisionEquality(self, target, num, denom):
    +        """Adds `target == num // denom` (integer division rounded towards 0)."""
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        model_ct.int_div.vars.extend(
    +            [self.GetOrMakeIndex(num),
    +             self.GetOrMakeIndex(denom)])
    +        model_ct.int_div.target = self.GetOrMakeIndex(target)
    +        return ct
    +
    + +
    + +

    Adds target == num // denom (integer division rounded towards 0).

    +
    + + +
    +
    +
    #   + + + def + AddAbsEquality(self, target, var): +
    + +
    + View Source +
        def AddAbsEquality(self, target, var):
    +        """Adds `target == Abs(var)`."""
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        index = self.GetOrMakeIndex(var)
    +        model_ct.int_max.vars.extend([index, -index - 1])
    +        model_ct.int_max.target = self.GetOrMakeIndex(target)
    +        return ct
    +
    + +
    + +

    Adds target == Abs(var).

    +
    + + +
    +
    +
    #   + + + def + AddModuloEquality(self, target, var, mod): +
    + +
    + View Source +
        def AddModuloEquality(self, target, var, mod):
    +        """Adds `target = var % mod`."""
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        model_ct.int_mod.vars.extend(
    +            [self.GetOrMakeIndex(var),
    +             self.GetOrMakeIndex(mod)])
    +        model_ct.int_mod.target = self.GetOrMakeIndex(target)
    +        return ct
    +
    + +
    + +

    Adds target = var % mod.

    +
    + + +
    +
    +
    #   + + + def + AddMultiplicationEquality(self, target, variables): +
    + +
    + View Source +
        def AddMultiplicationEquality(self, target, variables):
    +        """Adds `target == variables[0] * .. * variables[n]`."""
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        model_ct.int_prod.vars.extend(
    +            [self.GetOrMakeIndex(x) for x in variables])
    +        model_ct.int_prod.target = self.GetOrMakeIndex(target)
    +        return ct
    +
    + +
    + +

    Adds target == variables[0] * .. * variables[n].

    +
    + + +
    +
    +
    #   + + + def + AddProdEquality(self, target, variables): +
    + +
    + View Source +
        def AddProdEquality(self, target, variables):
    +        """Deprecated, use AddMultiplicationEquality."""
    +        warnings.warn(
    +            'AddProdEquality is deprecated; use' + 'AddMultiplicationEquality.',
    +            DeprecationWarning)
    +        return self.AddMultiplicationEquality(target, variables)
    +
    + +
    + +

    Deprecated, use AddMultiplicationEquality.

    +
    + + +
    +
    +
    #   + + + def + NewIntervalVar(self, start, size, end, name): +
    + +
    + View Source +
        def NewIntervalVar(self, start, size, end, name):
    +        """Creates an interval variable from start, size, and end.
    +
    +    An interval variable is a constraint, that is itself used in other
    +    constraints like NoOverlap.
    +
    +    Internally, it ensures that `start + size == end`.
    +
    +    Args:
    +      start: The start of the interval. It can be an affine or constant
    +        expression.
    +      size: The size of the interval. It can be an affine or constant
    +        expression.
    +      end: The end of the interval. It can be an affine or constant expression.
    +      name: The name of the interval variable.
    +
    +    Returns:
    +      An `IntervalVar` object.
    +    """
    +
    +        self.Add(start + size == end)
    +
    +        start_view = self.ParseLinearExpression(start)
    +        size_view = self.ParseLinearExpression(size)
    +        end_view = self.ParseLinearExpression(end)
    +        if len(start_view.vars) > 1:
    +            raise TypeError(
    +                'cp_model.NewIntervalVar: start must be affine or constant.')
    +        if len(size_view.vars) > 1:
    +            raise TypeError(
    +                'cp_model.NewIntervalVar: size must be affine or constant.')
    +        if len(end_view.vars) > 1:
    +            raise TypeError(
    +                'cp_model.NewIntervalVar: end must be affine or constant.')
    +        return IntervalVar(self.__model, start_view, size_view, end_view, None,
    +                           name)
    +
    + +
    + +

    Creates an interval variable from start, size, and end.

    -Returns: - a variable whose domain is the given domain. -""" - return IntVar(self.__model, domain, name)
    -
    -
    -
    -def NewIntervalVar(self, start, size, end, name) -
    -
    -

    Creates an interval variable from start, size, and end.

    An interval variable is a constraint, that is itself used in other constraints like NoOverlap.

    +

    Internally, it ensures that start + size == end.

    -

    Args

    -
    -
    start
    -
    The start of the interval. It can be an integer value, or an -integer variable.
    -
    size
    -
    The size of the interval. It can be an integer value, or an integer -variable.
    -
    end
    -
    The end of the interval. It can be an integer value, or an integer -variable.
    -
    name
    -
    The name of the interval variable.
    -
    -

    Returns

    -

    An IntervalVar object.

    -
    - -Expand source code - -
    def NewIntervalVar(self, start, size, end, name):
    -    """Creates an interval variable from start, size, and end.
     
    -An interval variable is a constraint, that is itself used in other
    -constraints like NoOverlap.
    +
    Args
    -Internally, it ensures that `start + size == end`. +
      +
    • start: The start of the interval. It can be an affine or constant +expression.
    • +
    • size: The size of the interval. It can be an affine or constant +expression.
    • +
    • end: The end of the interval. It can be an affine or constant expression.
    • +
    • name: The name of the interval variable.
    • +
    -Args: - start: The start of the interval. It can be an integer value, or an - integer variable. - size: The size of the interval. It can be an integer value, or an integer - variable. - end: The end of the interval. It can be an integer value, or an integer - variable. - name: The name of the interval variable. +
    Returns
    -Returns: - An `IntervalVar` object. -""" +
    +

    An IntervalVar object.

    +
    + + + + +
    +
    #   + + + def + NewFixedSizeIntervalVar(self, start, size, name): +
    + +
    + View Source +
        def NewFixedSizeIntervalVar(self, start, size, name):
    +        """Creates an interval variable from start, and a fixed size.
    +
    +    An interval variable is a constraint, that is itself used in other
    +    constraints like NoOverlap.
    +
    +    Args:
    +      start: The start of the interval. It can be an affine or constant
    +        expression.
    +      size: The size of the interval. It must be an integer value.
    +      name: The name of the interval variable.
    +
    +    Returns:
    +      An `IntervalVar` object.
    +    """
    +        cp_model_helper.AssertIsInt64(size)
    +        start_view = self.ParseLinearExpression(start)
    +        size_view = self.ParseLinearExpression(size)
    +        end_view = self.ParseLinearExpression(start + size)
    +        if len(start_view.vars) > 1:
    +            raise TypeError(
    +                'cp_model.NewIntervalVar: start must be affine or constant.')
    +        return IntervalVar(self.__model, start_view, size_view, end_view, None,
    +                           name)
    +
    + +
    + +

    Creates an interval variable from start, and a fixed size.

    + +

    An interval variable is a constraint, that is itself used in other +constraints like NoOverlap.

    + +
    Args
    + +
      +
    • start: The start of the interval. It can be an affine or constant +expression.
    • +
    • size: The size of the interval. It must be an integer value.
    • +
    • name: The name of the interval variable.
    • +
    + +
    Returns
    + +
    +

    An IntervalVar object.

    +
    +
    + + +
    +
    +
    #   + + + def + NewOptionalIntervalVar(self, start, size, end, is_present, name): +
    + +
    + View Source +
        def NewOptionalIntervalVar(self, start, size, end, is_present, name):
    +        """Creates an optional interval var from start, size, end, and is_present.
    +
    +    An optional interval variable is a constraint, that is itself used in other
    +    constraints like NoOverlap. This constraint is protected by an is_present
    +    literal that indicates if it is active or not.
    +
    +    Internally, it ensures that `is_present` implies `start + size == end`.
    +
    +    Args:
    +      start: The start of the interval. It can be an integer value, or an
    +        integer variable.
    +      size: The size of the interval. It can be an integer value, or an integer
    +        variable.
    +      end: The end of the interval. It can be an integer value, or an integer
    +        variable.
    +      is_present: A literal that indicates if the interval is active or not. A
    +        inactive interval is simply ignored by all constraints.
    +      name: The name of the interval variable.
    +
    +    Returns:
    +      An `IntervalVar` object.
    +    """
    +
    +        # Add the linear constraint.
    +        self.Add(start + size == end).OnlyEnforceIf(is_present)
    +
    +        # Creates the IntervalConstraintProto object.
    +        is_present_index = self.GetOrMakeBooleanIndex(is_present)
    +        start_view = self.ParseLinearExpression(start)
    +        size_view = self.ParseLinearExpression(size)
    +        end_view = self.ParseLinearExpression(end)
    +        if len(start_view.vars) > 1:
    +            raise TypeError(
    +                'cp_model.NewIntervalVar: start must be affine or constant.')
    +        if len(size_view.vars) > 1:
    +            raise TypeError(
    +                'cp_model.NewIntervalVar: size must be affine or constant.')
    +        if len(end_view.vars) > 1:
    +            raise TypeError(
    +                'cp_model.NewIntervalVar: end must be affine or constant.')
    +        return IntervalVar(self.__model, start_view, size_view, end_view,
    +                           is_present_index, name)
    +
    + +
    + +

    Creates an optional interval var from start, size, end, and is_present.

    - start_index = self.GetOrMakeIndex(start) - size_index = self.GetOrMakeIndex(size) - end_index = self.GetOrMakeIndex(end) - return IntervalVar(self.__model, start_index, size_index, end_index, - None, name)
    -
    -
    -
    -def NewOptionalIntervalVar(self, start, size, end, is_present, name) -
    -
    -

    Creates an optional interval var from start, size, end, and is_present.

    An optional interval variable is a constraint, that is itself used in other constraints like NoOverlap. This constraint is protected by an is_present literal that indicates if it is active or not.

    +

    Internally, it ensures that is_present implies start + size == end.

    -

    Args

    -
    -
    start
    -
    The start of the interval. It can be an integer value, or an -integer variable.
    -
    size
    -
    The size of the interval. It can be an integer value, or an integer -variable.
    -
    end
    -
    The end of the interval. It can be an integer value, or an integer -variable.
    -
    is_present
    -
    A literal that indicates if the interval is active or not. A -inactive interval is simply ignored by all constraints.
    -
    name
    -
    The name of the interval variable.
    -
    -

    Returns

    -

    An IntervalVar object.

    -
    - -Expand source code - -
    def NewOptionalIntervalVar(self, start, size, end, is_present, name):
    -    """Creates an optional interval var from start, size, end, and is_present.
     
    -An optional interval variable is a constraint, that is itself used in other
    -constraints like NoOverlap. This constraint is protected by an is_present
    -literal that indicates if it is active or not.
    +
    Args
    -Internally, it ensures that `is_present` implies `start + size == end`. +
      +
    • start: The start of the interval. It can be an integer value, or an +integer variable.
    • +
    • size: The size of the interval. It can be an integer value, or an integer +variable.
    • +
    • end: The end of the interval. It can be an integer value, or an integer +variable.
    • +
    • is_present: A literal that indicates if the interval is active or not. A +inactive interval is simply ignored by all constraints.
    • +
    • name: The name of the interval variable.
    • +
    -Args: - start: The start of the interval. It can be an integer value, or an - integer variable. - size: The size of the interval. It can be an integer value, or an integer - variable. - end: The end of the interval. It can be an integer value, or an integer - variable. - is_present: A literal that indicates if the interval is active or not. A - inactive interval is simply ignored by all constraints. - name: The name of the interval variable. +
    Returns
    + +
    +

    An IntervalVar object.

    +
    + + + + +
    +
    #   + + + def + NewOptionalFixedSizeIntervalVar(self, start, size, is_present, name): +
    + +
    + View Source +
        def NewOptionalFixedSizeIntervalVar(self, start, size, is_present, name):
    +        """Creates an interval variable from start, and a fixed size.
    +
    +    An interval variable is a constraint, that is itself used in other
    +    constraints like NoOverlap.
    +
    +    Args:
    +      start: The start of the interval. It can be an affine or constant
    +        expression.
    +      size: The size of the interval. It must be an integer value.
    +      is_present: A literal that indicates if the interval is active or not. A
    +        inactive interval is simply ignored by all constraints.
    +      name: The name of the interval variable.
    +
    +    Returns:
    +      An `IntervalVar` object.
    +    """
    +        cp_model_helper.AssertIsInt64(size)
    +        start_view = self.ParseLinearExpression(start)
    +        size_view = self.ParseLinearExpression(size)
    +        end_view = self.ParseLinearExpression(start + size)
    +        if len(start_view.vars) > 1:
    +            raise TypeError(
    +                'cp_model.NewIntervalVar: start must be affine or constant.')
    +        is_present_index = self.GetOrMakeBooleanIndex(is_present)
    +        return IntervalVar(self.__model, start_view, size_view, end_view,
    +                           is_present_index, name)
    +
    + +
    + +

    Creates an interval variable from start, and a fixed size.

    + +

    An interval variable is a constraint, that is itself used in other +constraints like NoOverlap.

    + +
    Args
    + +
      +
    • start: The start of the interval. It can be an affine or constant +expression.
    • +
    • size: The size of the interval. It must be an integer value.
    • +
    • is_present: A literal that indicates if the interval is active or not. A +inactive interval is simply ignored by all constraints.
    • +
    • name: The name of the interval variable.
    • +
    + +
    Returns
    + +
    +

    An IntervalVar object.

    +
    +
    + + +
    +
    +
    #   + + + def + AddNoOverlap(self, interval_vars): +
    + +
    + View Source +
        def AddNoOverlap(self, interval_vars):
    +        """Adds NoOverlap(interval_vars).
    +
    +    A NoOverlap constraint ensures that all present intervals do not overlap
    +    in time.
    +
    +    Args:
    +      interval_vars: The list of interval variables to constrain.
    +
    +    Returns:
    +      An instance of the `Constraint` class.
    +    """
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        model_ct.no_overlap.intervals.extend(
    +            [self.GetIntervalIndex(x) for x in interval_vars])
    +        return ct
    +
    + +
    + +

    Adds NoOverlap(interval_vars).

    + +

    A NoOverlap constraint ensures that all present intervals do not overlap +in time.

    + +
    Args
    + +
      +
    • interval_vars: The list of interval variables to constrain.
    • +
    + +
    Returns
    + +
    +

    An instance of the Constraint class.

    +
    +
    + + +
    +
    +
    #   + + + def + AddNoOverlap2D(self, x_intervals, y_intervals): +
    + +
    + View Source +
        def AddNoOverlap2D(self, x_intervals, y_intervals):
    +        """Adds NoOverlap2D(x_intervals, y_intervals).
    +
    +    A NoOverlap2D constraint ensures that all present rectangles do not overlap
    +    on a plane. Each rectangle is aligned with the X and Y axis, and is defined
    +    by two intervals which represent its projection onto the X and Y axis.
    +
    +    Args:
    +      x_intervals: The X coordinates of the rectangles.
    +      y_intervals: The Y coordinates of the rectangles.
    +
    +    Returns:
    +      An instance of the `Constraint` class.
    +    """
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        model_ct.no_overlap_2d.x_intervals.extend(
    +            [self.GetIntervalIndex(x) for x in x_intervals])
    +        model_ct.no_overlap_2d.y_intervals.extend(
    +            [self.GetIntervalIndex(x) for x in y_intervals])
    +        return ct
    +
    + +
    + +

    Adds NoOverlap2D(x_intervals, y_intervals).

    + +

    A NoOverlap2D constraint ensures that all present rectangles do not overlap +on a plane. Each rectangle is aligned with the X and Y axis, and is defined +by two intervals which represent its projection onto the X and Y axis.

    + +
    Args
    + +
      +
    • x_intervals: The X coordinates of the rectangles.
    • +
    • y_intervals: The Y coordinates of the rectangles.
    • +
    + +
    Returns
    + +
    +

    An instance of the Constraint class.

    +
    +
    + + +
    +
    +
    #   + + + def + AddCumulative(self, intervals, demands, capacity): +
    + +
    + View Source +
        def AddCumulative(self, intervals, demands, capacity):
    +        """Adds Cumulative(intervals, demands, capacity).
    +
    +    This constraint enforces that:
    +
    +        for all t:
    +          sum(demands[i]
    +            if (start(intervals[t]) <= t < end(intervals[t])) and
    +            (t is present)) <= capacity
    +
    +    Args:
    +      intervals: The list of intervals.
    +      demands: The list of demands for each interval. Each demand must be >= 0.
    +        Each demand can be an integer value, or an integer variable.
    +      capacity: The maximum capacity of the cumulative constraint. It must be a
    +        positive integer value or variable.
    +
    +    Returns:
    +      An instance of the `Constraint` class.
    +    """
    +        return self.AddCumulativeWithEnergy(intervals, demands, [], capacity)
    +
    + +
    + +

    Adds Cumulative(intervals, demands, capacity).

    + +
    This constraint enforces that
    + +
    +

    for all t: + sum(demands[i] + if (start(intervals[t]) <= t < end(intervals[t])) and + (t is present)) <= capacity

    +
    + +
    Args
    + +
      +
    • intervals: The list of intervals.
    • +
    • demands: The list of demands for each interval. Each demand must be >= 0. +Each demand can be an integer value, or an integer variable.
    • +
    • capacity: The maximum capacity of the cumulative constraint. It must be a +positive integer value or variable.
    • +
    + +
    Returns
    + +
    +

    An instance of the Constraint class.

    +
    +
    + + +
    +
    +
    #   + + + def + AddCumulativeWithEnergy(self, intervals, demands, energies, capacity): +
    + +
    + View Source +
        def AddCumulativeWithEnergy(self, intervals, demands, energies, capacity):
    +        """Adds Cumulative(intervals, demands, energies, capacity).
    +
    +    This constraint enforces that:
    +
    +        for all t:
    +          sum(demands[i]
    +            if (start(intervals[t]) <= t < end(intervals[t])) and
    +            (t is present)) <= capacity
    +
    +    The constraint assumes that:
    +
    +        for all t:
    +          energies[t] == size(intervals[t]) * demands[t]
    +
    +    Args:
    +      intervals: The list of intervals.
    +      demands: The list of demands for each interval. Each demand must be >= 0.
    +        Each demand can be an integer value, or an integer variable.
    +      energies: The list of linear expressions representing the energy of each
    +        task. This information is optional, and if given must be compatible with
    +        the demand and the size of each task (energy = size * demand).
    +      capacity: The maximum capacity of the cumulative constraint. It must be a
    +        positive integer value or variable.
    +
    +    Returns:
    +      An instance of the `Constraint` class.
    +    """
    +        ct = Constraint(self.__model.constraints)
    +        model_ct = self.__model.constraints[ct.Index()]
    +        model_ct.cumulative.intervals.extend(
    +            [self.GetIntervalIndex(x) for x in intervals])
    +        model_ct.cumulative.demands.extend(
    +            [self.GetOrMakeIndex(x) for x in demands])
    +        for e in energies:
    +            model_ct.cumulative.energies.append(self.ParseLinearExpression(e))
    +        model_ct.cumulative.capacity = self.GetOrMakeIndex(capacity)
    +        return ct
    +
    + +
    + +

    Adds Cumulative(intervals, demands, energies, capacity).

    + +
    This constraint enforces that
    + +
    +

    for all t: + sum(demands[i] + if (start(intervals[t]) <= t < end(intervals[t])) and + (t is present)) <= capacity

    +
    + +
    The constraint assumes that
    + +
    +

    for all t: + energies[t] == size(intervals[t]) * demands[t]

    +
    + +
    Args
    + +
      +
    • intervals: The list of intervals.
    • +
    • demands: The list of demands for each interval. Each demand must be >= 0. +Each demand can be an integer value, or an integer variable.
    • +
    • energies: The list of linear expressions representing the energy of each +task. This information is optional, and if given must be compatible with +the demand and the size of each task (energy = size * demand).
    • +
    • capacity: The maximum capacity of the cumulative constraint. It must be a +positive integer value or variable.
    • +
    + +
    Returns
    + +
    +

    An instance of the Constraint class.

    +
    +
    + + +
    +
    +
    #   + + + def + CopyFrom(self, other_model): +
    + +
    + View Source +
        def CopyFrom(self, other_model):
    +        """Reset the model, and creates a new one from a CpModelProto instance."""
    +        self.__model.CopyFrom(other_model.Proto())
    +
    +        # Rebuild constant map.
    +        self.__constant_map.clear()
    +        for i, var in enumerate(self.__model.variables):
    +            if len(var.domain) == 2 and var.domain[0] == var.domain[1]:
    +                self.__constant_map[var.domain[0]] = i
    +
    + +
    + +

    Reset the model, and creates a new one from a CpModelProto instance.

    +
    + + +
    +
    +
    #   + + + def + GetBoolVarFromProtoIndex(self, index): +
    + +
    + View Source +
        def GetBoolVarFromProtoIndex(self, index):
    +        """Returns an already created Boolean variable from its index."""
    +        if index < 0 or index >= len(self.__model.variables):
    +            raise ValueError(
    +                f'GetBoolVarFromProtoIndex: out of bound index {index}')
    +        var = self.__model.variables[index]
    +        if len(var.domain) != 2 or var.domain[0] < 0 or var.domain[1] > 1:
    +            raise ValueError(
    +                f'GetBoolVarFromProtoIndex: index {index} does not reference' +
    +                ' a Boolean variable')
    +
    +        return IntVar(self.__model, index, None)
    +
    + +
    + +

    Returns an already created Boolean variable from its index.

    +
    + + +
    +
    +
    #   + + + def + GetIntVarFromProtoIndex(self, index): +
    + +
    + View Source +
        def GetIntVarFromProtoIndex(self, index):
    +        """Returns an already created integer variable from its index."""
    +        if index < 0 or index >= len(self.__model.variables):
    +            raise ValueError(
    +                f'GetIntVarFromProtoIndex: out of bound index {index}')
    +        return IntVar(self.__model, index, None)
    +
    + +
    + +

    Returns an already created integer variable from its index.

    +
    + + +
    +
    +
    #   + + + def + GetIntervalVarFromProtoIndex(self, index): +
    + +
    + View Source +
        def GetIntervalVarFromProtoIndex(self, index):
    +        """Returns an already created interval variable from its index."""
    +        if index < 0 or index >= len(self.__model.constraints):
    +            raise ValueError(
    +                f'GetIntervalVarFromProtoIndex: out of bound index {index}')
    +        ct = self.__model.constraints[index]
    +        if not ct.HasField('interval'):
    +            raise ValueError(
    +                f'GetIntervalVarFromProtoIndex: index {index} does not reference an'
    +                + ' interval variable')
    +
    +        return IntervalVar(self.__model, index, None, None, None, None)
    +
    + +
    + +

    Returns an already created interval variable from its index.

    +
    + + +
    +
    +
    #   + + + def + Proto(self): +
    + +
    + View Source +
        def Proto(self):
    +        """Returns the underlying CpModelProto."""
    +        return self.__model
    +
    + +
    + +

    Returns the underlying CpModelProto.

    +
    + + +
    +
    +
    #   + + + def + Negated(self, index): +
    + +
    + View Source +
        def Negated(self, index):
    +        return -index - 1
    +
    + +
    + + + +
    +
    +
    #   + + + def + GetOrMakeIndex(self, arg): +
    + +
    + View Source +
        def GetOrMakeIndex(self, arg):
    +        """Returns the index of a variable, its negation, or a number."""
    +        if isinstance(arg, IntVar):
    +            return arg.Index()
    +        elif (isinstance(arg, _ProductCst) and
    +              isinstance(arg.Expression(), IntVar) and arg.Coefficient() == -1):
    +            return -arg.Expression().Index() - 1
    +        elif isinstance(arg, numbers.Integral):
    +            cp_model_helper.AssertIsInt64(arg)
    +            return self.GetOrMakeIndexFromConstant(arg)
    +        else:
    +            raise TypeError('NotSupported: model.GetOrMakeIndex(' + str(arg) +
    +                            ')')
    +
    + +
    + +

    Returns the index of a variable, its negation, or a number.

    +
    + + +
    +
    +
    #   + + + def + GetOrMakeBooleanIndex(self, arg): +
    + +
    + View Source +
        def GetOrMakeBooleanIndex(self, arg):
    +        """Returns an index from a boolean expression."""
    +        if isinstance(arg, IntVar):
    +            self.AssertIsBooleanVariable(arg)
    +            return arg.Index()
    +        elif isinstance(arg, _NotBooleanVariable):
    +            self.AssertIsBooleanVariable(arg.Not())
    +            return arg.Index()
    +        elif isinstance(arg, numbers.Integral):
    +            cp_model_helper.AssertIsBoolean(arg)
    +            return self.GetOrMakeIndexFromConstant(arg)
    +        else:
    +            raise TypeError('NotSupported: model.GetOrMakeBooleanIndex(' +
    +                            str(arg) + ')')
    +
    + +
    + +

    Returns an index from a boolean expression.

    +
    + + +
    +
    +
    #   + + + def + GetIntervalIndex(self, arg): +
    + +
    + View Source +
        def GetIntervalIndex(self, arg):
    +        if not isinstance(arg, IntervalVar):
    +            raise TypeError('NotSupported: model.GetIntervalIndex(%s)' % arg)
    +        return arg.Index()
    +
    + +
    + + + +
    +
    +
    #   + + + def + GetOrMakeIndexFromConstant(self, value): +
    + +
    + View Source +
        def GetOrMakeIndexFromConstant(self, value):
    +        if value in self.__constant_map:
    +            return self.__constant_map[value]
    +        index = len(self.__model.variables)
    +        var = self.__model.variables.add()
    +        var.domain.extend([value, value])
    +        self.__constant_map[value] = index
    +        return index
    +
    + +
    + + + +
    +
    +
    #   + + + def + VarIndexToVarProto(self, var_index): +
    + +
    + View Source +
        def VarIndexToVarProto(self, var_index):
    +        if var_index >= 0:
    +            return self.__model.variables[var_index]
    +        else:
    +            return self.__model.variables[-var_index - 1]
    +
    + +
    + + + +
    +
    +
    #   + + + def + ParseLinearExpression(self, linear_expr): +
    + +
    + View Source +
        def ParseLinearExpression(self, linear_expr):
    +        """Returns a LinearExpressionProto built from a LinearExpr instance."""
    +        result = cp_model_pb2.LinearExpressionProto()
    +        if isinstance(linear_expr, numbers.Integral):
    +            result.offset = linear_expr
    +            return result
    +
    +        if isinstance(linear_expr, IntVar):
    +            result.vars.append(self.GetOrMakeIndex(linear_expr))
    +            result.coeffs.append(1)
    +            return result
    +
    +        coeffs_map, constant = linear_expr.GetVarValueMap()
    +        result.offset = constant
    +        for t in coeffs_map.items():
    +            if not isinstance(t[0], IntVar):
    +                raise TypeError('Wrong argument' + str(t))
    +            cp_model_helper.AssertIsInt64(t[1])
    +            result.vars.append(t[0].Index())
    +            result.coeffs.append(t[1])
    +        return result
    +
    + +
    + +

    Returns a LinearExpressionProto built from a LinearExpr instance.

    +
    + + +
    +
    +
    #   + + + def + Minimize(self, obj): +
    + +
    + View Source +
        def Minimize(self, obj):
    +        """Sets the objective of the model to minimize(obj)."""
    +        self._SetObjective(obj, minimize=True)
    +
    + +
    + +

    Sets the objective of the model to minimize(obj).

    +
    + + +
    +
    +
    #   + + + def + Maximize(self, obj): +
    + +
    + View Source +
        def Maximize(self, obj):
    +        """Sets the objective of the model to maximize(obj)."""
    +        self._SetObjective(obj, minimize=False)
    +
    + +
    + +

    Sets the objective of the model to maximize(obj).

    +
    + + +
    +
    +
    #   + + + def + HasObjective(self): +
    + +
    + View Source +
        def HasObjective(self):
    +        return self.__model.HasField('objective')
    +
    + +
    + + + +
    +
    +
    #   + + + def + AddDecisionStrategy(self, variables, var_strategy, domain_strategy): +
    + +
    + View Source +
        def AddDecisionStrategy(self, variables, var_strategy, domain_strategy):
    +        """Adds a search strategy to the model.
    +
    +    Args:
    +      variables: a list of variables this strategy will assign.
    +      var_strategy: heuristic to choose the next variable to assign.
    +      domain_strategy: heuristic to reduce the domain of the selected variable.
    +        Currently, this is advanced code: the union of all strategies added to
    +          the model must be complete, i.e. instantiates all variables.
    +          Otherwise, Solve() will fail.
    +    """
    +
    +        strategy = self.__model.search_strategy.add()
    +        for v in variables:
    +            strategy.variables.append(v.Index())
    +        strategy.variable_selection_strategy = var_strategy
    +        strategy.domain_reduction_strategy = domain_strategy
    +
    + +
    + +

    Adds a search strategy to the model.

    + +
    Args
    + +
      +
    • variables: a list of variables this strategy will assign.
    • +
    • var_strategy: heuristic to choose the next variable to assign.
    • +
    • domain_strategy: heuristic to reduce the domain of the selected variable. +Currently, this is advanced code: the union of all strategies added to + the model must be complete, i.e. instantiates all variables. + Otherwise, Solve() will fail.
    • +
    +
    + + +
    +
    +
    #   + + + def + ModelStats(self): +
    + +
    + View Source +
        def ModelStats(self):
    +        """Returns a string containing some model statistics."""
    +        return pywrapsat.CpSatHelper.ModelStats(self.__model)
    +
    + +
    + +

    Returns a string containing some model statistics.

    +
    + + +
    +
    +
    #   + + + def + Validate(self): +
    + +
    + View Source +
        def Validate(self):
    +        """Returns a string indicating that the model is invalid."""
    +        return pywrapsat.CpSatHelper.ValidateModel(self.__model)
    +
    + +
    + +

    Returns a string indicating that the model is invalid.

    +
    + + +
    +
    +
    #   + + + def + ExportToFile(self, file): +
    + +
    + View Source +
        def ExportToFile(self, file):
    +        """Write the model as a protocol buffer to 'file'.
    +
    +    Args:
    +      file: file to write the model to. If the filename ends with 'txt', the
    +            model will be written as a text file, otherwise, the binary format
    +            will be used.
    +
    +
    +    Returns:
    +      True if the model was correctly written.
    +    """
    +        return pywrapsat.CpSatHelper.WriteModelToFile(self.__model, file)
    +
    + +
    + +

    Write the model as a protocol buffer to 'file'.

    + +
    Args
    + +
      +
    • file: file to write the model to. If the filename ends with 'txt', the +model will be written as a text file, otherwise, the binary format +will be used.
    • +
    + +
    Returns
    + +
    +

    True if the model was correctly written.

    +
    +
    + + +
    +
    +
    #   + + + def + AssertIsBooleanVariable(self, x): +
    + +
    + View Source +
        def AssertIsBooleanVariable(self, x):
    +        if isinstance(x, IntVar):
    +            var = self.__model.variables[x.Index()]
    +            if len(var.domain) != 2 or var.domain[0] < 0 or var.domain[1] > 1:
    +                raise TypeError('TypeError: ' + str(x) +
    +                                ' is not a boolean variable')
    +        elif not isinstance(x, _NotBooleanVariable):
    +            raise TypeError('TypeError: ' + str(x) +
    +                            ' is not a boolean variable')
    +
    + +
    + + + +
    +
    +
    #   + + + def + AddHint(self, var, value): +
    + +
    + View Source +
        def AddHint(self, var, value):
    +        """Adds 'var == value' as a hint to the solver."""
    +        self.__model.solution_hint.vars.append(self.GetOrMakeIndex(var))
    +        self.__model.solution_hint.values.append(value)
    +
    + +
    + +

    Adds 'var == value' as a hint to the solver.

    +
    + + +
    +
    +
    #   + + + def + ClearHints(self): +
    + +
    + View Source +
        def ClearHints(self):
    +        """Remove any solution hint from the model."""
    +        self.__model.ClearField('solution_hint')
    +
    + +
    + +

    Remove any solution hint from the model.

    +
    + + +
    +
    +
    #   + + + def + AddAssumption(self, lit): +
    + +
    + View Source +
        def AddAssumption(self, lit):
    +        """Add the literal 'lit' to the model as assumptions."""
    +        self.__model.assumptions.append(self.GetOrMakeBooleanIndex(lit))
    +
    + +
    + +

    Add the literal 'lit' to the model as assumptions.

    +
    + + +
    +
    +
    #   + + + def + AddAssumptions(self, literals): +
    + +
    + View Source +
        def AddAssumptions(self, literals):
    +        """Add the literals to the model as assumptions."""
    +        for lit in literals:
    +            self.AddAssumption(lit)
    +
    + +
    + +

    Add the literals to the model as assumptions.

    +
    + + +
    +
    +
    #   + + + def + ClearAssumptions(self): +
    + +
    + View Source +
        def ClearAssumptions(self):
    +        """Remove all assumptions from the model."""
    +        self.__model.ClearField('assumptions')
    +
    + +
    + +

    Remove all assumptions from the model.

    +
    + + +
    +
    +
    +
    #   + + + def + EvaluateLinearExpr(expression, solution): +
    + +
    + View Source +
    def EvaluateLinearExpr(expression, solution):
    +    """Evaluate a linear expression against a solution."""
    +    if isinstance(expression, numbers.Integral):
    +        return expression
    +    if not isinstance(expression, LinearExpr):
    +        raise TypeError('Cannot interpret %s as a linear expression.' %
    +                        expression)
    +
    +    value = 0
    +    to_process = [(expression, 1)]
    +    while to_process:
    +        expr, coef = to_process.pop()
    +        if isinstance(expr, _ProductCst):
    +            to_process.append((expr.Expression(), coef * expr.Coefficient()))
    +        elif isinstance(expr, _SumArray):
    +            for e in expr.Expressions():
    +                to_process.append((e, coef))
    +            value += expr.Constant() * coef
    +        elif isinstance(expr, _ScalProd):
    +            for e, c in zip(expr.Expressions(), expr.Coefficients()):
    +                to_process.append((e, coef * c))
    +            value += expr.Constant() * coef
    +        elif isinstance(expr, IntVar):
    +            value += coef * solution.solution[expr.Index()]
    +        elif isinstance(expr, _NotBooleanVariable):
    +            value += coef * (1 - solution.solution[expr.Not().Index()])
    +    return value
    +
    + +
    + +

    Evaluate a linear expression against a solution.

    +
    + + +
    +
    +
    #   + + + def + EvaluateBooleanExpression(literal, solution): +
    + +
    + View Source +
    def EvaluateBooleanExpression(literal, solution):
    +    """Evaluate a boolean expression against a solution."""
    +    if isinstance(literal, numbers.Integral):
    +        return bool(literal)
    +    elif isinstance(literal, IntVar) or isinstance(literal,
    +                                                   _NotBooleanVariable):
    +        index = literal.Index()
    +        if index >= 0:
    +            return bool(solution.solution[index])
    +        else:
    +            return not solution.solution[-index - 1]
    +    else:
    +        raise TypeError('Cannot interpret %s as a boolean expression.' %
    +                        literal)
    +
    + +
    + +

    Evaluate a boolean expression against a solution.

    +
    + + +
    +
    +
    + #   + + + class + CpSolver: +
    + +
    + View Source +
    class CpSolver(object):
    +    """Main solver class.
    +
    +  The purpose of this class is to search for a solution to the model provided
    +  to the Solve() method.
    +
    +  Once Solve() is called, this class allows inspecting the solution found
    +  with the Value() and BooleanValue() methods, as well as general statistics
    +  about the solve procedure.
    +  """
    +
    +    def __init__(self):
    +        self.__model = None
    +        self.__solution: cp_model_pb2.CpSolverResponse = None
    +        self.parameters = sat_parameters_pb2.SatParameters()
    +        self.log_callback = None
    +        self.__solve_wrapper: pywrapsat.SolveWrapper = None
    +        self.__lock = threading.Lock()
    +
    +    def Solve(self, model, solution_callback=None):
    +        """Solves a problem and passes each solution to the callback if not null."""
    +        with self.__lock:
    +            solve_wrapper = pywrapsat.SolveWrapper()
    +
    +        solve_wrapper.SetParameters(self.parameters)
    +        if solution_callback is not None:
    +            solve_wrapper.AddSolutionCallback(solution_callback)
    +
    +        if self.log_callback is not None:
    +            solve_wrapper.AddLogCallback(self.log_callback)
    +
    +        self.__solution = solve_wrapper.Solve(model.Proto())
    +
    +        if solution_callback is not None:
    +            solve_wrapper.ClearSolutionCallback(solution_callback)
    +
    +        with self.__lock:
    +            self.__solve_wrapper = None
    +
    +        return self.__solution.status
    +
    +    # DEPRECATED, just use Solve() with the callback argument.
    +    def SolveWithSolutionCallback(self, model, callback):
    +        """DEPRECATED Use Solve() with the callback argument."""
    +        warnings.warn("SolveWithSolutionCallback is deprecated; use Solve() with the callback argument.",
    +                      DeprecationWarning)
    +        return self.Solve(model, callback)
    +
    +    def SearchForAllSolutions(self, model, callback):
    +        """DEPRECATED Use Solve() with the right parameter.
    +
    +    Search for all solutions of a satisfiability problem.
    +
    +    This method searches for all feasible solutions of a given model.
    +    Then it feeds the solution to the callback.
    +
    +    Note that the model cannot contain an objective.
    +
    +    Args:
    +      model: The model to solve.
    +      callback: The callback that will be called at each solution.
    +
    +    Returns:
    +      The status of the solve:
    +
    +      * *FEASIBLE* if some solutions have been found
    +      * *INFEASIBLE* if the solver has proved there are no solution
    +      * *OPTIMAL* if all solutions have been found
    +    """
    +        warnings.warn("SearchForAllSolutions is deprecated; use Solve() with enumerate_all_solutions = True.",
    +                      DeprecationWarning)
    +        if model.HasObjective():
    +            raise TypeError('Search for all solutions is only defined on '
    +                            'satisfiability problems')
    +        # Store old parameter.
    +        enumerate_all = self.parameters.enumerate_all_solutions
    +        self.parameters.enumerate_all_solutions = True
    +
    +        self.Solve(model, callback)
    +
    +        # Restore parameter.
    +        self.parameters.enumerate_all_solutions = enumerate_all
    +        return self.__solution.status
    +
    +    def StopSearch(self):
    +        """Stops the current search asynchronously."""
    +        with self.__lock:
    +            if self.__solve_wrapper:
    +                self.__solve_wrapper.StopSearch()
    +
    +    def Value(self, expression):
    +        """Returns the value of a linear expression after solve."""
    +        if not self.__solution:
    +            raise RuntimeError('Solve() has not be called.')
    +        return EvaluateLinearExpr(expression, self.__solution)
    +
    +    def BooleanValue(self, literal):
    +        """Returns the boolean value of a literal after solve."""
    +        if not self.__solution:
    +            raise RuntimeError('Solve() has not be called.')
    +        return EvaluateBooleanExpression(literal, self.__solution)
    +
    +    def ObjectiveValue(self):
    +        """Returns the value of the objective after solve."""
    +        return self.__solution.objective_value
    +
    +    def BestObjectiveBound(self):
    +        """Returns the best lower (upper) bound found when min(max)imizing."""
    +        return self.__solution.best_objective_bound
    +
    +    def StatusName(self, status=None):
    +        """Returns the name of the status returned by Solve()."""
    +        if status is None:
    +            status = self.__solution.status
    +        return cp_model_pb2.CpSolverStatus.Name(status)
    +
    +    def NumBooleans(self):
    +        """Returns the number of boolean variables managed by the SAT solver."""
    +        return self.__solution.num_booleans
    +
    +    def NumConflicts(self):
    +        """Returns the number of conflicts since the creation of the solver."""
    +        return self.__solution.num_conflicts
    +
    +    def NumBranches(self):
    +        """Returns the number of search branches explored by the solver."""
    +        return self.__solution.num_branches
    +
    +    def WallTime(self):
    +        """Returns the wall time in seconds since the creation of the solver."""
    +        return self.__solution.wall_time
    +
    +    def UserTime(self):
    +        """Returns the user time in seconds since the creation of the solver."""
    +        return self.__solution.user_time
    +
    +    def ResponseStats(self):
    +        """Returns some statistics on the solution found as a string."""
    +        return pywrapsat.CpSatHelper.SolverResponseStats(self.__solution)
    +
    +    def ResponseProto(self):
    +        """Returns the response object."""
    +        return self.__solution
    +
    +    def SufficientAssumptionsForInfeasibility(self):
    +        """Returns the indices of the infeasible assumptions."""
    +        return self.__solution.sufficient_assumptions_for_infeasibility
    +
    + +
    + +

    Main solver class.

    -Returns: - An `IntervalVar` object. -""" - is_present_index = self.GetOrMakeBooleanIndex(is_present) - start_index = self.GetOrMakeIndex(start) - size_index = self.GetOrMakeIndex(size) - end_index = self.GetOrMakeIndex(end) - return IntervalVar(self.__model, start_index, size_index, end_index, - is_present_index, name)
    - - -
    -def Proto(self) -
    -
    -

    Returns the underlying CpModelProto.

    -
    - -Expand source code - -
    def Proto(self):
    -    """Returns the underlying CpModelProto."""
    -    return self.__model
    -
    -
    -
    -def Validate(self) -
    -
    -

    Returns a string indicating that the model is invalid.

    -
    - -Expand source code - -
    def Validate(self):
    -    """Returns a string indicating that the model is invalid."""
    -    return pywrapsat.CpSatHelper.ValidateModel(self.__model)
    -
    -
    -
    -def VarIndexToVarProto(self, var_index) -
    -
    -
    -
    - -Expand source code - -
    def VarIndexToVarProto(self, var_index):
    -    if var_index >= 0:
    -        return self.__model.variables[var_index]
    -    else:
    -        return self.__model.variables[-var_index - 1]
    -
    -
    - - -
    -class CpSolver -
    -
    -

    Main solver class.

    The purpose of this class is to search for a solution to the model provided to the Solve() method.

    +

    Once Solve() is called, this class allows inspecting the solution found with the Value() and BooleanValue() methods, as well as general statistics -about the solve procedure.

    -
    - -Expand source code - -
    class CpSolver(object):
    -    """Main solver class.
    +about the solve procedure.

    +
    - The purpose of this class is to search for a solution to the model provided - to the Solve() method. - Once Solve() is called, this class allows inspecting the solution found - with the Value() and BooleanValue() methods, as well as general statistics - about the solve procedure. - """ +
    +
    #   - def __init__(self): - self.__model = None - self.__solution: cp_model_pb2.CpSolverResponse = None - self.parameters = sat_parameters_pb2.SatParameters() - self.log_callback = None - self.__solve_wrapper: pywrapsat.SolveWrapper = None - self.__lock = threading.Lock() + + CpSolver() +
    - def Solve(self, model, solution_callback=None): - """Solves a problem and passes each solution to the callback if not null.""" - with self.__lock: - solve_wrapper = pywrapsat.SolveWrapper() +
    + View Source +
        def __init__(self):
    +        self.__model = None
    +        self.__solution: cp_model_pb2.CpSolverResponse = None
    +        self.parameters = sat_parameters_pb2.SatParameters()
    +        self.log_callback = None
    +        self.__solve_wrapper: pywrapsat.SolveWrapper = None
    +        self.__lock = threading.Lock()
    +
    - solve_wrapper.SetParameters(self.parameters) - if solution_callback is not None: - solve_wrapper.AddSolutionCallback(solution_callback) +
    - if self.log_callback is not None: - solve_wrapper.AddLogCallback(self.log_callback) + - self.__solution = solve_wrapper.Solve(model.Proto()) +
    +
    +
    #   - if solution_callback is not None: - solve_wrapper.ClearSolutionCallback(solution_callback) + + def + Solve(self, model, solution_callback=None): +
    - with self.__lock: - self.__solve_wrapper = None +
    + View Source +
        def Solve(self, model, solution_callback=None):
    +        """Solves a problem and passes each solution to the callback if not null."""
    +        with self.__lock:
    +            solve_wrapper = pywrapsat.SolveWrapper()
     
    -        return self.__solution.status
    +        solve_wrapper.SetParameters(self.parameters)
    +        if solution_callback is not None:
    +            solve_wrapper.AddSolutionCallback(solution_callback)
     
    -    # DEPRECATED, just use Solve() with the callback argument.
    -    def SolveWithSolutionCallback(self, model, callback):
    -        """DEPRECATED Use Solve() with the callback argument."""
    -        return self.Solve(model, callback)
    +        if self.log_callback is not None:
    +            solve_wrapper.AddLogCallback(self.log_callback)
     
    -    def SearchForAllSolutions(self, model, callback):
    -        """Search for all solutions of a satisfiability problem.
    +        self.__solution = solve_wrapper.Solve(model.Proto())
     
    -    This method searches for all feasible solutions of a given model.
    -    Then it feeds the solution to the callback.
    +        if solution_callback is not None:
    +            solve_wrapper.ClearSolutionCallback(solution_callback)
     
    -    Note that the model cannot contain an objective.
    +        with self.__lock:
    +            self.__solve_wrapper = None
     
    -    Args:
    -      model: The model to solve.
    -      callback: The callback that will be called at each solution.
    +        return self.__solution.status
    +
    - Returns: - The status of the solve: +
    - * *FEASIBLE* if some solutions have been found - * *INFEASIBLE* if the solver has proved there are no solution - * *OPTIMAL* if all solutions have been found - """ - if model.HasObjective(): - raise TypeError('Search for all solutions is only defined on ' - 'satisfiability problems') - # Store old parameter. - enumerate_all = self.parameters.enumerate_all_solutions - self.parameters.enumerate_all_solutions = True +

    Solves a problem and passes each solution to the callback if not null.

    +
    - self.Solve(model, callback) - # Restore parameter. - self.parameters.enumerate_all_solutions = enumerate_all - return self.__solution.status +
    +
    +
    #   - def StopSearch(self): - """Stops the current search asynchronously.""" - with self.__lock: - if self.__solve_wrapper: - self.__solve_wrapper.StopSearch() + + def + SolveWithSolutionCallback(self, model, callback): +
    - def Value(self, expression): - """Returns the value of a linear expression after solve.""" - if not self.__solution: - raise RuntimeError('Solve() has not be called.') - return EvaluateLinearExpr(expression, self.__solution) +
    + View Source +
        def SolveWithSolutionCallback(self, model, callback):
    +        """DEPRECATED Use Solve() with the callback argument."""
    +        warnings.warn("SolveWithSolutionCallback is deprecated; use Solve() with the callback argument.",
    +                      DeprecationWarning)
    +        return self.Solve(model, callback)
    +
    - def BooleanValue(self, literal): - """Returns the boolean value of a literal after solve.""" - if not self.__solution: - raise RuntimeError('Solve() has not be called.') - return EvaluateBooleanExpression(literal, self.__solution) +
    - def ObjectiveValue(self): - """Returns the value of the objective after solve.""" - return self.__solution.objective_value +

    DEPRECATED Use Solve() with the callback argument.

    +
    - def BestObjectiveBound(self): - """Returns the best lower (upper) bound found when min(max)imizing.""" - return self.__solution.best_objective_bound - def StatusName(self, status=None): - """Returns the name of the status returned by Solve().""" - if status is None: - status = self.__solution.status - return cp_model_pb2.CpSolverStatus.Name(status) +
    +
    +
    #   - def NumBooleans(self): - """Returns the number of boolean variables managed by the SAT solver.""" - return self.__solution.num_booleans + + def + SearchForAllSolutions(self, model, callback): +
    - def NumConflicts(self): - """Returns the number of conflicts since the creation of the solver.""" - return self.__solution.num_conflicts +
    + View Source +
        def SearchForAllSolutions(self, model, callback):
    +        """DEPRECATED Use Solve() with the right parameter.
     
    -    def NumBranches(self):
    -        """Returns the number of search branches explored by the solver."""
    -        return self.__solution.num_branches
    +    Search for all solutions of a satisfiability problem.
     
    -    def WallTime(self):
    -        """Returns the wall time in seconds since the creation of the solver."""
    -        return self.__solution.wall_time
    +    This method searches for all feasible solutions of a given model.
    +    Then it feeds the solution to the callback.
     
    -    def UserTime(self):
    -        """Returns the user time in seconds since the creation of the solver."""
    -        return self.__solution.user_time
    +    Note that the model cannot contain an objective.
     
    -    def ResponseStats(self):
    -        """Returns some statistics on the solution found as a string."""
    -        return pywrapsat.CpSatHelper.SolverResponseStats(self.__solution)
    +    Args:
    +      model: The model to solve.
    +      callback: The callback that will be called at each solution.
     
    -    def ResponseProto(self):
    -        """Returns the response object."""
    -        return self.__solution
    +    Returns:
    +      The status of the solve:
    +
    +      * *FEASIBLE* if some solutions have been found
    +      * *INFEASIBLE* if the solver has proved there are no solution
    +      * *OPTIMAL* if all solutions have been found
    +    """
    +        warnings.warn("SearchForAllSolutions is deprecated; use Solve() with enumerate_all_solutions = True.",
    +                      DeprecationWarning)
    +        if model.HasObjective():
    +            raise TypeError('Search for all solutions is only defined on '
    +                            'satisfiability problems')
    +        # Store old parameter.
    +        enumerate_all = self.parameters.enumerate_all_solutions
    +        self.parameters.enumerate_all_solutions = True
    +
    +        self.Solve(model, callback)
    +
    +        # Restore parameter.
    +        self.parameters.enumerate_all_solutions = enumerate_all
    +        return self.__solution.status
    +
    + +
    + +

    DEPRECATED Use Solve() with the right parameter.

    + +

    Search for all solutions of a satisfiability problem.

    - def SufficientAssumptionsForInfeasibility(self): - """Returns the indices of the infeasible assumptions.""" - return self.__solution.sufficient_assumptions_for_infeasibility
    - -

    Methods

    -
    -
    -def BestObjectiveBound(self) -
    -
    -

    Returns the best lower (upper) bound found when min(max)imizing.

    -
    - -Expand source code - -
    def BestObjectiveBound(self):
    -    """Returns the best lower (upper) bound found when min(max)imizing."""
    -    return self.__solution.best_objective_bound
    -
    -
    -
    -def BooleanValue(self, literal) -
    -
    -

    Returns the boolean value of a literal after solve.

    -
    - -Expand source code - -
    def BooleanValue(self, literal):
    -    """Returns the boolean value of a literal after solve."""
    -    if not self.__solution:
    -        raise RuntimeError('Solve() has not be called.')
    -    return EvaluateBooleanExpression(literal, self.__solution)
    -
    -
    -
    -def NumBooleans(self) -
    -
    -

    Returns the number of boolean variables managed by the SAT solver.

    -
    - -Expand source code - -
    def NumBooleans(self):
    -    """Returns the number of boolean variables managed by the SAT solver."""
    -    return self.__solution.num_booleans
    -
    -
    -
    -def NumBranches(self) -
    -
    -

    Returns the number of search branches explored by the solver.

    -
    - -Expand source code - -
    def NumBranches(self):
    -    """Returns the number of search branches explored by the solver."""
    -    return self.__solution.num_branches
    -
    -
    -
    -def NumConflicts(self) -
    -
    -

    Returns the number of conflicts since the creation of the solver.

    -
    - -Expand source code - -
    def NumConflicts(self):
    -    """Returns the number of conflicts since the creation of the solver."""
    -    return self.__solution.num_conflicts
    -
    -
    -
    -def ObjectiveValue(self) -
    -
    -

    Returns the value of the objective after solve.

    -
    - -Expand source code - -
    def ObjectiveValue(self):
    -    """Returns the value of the objective after solve."""
    -    return self.__solution.objective_value
    -
    -
    -
    -def ResponseProto(self) -
    -
    -

    Returns the response object.

    -
    - -Expand source code - -
    def ResponseProto(self):
    -    """Returns the response object."""
    -    return self.__solution
    -
    -
    -
    -def ResponseStats(self) -
    -
    -

    Returns some statistics on the solution found as a string.

    -
    - -Expand source code - -
    def ResponseStats(self):
    -    """Returns some statistics on the solution found as a string."""
    -    return pywrapsat.CpSatHelper.SolverResponseStats(self.__solution)
    -
    -
    -
    -def SearchForAllSolutions(self, model, callback) -
    -
    -

    Search for all solutions of a satisfiability problem.

    This method searches for all feasible solutions of a given model. Then it feeds the solution to the callback.

    +

    Note that the model cannot contain an objective.

    -

    Args

    -
    -
    model
    -
    The model to solve.
    -
    callback
    -
    The callback that will be called at each solution.
    -
    -

    Returns

    -

    The status of the solve:

    + +
    Args
    +
      -
    • FEASIBLE if some solutions have been found
    • -
    • INFEASIBLE if the solver has proved there are no solution
    • -
    • OPTIMAL if all solutions have been found
    • -
    -
    - -Expand source code - -
    def SearchForAllSolutions(self, model, callback):
    -    """Search for all solutions of a satisfiability problem.
    +
  • model: The model to solve.
  • +
  • callback: The callback that will be called at each solution.
  • + -This method searches for all feasible solutions of a given model. -Then it feeds the solution to the callback. +
    Returns
    -Note that the model cannot contain an objective. +
    +

    The status of the solve:

    + +
      +
    • FEASIBLE if some solutions have been found
    • +
    • INFEASIBLE if the solver has proved there are no solution
    • +
    • OPTIMAL if all solutions have been found
    • +
    +
    +
    -Args: - model: The model to solve. - callback: The callback that will be called at each solution. -Returns: - The status of the solve: +
    +
    +
    #   - * *FEASIBLE* if some solutions have been found - * *INFEASIBLE* if the solver has proved there are no solution - * *OPTIMAL* if all solutions have been found -""" - if model.HasObjective(): - raise TypeError('Search for all solutions is only defined on ' - 'satisfiability problems') - # Store old parameter. - enumerate_all = self.parameters.enumerate_all_solutions - self.parameters.enumerate_all_solutions = True + + def + StopSearch(self): +
    - self.Solve(model, callback) +
    + View Source +
        def StopSearch(self):
    +        """Stops the current search asynchronously."""
    +        with self.__lock:
    +            if self.__solve_wrapper:
    +                self.__solve_wrapper.StopSearch()
    +
    - # Restore parameter. - self.parameters.enumerate_all_solutions = enumerate_all - return self.__solution.status
    -
    - -
    -def Solve(self, model, solution_callback=None) -
    -
    -

    Solves a problem and passes each solution to the callback if not null.

    -
    - -Expand source code - -
    def Solve(self, model, solution_callback=None):
    -    """Solves a problem and passes each solution to the callback if not null."""
    -    with self.__lock:
    -        solve_wrapper = pywrapsat.SolveWrapper()
    +        
    - solve_wrapper.SetParameters(self.parameters) - if solution_callback is not None: - solve_wrapper.AddSolutionCallback(solution_callback) +

    Stops the current search asynchronously.

    +
    - if self.log_callback is not None: - solve_wrapper.AddLogCallback(self.log_callback) - self.__solution = solve_wrapper.Solve(model.Proto()) +
    +
    +
    #   - if solution_callback is not None: - solve_wrapper.ClearSolutionCallback(solution_callback) + + def + Value(self, expression): +
    - with self.__lock: - self.__solve_wrapper = None +
    + View Source +
        def Value(self, expression):
    +        """Returns the value of a linear expression after solve."""
    +        if not self.__solution:
    +            raise RuntimeError('Solve() has not be called.')
    +        return EvaluateLinearExpr(expression, self.__solution)
    +
    + +
    + +

    Returns the value of a linear expression after solve.

    +
    + + +
    +
    +
    #   + + + def + BooleanValue(self, literal): +
    + +
    + View Source +
        def BooleanValue(self, literal):
    +        """Returns the boolean value of a literal after solve."""
    +        if not self.__solution:
    +            raise RuntimeError('Solve() has not be called.')
    +        return EvaluateBooleanExpression(literal, self.__solution)
    +
    + +
    + +

    Returns the boolean value of a literal after solve.

    +
    + + +
    +
    +
    #   + + + def + ObjectiveValue(self): +
    + +
    + View Source +
        def ObjectiveValue(self):
    +        """Returns the value of the objective after solve."""
    +        return self.__solution.objective_value
    +
    + +
    + +

    Returns the value of the objective after solve.

    +
    + + +
    +
    +
    #   + + + def + BestObjectiveBound(self): +
    + +
    + View Source +
        def BestObjectiveBound(self):
    +        """Returns the best lower (upper) bound found when min(max)imizing."""
    +        return self.__solution.best_objective_bound
    +
    + +
    + +

    Returns the best lower (upper) bound found when min(max)imizing.

    +
    + + +
    +
    +
    #   + + + def + StatusName(self, status=None): +
    + +
    + View Source +
        def StatusName(self, status=None):
    +        """Returns the name of the status returned by Solve()."""
    +        if status is None:
    +            status = self.__solution.status
    +        return cp_model_pb2.CpSolverStatus.Name(status)
    +
    + +
    + +

    Returns the name of the status returned by Solve().

    +
    + + +
    +
    +
    #   + + + def + NumBooleans(self): +
    + +
    + View Source +
        def NumBooleans(self):
    +        """Returns the number of boolean variables managed by the SAT solver."""
    +        return self.__solution.num_booleans
    +
    + +
    + +

    Returns the number of boolean variables managed by the SAT solver.

    +
    + + +
    +
    +
    #   + + + def + NumConflicts(self): +
    + +
    + View Source +
        def NumConflicts(self):
    +        """Returns the number of conflicts since the creation of the solver."""
    +        return self.__solution.num_conflicts
    +
    + +
    + +

    Returns the number of conflicts since the creation of the solver.

    +
    + + +
    +
    +
    #   + + + def + NumBranches(self): +
    + +
    + View Source +
        def NumBranches(self):
    +        """Returns the number of search branches explored by the solver."""
    +        return self.__solution.num_branches
    +
    + +
    + +

    Returns the number of search branches explored by the solver.

    +
    + + +
    +
    +
    #   + + + def + WallTime(self): +
    + +
    + View Source +
        def WallTime(self):
    +        """Returns the wall time in seconds since the creation of the solver."""
    +        return self.__solution.wall_time
    +
    + +
    + +

    Returns the wall time in seconds since the creation of the solver.

    +
    + + +
    +
    +
    #   + + + def + UserTime(self): +
    + +
    + View Source +
        def UserTime(self):
    +        """Returns the user time in seconds since the creation of the solver."""
    +        return self.__solution.user_time
    +
    + +
    + +

    Returns the user time in seconds since the creation of the solver.

    +
    + + +
    +
    +
    #   + + + def + ResponseStats(self): +
    + +
    + View Source +
        def ResponseStats(self):
    +        """Returns some statistics on the solution found as a string."""
    +        return pywrapsat.CpSatHelper.SolverResponseStats(self.__solution)
    +
    + +
    + +

    Returns some statistics on the solution found as a string.

    +
    + + +
    +
    +
    #   + + + def + ResponseProto(self): +
    + +
    + View Source +
        def ResponseProto(self):
    +        """Returns the response object."""
    +        return self.__solution
    +
    + +
    + +

    Returns the response object.

    +
    + + +
    +
    +
    #   + + + def + SufficientAssumptionsForInfeasibility(self): +
    + +
    + View Source +
        def SufficientAssumptionsForInfeasibility(self):
    +        """Returns the indices of the infeasible assumptions."""
    +        return self.__solution.sufficient_assumptions_for_infeasibility
    +
    + +
    + +

    Returns the indices of the infeasible assumptions.

    +
    + + +
    +
    +
    +
    + #   + + + class + CpSolverSolutionCallback(ortools.sat.pywrapsat.SolutionCallback): +
    + +
    + View Source +
    class CpSolverSolutionCallback(pywrapsat.SolutionCallback):
    +    """Solution callback.
    +
    +  This class implements a callback that will be called at each new solution
    +  found during search.
    +
    +  The method OnSolutionCallback() will be called by the solver, and must be
    +  implemented. The current solution can be queried using the BooleanValue()
    +  and Value() methods.
    +
    +  It inherits the following methods from its base class:
    +
    +  * `ObjectiveValue(self)`
    +  * `BestObjectiveBound(self)`
    +  * `NumBooleans(self)`
    +  * `NumConflicts(self)`
    +  * `NumBranches(self)`
    +  * `WallTime(self)`
    +  * `UserTime(self)`
    +
    +  These methods returns the same information as their counterpart in the
    +  `CpSolver` class.
    +  """
    +
    +    def __init__(self):
    +        pywrapsat.SolutionCallback.__init__(self)
    +
    +    def OnSolutionCallback(self):
    +        """Proxy for the same method in snake case."""
    +        self.on_solution_callback()
    +
    +    def BooleanValue(self, lit):
    +        """Returns the boolean value of a boolean literal.
    +
    +    Args:
    +        lit: A boolean variable or its negation.
    +
    +    Returns:
    +        The Boolean value of the literal in the solution.
    +
    +    Raises:
    +        RuntimeError: if `lit` is not a boolean variable or its negation.
    +    """
    +        if not self.HasResponse():
    +            raise RuntimeError('Solve() has not be called.')
    +        if isinstance(lit, numbers.Integral):
    +            return bool(lit)
    +        elif isinstance(lit, IntVar) or isinstance(lit, _NotBooleanVariable):
    +            index = lit.Index()
    +            return self.SolutionBooleanValue(index)
    +        else:
    +            raise TypeError('Cannot interpret %s as a boolean expression.' %
    +                            lit)
    +
    +    def Value(self, expression):
    +        """Evaluates an linear expression in the current solution.
    +
    +    Args:
    +        expression: a linear expression of the model.
    +
    +    Returns:
    +        An integer value equal to the evaluation of the linear expression
    +        against the current solution.
    +
    +    Raises:
    +        RuntimeError: if 'expression' is not a LinearExpr.
    +    """
    +        if not self.HasResponse():
    +            raise RuntimeError('Solve() has not be called.')
    +        if isinstance(expression, numbers.Integral):
    +            return expression
    +        if not isinstance(expression, LinearExpr):
    +            raise TypeError('Cannot interpret %s as a linear expression.' %
    +                            expression)
    +
    +        value = 0
    +        to_process = [(expression, 1)]
    +        while to_process:
    +            expr, coef = to_process.pop()
    +            if isinstance(expr, _ProductCst):
    +                to_process.append(
    +                    (expr.Expression(), coef * expr.Coefficient()))
    +            elif isinstance(expr, _SumArray):
    +                for e in expr.Expressions():
    +                    to_process.append((e, coef))
    +                    value += expr.Constant() * coef
    +            elif isinstance(expr, _ScalProd):
    +                for e, c in zip(expr.Expressions(), expr.Coefficients()):
    +                    to_process.append((e, coef * c))
    +                value += expr.Constant() * coef
    +            elif isinstance(expr, IntVar):
    +                value += coef * self.SolutionIntegerValue(expr.Index())
    +            elif isinstance(expr, _NotBooleanVariable):
    +                value += coef * (1 -
    +                                 self.SolutionIntegerValue(expr.Not().Index()))
    +        return value
    +
    + +
    + +

    Solution callback.

    - return self.__solution.status
    - - -
    -def SolveWithSolutionCallback(self, model, callback) -
    -
    -

    DEPRECATED Use Solve() with the callback argument.

    -
    - -Expand source code - -
    def SolveWithSolutionCallback(self, model, callback):
    -    """DEPRECATED Use Solve() with the callback argument."""
    -    return self.Solve(model, callback)
    -
    -
    -
    -def StatusName(self, status=None) -
    -
    -

    Returns the name of the status returned by Solve().

    -
    - -Expand source code - -
    def StatusName(self, status=None):
    -    """Returns the name of the status returned by Solve()."""
    -    if status is None:
    -        status = self.__solution.status
    -    return cp_model_pb2.CpSolverStatus.Name(status)
    -
    -
    -
    -def StopSearch(self) -
    -
    -

    Stops the current search asynchronously.

    -
    - -Expand source code - -
    def StopSearch(self):
    -    """Stops the current search asynchronously."""
    -    with self.__lock:
    -        if self.__solve_wrapper:
    -            self.__solve_wrapper.StopSearch()
    -
    -
    -
    -def SufficientAssumptionsForInfeasibility(self) -
    -
    -

    Returns the indices of the infeasible assumptions.

    -
    - -Expand source code - -
    def SufficientAssumptionsForInfeasibility(self):
    -    """Returns the indices of the infeasible assumptions."""
    -    return self.__solution.sufficient_assumptions_for_infeasibility
    -
    -
    -
    -def UserTime(self) -
    -
    -

    Returns the user time in seconds since the creation of the solver.

    -
    - -Expand source code - -
    def UserTime(self):
    -    """Returns the user time in seconds since the creation of the solver."""
    -    return self.__solution.user_time
    -
    -
    -
    -def Value(self, expression) -
    -
    -

    Returns the value of a linear expression after solve.

    -
    - -Expand source code - -
    def Value(self, expression):
    -    """Returns the value of a linear expression after solve."""
    -    if not self.__solution:
    -        raise RuntimeError('Solve() has not be called.')
    -    return EvaluateLinearExpr(expression, self.__solution)
    -
    -
    -
    -def WallTime(self) -
    -
    -

    Returns the wall time in seconds since the creation of the solver.

    -
    - -Expand source code - -
    def WallTime(self):
    -    """Returns the wall time in seconds since the creation of the solver."""
    -    return self.__solution.wall_time
    -
    -
    - - -
    -class CpSolverSolutionCallback -
    -
    -

    Solution callback.

    This class implements a callback that will be called at each new solution found during search.

    +

    The method OnSolutionCallback() will be called by the solver, and must be implemented. The current solution can be queried using the BooleanValue() and Value() methods.

    +

    It inherits the following methods from its base class:

    +
    • ObjectiveValue(self)
    • BestObjectiveBound(self)
    • @@ -5715,1366 +8819,637 @@ and Value() methods.

    • WallTime(self)
    • UserTime(self)
    +

    These methods returns the same information as their counterpart in the -CpSolver class.

    -
    - -Expand source code - -
    class CpSolverSolutionCallback(pywrapsat.SolutionCallback):
    -    """Solution callback.
    -
    -  This class implements a callback that will be called at each new solution
    -  found during search.
    -
    -  The method OnSolutionCallback() will be called by the solver, and must be
    -  implemented. The current solution can be queried using the BooleanValue()
    -  and Value() methods.
    -
    -  It inherits the following methods from its base class:
    -
    -  * `ObjectiveValue(self)`
    -  * `BestObjectiveBound(self)`
    -  * `NumBooleans(self)`
    -  * `NumConflicts(self)`
    -  * `NumBranches(self)`
    -  * `WallTime(self)`
    -  * `UserTime(self)`
    -
    -  These methods returns the same information as their counterpart in the
    -  `CpSolver` class.
    -  """
    -
    -    def __init__(self):
    -        pywrapsat.SolutionCallback.__init__(self)
    -
    -    def OnSolutionCallback(self):
    -        """Proxy for the same method in snake case."""
    -        self.on_solution_callback()
    -
    -    def BooleanValue(self, lit):
    -        """Returns the boolean value of a boolean literal.
    -
    -    Args:
    -        lit: A boolean variable or its negation.
    -
    -    Returns:
    -        The Boolean value of the literal in the solution.
    -
    -    Raises:
    -        RuntimeError: if `lit` is not a boolean variable or its negation.
    -    """
    -        if not self.HasResponse():
    -            raise RuntimeError('Solve() has not be called.')
    -        if isinstance(lit, numbers.Integral):
    -            return bool(lit)
    -        elif isinstance(lit, IntVar) or isinstance(lit, _NotBooleanVariable):
    -            index = lit.Index()
    -            return self.SolutionBooleanValue(index)
    -        else:
    -            raise TypeError('Cannot interpret %s as a boolean expression.' %
    -                            lit)
    -
    -    def Value(self, expression):
    -        """Evaluates an linear expression in the current solution.
    -
    -    Args:
    -        expression: a linear expression of the model.
    -
    -    Returns:
    -        An integer value equal to the evaluation of the linear expression
    -        against the current solution.
    -
    -    Raises:
    -        RuntimeError: if 'expression' is not a LinearExpr.
    -    """
    -        if not self.HasResponse():
    -            raise RuntimeError('Solve() has not be called.')
    -        if isinstance(expression, numbers.Integral):
    -            return expression
    -        if not isinstance(expression, LinearExpr):
    -            raise TypeError('Cannot interpret %s as a linear expression.' %
    -                            expression)
    -
    -        value = 0
    -        to_process = [(expression, 1)]
    -        while to_process:
    -            expr, coef = to_process.pop()
    -            if isinstance(expr, _ProductCst):
    -                to_process.append(
    -                    (expr.Expression(), coef * expr.Coefficient()))
    -            elif isinstance(expr, _SumArray):
    -                for e in expr.Expressions():
    -                    to_process.append((e, coef))
    -                    value += expr.Constant() * coef
    -            elif isinstance(expr, _ScalProd):
    -                for e, c in zip(expr.Expressions(), expr.Coefficients()):
    -                    to_process.append((e, coef * c))
    -                value += expr.Constant() * coef
    -            elif isinstance(expr, IntVar):
    -                value += coef * self.SolutionIntegerValue(expr.Index())
    -            elif isinstance(expr, _NotBooleanVariable):
    -                value += coef * (1 -
    -                                 self.SolutionIntegerValue(expr.Not().Index()))
    -        return value
    -
    -

    Ancestors

    -
      -
    • ortools.sat.pywrapsat.SolutionCallback
    • -
    -

    Subclasses

    - -

    Methods

    -
    -
    -def BooleanValue(self, lit) -
    -
    -

    Returns the boolean value of a boolean literal.

    -

    Args

    -
    -
    lit
    -
    A boolean variable or its negation.
    -
    -

    Returns

    -

    The Boolean value of the literal in the solution.

    -

    Raises

    -
    -
    RuntimeError
    -
    if lit is not a boolean variable or its negation.
    -
    -
    - -Expand source code - -
    def BooleanValue(self, lit):
    -    """Returns the boolean value of a boolean literal.
    -
    -Args:
    -    lit: A boolean variable or its negation.
    -
    -Returns:
    -    The Boolean value of the literal in the solution.
    -
    -Raises:
    -    RuntimeError: if `lit` is not a boolean variable or its negation.
    -"""
    -    if not self.HasResponse():
    -        raise RuntimeError('Solve() has not be called.')
    -    if isinstance(lit, numbers.Integral):
    -        return bool(lit)
    -    elif isinstance(lit, IntVar) or isinstance(lit, _NotBooleanVariable):
    -        index = lit.Index()
    -        return self.SolutionBooleanValue(index)
    -    else:
    -        raise TypeError('Cannot interpret %s as a boolean expression.' %
    -                        lit)
    -
    -
    -
    -def OnSolutionCallback(self) -
    -
    -

    Proxy for the same method in snake case.

    -
    - -Expand source code - -
    def OnSolutionCallback(self):
    -    """Proxy for the same method in snake case."""
    -    self.on_solution_callback()
    -
    -
    -
    -def Value(self, expression) -
    -
    -

    Evaluates an linear expression in the current solution.

    -

    Args

    -
    -
    expression
    -
    a linear expression of the model.
    -
    -

    Returns

    -

    An integer value equal to the evaluation of the linear expression -against the current solution.

    -

    Raises

    -
    -
    RuntimeError
    -
    if 'expression' is not a LinearExpr.
    -
    -
    - -Expand source code - -
    def Value(self, expression):
    -    """Evaluates an linear expression in the current solution.
    -
    -Args:
    -    expression: a linear expression of the model.
    -
    -Returns:
    -    An integer value equal to the evaluation of the linear expression
    -    against the current solution.
    -
    -Raises:
    -    RuntimeError: if 'expression' is not a LinearExpr.
    -"""
    -    if not self.HasResponse():
    -        raise RuntimeError('Solve() has not be called.')
    -    if isinstance(expression, numbers.Integral):
    -        return expression
    -    if not isinstance(expression, LinearExpr):
    -        raise TypeError('Cannot interpret %s as a linear expression.' %
    -                        expression)
    -
    -    value = 0
    -    to_process = [(expression, 1)]
    -    while to_process:
    -        expr, coef = to_process.pop()
    -        if isinstance(expr, _ProductCst):
    -            to_process.append(
    -                (expr.Expression(), coef * expr.Coefficient()))
    -        elif isinstance(expr, _SumArray):
    -            for e in expr.Expressions():
    -                to_process.append((e, coef))
    -                value += expr.Constant() * coef
    -        elif isinstance(expr, _ScalProd):
    -            for e, c in zip(expr.Expressions(), expr.Coefficients()):
    -                to_process.append((e, coef * c))
    -            value += expr.Constant() * coef
    -        elif isinstance(expr, IntVar):
    -            value += coef * self.SolutionIntegerValue(expr.Index())
    -        elif isinstance(expr, _NotBooleanVariable):
    -            value += coef * (1 -
    -                             self.SolutionIntegerValue(expr.Not().Index()))
    -    return value
    -
    -
    -
    -
    -
    -class IntVar -(model, domain, name) -
    -
    -

    An integer variable.

    -

    An IntVar is an object that can take on any integer value within defined -ranges. Variables appear in constraint like:

    -
    x + y >= 5
    -AllDifferent([x, y, z])
    -
    -

    Solving a model is equivalent to finding, for each variable, a single value -from the set of initial values (called the initial domain), such that the -model is feasible, or optimal if you provided an objective function.

    -

    See CpModel.NewIntVar below.

    -
    - -Expand source code - -
    class IntVar(LinearExpr):
    -    """An integer variable.
    -
    -  An IntVar is an object that can take on any integer value within defined
    -  ranges. Variables appear in constraint like:
    -
    -      x + y >= 5
    -      AllDifferent([x, y, z])
    -
    -  Solving a model is equivalent to finding, for each variable, a single value
    -  from the set of initial values (called the initial domain), such that the
    -  model is feasible, or optimal if you provided an objective function.
    -  """
    -
    -    def __init__(self, model, domain, name):
    -        """See CpModel.NewIntVar below."""
    -        self.__model = model
    -        self.__negation = None
    -        # Python do not support multiple __init__ methods.
    -        # This method is only called from the CpModel class.
    -        # We hack the parameter to support the two cases:
    -        # case 1:
    -        #     model is a CpModelProto, domain is a Domain, and name is a string.
    -        # case 2:
    -        #     model is a CpModelProto, domain is an index (int), and name is None.
    -        if isinstance(domain, numbers.Integral) and name is None:
    -            self.__index = domain
    -            self.__var = model.variables[domain]
    -        else:
    -            self.__index = len(model.variables)
    -            self.__var = model.variables.add()
    -            self.__var.domain.extend(domain.FlattenedIntervals())
    -            self.__var.name = name
    -
    -    def Index(self):
    -        """Returns the index of the variable in the model."""
    -        return self.__index
    -
    -    def Proto(self):
    -        """Returns the variable protobuf."""
    -        return self.__var
    -
    -    def IsEqualTo(self, other):
    -        """Returns true if self == other in the python sense."""
    -        if not isinstance(other, IntVar):
    -            return False
    -        return self.Index() == other.Index()
    -
    -    def __str__(self):
    -        if not self.__var.name:
    -            if len(self.__var.domain
    -                  ) == 2 and self.__var.domain[0] == self.__var.domain[1]:
    -                # Special case for constants.
    -                return str(self.__var.domain[0])
    -            else:
    -                return 'unnamed_var_%i' % self.__index
    -        return self.__var.name
    -
    -    def __repr__(self):
    -        return '%s(%s)' % (self.__var.name, DisplayBounds(self.__var.domain))
    -
    -    def Name(self):
    -        return self.__var.name
    -
    -    def Not(self):
    -        """Returns the negation of a Boolean variable.
    -
    -    This method implements the logical negation of a Boolean variable.
    -    It is only valid if the variable has a Boolean domain (0 or 1).
    -
    -    Note that this method is nilpotent: `x.Not().Not() == x`.
    -    """
    -
    -        for bound in self.__var.domain:
    -            if bound < 0 or bound > 1:
    -                raise TypeError(
    -                    'Cannot call Not on a non boolean variable: %s' % self)
    -        if self.__negation is None:
    -            self.__negation = _NotBooleanVariable(self)
    -        return self.__negation
    -
    -

    Ancestors

    - -

    Methods

    -
    -
    -def Index(self) -
    -
    -

    Returns the index of the variable in the model.

    -
    - -Expand source code - -
    def Index(self):
    -    """Returns the index of the variable in the model."""
    -    return self.__index
    -
    -
    -
    -def IsEqualTo(self, other) -
    -
    -

    Returns true if self == other in the python sense.

    -
    - -Expand source code - -
    def IsEqualTo(self, other):
    -    """Returns true if self == other in the python sense."""
    -    if not isinstance(other, IntVar):
    -        return False
    -    return self.Index() == other.Index()
    -
    -
    -
    -def Name(self) -
    -
    -
    -
    - -Expand source code - -
    def Name(self):
    -    return self.__var.name
    -
    -
    -
    -def Not(self) -
    -
    -

    Returns the negation of a Boolean variable.

    -

    This method implements the logical negation of a Boolean variable. -It is only valid if the variable has a Boolean domain (0 or 1).

    -

    Note that this method is nilpotent: x.Not().Not() == x.

    -
    - -Expand source code - -
    def Not(self):
    -    """Returns the negation of a Boolean variable.
    -
    -This method implements the logical negation of a Boolean variable.
    -It is only valid if the variable has a Boolean domain (0 or 1).
    -
    -Note that this method is nilpotent: `x.Not().Not() == x`.
    -"""
    -
    -    for bound in self.__var.domain:
    -        if bound < 0 or bound > 1:
    -            raise TypeError(
    -                'Cannot call Not on a non boolean variable: %s' % self)
    -    if self.__negation is None:
    -        self.__negation = _NotBooleanVariable(self)
    -    return self.__negation
    -
    -
    -
    -def Proto(self) -
    -
    -

    Returns the variable protobuf.

    -
    - -Expand source code - -
    def Proto(self):
    -    """Returns the variable protobuf."""
    -    return self.__var
    -
    -
    -
    -

    Inherited members

    - -
    -
    -class IntervalVar -(model, start_index, size_index, end_index, is_present_index, name) -
    -
    -

    Represents an Interval variable.

    -

    An interval variable is both a constraint and a variable. It is defined by -three integer variables: start, size, and end.

    -

    It is a constraint because, internally, it enforces that start + size == end.

    -

    It is also a variable as it can appear in specific scheduling constraints: -NoOverlap, NoOverlap2D, Cumulative.

    -

    Optionally, an enforcement literal can be added to this constraint, in which -case these scheduling constraints will ignore interval variables with -enforcement literals assigned to false. Conversely, these constraints will -also set these enforcement literals to false if they cannot fit these -intervals into the schedule.

    -
    - -Expand source code - -
    class IntervalVar(object):
    -    """Represents an Interval variable.
    -
    -  An interval variable is both a constraint and a variable. It is defined by
    -  three integer variables: start, size, and end.
    -
    -  It is a constraint because, internally, it enforces that start + size == end.
    -
    -  It is also a variable as it can appear in specific scheduling constraints:
    -  NoOverlap, NoOverlap2D, Cumulative.
    -
    -  Optionally, an enforcement literal can be added to this constraint, in which
    -  case these scheduling constraints will ignore interval variables with
    -  enforcement literals assigned to false. Conversely, these constraints will
    -  also set these enforcement literals to false if they cannot fit these
    -  intervals into the schedule.
    -  """
    -
    -    def __init__(self, model, start_index, size_index, end_index,
    -                 is_present_index, name):
    -        self.__model = model
    -        # As with the IntVar::__init__ method, we hack the __init__ method to
    -        # support two use cases:
    -        #   case 1: called when creating a new interval variable.
    -        #      {start|size|end}_index are indices of integer variables
    -        #      is_present_index is either None or the index of a Boolean literal.
    -        #      name is a string
    -        #   case 2: called when querying an existing interval variable.
    -        #      start_index is an int, all parameters after are None.
    -        if (size_index is None and end_index is None and
    -                is_present_index is None and name is None):
    -            self.__index = start_index
    -            self.__ct = model.constraints[start_index]
    -        else:
    -            self.__index = len(model.constraints)
    -            self.__ct = self.__model.constraints.add()
    -            self.__ct.interval.start = start_index
    -            self.__ct.interval.size = size_index
    -            self.__ct.interval.end = end_index
    -            if is_present_index is not None:
    -                self.__ct.enforcement_literal.append(is_present_index)
    -            if name:
    -                self.__ct.name = name
    -
    -    def Index(self):
    -        """Returns the index of the interval constraint in the model."""
    -        return self.__index
    -
    -    def Proto(self):
    -        """Returns the interval protobuf."""
    -        return self.__ct.interval
    -
    -    def __str__(self):
    -        return self.__ct.name
    -
    -    def __repr__(self):
    -        interval = self.__ct.interval
    -        if self.__ct.enforcement_literal:
    -            return '%s(start = %s, size = %s, end = %s, is_present = %s)' % (
    -                self.__ct.name, ShortName(self.__model, interval.start),
    -                ShortName(self.__model,
    -                          interval.size), ShortName(self.__model, interval.end),
    -                ShortName(self.__model, self.__ct.enforcement_literal[0]))
    -        else:
    -            return '%s(start = %s, size = %s, end = %s)' % (
    -                self.__ct.name, ShortName(self.__model, interval.start),
    -                ShortName(self.__model,
    -                          interval.size), ShortName(self.__model, interval.end))
    -
    -    def Name(self):
    -        return self.__ct.name
    -
    -

    Methods

    -
    -
    -def Index(self) -
    -
    -

    Returns the index of the interval constraint in the model.

    -
    - -Expand source code - -
    def Index(self):
    -    """Returns the index of the interval constraint in the model."""
    -    return self.__index
    -
    -
    -
    -def Name(self) -
    -
    -
    -
    - -Expand source code - -
    def Name(self):
    -    return self.__ct.name
    -
    -
    -
    -def Proto(self) -
    -
    -

    Returns the interval protobuf.

    -
    - -Expand source code - -
    def Proto(self):
    -    """Returns the interval protobuf."""
    -    return self.__ct.interval
    -
    -
    -
    -
    -
    -class LinearExpr -
    -
    -

    Holds an integer linear expression.

    -

    A linear expression is built from integer constants and variables. -For example, x + 2 * (y - z + 1).

    -

    Linear expressions are used in CP-SAT models in two ways:

    -
      -
    • -

      To define constraints. For example

      -

      model.Add(x + 2 * y <= 5) -model.Add(sum(array_of_vars) == 5)

      -
    • -
    • -

      To define the objective function. For example

      -

      model.Minimize(x + 2 * y + z)

      -
    • -
    -

    For large arrays, you can create constraints and the objective -from lists of linear expressions or coefficients as follows:

    -
    model.Minimize(cp_model.LinearExpr.Sum(expressions))
    -model.Add(cp_model.LinearExpr.ScalProd(expressions, coefficients) >= 0)
    -
    -
    - -Expand source code - -
    class LinearExpr(object):
    -    """Holds an integer linear expression.
    -
    -  A linear expression is built from integer constants and variables.
    -  For example, x + 2 * (y - z + 1).
    -
    -  Linear expressions are used in CP-SAT models in two ways:
    -
    -  * To define constraints. For example
    -
    -      model.Add(x + 2 * y <= 5)
    -      model.Add(sum(array_of_vars) == 5)
    -
    -  * To define the objective function. For example
    -
    -      model.Minimize(x + 2 * y + z)
    -
    -  For large arrays, you can create constraints and the objective
    -  from lists of linear expressions or coefficients as follows:
    -
    -      model.Minimize(cp_model.LinearExpr.Sum(expressions))
    -      model.Add(cp_model.LinearExpr.ScalProd(expressions, coefficients) >= 0)
    -  """
    -
    -    @classmethod
    -    def Sum(cls, expressions):
    -        """Creates the expression sum(expressions)."""
    -        return _SumArray(expressions)
    -
    -    @classmethod
    -    def ScalProd(cls, expressions, coefficients):
    -        """Creates the expression sum(expressions[i] * coefficients[i])."""
    -        return _ScalProd(expressions, coefficients)
    -
    -    @classmethod
    -    def Term(cls, expression, coefficient):
    -        """Creates `expression * coefficient`."""
    -        return expression * coefficient
    -
    -    def GetVarValueMap(self):
    -        """Scans the expression, and return a list of (var_coef_map, constant)."""
    -        coeffs = collections.defaultdict(int)
    -        constant = 0
    -        to_process = [(self, 1)]
    -        while to_process:  # Flatten to avoid recursion.
    -            expr, coef = to_process.pop()
    -            if isinstance(expr, _ProductCst):
    -                to_process.append(
    -                    (expr.Expression(), coef * expr.Coefficient()))
    -            elif isinstance(expr, _SumArray):
    -                for e in expr.Expressions():
    -                    to_process.append((e, coef))
    -                constant += expr.Constant() * coef
    -            elif isinstance(expr, _ScalProd):
    -                for e, c in zip(expr.Expressions(), expr.Coefficients()):
    -                    to_process.append((e, coef * c))
    -                constant += expr.Constant() * coef
    -            elif isinstance(expr, IntVar):
    -                coeffs[expr] += coef
    -            elif isinstance(expr, _NotBooleanVariable):
    -                constant += coef
    -                coeffs[expr.Not()] -= coef
    -            else:
    -                raise TypeError('Unrecognized linear expression: ' + str(expr))
    -
    -        return coeffs, constant
    -
    -    def __hash__(self):
    -        return object.__hash__(self)
    -
    -    def __abs__(self):
    -        raise NotImplementedError(
    -            'calling abs() on a linear expression is not supported, '
    -            'please use CpModel.AddAbsEquality')
    -
    -    def __add__(self, expr):
    -        return _SumArray([self, expr])
    -
    -    def __radd__(self, arg):
    -        return _SumArray([self, arg])
    -
    -    def __sub__(self, expr):
    -        return _SumArray([self, -expr])
    -
    -    def __rsub__(self, arg):
    -        return _SumArray([-self, arg])
    -
    -    def __mul__(self, arg):
    -        if isinstance(arg, numbers.Integral):
    -            if arg == 1:
    -                return self
    -            elif arg == 0:
    -                return 0
    -            cp_model_helper.AssertIsInt64(arg)
    -            return _ProductCst(self, arg)
    -        else:
    -            raise TypeError('Not an integer linear expression: ' + str(arg))
    -
    -    def __rmul__(self, arg):
    -        cp_model_helper.AssertIsInt64(arg)
    -        if arg == 1:
    -            return self
    -        return _ProductCst(self, arg)
    -
    -    def __div__(self, _):
    -        raise NotImplementedError(
    -            'calling / on a linear expression is not supported, '
    -            'please use CpModel.AddDivisionEquality')
    -
    -    def __truediv__(self, _):
    -        raise NotImplementedError(
    -            'calling // on a linear expression is not supported, '
    -            'please use CpModel.AddDivisionEquality')
    -
    -    def __mod__(self, _):
    -        raise NotImplementedError(
    -            'calling %% on a linear expression is not supported, '
    -            'please use CpModel.AddModuloEquality')
    -
    -    def __pow__(self, _):
    -        raise NotImplementedError(
    -            'calling ** on a linear expression is not supported, '
    -            'please use CpModel.AddMultiplicationEquality')
    -
    -    def __lshift__(self, _):
    -        raise NotImplementedError(
    -            'calling left shift on a linear expression is not supported')
    -
    -    def __rshift__(self, _):
    -        raise NotImplementedError(
    -            'calling right shift on a linear expression is not supported')
    -
    -    def __and__(self, _):
    -        raise NotImplementedError(
    -            'calling and on a linear expression is not supported, '
    -            'please use CpModel.AddBoolAnd')
    -
    -    def __or__(self, _):
    -        raise NotImplementedError(
    -            'calling or on a linear expression is not supported, '
    -            'please use CpModel.AddBoolOr')
    -
    -    def __xor__(self, _):
    -        raise NotImplementedError(
    -            'calling xor on a linear expression is not supported, '
    -            'please use CpModel.AddBoolXor')
    -
    -    def __neg__(self):
    -        return _ProductCst(self, -1)
    -
    -    def __bool__(self):
    -        raise NotImplementedError(
    -            'Evaluating a LinearExpr instance as a Boolean is not implemented.')
    -
    -    def __eq__(self, arg):
    -        if arg is None:
    -            return False
    -        if isinstance(arg, numbers.Integral):
    -            cp_model_helper.AssertIsInt64(arg)
    -            return BoundedLinearExpression(self, [arg, arg])
    -        else:
    -            return BoundedLinearExpression(self - arg, [0, 0])
    -
    -    def __ge__(self, arg):
    -        if isinstance(arg, numbers.Integral):
    -            cp_model_helper.AssertIsInt64(arg)
    -            return BoundedLinearExpression(self, [arg, INT_MAX])
    -        else:
    -            return BoundedLinearExpression(self - arg, [0, INT_MAX])
    -
    -    def __le__(self, arg):
    -        if isinstance(arg, numbers.Integral):
    -            cp_model_helper.AssertIsInt64(arg)
    -            return BoundedLinearExpression(self, [INT_MIN, arg])
    -        else:
    -            return BoundedLinearExpression(self - arg, [INT_MIN, 0])
    -
    -    def __lt__(self, arg):
    -        if isinstance(arg, numbers.Integral):
    -            cp_model_helper.AssertIsInt64(arg)
    -            if arg == INT_MIN:
    -                raise ArithmeticError('< INT_MIN is not supported')
    -            return BoundedLinearExpression(self, [INT_MIN, arg - 1])
    -        else:
    -            return BoundedLinearExpression(self - arg, [INT_MIN, -1])
    -
    -    def __gt__(self, arg):
    -        if isinstance(arg, numbers.Integral):
    -            cp_model_helper.AssertIsInt64(arg)
    -            if arg == INT_MAX:
    -                raise ArithmeticError('> INT_MAX is not supported')
    -            return BoundedLinearExpression(self, [arg + 1, INT_MAX])
    -        else:
    -            return BoundedLinearExpression(self - arg, [1, INT_MAX])
    -
    -    def __ne__(self, arg):
    -        if arg is None:
    -            return True
    -        if isinstance(arg, numbers.Integral):
    -            cp_model_helper.AssertIsInt64(arg)
    -            if arg == INT_MAX:
    -                return BoundedLinearExpression(self, [INT_MIN, INT_MAX - 1])
    -            elif arg == INT_MIN:
    -                return BoundedLinearExpression(self, [INT_MIN + 1, INT_MAX])
    -            else:
    -                return BoundedLinearExpression(
    -                    self, [INT_MIN, arg - 1, arg + 1, INT_MAX])
    -        else:
    -            return BoundedLinearExpression(self - arg,
    -                                           [INT_MIN, -1, 1, INT_MAX])
    -
    -

    Subclasses

    -
      -
    • IntVar
    • -
    • cp_model._NotBooleanVariable
    • -
    • cp_model._ProductCst
    • -
    • cp_model._ScalProd
    • -
    • cp_model._SumArray
    • -
    -

    Static methods

    -
    -
    -def ScalProd(expressions, coefficients) -
    -
    -

    Creates the expression sum(expressions[i] * coefficients[i]).

    -
    - -Expand source code - -
    @classmethod
    -def ScalProd(cls, expressions, coefficients):
    -    """Creates the expression sum(expressions[i] * coefficients[i])."""
    -    return _ScalProd(expressions, coefficients)
    -
    -
    -
    -def Sum(expressions) -
    -
    -

    Creates the expression sum(expressions).

    -
    - -Expand source code - -
    @classmethod
    -def Sum(cls, expressions):
    -    """Creates the expression sum(expressions)."""
    -    return _SumArray(expressions)
    -
    -
    -
    -def Term(expression, coefficient) -
    -
    -

    Creates expression * coefficient.

    -
    - -Expand source code - -
    @classmethod
    -def Term(cls, expression, coefficient):
    -    """Creates `expression * coefficient`."""
    -    return expression * coefficient
    -
    -
    -
    -

    Methods

    -
    -
    -def GetVarValueMap(self) -
    -
    -

    Scans the expression, and return a list of (var_coef_map, constant).

    -
    - -Expand source code - -
    def GetVarValueMap(self):
    -    """Scans the expression, and return a list of (var_coef_map, constant)."""
    -    coeffs = collections.defaultdict(int)
    -    constant = 0
    -    to_process = [(self, 1)]
    -    while to_process:  # Flatten to avoid recursion.
    -        expr, coef = to_process.pop()
    -        if isinstance(expr, _ProductCst):
    -            to_process.append(
    -                (expr.Expression(), coef * expr.Coefficient()))
    -        elif isinstance(expr, _SumArray):
    -            for e in expr.Expressions():
    -                to_process.append((e, coef))
    -            constant += expr.Constant() * coef
    -        elif isinstance(expr, _ScalProd):
    -            for e, c in zip(expr.Expressions(), expr.Coefficients()):
    -                to_process.append((e, coef * c))
    -            constant += expr.Constant() * coef
    -        elif isinstance(expr, IntVar):
    -            coeffs[expr] += coef
    -        elif isinstance(expr, _NotBooleanVariable):
    -            constant += coef
    -            coeffs[expr.Not()] -= coef
    -        else:
    -            raise TypeError('Unrecognized linear expression: ' + str(expr))
    -
    -    return coeffs, constant
    -
    -
    -
    -
    -
    -class ObjectiveSolutionPrinter -
    -
    -

    Display the objective value and time of intermediate solutions.

    -
    - -Expand source code - -
    class ObjectiveSolutionPrinter(CpSolverSolutionCallback):
    -    """Display the objective value and time of intermediate solutions."""
    -
    -    def __init__(self):
    -        CpSolverSolutionCallback.__init__(self)
    -        self.__solution_count = 0
    -        self.__start_time = time.time()
    -
    -    def on_solution_callback(self):
    -        """Called on each new solution."""
    -        current_time = time.time()
    -        obj = self.ObjectiveValue()
    -        print('Solution %i, time = %0.2f s, objective = %i' %
    -              (self.__solution_count, current_time - self.__start_time, obj))
    -        self.__solution_count += 1
    -
    -    def solution_count(self):
    -        """Returns the number of solutions found."""
    -        return self.__solution_count
    -
    -

    Ancestors

    - -

    Methods

    -
    -
    -def on_solution_callback(self) -
    -
    -

    Called on each new solution.

    -
    - -Expand source code - -
    def on_solution_callback(self):
    -    """Called on each new solution."""
    -    current_time = time.time()
    -    obj = self.ObjectiveValue()
    -    print('Solution %i, time = %0.2f s, objective = %i' %
    -          (self.__solution_count, current_time - self.__start_time, obj))
    -    self.__solution_count += 1
    -
    -
    -
    -def solution_count(self) -
    -
    -

    Returns the number of solutions found.

    -
    - -Expand source code - -
    def solution_count(self):
    -    """Returns the number of solutions found."""
    -    return self.__solution_count
    -
    -
    -
    -

    Inherited members

    - -
    -
    -class VarArrayAndObjectiveSolutionPrinter -(variables) -
    -
    -

    Print intermediate solutions (objective, variable values, time).

    -
    - -Expand source code - -
    class VarArrayAndObjectiveSolutionPrinter(CpSolverSolutionCallback):
    -    """Print intermediate solutions (objective, variable values, time)."""
    -
    -    def __init__(self, variables):
    -        CpSolverSolutionCallback.__init__(self)
    -        self.__variables = variables
    -        self.__solution_count = 0
    -        self.__start_time = time.time()
    -
    -    def on_solution_callback(self):
    -        """Called on each new solution."""
    -        current_time = time.time()
    -        obj = self.ObjectiveValue()
    -        print('Solution %i, time = %0.2f s, objective = %i' %
    -              (self.__solution_count, current_time - self.__start_time, obj))
    -        for v in self.__variables:
    -            print('  %s = %i' % (v, self.Value(v)), end=' ')
    -        print()
    -        self.__solution_count += 1
    -
    -    def solution_count(self):
    -        """Returns the number of solutions found."""
    -        return self.__solution_count
    -
    -

    Ancestors

    - -

    Methods

    -
    -
    -def on_solution_callback(self) -
    -
    -

    Called on each new solution.

    -
    - -Expand source code - -
    def on_solution_callback(self):
    -    """Called on each new solution."""
    -    current_time = time.time()
    -    obj = self.ObjectiveValue()
    -    print('Solution %i, time = %0.2f s, objective = %i' %
    -          (self.__solution_count, current_time - self.__start_time, obj))
    -    for v in self.__variables:
    -        print('  %s = %i' % (v, self.Value(v)), end=' ')
    -    print()
    -    self.__solution_count += 1
    -
    -
    -
    -def solution_count(self) -
    -
    -

    Returns the number of solutions found.

    -
    - -Expand source code - -
    def solution_count(self):
    -    """Returns the number of solutions found."""
    -    return self.__solution_count
    -
    -
    -
    -

    Inherited members

    - -
    -
    -class VarArraySolutionPrinter -(variables) -
    -
    -

    Print intermediate solutions (variable values, time).

    -
    - -Expand source code - -
    class VarArraySolutionPrinter(CpSolverSolutionCallback):
    -    """Print intermediate solutions (variable values, time)."""
    -
    -    def __init__(self, variables):
    -        CpSolverSolutionCallback.__init__(self)
    -        self.__variables = variables
    -        self.__solution_count = 0
    -        self.__start_time = time.time()
    -
    -    def on_solution_callback(self):
    -        """Called on each new solution."""
    -        current_time = time.time()
    -        print('Solution %i, time = %0.2f s' %
    -              (self.__solution_count, current_time - self.__start_time))
    -        for v in self.__variables:
    -            print('  %s = %i' % (v, self.Value(v)), end=' ')
    -        print()
    -        self.__solution_count += 1
    -
    -    def solution_count(self):
    -        """Returns the number of solutions found."""
    -        return self.__solution_count
    -
    -

    Ancestors

    - -

    Methods

    -
    -
    -def on_solution_callback(self) -
    -
    -

    Called on each new solution.

    -
    - -Expand source code - -
    def on_solution_callback(self):
    -    """Called on each new solution."""
    -    current_time = time.time()
    -    print('Solution %i, time = %0.2f s' %
    -          (self.__solution_count, current_time - self.__start_time))
    -    for v in self.__variables:
    -        print('  %s = %i' % (v, self.Value(v)), end=' ')
    -    print()
    -    self.__solution_count += 1
    -
    -
    -
    -def solution_count(self) -
    -
    -

    Returns the number of solutions found.

    -
    - -Expand source code - -
    def solution_count(self):
    -    """Returns the number of solutions found."""
    -    return self.__solution_count
    -
    -
    -
    -

    Inherited members

    - -
    - -
    -
    - -
    - + + + + +
    +
    Inherited Members
    +
    +
    ortools.sat.pywrapsat.SolutionCallback
    +
    thisown
    +
    NumBooleans
    +
    NumBranches
    +
    NumConflicts
    +
    NumBinaryPropagations
    +
    NumIntegerPropagations
    +
    WallTime
    +
    UserTime
    +
    ObjectiveValue
    +
    BestObjectiveBound
    +
    SolutionIntegerValue
    +
    SolutionBooleanValue
    +
    StopSearch
    +
    Response
    +
    HasResponse
    + +
    +
    +
    + +
    +
    + #   + + + class + ObjectiveSolutionPrinter(CpSolverSolutionCallback): +
    + +
    + View Source +
    class ObjectiveSolutionPrinter(CpSolverSolutionCallback):
    +    """Display the objective value and time of intermediate solutions."""
    +
    +    def __init__(self):
    +        CpSolverSolutionCallback.__init__(self)
    +        self.__solution_count = 0
    +        self.__start_time = time.time()
    +
    +    def on_solution_callback(self):
    +        """Called on each new solution."""
    +        current_time = time.time()
    +        obj = self.ObjectiveValue()
    +        print('Solution %i, time = %0.2f s, objective = %i' %
    +              (self.__solution_count, current_time - self.__start_time, obj))
    +        self.__solution_count += 1
    +
    +    def solution_count(self):
    +        """Returns the number of solutions found."""
    +        return self.__solution_count
    +
    + +
    + +

    Display the objective value and time of intermediate solutions.

    +
    + + +
    +
    #   + + + ObjectiveSolutionPrinter() +
    + +
    + View Source +
        def __init__(self):
    +        CpSolverSolutionCallback.__init__(self)
    +        self.__solution_count = 0
    +        self.__start_time = time.time()
    +
    + +
    + + + +
    +
    +
    #   + + + def + on_solution_callback(self): +
    + +
    + View Source +
        def on_solution_callback(self):
    +        """Called on each new solution."""
    +        current_time = time.time()
    +        obj = self.ObjectiveValue()
    +        print('Solution %i, time = %0.2f s, objective = %i' %
    +              (self.__solution_count, current_time - self.__start_time, obj))
    +        self.__solution_count += 1
    +
    + +
    + +

    Called on each new solution.

    +
    + + +
    +
    +
    #   + + + def + solution_count(self): +
    + +
    + View Source +
        def solution_count(self):
    +        """Returns the number of solutions found."""
    +        return self.__solution_count
    +
    + +
    + +

    Returns the number of solutions found.

    +
    + + +
    +
    +
    Inherited Members
    +
    +
    CpSolverSolutionCallback
    +
    OnSolutionCallback
    +
    BooleanValue
    +
    Value
    + +
    +
    ortools.sat.pywrapsat.SolutionCallback
    +
    thisown
    +
    NumBooleans
    +
    NumBranches
    +
    NumConflicts
    +
    NumBinaryPropagations
    +
    NumIntegerPropagations
    +
    WallTime
    +
    UserTime
    +
    ObjectiveValue
    +
    BestObjectiveBound
    +
    SolutionIntegerValue
    +
    SolutionBooleanValue
    +
    StopSearch
    +
    Response
    +
    HasResponse
    + +
    +
    +
    +
    +
    +
    + #   + + + class + VarArrayAndObjectiveSolutionPrinter(CpSolverSolutionCallback): +
    + +
    + View Source +
    class VarArrayAndObjectiveSolutionPrinter(CpSolverSolutionCallback):
    +    """Print intermediate solutions (objective, variable values, time)."""
    +
    +    def __init__(self, variables):
    +        CpSolverSolutionCallback.__init__(self)
    +        self.__variables = variables
    +        self.__solution_count = 0
    +        self.__start_time = time.time()
    +
    +    def on_solution_callback(self):
    +        """Called on each new solution."""
    +        current_time = time.time()
    +        obj = self.ObjectiveValue()
    +        print('Solution %i, time = %0.2f s, objective = %i' %
    +              (self.__solution_count, current_time - self.__start_time, obj))
    +        for v in self.__variables:
    +            print('  %s = %i' % (v, self.Value(v)), end=' ')
    +        print()
    +        self.__solution_count += 1
    +
    +    def solution_count(self):
    +        """Returns the number of solutions found."""
    +        return self.__solution_count
    +
    + +
    + +

    Print intermediate solutions (objective, variable values, time).

    +
    + + +
    +
    #   + + + VarArrayAndObjectiveSolutionPrinter(variables) +
    + +
    + View Source +
        def __init__(self, variables):
    +        CpSolverSolutionCallback.__init__(self)
    +        self.__variables = variables
    +        self.__solution_count = 0
    +        self.__start_time = time.time()
    +
    + +
    + + + +
    +
    +
    #   + + + def + on_solution_callback(self): +
    + +
    + View Source +
        def on_solution_callback(self):
    +        """Called on each new solution."""
    +        current_time = time.time()
    +        obj = self.ObjectiveValue()
    +        print('Solution %i, time = %0.2f s, objective = %i' %
    +              (self.__solution_count, current_time - self.__start_time, obj))
    +        for v in self.__variables:
    +            print('  %s = %i' % (v, self.Value(v)), end=' ')
    +        print()
    +        self.__solution_count += 1
    +
    + +
    + +

    Called on each new solution.

    +
    + + +
    +
    +
    #   + + + def + solution_count(self): +
    + +
    + View Source +
        def solution_count(self):
    +        """Returns the number of solutions found."""
    +        return self.__solution_count
    +
    + +
    + +

    Returns the number of solutions found.

    +
    + + +
    +
    +
    Inherited Members
    +
    +
    CpSolverSolutionCallback
    +
    OnSolutionCallback
    +
    BooleanValue
    +
    Value
    + +
    +
    ortools.sat.pywrapsat.SolutionCallback
    +
    thisown
    +
    NumBooleans
    +
    NumBranches
    +
    NumConflicts
    +
    NumBinaryPropagations
    +
    NumIntegerPropagations
    +
    WallTime
    +
    UserTime
    +
    ObjectiveValue
    +
    BestObjectiveBound
    +
    SolutionIntegerValue
    +
    SolutionBooleanValue
    +
    StopSearch
    +
    Response
    +
    HasResponse
    + +
    +
    +
    +
    +
    +
    + #   + + + class + VarArraySolutionPrinter(CpSolverSolutionCallback): +
    + +
    + View Source +
    class VarArraySolutionPrinter(CpSolverSolutionCallback):
    +    """Print intermediate solutions (variable values, time)."""
    +
    +    def __init__(self, variables):
    +        CpSolverSolutionCallback.__init__(self)
    +        self.__variables = variables
    +        self.__solution_count = 0
    +        self.__start_time = time.time()
    +
    +    def on_solution_callback(self):
    +        """Called on each new solution."""
    +        current_time = time.time()
    +        print('Solution %i, time = %0.2f s' %
    +              (self.__solution_count, current_time - self.__start_time))
    +        for v in self.__variables:
    +            print('  %s = %i' % (v, self.Value(v)), end=' ')
    +        print()
    +        self.__solution_count += 1
    +
    +    def solution_count(self):
    +        """Returns the number of solutions found."""
    +        return self.__solution_count
    +
    + +
    + +

    Print intermediate solutions (variable values, time).

    +
    + + +
    +
    #   + + + VarArraySolutionPrinter(variables) +
    + +
    + View Source +
        def __init__(self, variables):
    +        CpSolverSolutionCallback.__init__(self)
    +        self.__variables = variables
    +        self.__solution_count = 0
    +        self.__start_time = time.time()
    +
    + +
    + + + +
    +
    +
    #   + + + def + on_solution_callback(self): +
    + +
    + View Source +
        def on_solution_callback(self):
    +        """Called on each new solution."""
    +        current_time = time.time()
    +        print('Solution %i, time = %0.2f s' %
    +              (self.__solution_count, current_time - self.__start_time))
    +        for v in self.__variables:
    +            print('  %s = %i' % (v, self.Value(v)), end=' ')
    +        print()
    +        self.__solution_count += 1
    +
    + +
    + +

    Called on each new solution.

    +
    + + +
    +
    +
    #   + + + def + solution_count(self): +
    + +
    + View Source +
        def solution_count(self):
    +        """Returns the number of solutions found."""
    +        return self.__solution_count
    +
    + +
    + +

    Returns the number of solutions found.

    +
    + + +
    +
    +
    Inherited Members
    +
    +
    CpSolverSolutionCallback
    +
    OnSolutionCallback
    +
    BooleanValue
    +
    Value
    + +
    +
    ortools.sat.pywrapsat.SolutionCallback
    +
    thisown
    +
    NumBooleans
    +
    NumBranches
    +
    NumConflicts
    +
    NumBinaryPropagations
    +
    NumIntegerPropagations
    +
    WallTime
    +
    UserTime
    +
    ObjectiveValue
    +
    BestObjectiveBound
    +
    SolutionIntegerValue
    +
    SolutionBooleanValue
    +
    StopSearch
    +
    Response
    +
    HasResponse
    + +
    +
    +
    +
    + \ No newline at end of file diff --git a/docs/python/ortools/util/sorted_interval_list.html b/docs/python/ortools/util/sorted_interval_list.html index 0344478558..84f77e5eb9 100644 --- a/docs/python/ortools/util/sorted_interval_list.html +++ b/docs/python/ortools/util/sorted_interval_list.html @@ -1,765 +1,1100 @@ - - - -sorted_interval_list API documentation - - - - - - - - - - - + + + + sorted_interval_list API documentation + + + + + + - -
    -
    -
    -

    Module sorted_interval_list

    -
    -
    -
    - -Expand source code - -
    # This file was automatically generated by SWIG (http://www.swig.org).
    -# Version 4.0.2
    -#
    -# Do not make changes to this file unless you know what you are doing--modify
    -# the SWIG interface file instead.
    +        
    +    
    +
    +

    +sorted_interval_list

    + + +
    + View Source +
    # This file was automatically generated by SWIG (http://www.swig.org).
    +# Version 4.0.1
    +#
    +# Do not make changes to this file unless you know what you are doing--modify
    +# the SWIG interface file instead.
     
     
    -def _swig_setattr_nondynamic_class_variable(set):
    -    def set_class_attr(cls, name, value):
    -        if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
    -            set(cls, name, value)
    -        else:
    -            raise AttributeError("You cannot add class attributes to %s" % cls)
    -    return set_class_attr
    +# Remove the documentation of some functions.
    +# See https://pdoc3.github.io/pdoc/doc/pdoc/#overriding-docstrings-with-
    +__pdoc__ = {}
    +__pdoc__['Domain_AllValues'] = False
    +__pdoc__['Domain_FromFlatIntervals'] = False
    +__pdoc__['Domain_FromIntervals'] = False
    +__pdoc__['Domain_FromValues'] = False
    +__pdoc__['Domain.thisown'] = False
     
     
    -def _swig_add_metaclass(metaclass):
    -    """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
    -    def wrapper(cls):
    -        return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
    -    return wrapper
    +
    +from sys import version_info as _swig_python_version_info
    +if _swig_python_version_info < (2, 7, 0):
    +    raise RuntimeError("Python 2.7 or later required")
    +
    +# Import the low-level C/C++ module
    +if __package__ or "." in __name__:
    +    from . import _sorted_interval_list
    +else:
    +    import _sorted_interval_list
    +
    +try:
    +    import builtins as __builtin__
    +except ImportError:
    +    import __builtin__
    +
    +def _swig_repr(self):
    +    try:
    +        strthis = "proxy of " + self.this.__repr__()
    +    except __builtin__.Exception:
    +        strthis = ""
    +    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
     
     
    -class _SwigNonDynamicMeta(type):
    -    """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
    -    __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)
    +def _swig_setattr_nondynamic_instance_variable(set):
    +    def set_instance_attr(self, name, value):
    +        if name == "thisown":
    +            self.this.own(value)
    +        elif name == "this":
    +            set(self, name, value)
    +        elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
    +            set(self, name, value)
    +        else:
    +            raise AttributeError("You cannot add instance attributes to %s" % self)
    +    return set_instance_attr
     
     
    -class Domain(object):
    -    r"""
    -    We call *domain* any subset of Int64 = [kint64min, kint64max].
    -
    -    This class can be used to represent such set efficiently as a sorted and
    -    non-adjacent list of intervals. This is efficient as long as the size of such
    -    list stays reasonable.
    -
    -    In the comments below, the domain of *this will always be written 'D'.
    -    Note that all the functions are safe with respect to integer overflow.
    -    """
    -
    -    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    -    __repr__ = _swig_repr
    -
    -    def __init__(self, *args):
    -        r"""
    -        *Overload 1:*
    -         By default, Domain will be empty.
    -
    -        |
    -
    -        *Overload 2:*
    -         Constructor for the common case of a singleton domain.
    -
    -        |
    -
    -        *Overload 3:*
    -
    -        Constructor for the common case of a single interval [left, right].
    -        If left > right, this will result in the empty domain.
    -        """
    -        _sorted_interval_list.Domain_swiginit(self, _sorted_interval_list.new_Domain(*args))
    -
    -    @staticmethod
    -    def AllValues() -> "operations_research::Domain":
    -        r"""Returns the full domain Int64."""
    -        return _sorted_interval_list.Domain_AllValues()
    -
    -    @staticmethod
    -    def FromValues(values: "std::vector< int64_t >") -> "operations_research::Domain":
    -        r"""
    -        Creates a domain from the union of an unsorted list of integer values.
    -        Input values may be repeated, with no consequence on the output
    -        """
    -        return _sorted_interval_list.Domain_FromValues(values)
    -
    -    @staticmethod
    -    def FromIntervals(intervals: "std::vector< std::vector< int64_t > > const &") -> "operations_research::Domain":
    -        r"""
    -        This method is available in Python, Java and .NET. It allows
    -        building a Domain object from a list of intervals (long[][] in Java and
    -        .NET, [[0, 2], [5, 5], [8, 10]] in python).
    -        """
    -        return _sorted_interval_list.Domain_FromIntervals(intervals)
    -
    -    @staticmethod
    -    def FromFlatIntervals(flat_intervals: "std::vector< int64_t > const &") -> "operations_research::Domain":
    -        r"""
    -        This method is available in Python, Java and .NET. It allows
    -        building a Domain object from a flattened list of intervals
    -        (long[] in Java and .NET, [0, 2, 5, 5, 8, 10] in python).
    -        """
    -        return _sorted_interval_list.Domain_FromFlatIntervals(flat_intervals)
    -
    -    def FlattenedIntervals(self) -> "std::vector< int64_t >":
    -        r"""
    -        This method returns the flattened list of interval bounds of the domain.
    -
    -        Thus the domain {0, 1, 2, 5, 8, 9, 10} will return [0, 2, 5, 5,
    -        8, 10] (as a C++ std::vector<int64_t>, as a java or C# long[], as
    -        a python list of integers).
    -        """
    -        return _sorted_interval_list.Domain_FlattenedIntervals(self)
    -
    -    def IsEmpty(self) -> "bool":
    -        r"""Returns true if this is the empty set."""
    -        return _sorted_interval_list.Domain_IsEmpty(self)
    -
    -    def Size(self) -> "int64_t":
    -        r"""Returns the number of elements in the domain. It is capped at kint64max"""
    -        return _sorted_interval_list.Domain_Size(self)
    -
    -    def Min(self) -> "int64_t":
    -        r"""
    -        Returns the min value of the domain.
    -        The domain must not be empty.
    -        """
    -        return _sorted_interval_list.Domain_Min(self)
    -
    -    def Max(self) -> "int64_t":
    -        r"""
    -        Returns the max value of the domain.
    -        The domain must not be empty.
    -        """
    -        return _sorted_interval_list.Domain_Max(self)
    -
    -    def Contains(self, value: "int64_t") -> "bool":
    -        r"""Returns true iff value is in Domain."""
    -        return _sorted_interval_list.Domain_Contains(self, value)
    -
    -    def Complement(self) -> "operations_research::Domain":
    -        r"""Returns the set Int64 ∖ D."""
    -        return _sorted_interval_list.Domain_Complement(self)
    -
    -    def Negation(self) -> "operations_research::Domain":
    -        r"""
    -        Returns {x ∈ Int64, ∃ e ∈ D, x = -e}.
    -
    -        Note in particular that if the negation of Int64 is not Int64 but
    -        Int64 \ {kint64min} !!
    -        """
    -        return _sorted_interval_list.Domain_Negation(self)
    -
    -    def IntersectionWith(self, domain: "Domain") -> "operations_research::Domain":
    -        r"""Returns the intersection of D and domain."""
    -        return _sorted_interval_list.Domain_IntersectionWith(self, domain)
    -
    -    def UnionWith(self, domain: "Domain") -> "operations_research::Domain":
    -        r"""Returns the union of D and domain."""
    -        return _sorted_interval_list.Domain_UnionWith(self, domain)
    -
    -    def AdditionWith(self, domain: "Domain") -> "operations_research::Domain":
    -        r"""Returns {x ∈ Int64, ∃ a ∈ D, ∃ b ∈ domain, x = a + b}."""
    -        return _sorted_interval_list.Domain_AdditionWith(self, domain)
    -
    -    def __str__(self) -> "std::string":
    -        r"""Returns a compact string of a vector of intervals like "[1,4][6][10,20]"."""
    -        return _sorted_interval_list.Domain___str__(self)
    -
    -    def __lt__(self, other: "Domain") -> "bool":
    -        r"""Lexicographic order on the intervals() representation."""
    -        return _sorted_interval_list.Domain___lt__(self, other)
    -
    -    def __eq__(self, other: "Domain") -> "bool":
    -        return _sorted_interval_list.Domain___eq__(self, other)
    -
    -    def __ne__(self, other: "Domain") -> "bool":
    -        return _sorted_interval_list.Domain___ne__(self, other)
    -    __swig_destroy__ = _sorted_interval_list.delete_Domain
    -
    -# Register Domain in _sorted_interval_list:
    -_sorted_interval_list.Domain_swigregister(Domain)
    -
    -def Domain_AllValues() -> "operations_research::Domain":
    -    r"""Returns the full domain Int64."""
    -    return _sorted_interval_list.Domain_AllValues()
    -
    -def Domain_FromValues(values: "std::vector< int64_t >") -> "operations_research::Domain":
    -    r"""
    -    Creates a domain from the union of an unsorted list of integer values.
    -    Input values may be repeated, with no consequence on the output
    -    """
    -    return _sorted_interval_list.Domain_FromValues(values)
    -
    -def Domain_FromIntervals(intervals: "std::vector< std::vector< int64_t > > const &") -> "operations_research::Domain":
    -    r"""
    -    This method is available in Python, Java and .NET. It allows
    -    building a Domain object from a list of intervals (long[][] in Java and
    -    .NET, [[0, 2], [5, 5], [8, 10]] in python).
    -    """
    -    return _sorted_interval_list.Domain_FromIntervals(intervals)
    -
    -def Domain_FromFlatIntervals(flat_intervals: "std::vector< int64_t > const &") -> "operations_research::Domain":
    -    r"""
    -    This method is available in Python, Java and .NET. It allows
    -    building a Domain object from a flattened list of intervals
    -    (long[] in Java and .NET, [0, 2, 5, 5, 8, 10] in python).
    -    """
    -    return _sorted_interval_list.Domain_FromFlatIntervals(flat_intervals)
    +def _swig_setattr_nondynamic_class_variable(set):
    +    def set_class_attr(cls, name, value):
    +        if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
    +            set(cls, name, value)
    +        else:
    +            raise AttributeError("You cannot add class attributes to %s" % cls)
    +    return set_class_attr
     
     
    -def __lshift__(*args) -> "std::ostream &":
    -    return _sorted_interval_list.__lshift__(*args)
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -

    Classes

    -
    -
    -class Domain -(*args) -
    -
    -

    We call domain any subset of Int64 = [kint64min, kint64max].

    +def _swig_add_metaclass(metaclass): + """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass""" + def wrapper(cls): + return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy()) + return wrapper + + +class _SwigNonDynamicMeta(type): + """Meta class to enforce nondynamic attributes (no new attributes) for a class""" + __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__) + + +class Domain(object): + r""" + We call *domain* any subset of Int64 = [kint64min, kint64max]. + + This class can be used to represent such set efficiently as a sorted and + non-adjacent list of intervals. This is efficient as long as the size of such + list stays reasonable. + + In the comments below, the domain of *this will always be written 'D'. + Note that all the functions are safe with respect to integer overflow. + """ + + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self, *args): + r""" + *Overload 1:* + By default, Domain will be empty. + + | + + *Overload 2:* + Constructor for the common case of a singleton domain. + + | + + *Overload 3:* + + Constructor for the common case of a single interval [left, right]. + If left > right, this will result in the empty domain. + """ + _sorted_interval_list.Domain_swiginit(self, _sorted_interval_list.new_Domain(*args)) + + @staticmethod + def AllValues() -> "operations_research::Domain": + r"""Returns the full domain Int64.""" + return _sorted_interval_list.Domain_AllValues() + + @staticmethod + def FromValues(values: "std::vector< int64_t >") -> "operations_research::Domain": + r""" + Creates a domain from the union of an unsorted list of integer values. + Input values may be repeated, with no consequence on the output + """ + return _sorted_interval_list.Domain_FromValues(values) + + @staticmethod + def FromIntervals(intervals: "std::vector< std::vector< int64_t > > const &") -> "operations_research::Domain": + r""" + This method is available in Python, Java and .NET. It allows + building a Domain object from a list of intervals (long[][] in Java and + .NET, [[0, 2], [5, 5], [8, 10]] in python). + """ + return _sorted_interval_list.Domain_FromIntervals(intervals) + + @staticmethod + def FromFlatIntervals(flat_intervals: "std::vector< int64_t > const &") -> "operations_research::Domain": + r""" + This method is available in Python, Java and .NET. It allows + building a Domain object from a flattened list of intervals + (long[] in Java and .NET, [0, 2, 5, 5, 8, 10] in python). + """ + return _sorted_interval_list.Domain_FromFlatIntervals(flat_intervals) + + def FlattenedIntervals(self) -> "std::vector< int64_t >": + r""" + This method returns the flattened list of interval bounds of the domain. + + Thus the domain {0, 1, 2, 5, 8, 9, 10} will return [0, 2, 5, 5, + 8, 10] (as a C++ std::vector<int64_t>, as a java or C# long[], as + a python list of integers). + """ + return _sorted_interval_list.Domain_FlattenedIntervals(self) + + def IsEmpty(self) -> "bool": + r"""Returns true if this is the empty set.""" + return _sorted_interval_list.Domain_IsEmpty(self) + + def Size(self) -> "int64_t": + r"""Returns the number of elements in the domain. It is capped at kint64max""" + return _sorted_interval_list.Domain_Size(self) + + def Min(self) -> "int64_t": + r""" + Returns the min value of the domain. + The domain must not be empty. + """ + return _sorted_interval_list.Domain_Min(self) + + def Max(self) -> "int64_t": + r""" + Returns the max value of the domain. + The domain must not be empty. + """ + return _sorted_interval_list.Domain_Max(self) + + def Contains(self, value: "int64_t") -> "bool": + r"""Returns true iff value is in Domain.""" + return _sorted_interval_list.Domain_Contains(self, value) + + def Complement(self) -> "operations_research::Domain": + r"""Returns the set Int64 ∖ D.""" + return _sorted_interval_list.Domain_Complement(self) + + def Negation(self) -> "operations_research::Domain": + r""" + Returns {x ∈ Int64, ∃ e ∈ D, x = -e}. + + Note in particular that if the negation of Int64 is not Int64 but + Int64 \ {kint64min} !! + """ + return _sorted_interval_list.Domain_Negation(self) + + def IntersectionWith(self, domain: "Domain") -> "operations_research::Domain": + r"""Returns the intersection of D and domain.""" + return _sorted_interval_list.Domain_IntersectionWith(self, domain) + + def UnionWith(self, domain: "Domain") -> "operations_research::Domain": + r"""Returns the union of D and domain.""" + return _sorted_interval_list.Domain_UnionWith(self, domain) + + def AdditionWith(self, domain: "Domain") -> "operations_research::Domain": + r"""Returns {x ∈ Int64, ∃ a ∈ D, ∃ b ∈ domain, x = a + b}.""" + return _sorted_interval_list.Domain_AdditionWith(self, domain) + + def __str__(self) -> "std::string": + r"""Returns a compact string of a vector of intervals like "[1,4][6][10,20]".""" + return _sorted_interval_list.Domain___str__(self) + + def __lt__(self, other: "Domain") -> "bool": + r"""Lexicographic order on the intervals() representation.""" + return _sorted_interval_list.Domain___lt__(self, other) + + def __eq__(self, other: "Domain") -> "bool": + return _sorted_interval_list.Domain___eq__(self, other) + + def __ne__(self, other: "Domain") -> "bool": + return _sorted_interval_list.Domain___ne__(self, other) + __swig_destroy__ = _sorted_interval_list.delete_Domain + +# Register Domain in _sorted_interval_list: +_sorted_interval_list.Domain_swigregister(Domain) + +def Domain_AllValues() -> "operations_research::Domain": + r"""Returns the full domain Int64.""" + return _sorted_interval_list.Domain_AllValues() + +def Domain_FromValues(values: "std::vector< int64_t >") -> "operations_research::Domain": + r""" + Creates a domain from the union of an unsorted list of integer values. + Input values may be repeated, with no consequence on the output + """ + return _sorted_interval_list.Domain_FromValues(values) + +def Domain_FromIntervals(intervals: "std::vector< std::vector< int64_t > > const &") -> "operations_research::Domain": + r""" + This method is available in Python, Java and .NET. It allows + building a Domain object from a list of intervals (long[][] in Java and + .NET, [[0, 2], [5, 5], [8, 10]] in python). + """ + return _sorted_interval_list.Domain_FromIntervals(intervals) + +def Domain_FromFlatIntervals(flat_intervals: "std::vector< int64_t > const &") -> "operations_research::Domain": + r""" + This method is available in Python, Java and .NET. It allows + building a Domain object from a flattened list of intervals + (long[] in Java and .NET, [0, 2, 5, 5, 8, 10] in python). + """ + return _sorted_interval_list.Domain_FromFlatIntervals(flat_intervals) + + +def __lshift__(*args) -> "std::ostream &": + return _sorted_interval_list.__lshift__(*args) +
    + +
    + +
    +
    +
    + #   + + + class + Domain: +
    + +
    + View Source +
    class Domain(object):
    +    r"""
    +    We call *domain* any subset of Int64 = [kint64min, kint64max].
    +
    +    This class can be used to represent such set efficiently as a sorted and
    +    non-adjacent list of intervals. This is efficient as long as the size of such
    +    list stays reasonable.
    +
    +    In the comments below, the domain of *this will always be written 'D'.
    +    Note that all the functions are safe with respect to integer overflow.
    +    """
    +
    +    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    +    __repr__ = _swig_repr
    +
    +    def __init__(self, *args):
    +        r"""
    +        *Overload 1:*
    +         By default, Domain will be empty.
    +
    +        |
    +
    +        *Overload 2:*
    +         Constructor for the common case of a singleton domain.
    +
    +        |
    +
    +        *Overload 3:*
    +
    +        Constructor for the common case of a single interval [left, right].
    +        If left > right, this will result in the empty domain.
    +        """
    +        _sorted_interval_list.Domain_swiginit(self, _sorted_interval_list.new_Domain(*args))
    +
    +    @staticmethod
    +    def AllValues() -> "operations_research::Domain":
    +        r"""Returns the full domain Int64."""
    +        return _sorted_interval_list.Domain_AllValues()
    +
    +    @staticmethod
    +    def FromValues(values: "std::vector< int64_t >") -> "operations_research::Domain":
    +        r"""
    +        Creates a domain from the union of an unsorted list of integer values.
    +        Input values may be repeated, with no consequence on the output
    +        """
    +        return _sorted_interval_list.Domain_FromValues(values)
    +
    +    @staticmethod
    +    def FromIntervals(intervals: "std::vector< std::vector< int64_t > > const &") -> "operations_research::Domain":
    +        r"""
    +        This method is available in Python, Java and .NET. It allows
    +        building a Domain object from a list of intervals (long[][] in Java and
    +        .NET, [[0, 2], [5, 5], [8, 10]] in python).
    +        """
    +        return _sorted_interval_list.Domain_FromIntervals(intervals)
    +
    +    @staticmethod
    +    def FromFlatIntervals(flat_intervals: "std::vector< int64_t > const &") -> "operations_research::Domain":
    +        r"""
    +        This method is available in Python, Java and .NET. It allows
    +        building a Domain object from a flattened list of intervals
    +        (long[] in Java and .NET, [0, 2, 5, 5, 8, 10] in python).
    +        """
    +        return _sorted_interval_list.Domain_FromFlatIntervals(flat_intervals)
    +
    +    def FlattenedIntervals(self) -> "std::vector< int64_t >":
    +        r"""
    +        This method returns the flattened list of interval bounds of the domain.
    +
    +        Thus the domain {0, 1, 2, 5, 8, 9, 10} will return [0, 2, 5, 5,
    +        8, 10] (as a C++ std::vector<int64_t>, as a java or C# long[], as
    +        a python list of integers).
    +        """
    +        return _sorted_interval_list.Domain_FlattenedIntervals(self)
    +
    +    def IsEmpty(self) -> "bool":
    +        r"""Returns true if this is the empty set."""
    +        return _sorted_interval_list.Domain_IsEmpty(self)
    +
    +    def Size(self) -> "int64_t":
    +        r"""Returns the number of elements in the domain. It is capped at kint64max"""
    +        return _sorted_interval_list.Domain_Size(self)
    +
    +    def Min(self) -> "int64_t":
    +        r"""
    +        Returns the min value of the domain.
    +        The domain must not be empty.
    +        """
    +        return _sorted_interval_list.Domain_Min(self)
    +
    +    def Max(self) -> "int64_t":
    +        r"""
    +        Returns the max value of the domain.
    +        The domain must not be empty.
    +        """
    +        return _sorted_interval_list.Domain_Max(self)
    +
    +    def Contains(self, value: "int64_t") -> "bool":
    +        r"""Returns true iff value is in Domain."""
    +        return _sorted_interval_list.Domain_Contains(self, value)
    +
    +    def Complement(self) -> "operations_research::Domain":
    +        r"""Returns the set Int64 ∖ D."""
    +        return _sorted_interval_list.Domain_Complement(self)
    +
    +    def Negation(self) -> "operations_research::Domain":
    +        r"""
    +        Returns {x ∈ Int64, ∃ e ∈ D, x = -e}.
    +
    +        Note in particular that if the negation of Int64 is not Int64 but
    +        Int64 \ {kint64min} !!
    +        """
    +        return _sorted_interval_list.Domain_Negation(self)
    +
    +    def IntersectionWith(self, domain: "Domain") -> "operations_research::Domain":
    +        r"""Returns the intersection of D and domain."""
    +        return _sorted_interval_list.Domain_IntersectionWith(self, domain)
    +
    +    def UnionWith(self, domain: "Domain") -> "operations_research::Domain":
    +        r"""Returns the union of D and domain."""
    +        return _sorted_interval_list.Domain_UnionWith(self, domain)
    +
    +    def AdditionWith(self, domain: "Domain") -> "operations_research::Domain":
    +        r"""Returns {x ∈ Int64, ∃ a ∈ D, ∃ b ∈ domain, x = a + b}."""
    +        return _sorted_interval_list.Domain_AdditionWith(self, domain)
    +
    +    def __str__(self) -> "std::string":
    +        r"""Returns a compact string of a vector of intervals like "[1,4][6][10,20]"."""
    +        return _sorted_interval_list.Domain___str__(self)
    +
    +    def __lt__(self, other: "Domain") -> "bool":
    +        r"""Lexicographic order on the intervals() representation."""
    +        return _sorted_interval_list.Domain___lt__(self, other)
    +
    +    def __eq__(self, other: "Domain") -> "bool":
    +        return _sorted_interval_list.Domain___eq__(self, other)
    +
    +    def __ne__(self, other: "Domain") -> "bool":
    +        return _sorted_interval_list.Domain___ne__(self, other)
    +    __swig_destroy__ = _sorted_interval_list.delete_Domain
    +
    + +
    + +

    We call domain any subset of Int64 = [kint64min, kint64max].

    +

    This class can be used to represent such set efficiently as a sorted and non-adjacent list of intervals. This is efficient as long as the size of such list stays reasonable.

    +

    In the comments below, the domain of *this will always be written 'D'. Note that all the functions are safe with respect to integer overflow.

    -

    Overload 1: -By default, Domain will be empty.

    +
    + + +
    +
    #   + + + Domain(*args) +
    + +
    + View Source +
        def __init__(self, *args):
    +        r"""
    +        *Overload 1:*
    +         By default, Domain will be empty.
    +
    +        |
    +
    +        *Overload 2:*
    +         Constructor for the common case of a singleton domain.
    +
    +        |
    +
    +        *Overload 3:*
    +
    +        Constructor for the common case of a single interval [left, right].
    +        If left > right, this will result in the empty domain.
    +        """
    +        _sorted_interval_list.Domain_swiginit(self, _sorted_interval_list.new_Domain(*args))
    +
    + +
    + +

    Overload 1: + By default, Domain will be empty.

    +

    |

    +

    Overload 2: -Constructor for the common case of a singleton domain.

    + Constructor for the common case of a singleton domain.

    +

    |

    +

    Overload 3:

    +

    Constructor for the common case of a single interval [left, right]. -If left > right, this will result in the empty domain.

    -
    - -Expand source code - -
    class Domain(object):
    -    r"""
    -    We call *domain* any subset of Int64 = [kint64min, kint64max].
    +If left > right, this will result in the empty domain.

    +
    - This class can be used to represent such set efficiently as a sorted and - non-adjacent list of intervals. This is efficient as long as the size of such - list stays reasonable. - In the comments below, the domain of *this will always be written 'D'. - Note that all the functions are safe with respect to integer overflow. - """ + +
    +
    #   - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr + thisown +
    - def __init__(self, *args): - r""" - *Overload 1:* - By default, Domain will be empty. +

    The membership flag

    +
    - | - *Overload 2:* - Constructor for the common case of a singleton domain. +
    +
    +
    #   - | +
    @staticmethod
    - *Overload 3:* + def + AllValues() -> 'operations_research::Domain': +
    - Constructor for the common case of a single interval [left, right]. - If left > right, this will result in the empty domain. - """ - _sorted_interval_list.Domain_swiginit(self, _sorted_interval_list.new_Domain(*args)) +
    + View Source +
        @staticmethod
    +    def AllValues() -> "operations_research::Domain":
    +        r"""Returns the full domain Int64."""
    +        return _sorted_interval_list.Domain_AllValues()
    +
    - @staticmethod - def AllValues() -> "operations_research::Domain": - r"""Returns the full domain Int64.""" - return _sorted_interval_list.Domain_AllValues() +
    - @staticmethod - def FromValues(values: "std::vector< int64_t >") -> "operations_research::Domain": - r""" - Creates a domain from the union of an unsorted list of integer values. - Input values may be repeated, with no consequence on the output - """ - return _sorted_interval_list.Domain_FromValues(values) +

    Returns the full domain Int64.

    +
    - @staticmethod - def FromIntervals(intervals: "std::vector< std::vector< int64_t > > const &") -> "operations_research::Domain": - r""" - This method is available in Python, Java and .NET. It allows - building a Domain object from a list of intervals (long[][] in Java and - .NET, [[0, 2], [5, 5], [8, 10]] in python). - """ - return _sorted_interval_list.Domain_FromIntervals(intervals) - @staticmethod - def FromFlatIntervals(flat_intervals: "std::vector< int64_t > const &") -> "operations_research::Domain": - r""" - This method is available in Python, Java and .NET. It allows - building a Domain object from a flattened list of intervals - (long[] in Java and .NET, [0, 2, 5, 5, 8, 10] in python). - """ - return _sorted_interval_list.Domain_FromFlatIntervals(flat_intervals) +
    +
    +
    #   - def FlattenedIntervals(self) -> "std::vector< int64_t >": - r""" - This method returns the flattened list of interval bounds of the domain. +
    @staticmethod
    - Thus the domain {0, 1, 2, 5, 8, 9, 10} will return [0, 2, 5, 5, - 8, 10] (as a C++ std::vector<int64_t>, as a java or C# long[], as - a python list of integers). - """ - return _sorted_interval_list.Domain_FlattenedIntervals(self) + def + FromValues(values: 'std::vector< int64_t >') -> 'operations_research::Domain': +
    - def IsEmpty(self) -> "bool": - r"""Returns true if this is the empty set.""" - return _sorted_interval_list.Domain_IsEmpty(self) +
    + View Source +
        @staticmethod
    +    def FromValues(values: "std::vector< int64_t >") -> "operations_research::Domain":
    +        r"""
    +        Creates a domain from the union of an unsorted list of integer values.
    +        Input values may be repeated, with no consequence on the output
    +        """
    +        return _sorted_interval_list.Domain_FromValues(values)
    +
    - def Size(self) -> "int64_t": - r"""Returns the number of elements in the domain. It is capped at kint64max""" - return _sorted_interval_list.Domain_Size(self) +
    - def Min(self) -> "int64_t": - r""" - Returns the min value of the domain. - The domain must not be empty. - """ - return _sorted_interval_list.Domain_Min(self) +

    Creates a domain from the union of an unsorted list of integer values. +Input values may be repeated, with no consequence on the output

    +
    - def Max(self) -> "int64_t": - r""" - Returns the max value of the domain. - The domain must not be empty. - """ - return _sorted_interval_list.Domain_Max(self) - def Contains(self, value: "int64_t") -> "bool": - r"""Returns true iff value is in Domain.""" - return _sorted_interval_list.Domain_Contains(self, value) +
    +
    +
    #   - def Complement(self) -> "operations_research::Domain": - r"""Returns the set Int64 ∖ D.""" - return _sorted_interval_list.Domain_Complement(self) +
    @staticmethod
    - def Negation(self) -> "operations_research::Domain": - r""" - Returns {x ∈ Int64, ∃ e ∈ D, x = -e}. + def + FromIntervals( + intervals: 'std::vector< std::vector< int64_t > > const &' +) -> 'operations_research::Domain': +
    - Note in particular that if the negation of Int64 is not Int64 but - Int64 \ {kint64min} !! - """ - return _sorted_interval_list.Domain_Negation(self) +
    + View Source +
        @staticmethod
    +    def FromIntervals(intervals: "std::vector< std::vector< int64_t > > const &") -> "operations_research::Domain":
    +        r"""
    +        This method is available in Python, Java and .NET. It allows
    +        building a Domain object from a list of intervals (long[][] in Java and
    +        .NET, [[0, 2], [5, 5], [8, 10]] in python).
    +        """
    +        return _sorted_interval_list.Domain_FromIntervals(intervals)
    +
    - def IntersectionWith(self, domain: "Domain") -> "operations_research::Domain": - r"""Returns the intersection of D and domain.""" - return _sorted_interval_list.Domain_IntersectionWith(self, domain) +
    - def UnionWith(self, domain: "Domain") -> "operations_research::Domain": - r"""Returns the union of D and domain.""" - return _sorted_interval_list.Domain_UnionWith(self, domain) - - def AdditionWith(self, domain: "Domain") -> "operations_research::Domain": - r"""Returns {x ∈ Int64, ∃ a ∈ D, ∃ b ∈ domain, x = a + b}.""" - return _sorted_interval_list.Domain_AdditionWith(self, domain) - - def __str__(self) -> "std::string": - r"""Returns a compact string of a vector of intervals like "[1,4][6][10,20]".""" - return _sorted_interval_list.Domain___str__(self) - - def __lt__(self, other: "Domain") -> "bool": - r"""Lexicographic order on the intervals() representation.""" - return _sorted_interval_list.Domain___lt__(self, other) - - def __eq__(self, other: "Domain") -> "bool": - return _sorted_interval_list.Domain___eq__(self, other) - - def __ne__(self, other: "Domain") -> "bool": - return _sorted_interval_list.Domain___ne__(self, other) - __swig_destroy__ = _sorted_interval_list.delete_Domain
    - -

    Static methods

    -
    -
    -def AllValues() ‑> operations_research::Domain -
    -
    -

    Returns the full domain Int64.

    -
    - -Expand source code - -
    @staticmethod
    -def AllValues() -> "operations_research::Domain":
    -    r"""Returns the full domain Int64."""
    -    return _sorted_interval_list.Domain_AllValues()
    -
    -
    -
    -def FromFlatIntervals(flat_intervals: std::vector< int64_t > const &) ‑> operations_research::Domain -
    -
    -

    This method is available in Python, Java and .NET. It allows -building a Domain object from a flattened list of intervals -(long[] in Java and .NET, [0, 2, 5, 5, 8, 10] in python).

    -
    - -Expand source code - -
    @staticmethod
    -def FromFlatIntervals(flat_intervals: "std::vector< int64_t > const &") -> "operations_research::Domain":
    -    r"""
    -    This method is available in Python, Java and .NET. It allows
    -    building a Domain object from a flattened list of intervals
    -    (long[] in Java and .NET, [0, 2, 5, 5, 8, 10] in python).
    -    """
    -    return _sorted_interval_list.Domain_FromFlatIntervals(flat_intervals)
    -
    -
    -
    -def FromIntervals(intervals: std::vector< std::vector< int64_t > > const &) ‑> operations_research::Domain -
    -
    -

    This method is available in Python, Java and .NET. It allows +

    This method is available in Python, Java and .NET. It allows building a Domain object from a list of intervals (long[][] in Java and -.NET, [[0, 2], [5, 5], [8, 10]] in python).

    -
    - -Expand source code - -
    @staticmethod
    -def FromIntervals(intervals: "std::vector< std::vector< int64_t > > const &") -> "operations_research::Domain":
    -    r"""
    -    This method is available in Python, Java and .NET. It allows
    -    building a Domain object from a list of intervals (long[][] in Java and
    -    .NET, [[0, 2], [5, 5], [8, 10]] in python).
    -    """
    -    return _sorted_interval_list.Domain_FromIntervals(intervals)
    -
    -
    -
    -def FromValues(values: std::vector< int64_t >) ‑> operations_research::Domain -
    -
    -

    Creates a domain from the union of an unsorted list of integer values. -Input values may be repeated, with no consequence on the output

    -
    - -Expand source code - -
    @staticmethod
    -def FromValues(values: "std::vector< int64_t >") -> "operations_research::Domain":
    -    r"""
    -    Creates a domain from the union of an unsorted list of integer values.
    -    Input values may be repeated, with no consequence on the output
    -    """
    -    return _sorted_interval_list.Domain_FromValues(values)
    -
    -
    -
    -

    Methods

    -
    -
    -def AdditionWith(self, domain: Domain) ‑> operations_research::Domain -
    -
    -

    Returns {x ∈ Int64, ∃ a ∈ D, ∃ b ∈ domain, x = a + b}.

    -
    - -Expand source code - -
    def AdditionWith(self, domain: "Domain") -> "operations_research::Domain":
    -    r"""Returns {x ∈ Int64, ∃ a ∈ D, ∃ b ∈ domain, x = a + b}."""
    -    return _sorted_interval_list.Domain_AdditionWith(self, domain)
    -
    -
    -
    -def Complement(self) ‑> operations_research::Domain -
    -
    -

    Returns the set Int64 ∖ D.

    -
    - -Expand source code - -
    def Complement(self) -> "operations_research::Domain":
    -    r"""Returns the set Int64 ∖ D."""
    -    return _sorted_interval_list.Domain_Complement(self)
    -
    -
    -
    -def Contains(self, value: int64_t) ‑> bool -
    -
    -

    Returns true iff value is in Domain.

    -
    - -Expand source code - -
    def Contains(self, value: "int64_t") -> "bool":
    -    r"""Returns true iff value is in Domain."""
    -    return _sorted_interval_list.Domain_Contains(self, value)
    -
    -
    -
    -def FlattenedIntervals(self) ‑> std::vector< int64_t > -
    -
    -

    This method returns the flattened list of interval bounds of the domain.

    +.NET, [[0, 2], [5, 5], [8, 10]] in python).

    +
    + + +
    +
    +
    #   + +
    @staticmethod
    + + def + FromFlatIntervals( + flat_intervals: 'std::vector< int64_t > const &' +) -> 'operations_research::Domain': +
    + +
    + View Source +
        @staticmethod
    +    def FromFlatIntervals(flat_intervals: "std::vector< int64_t > const &") -> "operations_research::Domain":
    +        r"""
    +        This method is available in Python, Java and .NET. It allows
    +        building a Domain object from a flattened list of intervals
    +        (long[] in Java and .NET, [0, 2, 5, 5, 8, 10] in python).
    +        """
    +        return _sorted_interval_list.Domain_FromFlatIntervals(flat_intervals)
    +
    + +
    + +

    This method is available in Python, Java and .NET. It allows +building a Domain object from a flattened list of intervals +(long[] in Java and .NET, [0, 2, 5, 5, 8, 10] in python).

    +
    + + +
    +
    +
    #   + + + def + FlattenedIntervals(self) -> 'std::vector< int64_t >': +
    + +
    + View Source +
        def FlattenedIntervals(self) -> "std::vector< int64_t >":
    +        r"""
    +        This method returns the flattened list of interval bounds of the domain.
    +
    +        Thus the domain {0, 1, 2, 5, 8, 9, 10} will return [0, 2, 5, 5,
    +        8, 10] (as a C++ std::vector<int64_t>, as a java or C# long[], as
    +        a python list of integers).
    +        """
    +        return _sorted_interval_list.Domain_FlattenedIntervals(self)
    +
    + +
    + +

    This method returns the flattened list of interval bounds of the domain.

    +

    Thus the domain {0, 1, 2, 5, 8, 9, 10} will return [0, 2, 5, 5, 8, 10] (as a C++ std::vector, as a java or C# long[], as -a python list of integers).

    -
    - -Expand source code - -
    def FlattenedIntervals(self) -> "std::vector< int64_t >":
    -    r"""
    -    This method returns the flattened list of interval bounds of the domain.
    -
    -    Thus the domain {0, 1, 2, 5, 8, 9, 10} will return [0, 2, 5, 5,
    -    8, 10] (as a C++ std::vector<int64_t>, as a java or C# long[], as
    -    a python list of integers).
    -    """
    -    return _sorted_interval_list.Domain_FlattenedIntervals(self)
    -
    - -
    -def IntersectionWith(self, domain: Domain) ‑> operations_research::Domain -
    -
    -

    Returns the intersection of D and domain.

    -
    - -Expand source code - -
    def IntersectionWith(self, domain: "Domain") -> "operations_research::Domain":
    -    r"""Returns the intersection of D and domain."""
    -    return _sorted_interval_list.Domain_IntersectionWith(self, domain)
    -
    -
    -
    -def IsEmpty(self) ‑> bool -
    -
    -

    Returns true if this is the empty set.

    -
    - -Expand source code - -
    def IsEmpty(self) -> "bool":
    -    r"""Returns true if this is the empty set."""
    -    return _sorted_interval_list.Domain_IsEmpty(self)
    -
    -
    -
    -def Max(self) ‑> int64_t -
    -
    -

    Returns the max value of the domain. -The domain must not be empty.

    -
    - -Expand source code - -
    def Max(self) -> "int64_t":
    -    r"""
    -    Returns the max value of the domain.
    -    The domain must not be empty.
    -    """
    -    return _sorted_interval_list.Domain_Max(self)
    -
    -
    -
    -def Min(self) ‑> int64_t -
    -
    -

    Returns the min value of the domain. -The domain must not be empty.

    -
    - -Expand source code - -
    def Min(self) -> "int64_t":
    -    r"""
    -    Returns the min value of the domain.
    -    The domain must not be empty.
    -    """
    -    return _sorted_interval_list.Domain_Min(self)
    -
    -
    -
    -def Negation(self) ‑> operations_research::Domain -
    -
    -

    Returns {x ∈ Int64, ∃ e ∈ D, x = -e}.

    -

    Note in particular that if the negation of Int64 is not Int64 but -Int64 \ {kint64min} !!

    -
    - -Expand source code - -
    def Negation(self) -> "operations_research::Domain":
    -    r"""
    -    Returns {x ∈ Int64, ∃ e ∈ D, x = -e}.
    -
    -    Note in particular that if the negation of Int64 is not Int64 but
    -    Int64 \ {kint64min} !!
    -    """
    -    return _sorted_interval_list.Domain_Negation(self)
    -
    -
    -
    -def Size(self) ‑> int64_t -
    -
    -

    Returns the number of elements in the domain. It is capped at kint64max

    -
    - -Expand source code - -
    def Size(self) -> "int64_t":
    -    r"""Returns the number of elements in the domain. It is capped at kint64max"""
    -    return _sorted_interval_list.Domain_Size(self)
    -
    -
    -
    -def UnionWith(self, domain: Domain) ‑> operations_research::Domain -
    -
    -

    Returns the union of D and domain.

    -
    - -Expand source code - -
    def UnionWith(self, domain: "Domain") -> "operations_research::Domain":
    -    r"""Returns the union of D and domain."""
    -    return _sorted_interval_list.Domain_UnionWith(self, domain)
    -
    -
    - - - -
    -
    - -
    - + + + +
    +
    #   + + + def + IsEmpty(self) -> bool: +
    + +
    + View Source +
        def IsEmpty(self) -> "bool":
    +        r"""Returns true if this is the empty set."""
    +        return _sorted_interval_list.Domain_IsEmpty(self)
    +
    + +
    + +

    Returns true if this is the empty set.

    +
    + + +
    +
    +
    #   + + + def + Size(self) -> 'int64_t': +
    + +
    + View Source +
        def Size(self) -> "int64_t":
    +        r"""Returns the number of elements in the domain. It is capped at kint64max"""
    +        return _sorted_interval_list.Domain_Size(self)
    +
    + +
    + +

    Returns the number of elements in the domain. It is capped at kint64max

    +
    + + +
    +
    +
    #   + + + def + Min(self) -> 'int64_t': +
    + +
    + View Source +
        def Min(self) -> "int64_t":
    +        r"""
    +        Returns the min value of the domain.
    +        The domain must not be empty.
    +        """
    +        return _sorted_interval_list.Domain_Min(self)
    +
    + +
    + +

    Returns the min value of the domain. +The domain must not be empty.

    +
    + + +
    +
    +
    #   + + + def + Max(self) -> 'int64_t': +
    + +
    + View Source +
        def Max(self) -> "int64_t":
    +        r"""
    +        Returns the max value of the domain.
    +        The domain must not be empty.
    +        """
    +        return _sorted_interval_list.Domain_Max(self)
    +
    + +
    + +

    Returns the max value of the domain. +The domain must not be empty.

    +
    + + +
    +
    +
    #   + + + def + Contains(self, value: 'int64_t') -> bool: +
    + +
    + View Source +
        def Contains(self, value: "int64_t") -> "bool":
    +        r"""Returns true iff value is in Domain."""
    +        return _sorted_interval_list.Domain_Contains(self, value)
    +
    + +
    + +

    Returns true iff value is in Domain.

    +
    + + +
    +
    +
    #   + + + def + Complement(self) -> 'operations_research::Domain': +
    + +
    + View Source +
        def Complement(self) -> "operations_research::Domain":
    +        r"""Returns the set Int64 ∖ D."""
    +        return _sorted_interval_list.Domain_Complement(self)
    +
    + +
    + +

    Returns the set Int64 ∖ D.

    +
    + + +
    +
    +
    #   + + + def + Negation(self) -> 'operations_research::Domain': +
    + +
    + View Source +
        def Negation(self) -> "operations_research::Domain":
    +        r"""
    +        Returns {x ∈ Int64, ∃ e ∈ D, x = -e}.
    +
    +        Note in particular that if the negation of Int64 is not Int64 but
    +        Int64 \ {kint64min} !!
    +        """
    +        return _sorted_interval_list.Domain_Negation(self)
    +
    + +
    + +

    Returns {x ∈ Int64, ∃ e ∈ D, x = -e}.

    + +

    Note in particular that if the negation of Int64 is not Int64 but +Int64 \ {kint64min} !!

    +
    + + +
    +
    +
    #   + + + def + IntersectionWith( + self, + domain: sorted_interval_list.Domain +) -> 'operations_research::Domain': +
    + +
    + View Source +
        def IntersectionWith(self, domain: "Domain") -> "operations_research::Domain":
    +        r"""Returns the intersection of D and domain."""
    +        return _sorted_interval_list.Domain_IntersectionWith(self, domain)
    +
    + +
    + +

    Returns the intersection of D and domain.

    +
    + + +
    +
    +
    #   + + + def + UnionWith( + self, + domain: sorted_interval_list.Domain +) -> 'operations_research::Domain': +
    + +
    + View Source +
        def UnionWith(self, domain: "Domain") -> "operations_research::Domain":
    +        r"""Returns the union of D and domain."""
    +        return _sorted_interval_list.Domain_UnionWith(self, domain)
    +
    + +
    + +

    Returns the union of D and domain.

    +
    + + +
    +
    +
    #   + + + def + AdditionWith( + self, + domain: sorted_interval_list.Domain +) -> 'operations_research::Domain': +
    + +
    + View Source +
        def AdditionWith(self, domain: "Domain") -> "operations_research::Domain":
    +        r"""Returns {x ∈ Int64, ∃ a ∈ D, ∃ b ∈ domain, x = a + b}."""
    +        return _sorted_interval_list.Domain_AdditionWith(self, domain)
    +
    + +
    + +

    Returns {x ∈ Int64, ∃ a ∈ D, ∃ b ∈ domain, x = a + b}.

    +
    + + +
    + +
    +
    #   + + + def + Domain_AllValues() -> 'operations_research::Domain': +
    + +
    + View Source +
    def Domain_AllValues() -> "operations_research::Domain":
    +    r"""Returns the full domain Int64."""
    +    return _sorted_interval_list.Domain_AllValues()
    +
    + +
    + +

    Returns the full domain Int64.

    +
    + + +
    +
    +
    #   + + + def + Domain_FromValues(values: 'std::vector< int64_t >') -> 'operations_research::Domain': +
    + +
    + View Source +
    def Domain_FromValues(values: "std::vector< int64_t >") -> "operations_research::Domain":
    +    r"""
    +    Creates a domain from the union of an unsorted list of integer values.
    +    Input values may be repeated, with no consequence on the output
    +    """
    +    return _sorted_interval_list.Domain_FromValues(values)
    +
    + +
    + +

    Creates a domain from the union of an unsorted list of integer values. +Input values may be repeated, with no consequence on the output

    +
    + + +
    +
    +
    #   + + + def + Domain_FromIntervals( + intervals: 'std::vector< std::vector< int64_t > > const &' +) -> 'operations_research::Domain': +
    + +
    + View Source +
    def Domain_FromIntervals(intervals: "std::vector< std::vector< int64_t > > const &") -> "operations_research::Domain":
    +    r"""
    +    This method is available in Python, Java and .NET. It allows
    +    building a Domain object from a list of intervals (long[][] in Java and
    +    .NET, [[0, 2], [5, 5], [8, 10]] in python).
    +    """
    +    return _sorted_interval_list.Domain_FromIntervals(intervals)
    +
    + +
    + +

    This method is available in Python, Java and .NET. It allows +building a Domain object from a list of intervals (long[][] in Java and +.NET, [[0, 2], [5, 5], [8, 10]] in python).

    +
    + + +
    +
    +
    #   + + + def + Domain_FromFlatIntervals( + flat_intervals: 'std::vector< int64_t > const &' +) -> 'operations_research::Domain': +
    + +
    + View Source +
    def Domain_FromFlatIntervals(flat_intervals: "std::vector< int64_t > const &") -> "operations_research::Domain":
    +    r"""
    +    This method is available in Python, Java and .NET. It allows
    +    building a Domain object from a flattened list of intervals
    +    (long[] in Java and .NET, [0, 2, 5, 5, 8, 10] in python).
    +    """
    +    return _sorted_interval_list.Domain_FromFlatIntervals(flat_intervals)
    +
    + +
    + +

    This method is available in Python, Java and .NET. It allows +building a Domain object from a flattened list of intervals +(long[] in Java and .NET, [0, 2, 5, 5, 8, 10] in python).

    +
    + + +
    + \ No newline at end of file diff --git a/makefiles/Makefile.doc.mk b/makefiles/Makefile.doc.mk index eb35b7700d..58a1f20e7c 100644 --- a/makefiles/Makefile.doc.mk +++ b/makefiles/Makefile.doc.mk @@ -21,10 +21,41 @@ java-doc: java .PHONY: python-doc # Create python documentation. python-doc: - bash -c "command -v pdoc3" - $(SET_PYTHONPATH) pdoc3 --html --force --template-dir tools/doc/templates -o docs/python/ortools/sat/python/ ortools/sat/python/cp_model.py - $(SET_PYTHONPATH) pdoc3 --html --force --template-dir tools/doc/templates -o docs/python/ortools/util/ ortools/gen/ortools/util/sorted_interval_list.py - $(SET_PYTHONPATH) pdoc3 --html --force --template-dir tools/doc/templates -o docs/python/ortools/linear_solver ortools/gen/ortools/linear_solver/pywraplp.py - $(SET_PYTHONPATH) pdoc3 --html --force --template-dir tools/doc/templates -o docs/python/ortools/constraint_solver ortools/gen/ortools/constraint_solver/pywrapcp.py - $(SET_PYTHONPATH) pdoc3 --html --force --template-dir tools/doc/templates -o docs/python/ortools/algorithms ortools/gen/ortools/algorithms/pywrapknapsack_solver.py - $(SET_PYTHONPATH) pdoc3 --html --force --template-dir tools/doc/templates -o docs/python/ortools/graph ortools/gen/ortools/graph/pywrapgraph.py + bash -c "command -v pdoc" + $(SET_PYTHONPATH) pdoc \ + --logo https://developers.google.com/optimization/images/orLogo.png \ + -o docs/python/ \ + --no-search -d google \ + --footer-text "OR-Tools ${OR_TOOLS_MAJOR}.${OR_TOOLS_MINOR}" \ + ortools/sat/python/cp_model.py + $(SET_PYTHONPATH) pdoc \ + --logo https://developers.google.com/optimization/images/orLogo.png \ + -o docs/python/ortools/util/ \ + --no-search -d google \ + --footer-text "OR-Tools ${ORTOOLS_MAJOR}.${ORTOOLS_MINOR}" \ + --footer-text "OR-Tools ${OR_TOOLS_MAJOR}.${OR_TOOLS_MINOR}" \ + ortools/gen/ortools/util/sorted_interval_list.py + $(SET_PYTHONPATH) pdoc \ + --logo https://developers.google.com/optimization/images/orLogo.png \ + -o docs/python/ortools/linear_solver/ \ + --no-search -d google \ + --footer-text "OR-Tools ${OR_TOOLS_MAJOR}.${OR_TOOLS_MINOR}" \ + ortools/gen/ortools/linear_solver/pywraplp.py + $(SET_PYTHONPATH) pdoc \ + --logo https://developers.google.com/optimization/images/orLogo.png \ + -o docs/python/ortools/constraint_solver/ \ + --no-search -d google \ + --footer-text "OR-Tools ${OR_TOOLS_MAJOR}.${OR_TOOLS_MINOR}" \ + ortools/gen/ortools/constraint_solver/pywrapcp.py + $(SET_PYTHONPATH) pdoc \ + --logo https://developers.google.com/optimization/images/orLogo.png \ + -o docs/python/ortools/algorithms/ \ + --no-search -d google \ + --footer-text "OR-Tools ${OR_TOOLS_MAJOR}.${OR_TOOLS_MINOR}" \ + ortools/gen/ortools/algorithms/pywrapknapsack_solver.py + $(SET_PYTHONPATH) pdoc \ + --logo https://developers.google.com/optimization/images/orLogo.png \ + -o docs/python/ortools/graph/ \ + --no-search -d google \ + --footer-text "OR-Tools ${OR_TOOLS_MAJOR}.${OR_TOOLS_MINOR}" \ + ortools/gen/ortools/graph/pywrapgraph.py diff --git a/ortools/linear_solver/python/linear_solver.i b/ortools/linear_solver/python/linear_solver.i index 40f1048ca5..c46b1b721f 100644 --- a/ortools/linear_solver/python/linear_solver.i +++ b/ortools/linear_solver/python/linear_solver.i @@ -63,22 +63,6 @@ from ortools.linear_solver.linear_solver_natural_api import SumArray from ortools.linear_solver.linear_solver_natural_api import SumCst from ortools.linear_solver.linear_solver_natural_api import LinearConstraint from ortools.linear_solver.linear_solver_natural_api import VariableExpr - -# Remove the documentation of some functions. -# See https://pdoc3.github.io/pdoc/doc/pdoc/#overriding-docstrings-with- -__pdoc__ = {} -__pdoc__['Solver_infinity'] = False -__pdoc__['Solver_Infinity'] = False -__pdoc__['Solver_SolveWithProto'] = False -__pdoc__['Solver_SupportsProblemType'] = False -__pdoc__['setup_variable_operator'] = False -__pdoc__['Constraint.thisown'] = False -__pdoc__['Constraint.thisown'] = False -__pdoc__['MPSolverParameters.thisown'] = False -__pdoc__['ModelExportOptions.thisown'] = False -__pdoc__['Objective.thisown'] = False -__pdoc__['Solver.thisown'] = False -__pdoc__['Variable.thisown'] = False %} // %pythoncode %extend operations_research::MPVariable { diff --git a/ortools/sat/python/cp_model.py b/ortools/sat/python/cp_model.py index a11dff796f..fe2c8688f8 100644 --- a/ortools/sat/python/cp_model.py +++ b/ortools/sat/python/cp_model.py @@ -58,15 +58,6 @@ from ortools.util import sorted_interval_list Domain = sorted_interval_list.Domain -# Documentation cleaning. -# Remove the documentation of some functions. -# See https://pdoc3.github.io/pdoc/doc/pdoc/#overriding-docstrings-with- -__pdoc__ = {} -__pdoc__['DisplayBounds'] = False -__pdoc__['EvaluateLinearExpr'] = False -__pdoc__['EvaluateBooleanExpression'] = False -__pdoc__['ShortName'] = False - # The classes below allow linear expressions to be expressed naturally with the # usual arithmetic operators +-*/ and with constant numbers, which makes the # python API very intuitive. See ../samples/*.py for examples. @@ -1207,8 +1198,8 @@ class CpModel(object): sum(demands[i] if times[i] <= t) in [min_level, max_level] Args: - times: A list of integer variables which specify the time of the - filling or emptying the reservoir. + times: A list of integer variables which specify the time of the filling + or emptying the reservoir. demands: A list of integer values that specifies the amount of the emptying or filling. min_level: At any time, the level of the reservoir must be greater or @@ -1267,8 +1258,8 @@ class CpModel(object): actions are actually performed. Args: - times: A list of integer variables which specify the time of the - filling or emptying the reservoir. + times: A list of integer variables which specify the time of the filling + or emptying the reservoir. demands: A list of integer values that specifies the amount of the emptying or filling. actives: a list of boolean variables. They indicates if the @@ -1420,7 +1411,9 @@ class CpModel(object): def AddProdEquality(self, target, variables): """Deprecated, use AddMultiplicationEquality.""" - warnings.warn("AddProdEquality is deprecated; use AddMultiplicationEquality.", DeprecationWarning) + warnings.warn( + 'AddProdEquality is deprecated; use' + 'AddMultiplicationEquality.', + DeprecationWarning) return self.AddMultiplicationEquality(target, variables) # Scheduling support @@ -1435,11 +1428,10 @@ class CpModel(object): Args: start: The start of the interval. It can be an affine or constant - expression. + expression. size: The size of the interval. It can be an affine or constant - expression. - end: The end of the interval. It can be an affine or constant - expression. + expression. + end: The end of the interval. It can be an affine or constant expression. name: The name of the interval variable. Returns: diff --git a/ortools/util/python/sorted_interval_list.i b/ortools/util/python/sorted_interval_list.i index 2fc79bb0c6..34e82135da 100644 --- a/ortools/util/python/sorted_interval_list.i +++ b/ortools/util/python/sorted_interval_list.i @@ -22,17 +22,6 @@ #include "ortools/util/sorted_interval_list.h" %} -%pythonbegin %{ -# Remove the documentation of some functions. -# See https://pdoc3.github.io/pdoc/doc/pdoc/#overriding-docstrings-with- -__pdoc__ = {} -__pdoc__['Domain_AllValues'] = False -__pdoc__['Domain_FromFlatIntervals'] = False -__pdoc__['Domain_FromIntervals'] = False -__pdoc__['Domain_FromValues'] = False -__pdoc__['Domain.thisown'] = False -%} - %ignoreall %unignore operations_research;