ortools.math_opt.python.expressions

Utilities for working with linear and quadratic expressions.

 1#!/usr/bin/env python3
 2# Copyright 2010-2025 Google LLC
 3# Licensed under the Apache License, Version 2.0 (the "License");
 4# you may not use this file except in compliance with the License.
 5# You may obtain a copy of the License at
 6#
 7#     http://www.apache.org/licenses/LICENSE-2.0
 8#
 9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Utilities for working with linear and quadratic expressions."""
16
17import typing
18from typing import Iterable, Mapping, Union
19
20from ortools.math_opt.python import variables
21
22
23@typing.overload
24def fast_sum(summands: Iterable[variables.LinearTypes]) -> variables.LinearSum: ...
25
26
27@typing.overload
28def fast_sum(
29    summands: Iterable[variables.QuadraticTypes],
30) -> Union[variables.LinearSum, variables.QuadraticSum]: ...
31
32
33# TODO(b/312200030): There is a pytype bug so that for the code:
34#   m = mathopt.Model()
35#   x = m.Variable()
36#   s = expressions.fast_sum([x*x, 4.0])
37# pytype picks the wrong overload and thinks s has type variables.LinearSum,
38# rather than Union[variables.LinearSum, variables.QuadraticSum]. Once the bug
39# is fixed, confirm that the overloads actually work.
40def fast_sum(summands):
41    """Sums the elements of summand into a linear or quadratic expression.
42
43    Similar to Python's sum function, but faster for input that not just integers
44    and floats.
45
46    Unlike sum(), the function returns a linear expression when all inputs are
47    floats and/or integers. Importantly, the code:
48      model.add_linear_constraint(fast_sum(maybe_empty_list) <= 1.0)
49    is safe to call, while:
50      model.add_linear_constraint(sum(maybe_empty_list) <= 1.0)
51    fails at runtime when the list is empty.
52
53    Args:
54      summands: The elements to add up.
55
56    Returns:
57      A linear or quadratic expression with the sum of the elements of summand.
58    """
59    summands_tuple = tuple(summands)
60    for s in summands_tuple:
61        if isinstance(s, variables.QuadraticBase):
62            return variables.QuadraticSum(summands_tuple)
63    return variables.LinearSum(summands_tuple)
64
65
66def evaluate_expression(
67    expression: variables.QuadraticTypes,
68    variable_values: Mapping[variables.Variable, float],
69) -> float:
70    """Evaluates a linear or quadratic expression for given variable values.
71
72    E.g. if expression  = 3 * x + 4 and variable_values = {x: 2.0}, then
73    evaluate_expression(expression, variable_values) equals 10.0.
74
75    Args:
76      expression: The expression to evaluate.
77      variable_values: Must contain a value for every variable in expression.
78
79    Returns:
80      The value of the expression when replacing variables by their value.
81    """
82    if isinstance(expression, variables.QuadraticBase):
83        return variables.as_flat_quadratic_expression(expression).evaluate(
84            variable_values
85        )
86    return variables.as_flat_linear_expression(expression).evaluate(variable_values)
def fast_sum(summands):
41def fast_sum(summands):
42    """Sums the elements of summand into a linear or quadratic expression.
43
44    Similar to Python's sum function, but faster for input that not just integers
45    and floats.
46
47    Unlike sum(), the function returns a linear expression when all inputs are
48    floats and/or integers. Importantly, the code:
49      model.add_linear_constraint(fast_sum(maybe_empty_list) <= 1.0)
50    is safe to call, while:
51      model.add_linear_constraint(sum(maybe_empty_list) <= 1.0)
52    fails at runtime when the list is empty.
53
54    Args:
55      summands: The elements to add up.
56
57    Returns:
58      A linear or quadratic expression with the sum of the elements of summand.
59    """
60    summands_tuple = tuple(summands)
61    for s in summands_tuple:
62        if isinstance(s, variables.QuadraticBase):
63            return variables.QuadraticSum(summands_tuple)
64    return variables.LinearSum(summands_tuple)

Sums the elements of summand into a linear or quadratic expression.

Similar to Python's sum function, but faster for input that not just integers and floats.

Unlike sum(), the function returns a linear expression when all inputs are floats and/or integers. Importantly, the code: model.add_linear_constraint(fast_sum(maybe_empty_list) <= 1.0) is safe to call, while: model.add_linear_constraint(sum(maybe_empty_list) <= 1.0) fails at runtime when the list is empty.

Arguments:
  • summands: The elements to add up.
Returns:

A linear or quadratic expression with the sum of the elements of summand.

def evaluate_expression( expression: int | float | ForwardRef('LinearBase') | ForwardRef('QuadraticBase'), variable_values: Mapping[ortools.math_opt.python.variables.Variable, float]) -> float:
67def evaluate_expression(
68    expression: variables.QuadraticTypes,
69    variable_values: Mapping[variables.Variable, float],
70) -> float:
71    """Evaluates a linear or quadratic expression for given variable values.
72
73    E.g. if expression  = 3 * x + 4 and variable_values = {x: 2.0}, then
74    evaluate_expression(expression, variable_values) equals 10.0.
75
76    Args:
77      expression: The expression to evaluate.
78      variable_values: Must contain a value for every variable in expression.
79
80    Returns:
81      The value of the expression when replacing variables by their value.
82    """
83    if isinstance(expression, variables.QuadraticBase):
84        return variables.as_flat_quadratic_expression(expression).evaluate(
85            variable_values
86        )
87    return variables.as_flat_linear_expression(expression).evaluate(variable_values)

Evaluates a linear or quadratic expression for given variable values.

E.g. if expression = 3 * x + 4 and variable_values = {x: 2.0}, then evaluate_expression(expression, variable_values) equals 10.0.

Arguments:
  • expression: The expression to evaluate.
  • variable_values: Must contain a value for every variable in expression.
Returns:

The value of the expression when replacing variables by their value.