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
 
    6//     http://www.apache.org/licenses/LICENSE-2.0
 
    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.
 
   14// An encoding format for mathematical optimization problems.
 
   18package operations_research.service.v1.mathopt;
 
   20import "ortools/service/v1/mathopt/sparse_containers.proto";
 
   22option java_multiple_files = true;
 
   23option java_package = "com.google.ortools.service.v1.mathopt";
 
   24option csharp_namespace = "Google.OrTools.Service";
 
   26// As used below, we define "#variables" = size(VariablesProto.ids).
 
   27message VariablesProto {
 
   28  // Must be nonnegative and strictly increasing. The max(int64) value can't be
 
   30  repeated int64 ids = 1;
 
   32  // Should have length equal to #variables, values in [-inf, inf).
 
   33  repeated double lower_bounds = 2;
 
   35  // Should have length equal to #variables, values in (-inf, inf].
 
   36  repeated double upper_bounds = 3;
 
   38  // Should have length equal to #variables. Value is false for continuous
 
   39  // variables and true for integer variables.
 
   40  repeated bool integers = 4;
 
   42  // If not set, assumed to be all empty strings. Otherwise, should have length
 
   43  // equal to #variables.
 
   45  // All nonempty names must be distinct. TODO(b/169575522): we may relax this.
 
   46  repeated string names = 5;
 
   49message ObjectiveProto {
 
   50  // false is minimize, true is maximize
 
   53  // Must be finite and not NaN.
 
   56  // ObjectiveProto terms that are linear in the decision variables.
 
   59  //  * linear_coefficients.ids are elements of VariablesProto.ids.
 
   60  //  * VariablesProto not specified correspond to zero.
 
   61  //  * linear_coefficients.values must all be finite.
 
   62  //  * linear_coefficients.values can be zero, but this just wastes space.
 
   63  SparseDoubleVectorProto linear_coefficients = 3;
 
   65  // Objective terms that are quadratic in the decision variables.
 
   67  // Requirements in addition to those on SparseDoubleMatrixProto messages:
 
   68  //  * Each element of quadratic_coefficients.row_ids and each element of
 
   69  //    quadratic_coefficients.column_ids must be an element of
 
   70  //    VariablesProto.ids.
 
   71  //  * The matrix must be upper triangular: for each i,
 
   72  //    quadratic_coefficients.row_ids[i] <=
 
   73  //    quadratic_coefficients.column_ids[i].
 
   76  //  * Terms not explicitly stored have zero coefficient.
 
   77  //  * Elements of quadratic_coefficients.coefficients can be zero, but this
 
   79  SparseDoubleMatrixProto quadratic_coefficients = 4;
 
   81  // Parent messages may have uniqueness requirements on this field; e.g., see
 
   82  // ModelProto.objectives and AuxiliaryObjectivesUpdatesProto.new_objectives.
 
   85  // For multi-objective problems, the priority of this objective relative to
 
   86  // the others (lower is more important). This value must be nonnegative.
 
   87  // Furthermore, each objective priority in the model must be distinct at solve
 
   88  // time. This condition is not validated at the proto level, so models may
 
   89  // temporarily have objectives with the same priority.
 
   93// As used below, we define "#linear constraints" =
 
   94// size(LinearConstraintsProto.ids).
 
   95message LinearConstraintsProto {
 
   96  // Must be nonnegative and strictly increasing. The max(int64) value can't be
 
   98  repeated int64 ids = 1;
 
  100  // Should have length equal to #linear constraints, values in [-inf, inf).
 
  101  repeated double lower_bounds = 2;
 
  103  // Should have length equal to #linear constraints, values in (-inf, inf].
 
  104  repeated double upper_bounds = 3;
 
  106  // If not set, assumed to be all empty strings. Otherwise, should have length
 
  107  // equal to #linear constraints.
 
  109  // All nonempty names must be distinct. TODO(b/169575522): we may relax this.
 
  110  repeated string names = 4;
 
  113// A single quadratic constraint of the form:
 
  114//    lb <= sum{linear_terms} + sum{quadratic_terms} <= ub.
 
  116// If a variable involved in this constraint is deleted, it is treated as if it
 
  118message QuadraticConstraintProto {
 
  119  // Terms that are linear in the decision variables.
 
  121  // In addition to requirements on SparseDoubleVectorProto messages we require
 
  123  //  * linear_terms.ids are elements of VariablesProto.ids.
 
  124  //  * linear_terms.values must all be finite and not-NaN.
 
  127  //  * Variable ids omitted have a corresponding coefficient of zero.
 
  128  //  * linear_terms.values can be zero, but this just wastes space.
 
  129  SparseDoubleVectorProto linear_terms = 1;
 
  131  // Terms that are quadratic in the decision variables.
 
  133  // In addition to requirements on SparseDoubleMatrixProto messages we require
 
  135  //  * Each element of quadratic_terms.row_ids and each element of
 
  136  //    quadratic_terms.column_ids must be an element of VariablesProto.ids.
 
  137  //  * The matrix must be upper triangular: for each i,
 
  138  //    quadratic_terms.row_ids[i] <= quadratic_terms.column_ids[i].
 
  141  //  * Terms not explicitly stored have zero coefficient.
 
  142  //  * Elements of quadratic_terms.coefficients can be zero, but this just
 
  144  SparseDoubleMatrixProto quadratic_terms = 2;
 
  146  // Must have value in [-inf, inf), and be less than or equal to `upper_bound`.
 
  147  double lower_bound = 3;
 
  149  // Must have value in (-inf, inf], and be greater than or equal to
 
  151  double upper_bound = 4;
 
  153  // Parent messages may have uniqueness requirements on this field; e.g., see
 
  154  // ModelProto.quadratic_constraints and
 
  155  // QuadraticConstraintUpdatesProto.new_constraints.
 
  159// A single second-order cone constraint of the form:
 
  161//    ||`arguments_to_norm`||_2 <= `upper_bound`,
 
  163// where `upper_bound` and each element of `arguments_to_norm` are linear
 
  166// If a variable involved in this constraint is deleted, it is treated as if it
 
  168message SecondOrderConeConstraintProto {
 
  169  LinearExpressionProto upper_bound = 1;
 
  170  repeated LinearExpressionProto arguments_to_norm = 2;
 
  172  // Parent messages may have uniqueness requirements on this field; e.g., see
 
  173  // `ModelProto.second_order_cone_constraints` and
 
  174  // `SecondOrderConeConstraintUpdatesProto.new_constraints`.
 
  178// Data for representing a single SOS1 or SOS2 constraint.
 
  180// If a variable involved in this constraint is deleted, it is treated as if it
 
  182message SosConstraintProto {
 
  183  // The expressions over which to apply the SOS constraint:
 
  184  //   * SOS1: At most one element takes a nonzero value.
 
  185  //   * SOS2: At most two elements take nonzero values, and they must be
 
  186  //           adjacent in the repeated ordering.
 
  187  repeated LinearExpressionProto expressions = 1;
 
  189  // Either empty or of equal length to expressions. If empty, default weights
 
  191  // If present, the entries must be unique.
 
  192  repeated double weights = 2;
 
  194  // Parent messages may have uniqueness requirements on this field; e.g., see
 
  195  // ModelProto.sos1_constraints and SosConstraintUpdatesProto.new_constraints.
 
  199// Data for representing a single indicator constraint of the form:
 
  200//    Variable(indicator_id) = (activate_on_zero ? 0 : 1) ⇒
 
  201//    lower_bound <= expression <= upper_bound.
 
  203// If a variable involved in this constraint (either the indicator, or appearing
 
  204// in `expression`) is deleted, it is treated as if it were set to zero. In
 
  205// particular, deleting the indicator variable means that the indicator
 
  206// constraint is vacuous if `activate_on_zero` is false, and that it is
 
  207// equivalent to a linear constraint if `activate_on_zero` is true.
 
  208message IndicatorConstraintProto {
 
  209  // An ID corresponding to a binary variable, or unset. If unset, the indicator
 
  210  // constraint is ignored. If set, we require that:
 
  211  //   * VariablesProto.integers[indicator_id] = true,
 
  212  //   * VariablesProto.lower_bounds[indicator_id] >= 0,
 
  213  //   * VariablesProto.upper_bounds[indicator_id] <= 1.
 
  214  // These conditions are not validated by MathOpt, but if not satisfied will
 
  215  // lead to the solver returning an error upon solving.
 
  216  optional int64 indicator_id = 1;
 
  218  // If true, then if the indicator variable takes value 0, the implied
 
  219  // constraint must hold. Otherwise, if the indicator variable takes value 1,
 
  220  // then the implied constraint must hold.
 
  221  bool activate_on_zero = 6;
 
  223  // Must be a valid linear expression with respect to the containing model:
 
  224  //   * All stated conditions on `SparseDoubleVectorProto`,
 
  225  //   * All elements of `expression.values` must be finite,
 
  226  //   * `expression.ids` are a subset of `VariablesProto.ids`.
 
  227  SparseDoubleVectorProto expression = 2;
 
  229  // Must have value in [-inf, inf); cannot be NaN.
 
  230  double lower_bound = 3;
 
  232  // Must have value in (-inf, inf]; cannot be NaN.
 
  233  double upper_bound = 4;
 
  235  // Parent messages may have uniqueness requirements on this field; e.g., see
 
  236  // `ModelProto.indicator_constraints` and
 
  237  // `IndicatorConstraintUpdatesProto.new_constraints`.
 
  241// An optimization problem.
 
  243//   - Continuous and integer decision variables with optional finite bounds.
 
  244//   - Linear and quadratic objectives (single or multiple objectives), either
 
  245//   minimized or maximized.
 
  246//   - A number of constraints types, including:
 
  247//     * Linear constraints
 
  248//     * Quadratic constraints
 
  249//     * Second-order cone constraints
 
  250//     * Logical constraints
 
  251//       > SOS1 and SOS2 constraints
 
  252//       > Indicator constraints
 
  254// By default, constraints are represented in "id-to-data" maps. However, we
 
  255// represent linear constraints in a more efficient "struct-of-arrays" format.
 
  258  VariablesProto variables = 2;
 
  260  // The primary objective in the model.
 
  261  ObjectiveProto objective = 3;
 
  263  // Auxiliary objectives for use in multi-objective models.
 
  265  // Map key IDs must be in [0, max(int64)). Each priority, and each nonempty
 
  266  // name, must be unique and also distinct from the primary `objective`.
 
  267  map<int64, ObjectiveProto> auxiliary_objectives = 10;
 
  268  LinearConstraintsProto linear_constraints = 4;
 
  270  // The variable coefficients for the linear constraints.
 
  272  // If a variable involved in this constraint is deleted, it is treated as if
 
  273  // it were set to zero.
 
  276  //  * linear_constraint_matrix.row_ids are elements of linear_constraints.ids.
 
  277  //  * linear_constraint_matrix.column_ids are elements of variables.ids.
 
  278  //  * Matrix entries not specified are zero.
 
  279  //  * linear_constraint_matrix.values must all be finite.
 
  280  SparseDoubleMatrixProto linear_constraint_matrix = 5;
 
  282  // Mapped constraints (i.e., stored in "constraint ID"-to-"constraint data"
 
  283  // map). For each subsequent submessage, we require that:
 
  284  //   * Each key is in [0, max(int64)).
 
  285  //   * Each key is unique in its respective map (but not necessarily across
 
  287  //   * Each value contains a name field (called `name`), and each nonempty
 
  288  //     name must be distinct across all map entries (but not necessarily
 
  289  //     across constraint types).
 
  291  // Quadratic constraints in the model.
 
  292  map<int64, QuadraticConstraintProto> quadratic_constraints = 6;
 
  294  // Second-order cone constraints in the model.
 
  295  map<int64, SecondOrderConeConstraintProto> second_order_cone_constraints = 11;
 
  297  // SOS1 constraints in the model, which constrain that at most one
 
  298  // `expression` can be nonzero. The optional `weights` entries are an
 
  299  // implementation detail used by the solver to (hopefully) converge more
 
  300  // quickly. In more detail, solvers may (or may not) use these weights to
 
  301  // select branching decisions that produce "balanced" children nodes.
 
  302  map<int64, SosConstraintProto> sos1_constraints = 7;
 
  304  // SOS2 constraints in the model, which constrain that at most two entries of
 
  305  // `expression` can be nonzero, and they must be adjacent in their ordering.
 
  306  // If no `weights` are provided, this ordering is their linear ordering in the
 
  307  // `expressions` list; if `weights` are presented, the ordering is taken with
 
  308  // respect to these values in increasing order.
 
  309  map<int64, SosConstraintProto> sos2_constraints = 8;
 
  311  // Indicator constraints in the model, which enforce that, if a binary
 
  312  // "indicator variable" is set to one, then an "implied constraint" must hold.
 
  313  map<int64, IndicatorConstraintProto> indicator_constraints = 9;