enable setting random generator on glop

This commit is contained in:
Laurent Perron
2025-04-08 17:29:17 +02:00
parent a5bbbcbcff
commit 7f009bded5
6 changed files with 41 additions and 9 deletions

View File

@@ -74,12 +74,14 @@ class EnteringVariable {
// Sets the parameters.
void SetParameters(const GlopParameters& parameters);
void SetRandom(absl::BitGenRef random) { random_ = random; }
// Stats related functions.
std::string StatString() const { return stats_.StatString(); }
// Deterministic time used by some of the functions of this class.
//
// TODO(user): Be exhausitive and more precise.
// TODO(user): Be exhaustive and more precise.
double DeterministicTime() const {
return DeterministicTimeForFpOperations(num_operations_);
}

View File

@@ -24,7 +24,7 @@ package operations_research.glop;
option java_package = "com.google.ortools.glop";
option java_multiple_files = true;
option csharp_namespace = "Google.OrTools.Glop";
// next id = 72
// next id = 73
message GlopParameters {
// Supported algorithms for scaling:
// EQUILIBRATION - progressive scaling by row and column norms until the
@@ -404,6 +404,12 @@ message GlopParameters {
// advanced farther than the other.
optional int32 random_seed = 43 [default = 1];
// Whether to use absl::BitGen instead of MTRandom.
// MOE:begin_strip
// Note that in unit tests if this field is not explicitly set it will be
// default to true. MOE:end_strip
optional bool use_absl_random = 72 [default = false];
// Number of threads in the OMP parallel sections. If left to 1, the code will
// not create any OMP threads and will remain single-threaded.
optional int32 num_omp_threads = 44 [default = 1];

View File

@@ -76,6 +76,8 @@ class DynamicMaximum {
// Removes the given index from the set of candidates.
void Remove(Index position);
void SetRandom(absl::BitGenRef random) { random_ = random; }
// Adds an element to the set of candidate and sets its value. If the element
// is already present, this updates its value. The value must be finite.
void AddOrUpdate(Index position, Fractional value);

View File

@@ -67,6 +67,8 @@ class ReducedCosts {
// next call to GetReducedCosts().
bool NeedsBasisRefactorization() const;
void SetRandom(absl::BitGenRef random) { random_ = random; }
// Checks the precision of the entering variable choice now that the direction
// is computed. Returns its precise version. This will also trigger a
// reduced cost recomputation if it was deemed too imprecise.
@@ -307,6 +309,8 @@ class PrimalPrices {
// the basis during a primal simplex iterations.
ColIndex GetBestEnteringColumn();
void SetRandom(absl::BitGenRef random) { prices_.SetRandom(random); }
// Similar to the other UpdateBeforeBasisPivot() functions.
//
// Important: Both the primal norms and reduced costs must have been updated

View File

@@ -97,7 +97,9 @@ constexpr const uint64_t kDeterministicSeed = 42;
namespace {
bool UseAbslRandom() { return false; }
bool UseAbslRandom(const GlopParameters& parameters) {
return parameters.use_absl_random();
}
} // namespace
@@ -108,8 +110,7 @@ RevisedSimplex::RevisedSimplex()
variable_name_(),
direction_(),
error_(),
random_(UseAbslRandom() ? absl::BitGenRef(absl_random_)
: absl::BitGenRef(deterministic_random_)),
random_(absl::BitGenRef(deterministic_random_)),
basis_factorization_(&compact_matrix_, &basis_),
variables_info_(compact_matrix_),
primal_edge_norms_(compact_matrix_, variables_info_,
@@ -876,7 +877,7 @@ void RevisedSimplex::UpdateBasis(ColIndex entering_col, RowIndex basis_row,
DCHECK(variables_info_.GetIsBasicBitRow().IsSet(leaving_col));
// Make leaving_col leave the basis and update relevant data.
// Note thate the leaving variable value is not necessarily at its exact
// Note that the leaving variable value is not necessarily at its exact
// bound, which is like a bound shift.
variables_info_.UpdateToNonBasicStatus(leaving_col, leaving_variable_status);
DCHECK(leaving_variable_status == VariableStatus::AT_UPPER_BOUND ||
@@ -3678,10 +3679,21 @@ Fractional RevisedSimplex::ComputeInitialProblemObjectiveValue() const {
return objective_scaling_factor_ * (sum + objective_offset_);
}
void RevisedSimplex::SetRandom(absl::BitGenRef random) {
random_ = random;
dual_prices_.SetRandom(random_);
entering_variable_.SetRandom(random_);
reduced_costs_.SetRandom(random_);
primal_prices_.SetRandom(random_);
}
void RevisedSimplex::SetParameters(const GlopParameters& parameters) {
SCOPED_TIME_STAT(&function_stats_);
deterministic_random_.seed(parameters.random_seed());
absl_random_ = absl::BitGen(absl::SeedSeq({parameters.random_seed()}));
SetRandom((UseAbslRandom(parameters)
? absl::BitGenRef(absl_random_)
: absl::BitGenRef(deterministic_random_)));
initial_parameters_ = parameters;
parameters_ = parameters;
PropagateParameters();
@@ -3911,7 +3923,7 @@ void RevisedSimplex::ComputeBasicVariablesForState(
void RevisedSimplex::DisplayRevisedSimplexDebugInfo() {
if (VLOG_IS_ON(3)) {
// This function has a complexity in O(num_non_zeros_in_matrix).
variable_name_.resize(num_cols_, "");
DisplayInfoOnVariables();
std::string output = "z = " + StringifyWithFlags(ComputeObjectiveValue());
@@ -3944,10 +3956,11 @@ void RevisedSimplex::DisplayRevisedSimplexDebugInfo() {
}
}
void RevisedSimplex::DisplayProblem() const {
void RevisedSimplex::DisplayProblem() {
// This function has a complexity in O(num_rows * num_cols *
// num_non_zeros_in_row).
if (VLOG_IS_ON(3)) {
variable_name_.resize(num_cols_, "");
DisplayInfoOnVariables();
std::string output = "min: ";
bool has_objective = false;

View File

@@ -248,6 +248,11 @@ class RevisedSimplex {
void SetLogger(SolverLogger* logger) { logger_ = logger; }
// Note: SetParameters() calls SetRandom() on its implementation, so if you
// want to set the parameters and then set the random generator, you should
// call SetRandom() after SetParameters().
void SetRandom(absl::BitGenRef random);
// Advanced usage. For fast incremental call to the solver, it is better not
// to use LinearProgram at all. This api allows to directly modify the
// internal data of glop and then call solve.
@@ -376,7 +381,7 @@ class RevisedSimplex {
void DisplayRevisedSimplexDebugInfo();
// Displays the Linear Programming problem as it was input.
void DisplayProblem() const;
void DisplayProblem();
// Returns the current objective value. This is just the sum of the current
// variable values times their current cost.