ortools.math_opt.python.solve

Solve optimization problems, as defined by Model in model.py.

  1# Copyright 2010-2025 Google LLC
  2# Licensed under the Apache License, Version 2.0 (the "License");
  3# you may not use this file except in compliance with the License.
  4# You may obtain a copy of the License at
  5#
  6#     http://www.apache.org/licenses/LICENSE-2.0
  7#
  8# Unless required by applicable law or agreed to in writing, software
  9# distributed under the License is distributed on an "AS IS" BASIS,
 10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 11# See the License for the specific language governing permissions and
 12# limitations under the License.
 13
 14"""Solve optimization problems, as defined by Model in model.py."""
 15import types
 16from typing import Callable, Optional
 17
 18from ortools.math_opt import parameters_pb2
 19from ortools.math_opt import rpc_pb2
 20from ortools.math_opt.core.python import solver
 21from ortools.math_opt.python import callback
 22from ortools.math_opt.python import compute_infeasible_subsystem_result
 23from ortools.math_opt.python import errors
 24from ortools.math_opt.python import init_arguments
 25from ortools.math_opt.python import message_callback
 26from ortools.math_opt.python import model
 27from ortools.math_opt.python import model_parameters
 28from ortools.math_opt.python import parameters
 29from ortools.math_opt.python import result
 30from pybind11_abseil.status import StatusNotOk
 31
 32SolveCallback = Callable[[callback.CallbackData], callback.CallbackResult]
 33
 34
 35def solve(
 36    opt_model: model.Model,
 37    solver_type: parameters.SolverType,
 38    *,
 39    params: Optional[parameters.SolveParameters] = None,
 40    model_params: Optional[model_parameters.ModelSolveParameters] = None,
 41    msg_cb: Optional[message_callback.SolveMessageCallback] = None,
 42    callback_reg: Optional[callback.CallbackRegistration] = None,
 43    cb: Optional[SolveCallback] = None,
 44    streamable_init_args: Optional[init_arguments.StreamableSolverInitArguments] = None,
 45) -> result.SolveResult:
 46    """Solves an optimization model.
 47
 48    Thread-safety: this function must not be called while modifying the Model
 49    (adding variables...). Some solvers may add more restriction regarding
 50    threading. Please see SolverType::XXX documentation for details.
 51
 52    Args:
 53      opt_model: The optimization model.
 54      solver_type: The underlying solver to use.
 55      params: Configuration of the underlying solver.
 56      model_params: Configuration of the solver that is model specific.
 57      msg_cb: A callback that gives back the underlying solver's logs by the line.
 58      callback_reg: Configures when the callback will be invoked (if provided) and
 59        what data will be collected to access in the callback.
 60      cb: A callback that will be called periodically as the solver runs.
 61      streamable_init_args: Configuration for initializing the underlying solver.
 62
 63    Returns:
 64      A SolveResult containing the termination reason, solution(s) and stats.
 65
 66    Raises:
 67      RuntimeError: On a solve error.
 68    """
 69    # First, initialize optional arguments that were not set to default values.
 70    # Note that in python, default arguments must be immutable, and these are not.
 71    params = params or parameters.SolveParameters()
 72    model_params = model_params or model_parameters.ModelSolveParameters()
 73    callback_reg = callback_reg or callback.CallbackRegistration()
 74    streamable_init_args = (
 75        streamable_init_args or init_arguments.StreamableSolverInitArguments()
 76    )
 77    model_proto = opt_model.export_model()
 78    proto_cb = None
 79    if cb is not None:
 80        proto_cb = lambda x: cb(  # pylint: disable=g-long-lambda
 81            callback.parse_callback_data(x, opt_model)
 82        ).to_proto()
 83    # Solve
 84    try:
 85        proto_result = solver.solve(
 86            model_proto,
 87            solver_type.value,
 88            streamable_init_args.to_proto(),
 89            params.to_proto(),
 90            model_params.to_proto(),
 91            msg_cb,
 92            callback_reg.to_proto(),
 93            proto_cb,
 94            None,
 95        )
 96    except StatusNotOk as e:
 97        raise _status_not_ok_to_exception(e) from None
 98    return result.parse_solve_result(proto_result, opt_model)
 99
100
101def compute_infeasible_subsystem(
102    opt_model: model.Model,
103    solver_type: parameters.SolverType,
104    *,
105    params: Optional[parameters.SolveParameters] = None,
106    msg_cb: Optional[message_callback.SolveMessageCallback] = None,
107    streamable_init_args: Optional[init_arguments.StreamableSolverInitArguments] = None,
108) -> compute_infeasible_subsystem_result.ComputeInfeasibleSubsystemResult:
109    """Computes an infeasible subsystem of the input model.
110
111    Args:
112      opt_model: The optimization model to check for infeasibility.
113      solver_type: Which solver to use to compute the infeasible subsystem. As of
114        August 2023, the only supported solver is Gurobi.
115      params: Configuration of the underlying solver.
116      msg_cb: A callback that gives back the underlying solver's logs by the line.
117      streamable_init_args: Configuration for initializing the underlying solver.
118
119    Returns:
120      An `ComputeInfeasibleSubsystemResult` where `feasibility` indicates if the
121      problem was proven infeasible.
122
123    Throws:
124      RuntimeError: on invalid inputs or an internal solver error.
125    """
126    params = params or parameters.SolveParameters()
127    streamable_init_args = (
128        streamable_init_args or init_arguments.StreamableSolverInitArguments()
129    )
130    model_proto = opt_model.export_model()
131    # Solve
132    try:
133        proto_result = solver.compute_infeasible_subsystem(
134            model_proto,
135            solver_type.value,
136            streamable_init_args.to_proto(),
137            params.to_proto(),
138            msg_cb,
139            None,
140        )
141    except StatusNotOk as e:
142        raise _status_not_ok_to_exception(e) from None
143    return (
144        compute_infeasible_subsystem_result.parse_compute_infeasible_subsystem_result(
145            proto_result, opt_model
146        )
147    )
148
149
150class IncrementalSolver:
151    """Solve an optimization multiple times, with modifications between solves.
152
153    Prefer calling simply solve() above in most cases when incrementalism is not
154    needed.
155
156    Thread-safety: The __init__(), solve() methods must not be called while
157    modifying the Model (adding variables...). The user is expected to use proper
158    synchronization primitives to serialize changes to the model and the use of
159    this object. Note though that it is safe to call methods from different
160    IncrementalSolver instances on the same Model concurrently. The solve() method
161    must not be called concurrently on different threads for the same
162    IncrementalSolver. Some solvers may add more restriction regarding
163    threading. Please see to SolverType::XXX documentation for details.
164
165    This class references some resources that are freed when it is garbage
166    collected (which should usually happen when the last reference is lost). In
167    particular, it references some C++ objects. Although it is not mandatory, it
168    is recommended to free those as soon as possible. To do so it is possible to
169    use this class in the `with` statement:
170
171    with IncrementalSolver(model, SolverType.GLOP) as solver:
172      ...
173
174    When it is not possible to use `with`, the close() method can be called.
175    """
176
177    def __init__(
178        self,
179        opt_model: model.Model,
180        solver_type: parameters.SolverType,
181        *,
182        streamable_init_args: Optional[
183            init_arguments.StreamableSolverInitArguments
184        ] = None,
185    ):
186        streamable_init_args = (
187            streamable_init_args or init_arguments.StreamableSolverInitArguments()
188        )
189        self._model = opt_model
190        self._solver_type = solver_type
191        self._update_tracker = self._model.add_update_tracker()
192        try:
193            self._proto_solver = solver.new(
194                solver_type.value,
195                self._model.export_model(),
196                streamable_init_args.to_proto(),
197            )
198        except StatusNotOk as e:
199            raise _status_not_ok_to_exception(e) from None
200        self._closed = False
201
202    def solve(
203        self,
204        *,
205        params: Optional[parameters.SolveParameters] = None,
206        model_params: Optional[model_parameters.ModelSolveParameters] = None,
207        msg_cb: Optional[message_callback.SolveMessageCallback] = None,
208        callback_reg: Optional[callback.CallbackRegistration] = None,
209        cb: Optional[SolveCallback] = None,
210    ) -> result.SolveResult:
211        """Solves the current optimization model.
212
213        Args:
214          params: The non-model specific solve parameters.
215          model_params: The model specific solve parameters.
216          msg_cb: An optional callback for solver messages.
217          callback_reg: The parameters controlling when cb is called.
218          cb: An optional callback for LP/MIP events.
219
220        Returns:
221          The result of the solve.
222
223        Raises:
224          RuntimeError: If called after being closed, or on a solve error.
225        """
226        if self._closed:
227            raise RuntimeError("the solver is closed")
228
229        update = self._update_tracker.export_update()
230        if update is not None:
231            try:
232                if not self._proto_solver.update(update):
233                    self._proto_solver = solver.new(
234                        self._solver_type.value,
235                        self._model.export_model(),
236                        parameters_pb2.SolverInitializerProto(),
237                    )
238            except StatusNotOk as e:
239                raise _status_not_ok_to_exception(e) from None
240            self._update_tracker.advance_checkpoint()
241        params = params or parameters.SolveParameters()
242        model_params = model_params or model_parameters.ModelSolveParameters()
243        callback_reg = callback_reg or callback.CallbackRegistration()
244        proto_cb = None
245        if cb is not None:
246            proto_cb = lambda x: cb(  # pylint: disable=g-long-lambda
247                callback.parse_callback_data(x, self._model)
248            ).to_proto()
249        try:
250            result_proto = self._proto_solver.solve(
251                params.to_proto(),
252                model_params.to_proto(),
253                msg_cb,
254                callback_reg.to_proto(),
255                proto_cb,
256                None,
257            )
258        except StatusNotOk as e:
259            raise _status_not_ok_to_exception(e) from None
260        return result.parse_solve_result(result_proto, self._model)
261
262    def close(self) -> None:
263        """Closes this solver, freeing all its resources.
264
265        This is optional, the code is correct without calling this function. See the
266        class documentation for details.
267
268        After a solver has been closed, it can't be used anymore. Prefer using the
269        context manager API when possible instead of calling close() directly:
270
271        with IncrementalSolver(model, SolverType.GLOP) as solver:
272          ...
273        """
274        if self._closed:
275            return
276        self._closed = True
277
278        del self._model
279        del self._solver_type
280        del self._update_tracker
281        del self._proto_solver
282
283    def __enter__(self) -> "IncrementalSolver":
284        """Returns the solver itself."""
285        return self
286
287    def __exit__(
288        self,
289        exc_type: Optional[type[BaseException]],
290        exc_val: Optional[BaseException],
291        exc_tb: Optional[types.TracebackType],
292    ) -> None:
293        """Closes the solver."""
294        self.close()
295
296
297def _status_not_ok_to_exception(err: StatusNotOk) -> Exception:
298    """Converts a StatusNotOk to the best matching Python exception.
299
300    Args:
301      err: The input errors.
302
303    Returns:
304      The corresponding exception.
305    """
306    ret = errors.status_proto_to_exception(
307        rpc_pb2.StatusProto(code=err.canonical_code, message=err.message)
308    )
309    # We never expect StatusNotOk to be OK.
310    assert ret is not None, err
311    return ret
36def solve(
37    opt_model: model.Model,
38    solver_type: parameters.SolverType,
39    *,
40    params: Optional[parameters.SolveParameters] = None,
41    model_params: Optional[model_parameters.ModelSolveParameters] = None,
42    msg_cb: Optional[message_callback.SolveMessageCallback] = None,
43    callback_reg: Optional[callback.CallbackRegistration] = None,
44    cb: Optional[SolveCallback] = None,
45    streamable_init_args: Optional[init_arguments.StreamableSolverInitArguments] = None,
46) -> result.SolveResult:
47    """Solves an optimization model.
48
49    Thread-safety: this function must not be called while modifying the Model
50    (adding variables...). Some solvers may add more restriction regarding
51    threading. Please see SolverType::XXX documentation for details.
52
53    Args:
54      opt_model: The optimization model.
55      solver_type: The underlying solver to use.
56      params: Configuration of the underlying solver.
57      model_params: Configuration of the solver that is model specific.
58      msg_cb: A callback that gives back the underlying solver's logs by the line.
59      callback_reg: Configures when the callback will be invoked (if provided) and
60        what data will be collected to access in the callback.
61      cb: A callback that will be called periodically as the solver runs.
62      streamable_init_args: Configuration for initializing the underlying solver.
63
64    Returns:
65      A SolveResult containing the termination reason, solution(s) and stats.
66
67    Raises:
68      RuntimeError: On a solve error.
69    """
70    # First, initialize optional arguments that were not set to default values.
71    # Note that in python, default arguments must be immutable, and these are not.
72    params = params or parameters.SolveParameters()
73    model_params = model_params or model_parameters.ModelSolveParameters()
74    callback_reg = callback_reg or callback.CallbackRegistration()
75    streamable_init_args = (
76        streamable_init_args or init_arguments.StreamableSolverInitArguments()
77    )
78    model_proto = opt_model.export_model()
79    proto_cb = None
80    if cb is not None:
81        proto_cb = lambda x: cb(  # pylint: disable=g-long-lambda
82            callback.parse_callback_data(x, opt_model)
83        ).to_proto()
84    # Solve
85    try:
86        proto_result = solver.solve(
87            model_proto,
88            solver_type.value,
89            streamable_init_args.to_proto(),
90            params.to_proto(),
91            model_params.to_proto(),
92            msg_cb,
93            callback_reg.to_proto(),
94            proto_cb,
95            None,
96        )
97    except StatusNotOk as e:
98        raise _status_not_ok_to_exception(e) from None
99    return result.parse_solve_result(proto_result, opt_model)

Solves an optimization model.

Thread-safety: this function must not be called while modifying the Model (adding variables...). Some solvers may add more restriction regarding threading. Please see SolverType::XXX documentation for details.

Arguments:
  • opt_model: The optimization model.
  • solver_type: The underlying solver to use.
  • params: Configuration of the underlying solver.
  • model_params: Configuration of the solver that is model specific.
  • msg_cb: A callback that gives back the underlying solver's logs by the line.
  • callback_reg: Configures when the callback will be invoked (if provided) and what data will be collected to access in the callback.
  • cb: A callback that will be called periodically as the solver runs.
  • streamable_init_args: Configuration for initializing the underlying solver.
Returns:

A SolveResult containing the termination reason, solution(s) and stats.

Raises:
  • RuntimeError: On a solve error.
def compute_infeasible_subsystem( opt_model: ortools.math_opt.python.model.Model, solver_type: ortools.math_opt.python.parameters.SolverType, *, params: Optional[ortools.math_opt.python.parameters.SolveParameters] = None, msg_cb: Optional[Callable[[Sequence[str]], NoneType]] = None, streamable_init_args: Optional[ortools.math_opt.python.init_arguments.StreamableSolverInitArguments] = None) -> ortools.math_opt.python.compute_infeasible_subsystem_result.ComputeInfeasibleSubsystemResult:
102def compute_infeasible_subsystem(
103    opt_model: model.Model,
104    solver_type: parameters.SolverType,
105    *,
106    params: Optional[parameters.SolveParameters] = None,
107    msg_cb: Optional[message_callback.SolveMessageCallback] = None,
108    streamable_init_args: Optional[init_arguments.StreamableSolverInitArguments] = None,
109) -> compute_infeasible_subsystem_result.ComputeInfeasibleSubsystemResult:
110    """Computes an infeasible subsystem of the input model.
111
112    Args:
113      opt_model: The optimization model to check for infeasibility.
114      solver_type: Which solver to use to compute the infeasible subsystem. As of
115        August 2023, the only supported solver is Gurobi.
116      params: Configuration of the underlying solver.
117      msg_cb: A callback that gives back the underlying solver's logs by the line.
118      streamable_init_args: Configuration for initializing the underlying solver.
119
120    Returns:
121      An `ComputeInfeasibleSubsystemResult` where `feasibility` indicates if the
122      problem was proven infeasible.
123
124    Throws:
125      RuntimeError: on invalid inputs or an internal solver error.
126    """
127    params = params or parameters.SolveParameters()
128    streamable_init_args = (
129        streamable_init_args or init_arguments.StreamableSolverInitArguments()
130    )
131    model_proto = opt_model.export_model()
132    # Solve
133    try:
134        proto_result = solver.compute_infeasible_subsystem(
135            model_proto,
136            solver_type.value,
137            streamable_init_args.to_proto(),
138            params.to_proto(),
139            msg_cb,
140            None,
141        )
142    except StatusNotOk as e:
143        raise _status_not_ok_to_exception(e) from None
144    return (
145        compute_infeasible_subsystem_result.parse_compute_infeasible_subsystem_result(
146            proto_result, opt_model
147        )
148    )

Computes an infeasible subsystem of the input model.

Arguments:
  • opt_model: The optimization model to check for infeasibility.
  • solver_type: Which solver to use to compute the infeasible subsystem. As of August 2023, the only supported solver is Gurobi.
  • params: Configuration of the underlying solver.
  • msg_cb: A callback that gives back the underlying solver's logs by the line.
  • streamable_init_args: Configuration for initializing the underlying solver.
Returns:

An ComputeInfeasibleSubsystemResult where feasibility indicates if the problem was proven infeasible.

Throws:

RuntimeError: on invalid inputs or an internal solver error.

class IncrementalSolver:
151class IncrementalSolver:
152    """Solve an optimization multiple times, with modifications between solves.
153
154    Prefer calling simply solve() above in most cases when incrementalism is not
155    needed.
156
157    Thread-safety: The __init__(), solve() methods must not be called while
158    modifying the Model (adding variables...). The user is expected to use proper
159    synchronization primitives to serialize changes to the model and the use of
160    this object. Note though that it is safe to call methods from different
161    IncrementalSolver instances on the same Model concurrently. The solve() method
162    must not be called concurrently on different threads for the same
163    IncrementalSolver. Some solvers may add more restriction regarding
164    threading. Please see to SolverType::XXX documentation for details.
165
166    This class references some resources that are freed when it is garbage
167    collected (which should usually happen when the last reference is lost). In
168    particular, it references some C++ objects. Although it is not mandatory, it
169    is recommended to free those as soon as possible. To do so it is possible to
170    use this class in the `with` statement:
171
172    with IncrementalSolver(model, SolverType.GLOP) as solver:
173      ...
174
175    When it is not possible to use `with`, the close() method can be called.
176    """
177
178    def __init__(
179        self,
180        opt_model: model.Model,
181        solver_type: parameters.SolverType,
182        *,
183        streamable_init_args: Optional[
184            init_arguments.StreamableSolverInitArguments
185        ] = None,
186    ):
187        streamable_init_args = (
188            streamable_init_args or init_arguments.StreamableSolverInitArguments()
189        )
190        self._model = opt_model
191        self._solver_type = solver_type
192        self._update_tracker = self._model.add_update_tracker()
193        try:
194            self._proto_solver = solver.new(
195                solver_type.value,
196                self._model.export_model(),
197                streamable_init_args.to_proto(),
198            )
199        except StatusNotOk as e:
200            raise _status_not_ok_to_exception(e) from None
201        self._closed = False
202
203    def solve(
204        self,
205        *,
206        params: Optional[parameters.SolveParameters] = None,
207        model_params: Optional[model_parameters.ModelSolveParameters] = None,
208        msg_cb: Optional[message_callback.SolveMessageCallback] = None,
209        callback_reg: Optional[callback.CallbackRegistration] = None,
210        cb: Optional[SolveCallback] = None,
211    ) -> result.SolveResult:
212        """Solves the current optimization model.
213
214        Args:
215          params: The non-model specific solve parameters.
216          model_params: The model specific solve parameters.
217          msg_cb: An optional callback for solver messages.
218          callback_reg: The parameters controlling when cb is called.
219          cb: An optional callback for LP/MIP events.
220
221        Returns:
222          The result of the solve.
223
224        Raises:
225          RuntimeError: If called after being closed, or on a solve error.
226        """
227        if self._closed:
228            raise RuntimeError("the solver is closed")
229
230        update = self._update_tracker.export_update()
231        if update is not None:
232            try:
233                if not self._proto_solver.update(update):
234                    self._proto_solver = solver.new(
235                        self._solver_type.value,
236                        self._model.export_model(),
237                        parameters_pb2.SolverInitializerProto(),
238                    )
239            except StatusNotOk as e:
240                raise _status_not_ok_to_exception(e) from None
241            self._update_tracker.advance_checkpoint()
242        params = params or parameters.SolveParameters()
243        model_params = model_params or model_parameters.ModelSolveParameters()
244        callback_reg = callback_reg or callback.CallbackRegistration()
245        proto_cb = None
246        if cb is not None:
247            proto_cb = lambda x: cb(  # pylint: disable=g-long-lambda
248                callback.parse_callback_data(x, self._model)
249            ).to_proto()
250        try:
251            result_proto = self._proto_solver.solve(
252                params.to_proto(),
253                model_params.to_proto(),
254                msg_cb,
255                callback_reg.to_proto(),
256                proto_cb,
257                None,
258            )
259        except StatusNotOk as e:
260            raise _status_not_ok_to_exception(e) from None
261        return result.parse_solve_result(result_proto, self._model)
262
263    def close(self) -> None:
264        """Closes this solver, freeing all its resources.
265
266        This is optional, the code is correct without calling this function. See the
267        class documentation for details.
268
269        After a solver has been closed, it can't be used anymore. Prefer using the
270        context manager API when possible instead of calling close() directly:
271
272        with IncrementalSolver(model, SolverType.GLOP) as solver:
273          ...
274        """
275        if self._closed:
276            return
277        self._closed = True
278
279        del self._model
280        del self._solver_type
281        del self._update_tracker
282        del self._proto_solver
283
284    def __enter__(self) -> "IncrementalSolver":
285        """Returns the solver itself."""
286        return self
287
288    def __exit__(
289        self,
290        exc_type: Optional[type[BaseException]],
291        exc_val: Optional[BaseException],
292        exc_tb: Optional[types.TracebackType],
293    ) -> None:
294        """Closes the solver."""
295        self.close()

Solve an optimization multiple times, with modifications between solves.

Prefer calling simply solve() above in most cases when incrementalism is not needed.

Thread-safety: The __init__(), solve() methods must not be called while modifying the Model (adding variables...). The user is expected to use proper synchronization primitives to serialize changes to the model and the use of this object. Note though that it is safe to call methods from different IncrementalSolver instances on the same Model concurrently. The solve() method must not be called concurrently on different threads for the same IncrementalSolver. Some solvers may add more restriction regarding threading. Please see to SolverType::XXX documentation for details.

This class references some resources that are freed when it is garbage collected (which should usually happen when the last reference is lost). In particular, it references some C++ objects. Although it is not mandatory, it is recommended to free those as soon as possible. To do so it is possible to use this class in the with statement:

with IncrementalSolver(model, SolverType.GLOP) as solver: ...

When it is not possible to use with, the close() method can be called.

IncrementalSolver( opt_model: ortools.math_opt.python.model.Model, solver_type: ortools.math_opt.python.parameters.SolverType, *, streamable_init_args: Optional[ortools.math_opt.python.init_arguments.StreamableSolverInitArguments] = None)
178    def __init__(
179        self,
180        opt_model: model.Model,
181        solver_type: parameters.SolverType,
182        *,
183        streamable_init_args: Optional[
184            init_arguments.StreamableSolverInitArguments
185        ] = None,
186    ):
187        streamable_init_args = (
188            streamable_init_args or init_arguments.StreamableSolverInitArguments()
189        )
190        self._model = opt_model
191        self._solver_type = solver_type
192        self._update_tracker = self._model.add_update_tracker()
193        try:
194            self._proto_solver = solver.new(
195                solver_type.value,
196                self._model.export_model(),
197                streamable_init_args.to_proto(),
198            )
199        except StatusNotOk as e:
200            raise _status_not_ok_to_exception(e) from None
201        self._closed = False
def solve( self, *, params: Optional[ortools.math_opt.python.parameters.SolveParameters] = None, model_params: Optional[ortools.math_opt.python.model_parameters.ModelSolveParameters] = None, msg_cb: Optional[Callable[[Sequence[str]], NoneType]] = None, callback_reg: Optional[ortools.math_opt.python.callback.CallbackRegistration] = None, cb: Optional[Callable[[ortools.math_opt.python.callback.CallbackData], ortools.math_opt.python.callback.CallbackResult]] = None) -> ortools.math_opt.python.result.SolveResult:
203    def solve(
204        self,
205        *,
206        params: Optional[parameters.SolveParameters] = None,
207        model_params: Optional[model_parameters.ModelSolveParameters] = None,
208        msg_cb: Optional[message_callback.SolveMessageCallback] = None,
209        callback_reg: Optional[callback.CallbackRegistration] = None,
210        cb: Optional[SolveCallback] = None,
211    ) -> result.SolveResult:
212        """Solves the current optimization model.
213
214        Args:
215          params: The non-model specific solve parameters.
216          model_params: The model specific solve parameters.
217          msg_cb: An optional callback for solver messages.
218          callback_reg: The parameters controlling when cb is called.
219          cb: An optional callback for LP/MIP events.
220
221        Returns:
222          The result of the solve.
223
224        Raises:
225          RuntimeError: If called after being closed, or on a solve error.
226        """
227        if self._closed:
228            raise RuntimeError("the solver is closed")
229
230        update = self._update_tracker.export_update()
231        if update is not None:
232            try:
233                if not self._proto_solver.update(update):
234                    self._proto_solver = solver.new(
235                        self._solver_type.value,
236                        self._model.export_model(),
237                        parameters_pb2.SolverInitializerProto(),
238                    )
239            except StatusNotOk as e:
240                raise _status_not_ok_to_exception(e) from None
241            self._update_tracker.advance_checkpoint()
242        params = params or parameters.SolveParameters()
243        model_params = model_params or model_parameters.ModelSolveParameters()
244        callback_reg = callback_reg or callback.CallbackRegistration()
245        proto_cb = None
246        if cb is not None:
247            proto_cb = lambda x: cb(  # pylint: disable=g-long-lambda
248                callback.parse_callback_data(x, self._model)
249            ).to_proto()
250        try:
251            result_proto = self._proto_solver.solve(
252                params.to_proto(),
253                model_params.to_proto(),
254                msg_cb,
255                callback_reg.to_proto(),
256                proto_cb,
257                None,
258            )
259        except StatusNotOk as e:
260            raise _status_not_ok_to_exception(e) from None
261        return result.parse_solve_result(result_proto, self._model)

Solves the current optimization model.

Arguments:
  • params: The non-model specific solve parameters.
  • model_params: The model specific solve parameters.
  • msg_cb: An optional callback for solver messages.
  • callback_reg: The parameters controlling when cb is called.
  • cb: An optional callback for LP/MIP events.
Returns:

The result of the solve.

Raises:
  • RuntimeError: If called after being closed, or on a solve error.
def close(self) -> None:
263    def close(self) -> None:
264        """Closes this solver, freeing all its resources.
265
266        This is optional, the code is correct without calling this function. See the
267        class documentation for details.
268
269        After a solver has been closed, it can't be used anymore. Prefer using the
270        context manager API when possible instead of calling close() directly:
271
272        with IncrementalSolver(model, SolverType.GLOP) as solver:
273          ...
274        """
275        if self._closed:
276            return
277        self._closed = True
278
279        del self._model
280        del self._solver_type
281        del self._update_tracker
282        del self._proto_solver

Closes this solver, freeing all its resources.

This is optional, the code is correct without calling this function. See the class documentation for details.

After a solver has been closed, it can't be used anymore. Prefer using the context manager API when possible instead of calling close() directly:

with IncrementalSolver(model, SolverType.GLOP) as solver: ...