Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
initial_basis.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#ifndef OR_TOOLS_GLOP_INITIAL_BASIS_H_
15#define OR_TOOLS_GLOP_INITIAL_BASIS_H_
16
17#include <vector>
18
22
23namespace operations_research {
24namespace glop {
25
26// This class implements two initial basis algorithms. The idea is to replace as
27// much as possible the columns of B that correspond to fixed slack variables
28// with some column of A in order to have more freedom in the values the basic
29// variables can take.
30//
31// The first algorithm is Bixby's initial basis algorithm, described in the
32// paper below. It considers the columns of A in a particular order (the ones
33// with more freedom first) and adds the current column to the basis if it keeps
34// B almost triangular and with coefficients close to 1.0 on the diagonal for
35// good numerical stability.
36//
37// Robert E. Bixby, "Implementing the Simplex Method: The Initial Basis"
38// ORSA Jounal on Computing, Vol. 4, No. 3, Summer 1992.
39// http://joc.journal.informs.org/content/4/3/267.abstract
40//
41// The second algorithm is is similar to the "advanced initial basis" that GLPK
42// uses by default. It adds columns one by one to the basis B while keeping it
43// triangular (not almost triangular as in Bixby's algorithm). The next
44// column to add is chosen amongst the set of possible candidates using a
45// heuristic similar to the one used by Bixby.
47 public:
48 // Takes references to the linear program data we need.
49 InitialBasis(const CompactSparseMatrix& compact_matrix,
50 const DenseRow& objective, const DenseRow& lower_bound,
51 const DenseRow& upper_bound,
52 const VariableTypeRow& variable_type);
53
54 // This type is neither copyable nor movable.
55 InitialBasis(const InitialBasis&) = delete;
57
58 // Completes the entries of the given basis that are equal to kInvalidCol with
59 // one of the first num_cols columns of A using Bixby's algorithm.
60 //
61 // Important: For this function, the matrix must be scaled such that the
62 // maximum absolute value in each column is 1.0.
63 void CompleteBixbyBasis(ColIndex num_cols, RowToColMapping* basis);
64
65 // Similar to CompleteBixbyBasis() but completes the basis into a triangular
66 // one. This function usually produces better initial bases. The dual version
67 // just restricts the possible entering columns to the ones with a cost of 0.0
68 // in order to always start with the all-zeros vector of dual values.
69 //
70 // Returns false if an error occurred during the algorithm (numerically
71 // instable basis).
72 void CompleteTriangularPrimalBasis(ColIndex num_cols, RowToColMapping* basis);
73 void CompleteTriangularDualBasis(ColIndex num_cols, RowToColMapping* basis);
74
75 // Use Maros's LTSF crash from the book "Computational Techniques of the
76 // Simplex Method". Unlike the other crashes this does not use the initial
77 // content of the basis parameter.
78 void GetPrimalMarosBasis(ColIndex num_cols, RowToColMapping* basis);
79 void GetDualMarosBasis(ColIndex num_cols, RowToColMapping* basis);
80
81 // Visible for testing. Computes a list of candidate column indices out of the
82 // fist num_candidate_columns of A and sorts them using the
83 // bixby_column_comparator_. This also fills max_scaled_abs_cost_.
84 void ComputeCandidates(ColIndex num_cols, std::vector<ColIndex>* candidates);
85
86 private:
87 // Internal implementation of the Primal/Dual CompleteTriangularBasis().
88 template <bool only_allow_zero_cost_column>
89 void CompleteTriangularBasis(ColIndex num_cols, RowToColMapping* basis);
90
91 template <bool only_allow_zero_cost_column>
92 void GetMarosBasis(ColIndex num_cols, RowToColMapping* basis);
93
94 // Returns an integer representing the order (the lower the better)
95 // between column categories (known as C2, C3 or C4 in the paper).
96 // Also returns a greater index for fixed columns.
97 int GetColumnCategory(ColIndex col) const;
98
99 // Row and column priorities for Maros crash.
100 int GetMarosPriority(RowIndex row) const;
101 int GetMarosPriority(ColIndex col) const;
102
103 // Returns the penalty (the lower the better) of a column. This is 'q_j' for a
104 // column 'j' in the paper.
105 Fractional GetColumnPenalty(ColIndex col) const;
106
107 // Maximum scaled absolute value of the objective for the columns which are
108 // entering candidates. This is used by GetColumnPenalty().
109 Fractional max_scaled_abs_cost_;
110
111 // Comparator used to sort column indices according to their penalty.
112 // Lower is better.
113 struct BixbyColumnComparator {
114 explicit BixbyColumnComparator(const InitialBasis& initial_basis)
115 : initial_basis_(initial_basis) {}
116 bool operator()(ColIndex col_a, ColIndex col_b) const;
117 const InitialBasis& initial_basis_;
118 } bixby_column_comparator_;
119
120 // Comparator used by CompleteTriangularBasis(). Note that this one is meant
121 // to be used by a priority queue, so higher is better.
122 struct TriangularColumnComparator {
123 explicit TriangularColumnComparator(const InitialBasis& initial_basis)
124 : initial_basis_(initial_basis) {}
125 bool operator()(ColIndex col_a, ColIndex col_b) const;
126 const InitialBasis& initial_basis_;
127 } triangular_column_comparator_;
128
129 const CompactSparseMatrix& compact_matrix_;
130 const DenseRow& objective_;
131 const DenseRow& lower_bound_;
132 const DenseRow& upper_bound_;
133 const VariableTypeRow& variable_type_;
134};
135
136} // namespace glop
137} // namespace operations_research
138
139#endif // OR_TOOLS_GLOP_INITIAL_BASIS_H_
void CompleteTriangularPrimalBasis(ColIndex num_cols, RowToColMapping *basis)
InitialBasis(const CompactSparseMatrix &compact_matrix, const DenseRow &objective, const DenseRow &lower_bound, const DenseRow &upper_bound, const VariableTypeRow &variable_type)
Takes references to the linear program data we need.
void CompleteBixbyBasis(ColIndex num_cols, RowToColMapping *basis)
void GetPrimalMarosBasis(ColIndex num_cols, RowToColMapping *basis)
InitialBasis(const InitialBasis &)=delete
This type is neither copyable nor movable.
void ComputeCandidates(ColIndex num_cols, std::vector< ColIndex > *candidates)
void GetDualMarosBasis(ColIndex num_cols, RowToColMapping *basis)
void CompleteTriangularDualBasis(ColIndex num_cols, RowToColMapping *basis)
InitialBasis & operator=(const InitialBasis &)=delete
double upper_bound
double lower_bound
ColIndex col
Definition markowitz.cc:187
RowIndex row
Definition markowitz.cc:186
StrictITIVector< ColIndex, VariableType > VariableTypeRow
Row of variable types.
Definition lp_types.h:371
StrictITIVector< ColIndex, Fractional > DenseRow
Row-vector types. Row-vector types are indexed by a column index.
Definition lp_types.h:353
In SWIG mode, we don't want anything besides these top-level includes.