2024-01-04 13:43:15 +01:00
|
|
|
// Copyright 2010-2024 Google LLC
|
2014-07-08 17:35:15 +00:00
|
|
|
// 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.
|
2014-07-09 15:18:27 +00:00
|
|
|
|
2014-07-08 09:27:02 +00:00
|
|
|
#ifndef OR_TOOLS_GLOP_ENTERING_VARIABLE_H_
|
|
|
|
|
#define OR_TOOLS_GLOP_ENTERING_VARIABLE_H_
|
|
|
|
|
|
2021-05-03 12:12:42 +02:00
|
|
|
#include <cstdint>
|
2022-03-25 15:10:39 +01:00
|
|
|
#include <string>
|
2022-07-22 14:35:40 +02:00
|
|
|
#include <vector>
|
2021-05-03 12:12:42 +02:00
|
|
|
|
2021-04-13 14:31:06 +02:00
|
|
|
#include "absl/random/bit_gen_ref.h"
|
2017-04-26 17:30:25 +02:00
|
|
|
#include "ortools/glop/basis_representation.h"
|
|
|
|
|
#include "ortools/glop/parameters.pb.h"
|
|
|
|
|
#include "ortools/glop/primal_edge_norms.h"
|
|
|
|
|
#include "ortools/glop/reduced_costs.h"
|
|
|
|
|
#include "ortools/glop/status.h"
|
|
|
|
|
#include "ortools/glop/update_row.h"
|
|
|
|
|
#include "ortools/glop/variables_info.h"
|
|
|
|
|
#include "ortools/lp_data/lp_data.h"
|
|
|
|
|
#include "ortools/lp_data/lp_types.h"
|
|
|
|
|
#include "ortools/util/bitset.h"
|
|
|
|
|
#include "ortools/util/stats.h"
|
2014-07-08 09:27:02 +00:00
|
|
|
|
|
|
|
|
#if !SWIG
|
|
|
|
|
|
|
|
|
|
namespace operations_research {
|
|
|
|
|
namespace glop {
|
|
|
|
|
|
2021-04-14 14:33:47 +02:00
|
|
|
// This class contains the dual algorithms that choose the entering column (i.e.
|
|
|
|
|
// variable) during a dual simplex iteration. That is the dual ratio test.
|
2014-07-08 09:27:02 +00:00
|
|
|
//
|
|
|
|
|
// Terminology:
|
|
|
|
|
// - The entering edge is the edge we are following during a simplex step,
|
|
|
|
|
// and we call "direction" the reverse of this edge restricted to the
|
|
|
|
|
// basic variables, i.e. the right inverse of the entering column.
|
|
|
|
|
class EnteringVariable {
|
2020-10-22 23:36:58 +02:00
|
|
|
public:
|
2014-07-08 09:27:02 +00:00
|
|
|
// Takes references to the linear program data we need.
|
2021-04-13 14:31:06 +02:00
|
|
|
EnteringVariable(const VariablesInfo& variables_info, absl::BitGenRef random,
|
2021-04-14 14:33:47 +02:00
|
|
|
ReducedCosts* reduced_costs);
|
2014-07-08 09:27:02 +00:00
|
|
|
|
2023-08-30 10:04:47 -04:00
|
|
|
// This type is neither copyable nor movable.
|
|
|
|
|
EnteringVariable(const EnteringVariable&) = delete;
|
|
|
|
|
EnteringVariable& operator=(const EnteringVariable&) = delete;
|
|
|
|
|
|
2014-07-08 09:27:02 +00:00
|
|
|
// Dual optimization phase (i.e. phase II) ratio test.
|
|
|
|
|
// Returns the index of the entering column given that we want to move along
|
|
|
|
|
// the "update" row vector in the direction given by the sign of
|
|
|
|
|
// cost_variation. Computes the smallest step that keeps the dual feasibility
|
2018-07-25 10:21:35 -07:00
|
|
|
// for all the columns.
|
2020-10-22 23:36:58 +02:00
|
|
|
ABSL_MUST_USE_RESULT Status DualChooseEnteringColumn(
|
2021-03-24 20:59:34 +01:00
|
|
|
bool nothing_to_recompute, const UpdateRow& update_row,
|
|
|
|
|
Fractional cost_variation, std::vector<ColIndex>* bound_flip_candidates,
|
2021-03-25 22:38:06 +01:00
|
|
|
ColIndex* entering_col);
|
2014-07-08 09:27:02 +00:00
|
|
|
|
|
|
|
|
// Dual feasibility phase (i.e. phase I) ratio test.
|
|
|
|
|
// Similar to the optimization phase test, but allows a step that increases
|
|
|
|
|
// the infeasibility of an already infeasible column. The step magnitude is
|
|
|
|
|
// the one that minimize the sum of infeasibilities when applied.
|
2020-10-22 23:36:58 +02:00
|
|
|
ABSL_MUST_USE_RESULT Status DualPhaseIChooseEnteringColumn(
|
2021-03-24 20:59:34 +01:00
|
|
|
bool nothing_to_recompute, const UpdateRow& update_row,
|
2021-03-25 22:38:06 +01:00
|
|
|
Fractional cost_variation, ColIndex* entering_col);
|
2014-07-08 09:27:02 +00:00
|
|
|
|
2021-04-14 14:33:47 +02:00
|
|
|
// Sets the parameters.
|
2020-10-29 14:25:39 +01:00
|
|
|
void SetParameters(const GlopParameters& parameters);
|
2014-07-08 09:27:02 +00:00
|
|
|
|
|
|
|
|
// Stats related functions.
|
|
|
|
|
std::string StatString() const { return stats_.StatString(); }
|
|
|
|
|
|
2021-03-23 17:55:40 +01:00
|
|
|
// Deterministic time used by some of the functions of this class.
|
|
|
|
|
//
|
|
|
|
|
// TODO(user): Be exhausitive and more precise.
|
|
|
|
|
double DeterministicTime() const {
|
|
|
|
|
return DeterministicTimeForFpOperations(num_operations_);
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-22 23:36:58 +02:00
|
|
|
private:
|
2014-07-08 09:27:02 +00:00
|
|
|
// Problem data that should be updated from outside.
|
2020-10-29 14:25:39 +01:00
|
|
|
const VariablesInfo& variables_info_;
|
2014-07-08 09:27:02 +00:00
|
|
|
|
2021-04-13 14:31:06 +02:00
|
|
|
absl::BitGenRef random_;
|
2020-10-29 14:25:39 +01:00
|
|
|
ReducedCosts* reduced_costs_;
|
2014-07-08 09:27:02 +00:00
|
|
|
|
|
|
|
|
// Internal data.
|
|
|
|
|
GlopParameters parameters_;
|
|
|
|
|
|
|
|
|
|
// Stats.
|
|
|
|
|
struct Stats : public StatsGroup {
|
|
|
|
|
Stats()
|
|
|
|
|
: StatsGroup("EnteringVariable"),
|
|
|
|
|
num_perfect_ties("num_perfect_ties", this) {}
|
|
|
|
|
IntegerDistribution num_perfect_ties;
|
|
|
|
|
};
|
|
|
|
|
Stats stats_;
|
|
|
|
|
|
|
|
|
|
// Temporary vector used to hold the best entering column candidates that are
|
|
|
|
|
// tied using the current choosing criteria. We actually only store the tied
|
|
|
|
|
// candidate #2, #3, ...; because the first tied candidate is remembered
|
|
|
|
|
// anyway.
|
|
|
|
|
std::vector<ColIndex> equivalent_entering_choices_;
|
|
|
|
|
|
2017-11-10 18:31:37 +01:00
|
|
|
// Store a column with its update coefficient and ratio.
|
|
|
|
|
// This is used during the dual phase I & II ratio tests.
|
|
|
|
|
struct ColWithRatio {
|
2022-11-10 11:28:22 +01:00
|
|
|
ColWithRatio() = default;
|
2017-11-10 18:31:37 +01:00
|
|
|
ColWithRatio(ColIndex _col, Fractional reduced_cost, Fractional coeff_m)
|
|
|
|
|
: col(_col), ratio(reduced_cost / coeff_m), coeff_magnitude(coeff_m) {}
|
|
|
|
|
|
|
|
|
|
// Returns false if "this" is before "other" in a priority queue.
|
2020-10-29 14:25:39 +01:00
|
|
|
bool operator<(const ColWithRatio& other) const {
|
2017-11-10 18:31:37 +01:00
|
|
|
if (ratio == other.ratio) {
|
|
|
|
|
if (coeff_magnitude == other.coeff_magnitude) {
|
|
|
|
|
return col > other.col;
|
|
|
|
|
}
|
|
|
|
|
return coeff_magnitude < other.coeff_magnitude;
|
|
|
|
|
}
|
|
|
|
|
return ratio > other.ratio;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ColIndex col;
|
|
|
|
|
Fractional ratio;
|
|
|
|
|
Fractional coeff_magnitude;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Temporary vector used to hold breakpoints.
|
|
|
|
|
std::vector<ColWithRatio> breakpoints_;
|
|
|
|
|
|
2021-03-23 17:55:40 +01:00
|
|
|
// Counter for the deterministic time.
|
2021-04-01 12:13:35 +02:00
|
|
|
int64_t num_operations_ = 0;
|
2014-07-08 09:27:02 +00:00
|
|
|
};
|
|
|
|
|
|
2020-10-22 23:36:58 +02:00
|
|
|
} // namespace glop
|
|
|
|
|
} // namespace operations_research
|
2014-07-08 09:27:02 +00:00
|
|
|
|
2020-10-22 23:36:58 +02:00
|
|
|
#endif // SWIG
|
|
|
|
|
#endif // OR_TOOLS_GLOP_ENTERING_VARIABLE_H_
|