Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
glpk_computational_form.h
Go to the documentation of this file.
1// Copyright 2010-2024 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
70extern "C" {
71#include <glpk.h>
72}
73
74namespace 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.
88inline 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.
98inline 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.
108inline 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.
118inline 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.
128inline 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_
In SWIG mode, we don't want anything besides these top-level includes.
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)