// Copyright 2010-2018 Google LLC // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef OR_TOOLS_GLOP_VARIABLES_INFO_H_ #define OR_TOOLS_GLOP_VARIABLES_INFO_H_ #include "ortools/lp_data/lp_types.h" #include "ortools/lp_data/sparse.h" namespace operations_research { namespace glop { // Class responsible for maintaining diverse information for each variable that // depend on its bounds and status. // // Note(user): Not all information is needed at all time, but it is cheap to // maintain it since it only requires a few calls to Update() per simplex // iteration. class VariablesInfo { public: // Takes references to the linear program data we need. VariablesInfo(const CompactSparseMatrix& matrix, const DenseRow& lower_bound, const DenseRow& upper_bound); // Recomputes the variable types from the bounds (this is the only function // that changes them). This also resets all the non-type quantities to a // default value. Note however that nothing should be assumed on the return // values of the getters until Update() has been called at least once on all // the columns. void InitializeAndComputeType(); // Updates the information of the given variable. Note that it is not needed // to call this if the status or the bound of a variable didn't change. void Update(ColIndex col, VariableStatus status); // Slightly optimized version of Update() above for the two separate cases. void UpdateToBasicStatus(ColIndex col); void UpdateToNonBasicStatus(ColIndex col, VariableStatus status); // Various getter, see the corresponding member declaration below for more // information. const VariableTypeRow& GetTypeRow() const; const VariableStatusRow& GetStatusRow() const; const DenseBitRow& GetCanIncreaseBitRow() const; const DenseBitRow& GetCanDecreaseBitRow() const; const DenseBitRow& GetIsRelevantBitRow() const; const DenseBitRow& GetIsBasicBitRow() const; const DenseBitRow& GetNotBasicBitRow() const; const DenseBitRow& GetNonBasicBoxedVariables() const; // Returns the variable bounds. const DenseRow& GetVariableLowerBounds() const { return lower_bound_; } const DenseRow& GetVariableUpperBounds() const { return upper_bound_; } const ColIndex GetNumberOfColumns() const { return matrix_.num_cols(); } // Changes whether or not a non-basic boxed variable is 'relevant' and will be // returned as such by GetIsRelevantBitRow(). void MakeBoxedVariableRelevant(bool value); // This is used in UpdateRow to decide whether to compute it using the // row-wise or column-wise representation. EntryIndex GetNumEntriesInRelevantColumns() const; // Returns the distance between the upper and lower bound of the given column. Fractional GetBoundDifference(ColIndex col) const { return upper_bound_[col] - lower_bound_[col]; } private: // Computes the variable type from its lower and upper bound. VariableType ComputeVariableType(ColIndex col) const; // Sets the column relevance and updates num_entries_in_relevant_columns_. void SetRelevance(ColIndex col, bool relevance); // Problem data that should be updated from outside. const CompactSparseMatrix& matrix_; const DenseRow& lower_bound_; const DenseRow& upper_bound_; // Array of variable statuses, indexed by column index. VariableStatusRow variable_status_; // Array of variable types, indexed by column index. VariableTypeRow variable_type_; // Indicates if a non-basic variable can move up or down while not increasing // the primal infeasibility. Note that all combinaisons are possible for a // variable according to its status: fixed, free, upper or lower bounded. This // is always false for basic variable. DenseBitRow can_increase_; DenseBitRow can_decrease_; // Indicates if we should consider this variable for entering the basis during // the simplex algorithm. We never consider fixed variables and in the dual // feasibility phase, we don't consider boxed variable. DenseBitRow relevance_; // Indicates if a variable is BASIC or not. There are currently two members // because the DenseBitRow class only supports a nice range-based iteration on // the non-zero positions and not on the others. DenseBitRow is_basic_; DenseBitRow not_basic_; // Set of boxed variables that are non-basic. DenseBitRow non_basic_boxed_variables_; // Number of entries for the relevant matrix columns (see relevance_). EntryIndex num_entries_in_relevant_columns_; // Whether or not a boxed variable should be considered relevant. bool boxed_variables_are_relevant_; DISALLOW_COPY_AND_ASSIGN(VariablesInfo); }; } // namespace glop } // namespace operations_research #endif // OR_TOOLS_GLOP_VARIABLES_INFO_H_