19#include "absl/log/check.h"
31 const ColIndex num_cols = matrix_.
num_cols();
32 DCHECK_EQ(num_cols, new_lower_bounds.
size());
33 DCHECK_EQ(num_cols, new_upper_bounds.
size());
36 if (lower_bounds_ == new_lower_bounds && upper_bounds_ == new_upper_bounds) {
40 lower_bounds_ = new_lower_bounds;
41 upper_bounds_ = new_upper_bounds;
43 for (ColIndex
col(0);
col < num_cols; ++
col) {
44 variable_type_[
col] = ComputeVariableType(
col);
50 const DenseRow& variable_lower_bounds,
51 const DenseRow& variable_upper_bounds,
54 const ColIndex num_cols = matrix_.
num_cols();
55 const ColIndex num_variables = variable_upper_bounds.
size();
56 const RowIndex num_rows = constraint_lower_bounds.
size();
58 bool is_unchanged = (num_cols == lower_bounds_.
size());
60 lower_bounds_.
resize(num_cols, 0.0);
61 upper_bounds_.
resize(num_cols, 0.0);
65 for (ColIndex
col(0);
col < num_variables; ++
col) {
66 if (lower_bounds_[
col] != variable_lower_bounds[
col] ||
67 upper_bounds_[
col] != variable_upper_bounds[
col]) {
68 lower_bounds_[
col] = variable_lower_bounds[
col];
69 upper_bounds_[
col] = variable_upper_bounds[
col];
71 variable_type_[
col] = ComputeVariableType(
col);
76 for (RowIndex
row(0);
row < num_rows; ++
row) {
78 if (lower_bounds_[
col] != -constraint_upper_bounds[
row] ||
79 upper_bounds_[
col] != -constraint_lower_bounds[
row]) {
80 lower_bounds_[
col] = -constraint_upper_bounds[
row];
81 upper_bounds_[
col] = -constraint_lower_bounds[
row];
83 variable_type_[
col] = ComputeVariableType(
col);
90void VariablesInfo::ResetStatusInfo() {
91 const ColIndex num_cols = matrix_.
num_cols();
92 DCHECK_EQ(num_cols, lower_bounds_.
size());
93 DCHECK_EQ(num_cols, upper_bounds_.
size());
107 boxed_variables_are_relevant_ =
true;
108 num_entries_in_relevant_columns_ = 0;
113 ColIndex num_new_cols,
117 const ColIndex num_cols = lower_bounds_.
size();
118 DCHECK_LE(num_new_cols, first_slack_col);
119 const ColIndex first_new_col(first_slack_col - num_new_cols);
123 for (ColIndex
col(0);
col < num_cols; ++
col) {
128 }
else if (
col >= first_slack_col &&
147 if (lower_bounds_[
col] == upper_bounds_[
col]) {
151 ? DefaultVariableStatus(
col)
156 if (lower_bounds_[
col] == upper_bounds_[
col]) {
160 ? DefaultVariableStatus(
col)
172 const ColIndex num_cols = lower_bounds_.
size();
174 for (
const ColIndex
col : basis) {
177 int num_no_longer_in_basis = 0;
178 for (ColIndex
col(0);
col < num_cols; ++
col) {
180 ++num_no_longer_in_basis;
188 return num_no_longer_in_basis;
194 const ColIndex num_cols = lower_bounds_.
size();
195 for (ColIndex
col(0);
col < num_cols; ++
col) {
199 col < starting_values.
size() ? starting_values[
col] : 0.0;
202 if (diff_lb <= diff_ub) {
219 const ColIndex num_cols = lower_bounds_.
size();
220 for (ColIndex
col(0);
col < num_cols; ++
col) {
227 DCHECK_LT(
col, lower_bounds_.
size());
228 if (lower_bounds_[
col] == upper_bounds_[
col]) {
231 if (lower_bounds_[
col] == -kInfinity && upper_bounds_[
col] == kInfinity) {
238 return std::abs(lower_bounds_[
col]) <= std::abs(upper_bounds_[
col])
244 if (
value == boxed_variables_are_relevant_)
return;
245 boxed_variables_are_relevant_ =
value;
247 for (
const ColIndex
col : non_basic_boxed_variables_) {
251 for (
const ColIndex
col : non_basic_boxed_variables_) {
252 SetRelevance(
col,
false);
258 if (in_dual_phase_one_) {
263 variable_type_[
col] = ComputeVariableType(
col);
267 not_basic_.
Set(
col,
false);
268 can_increase_.
Set(
col,
false);
269 can_decrease_.
Set(
col,
false);
270 non_basic_boxed_variables_.
Set(
col,
false);
271 SetRelevance(
col,
false);
278 is_basic_.
Set(
col,
false);
279 not_basic_.
Set(
col,
true);
287 non_basic_boxed_variables_.
Set(
col, boxed);
289 (boxed_variables_are_relevant_ || !boxed);
290 SetRelevance(
col, relevance);
294 return variable_type_;
298 return variable_status_;
302 return can_increase_;
306 return can_decrease_;
320 return non_basic_boxed_variables_;
324 return num_entries_in_relevant_columns_;
328 DCHECK_LE(lower_bounds_[
col], upper_bounds_[
col]);
329 if (lower_bounds_[
col] == -kInfinity) {
330 if (upper_bounds_[
col] == kInfinity) {
334 }
else if (upper_bounds_[
col] == kInfinity) {
336 }
else if (lower_bounds_[
col] == upper_bounds_[
col]) {
343void VariablesInfo::SetRelevance(ColIndex
col,
bool relevance) {
344 if (relevance_.
IsSet(
col) == relevance)
return;
356void VariablesInfo::UpdateStatusForNewType(ColIndex
col) {
357 switch (variable_status_[
col]) {
362 if (lower_bounds_[
col] == upper_bounds_[
col]) {
364 }
else if (lower_bounds_[
col] == -kInfinity) {
374 if (lower_bounds_[
col] == upper_bounds_[
col]) {
376 }
else if (upper_bounds_[
col] == kInfinity) {
394 DCHECK(!in_dual_phase_one_);
395 in_dual_phase_one_ =
true;
396 saved_lower_bounds_ = lower_bounds_;
397 saved_upper_bounds_ = upper_bounds_;
403 const ColIndex num_cols = matrix_.
num_cols();
404 for (ColIndex
col(0);
col < num_cols; ++
col) {
405 switch (variable_type_[
col]) {
408 lower_bounds_[
col] = 0.0;
409 upper_bounds_[
col] = 0.0;
413 lower_bounds_[
col] = 0.0;
414 upper_bounds_[
col] = 1.0;
418 lower_bounds_[
col] = -1.0;
419 upper_bounds_[
col] = 0.0;
423 lower_bounds_[
col] = -1000.0;
424 upper_bounds_[
col] = 1000.0;
432 if (reduced_costs[
col] > dual_feasibility_tolerance) {
434 }
else if (reduced_costs[
col] < -dual_feasibility_tolerance) {
439 UpdateStatusForNewType(
col);
445 DCHECK(in_dual_phase_one_);
446 in_dual_phase_one_ =
false;
447 std::swap(saved_lower_bounds_, lower_bounds_);
448 std::swap(saved_upper_bounds_, upper_bounds_);
453 std::swap(empty1, saved_lower_bounds_);
454 std::swap(empty1, saved_upper_bounds_);
457 const ColIndex num_cols = matrix_.
num_cols();
458 for (ColIndex
col(0);
col < num_cols; ++
col) {
459 variable_type_[
col] = ComputeVariableType(
col);
468 if (reduced_costs[
col] > dual_feasibility_tolerance) {
470 }
else if (reduced_costs[
col] < -dual_feasibility_tolerance) {
475 UpdateStatusForNewType(
col);
bool IsSet(IndexType i) const
Returns true if the bit at position i is set.
void Clear(IndexType i)
Sets the bit at position i to 0.
void ClearAndResize(IndexType size)
Changes the number of bits the Bitset64 can hold and set all of them to 0.
void Set(IndexType i)
Sets the bit at position i to 1.
ColIndex num_cols() const
EntryIndex ColumnNumEntries(ColIndex col) const
Returns the number of entries (i.e. degree) of the given column.
StrictITISpan< ColIndex, const Fractional > ConstView
void resize(IntType size)
void TransformToDualPhaseIProblem(Fractional dual_feasibility_tolerance, DenseRow::ConstView reduced_costs)
const DenseBitRow & GetCanDecreaseBitRow() const
const DenseBitRow & GetCanIncreaseBitRow() const
const VariableStatusRow & GetStatusRow() const
const VariableTypeRow & GetTypeRow() const
EntryIndex GetNumEntriesInRelevantColumns() const
void MakeBoxedVariableRelevant(bool value)
const DenseBitRow & GetNotBasicBitRow() const
const DenseBitRow & GetIsRelevantBitRow() const
int ChangeUnusedBasicVariablesToFree(const RowToColMapping &basis)
void UpdateToBasicStatus(ColIndex col)
const DenseBitRow & GetNonBasicBoxedVariables() const
void UpdateToNonBasicStatus(ColIndex col, VariableStatus status)
void EndDualPhaseI(Fractional dual_feasibility_tolerance, DenseRow::ConstView reduced_costs)
bool LoadBoundsAndReturnTrueIfUnchanged(const DenseRow &new_lower_bounds, const DenseRow &new_upper_bounds)
void InitializeFromBasisState(ColIndex first_slack, ColIndex num_new_cols, const BasisState &state)
void InitializeToDefaultStatus()
const DenseBitRow & GetIsBasicBitRow() const
int SnapFreeVariablesToBound(Fractional distance, const DenseRow &starting_values)
VariablesInfo(const CompactSparseMatrix &matrix)
Takes references to the linear program data we need.
constexpr double kInfinity
Infinity for type Fractional.
ColIndex RowToColIndex(RowIndex row)
Get the ColIndex corresponding to the column # row.
bool IsFinite(Fractional value)
VariableType
Different types of variables.
@ UPPER_AND_LOWER_BOUNDED
In SWIG mode, we don't want anything besides these top-level includes.
VariableStatusRow statuses