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// The solution to an optimization model.
 
   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// Feasibility of a primal or dual solution as claimed by the solver.
 
   27enum SolutionStatusProto {
 
   28  // Guard value representing no status.
 
   29  SOLUTION_STATUS_UNSPECIFIED = 0;
 
   31  // Solver does not claim a feasibility status.
 
   32  SOLUTION_STATUS_UNDETERMINED = 1;
 
   34  // Solver claims the solution is feasible.
 
   35  SOLUTION_STATUS_FEASIBLE = 2;
 
   37  // Solver claims the solution is infeasible.
 
   38  SOLUTION_STATUS_INFEASIBLE = 3;
 
   41// A solution to an optimization problem.
 
   43// E.g. consider a simple linear program:
 
   47// A primal solution is assignment values to x. It is feasible if it satisfies
 
   48// A * x >= b and x >= 0 from above. In the message PrimalSolutionProto below,
 
   49// variable_values is x and objective_value is c * x.
 
   50message PrimalSolutionProto {
 
   52  //  * variable_values.ids are elements of VariablesProto.ids.
 
   53  //  * variable_values.values must all be finite.
 
   54  SparseDoubleVectorProto variable_values = 1;
 
   56  // Objective value as computed by the underlying solver. Cannot be infinite or
 
   58  double objective_value = 2;
 
   60  // Auxiliary objective values as computed by the underlying solver. Keys must
 
   61  // be valid auxiliary objective IDs. Values cannot be infinite or NaN.
 
   62  map<int64, double> auxiliary_objective_values = 4;
 
   64  // Feasibility status of the solution according to the underlying solver.
 
   65  SolutionStatusProto feasibility_status = 3;
 
   68// A direction of unbounded improvement to an optimization problem;
 
   69// equivalently, a certificate of infeasibility for the dual of the
 
   70// optimization problem.
 
   72// E.g. consider a simple linear program:
 
   76// A primal ray is an x that satisfies:
 
   80// Observe that given a feasible solution, any positive multiple of the primal
 
   81// ray plus that solution is still feasible, and gives a better objective
 
   82// value. A primal ray also proves the dual optimization problem infeasible.
 
   84// In the message PrimalRay below, variable_values is x.
 
   85message PrimalRayProto {
 
   87  //  * variable_values.ids are elements of VariablesProto.ids.
 
   88  //  * variable_values.values must all be finite.
 
   89  SparseDoubleVectorProto variable_values = 1;
 
   91  // TODO(b/185365397): indicate if the ray is feasible.
 
   94// A solution to the dual of an optimization problem.
 
   96// E.g. consider the primal dual pair linear program pair:
 
   99//   s.t. A * x >= b      s.t. y * A + r = c
 
  101// The dual solution is the pair (y, r). It is feasible if it satisfies the
 
  102// constraints from (Dual) above.
 
  104// In the message below, y is dual_values, r is reduced_costs, and
 
  105// b * y is objective value.
 
  106message DualSolutionProto {
 
  108  //  * dual_values.ids are elements of LinearConstraints.ids.
 
  109  //  * dual_values.values must all be finite.
 
  110  SparseDoubleVectorProto dual_values = 1;
 
  113  //  * reduced_costs.ids are elements of VariablesProto.ids.
 
  114  //  * reduced_costs.values must all be finite.
 
  115  SparseDoubleVectorProto reduced_costs = 2;
 
  117  // TODO(b/195295177): consider making this non-optional
 
  118  // Objective value as computed by the underlying solver.
 
  119  optional double objective_value = 3;
 
  121  // Feasibility status of the solution according to the underlying solver.
 
  122  SolutionStatusProto feasibility_status = 4;
 
  125// A direction of unbounded improvement to the dual of an optimization,
 
  126// problem; equivalently, a certificate of primal infeasibility.
 
  128// E.g. consider the primal dual pair linear program pair:
 
  130//    min c * x             max b * y
 
  131//    s.t. A * x >= b       s.t. y * A + r = c
 
  133// The dual ray is the pair (y, r) satisfying:
 
  137// Observe that adding a positive multiple of (y, r) to dual feasible solution
 
  138// maintains dual feasibility and improves the objective (proving the dual is
 
  139// unbounded). The dual ray also proves the primal problem is infeasible.
 
  141// In the message DualRay below, y is dual_values and r is reduced_costs.
 
  142message DualRayProto {
 
  144  //  * dual_values.ids are elements of LinearConstraints.ids.
 
  145  //  * dual_values.values must all be finite.
 
  146  SparseDoubleVectorProto dual_values = 1;
 
  149  //  * reduced_costs.ids are elements of VariablesProto.ids.
 
  150  //  * reduced_costs.values must all be finite.
 
  151  SparseDoubleVectorProto reduced_costs = 2;
 
  153  // TODO(b/185365397): indicate if the ray is feasible.
 
  156// Status of a variable/constraint in a LP basis.
 
  157enum BasisStatusProto {
 
  158  // Guard value representing no status.
 
  159  BASIS_STATUS_UNSPECIFIED = 0;
 
  161  // The variable/constraint is free (it has no finite bounds).
 
  162  BASIS_STATUS_FREE = 1;
 
  164  // The variable/constraint is at its lower bound (which must be finite).
 
  165  BASIS_STATUS_AT_LOWER_BOUND = 2;
 
  167  // The variable/constraint is at its upper bound (which must be finite).
 
  168  BASIS_STATUS_AT_UPPER_BOUND = 3;
 
  170  // The variable/constraint has identical finite lower and upper bounds.
 
  171  BASIS_STATUS_FIXED_VALUE = 4;
 
  173  // The variable/constraint is basic.
 
  174  BASIS_STATUS_BASIC = 5;
 
  177// A sparse representation of a vector of basis statuses.
 
  178message SparseBasisStatusVector {
 
  179  // Must be sorted (in increasing ordering) with all elements distinct.
 
  180  repeated int64 ids = 1;
 
  182  // Must have equal length to ids.
 
  183  repeated BasisStatusProto values = 2;
 
  186// A combinatorial characterization for a solution to a linear program.
 
  188// The simplex method for solving linear programs always returns a "basic
 
  189// feasible solution" which can be described combinatorially by a Basis. A basis
 
  190// assigns a BasisStatusProto for every variable and linear constraint.
 
  192// E.g. consider a standard form LP:
 
  196// that has more variables than constraints and with full row rank A.
 
  198// Let n be the number of variables and m the number of linear constraints. A
 
  199// valid basis for this problem can be constructed as follows:
 
  200//  * All constraints will have basis status FIXED.
 
  201//  * Pick m variables such that the columns of A are linearly independent and
 
  202//    assign the status BASIC.
 
  203//  * Assign the status AT_LOWER for the remaining n - m variables.
 
  205// The basic solution for this basis is the unique solution of A * x = b that
 
  206// has all variables with status AT_LOWER fixed to their lower bounds (all
 
  207// zero). The resulting solution is called a basic feasible solution if it also
 
  210  // Constraint basis status.
 
  213  //  * constraint_status.ids is equal to LinearConstraints.ids.
 
  214  SparseBasisStatusVector constraint_status = 1;
 
  216  // Variable basis status.
 
  219  //  * constraint_status.ids is equal to VariablesProto.ids.
 
  220  SparseBasisStatusVector variable_status = 2;
 
  222  // This is an advanced feature used by MathOpt to characterize feasibility of
 
  223  // suboptimal LP solutions (optimal solutions will always have status
 
  224  // SOLUTION_STATUS_FEASIBLE).
 
  226  // For single-sided LPs it should be equal to the feasibility status of the
 
  227  // associated dual solution. For two-sided LPs it may be different in some
 
  228  // edge cases (e.g. incomplete solves with primal simplex).
 
  230  // If you are providing a starting basis via
 
  231  // ModelSolveParametersProto.initial_basis, this value is ignored. It is only
 
  232  // relevant for the basis returned by SolutionProto.basis.
 
  233  SolutionStatusProto basic_dual_feasibility = 3;
 
  236// What is included in a solution depends on the kind of problem and solver.
 
  237// The current common patterns are
 
  238//   1. MIP solvers return only a primal solution.
 
  239//   2. Simplex LP solvers often return a basis and the primal and dual
 
  240//      solutions associated to this basis.
 
  241//   3. Other continuous solvers often return a primal and dual solution
 
  242//      solution that are connected in a solver-dependent form.
 
  245//  * at least one field must be set; a solution can't be empty.
 
  246message SolutionProto {
 
  247  optional PrimalSolutionProto primal_solution = 1;
 
  248  optional DualSolutionProto dual_solution = 2;
 
  249  optional BasisProto basis = 3;