OR-Tools  9.6
glpk_computational_form.h
Go to the documentation of this file.
1 // Copyright 2010-2022 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 // This headers defines APIs that wrap GLPK APIs for indices of variables from
15 // the computational form.
16 //
17 // In GLPK (for details see glpk-5.0/doc/glpk.pdf available from
18 // glpk-5.0.tar.gz) the general form of the problem is:
19 //
20 // min (or max) z = c^T x_S + c_0
21 // s.t. x_R = A x_S
22 // l_R <= x_R <= u_R
23 // l_S <= x_S <= u_S
24 //
25 // where:
26 // x_S are the structural variables
27 // x_R are the auxiliary variables used to define constraints
28 //
29 // This is this form that is used by most GLPK's APIs.
30 //
31 // But to implement the simplex algorithms, GLPK uses the following
32 // computational form:
33 //
34 // min (or max) z = (0 | c)^T x + c_0
35 // s.t. (I | -A) x = 0
36 // l <= x <= u
37 //
38 // where:
39 // x = (x_R | x_S)
40 //
41 // That is it merges the auxiliary and structural variables in a single set of
42 // variables.
43 //
44 // The dual of this problem is, when the primal is a minimization:
45 //
46 // max Z = l^T λ_l + u^T λ_u
47 // s.t. (I | -A)^T π + λ_l + λ_u = (O | c)^T
48 // λ_l >= 0, λ_u <= 0
49 //
50 // and if the primal is a maximization:
51 //
52 // min Z = l^T λ_l + u^T λ_u
53 // s.t. (I | -A)^T π + λ_l + λ_u = (O | c)^T
54 // λ_l <= 0, λ_u >= 0
55 //
56 // There is a reduced cost λ_k for each variable x_k:
57 //
58 // λ = λ_l + λ_u
59 //
60 // This header contains basic adapter functions that takes the index of a
61 // variable x in the computational form and use the corresponding API for either
62 // x_R or x_S (a.k.a. primal values) and for the corresponding reduced costs λ
63 // (a.k.a. dual values).
64 //
65 // This logic is usually necessary when using advanced APIs that deal with
66 // indices in the computational form.
67 #ifndef OR_TOOLS_GLPK_GLPK_COMPUTATIONAL_FORM_H_
68 #define OR_TOOLS_GLPK_GLPK_COMPUTATIONAL_FORM_H_
69 
70 extern "C" {
71 #include <glpk.h>
72 }
73 
74 namespace operations_research {
75 
76 // Returns the status of the variable k of the computational form by calling
77 // either glp_get_row_stat() or glp_get_col_stat().
78 //
79 // Here k is an index in the joint set of indices of variables and constraints
80 // in the computational form (see the comment at the top of this header for
81 // details):
82 //
83 // - 1 <= k <= num_cstrs: index of the k-th auxiliary variable in the general
84 // form (the variable associate with the k-th constraint).
85 //
86 // - num_cstrs + 1 <= k <= num_cstrs + num_vars: index of the (k-num_cstrs)-th
87 // structural variable in the general form.
88 inline int ComputeFormVarStatus(glp_prob* const problem, const int num_cstrs,
89  const int k) {
90  return k <= num_cstrs ? glp_get_row_stat(problem, k)
91  : glp_get_col_stat(problem, k - num_cstrs);
92 }
93 
94 // Returns the reduced cost of the variable k of the computational form by
95 // calling either glp_get_row_dual() or glp_get_col_dual().
96 //
97 // See ComputeFormVarStatus() for details about k.
98 inline double ComputeFormVarReducedCost(glp_prob* const problem,
99  const int num_cstrs, const int k) {
100  return k <= num_cstrs ? glp_get_row_dual(problem, k)
101  : glp_get_col_dual(problem, k - num_cstrs);
102 }
103 
104 // Returns the primal value of the variable k of the computational form by
105 // calling either glp_get_row_prim() or glp_get_col_prim().
106 //
107 // See ComputeFormVarStatus() for details about k.
108 inline double ComputeFormVarPrimalValue(glp_prob* const problem,
109  const int num_cstrs, const int k) {
110  return k <= num_cstrs ? glp_get_row_prim(problem, k)
111  : glp_get_col_prim(problem, k - num_cstrs);
112 }
113 
114 // Returns the lower bound of the variable k of the computational form by
115 // calling either glp_get_row_lb() or glp_get_col_lb().
116 //
117 // See ComputeFormVarStatus() for details about k.
118 inline double ComputeFormVarLowerBound(glp_prob* const problem,
119  const int num_cstrs, const int k) {
120  return k <= num_cstrs ? glp_get_row_lb(problem, k)
121  : glp_get_col_lb(problem, k - num_cstrs);
122 }
123 
124 // Returns the upper bound of the variable k of the computational form by
125 // calling either glp_get_row_ub() or glp_get_col_ub().
126 //
127 // See ComputeFormVarStatus() for details about k.
128 inline double ComputeFormVarUpperBound(glp_prob* const problem,
129  const int num_cstrs, const int k) {
130  return k <= num_cstrs ? glp_get_row_ub(problem, k)
131  : glp_get_col_ub(problem, k - num_cstrs);
132 }
133 
134 } // namespace operations_research
135 
136 #endif // OR_TOOLS_GLPK_GLPK_COMPUTATIONAL_FORM_H_
Collection of objects used to extend the Constraint Solver library.
double ComputeFormVarPrimalValue(glp_prob *const problem, const int num_cstrs, const int k)
int ComputeFormVarStatus(glp_prob *const problem, const int num_cstrs, const int k)
double ComputeFormVarReducedCost(glp_prob *const problem, const int num_cstrs, const int k)
double ComputeFormVarLowerBound(glp_prob *const problem, const int num_cstrs, const int k)
double ComputeFormVarUpperBound(glp_prob *const problem, const int num_cstrs, const int k)