pub(super) fn presolve_step(&mut self) -> Result<Change, LinearProgramType<OF>> {
        // Rules that are guaranteed to make the problem smaller
        if let Some(variable) = self.queues.substitution.pop() {
            return self.presolve_fixed_variable(variable)
                // always removes a variable
                .map(|()| Change::Meaningful);
        }
        while let Some(constraint) = self.queues.bound.pop() {
            if self.counters.is_constraint_still_active(constraint) {
                return self.presolve_bound_constraint(constraint)
                    // always removes a constraint
                    .map(|()| Change::Meaningful);
            }
        }
        while let Some(variable) = self.queues.slack.pop() {
            if self.counters.is_variable_still_active(variable) {
                return self.presolve_slack(variable)
                    // always removes a variable
                    .map(|()| Change::Meaningful);
            }
        }

        // Rules not guaranteed to make the problem smaller
        while let Some((constraint, direction)) = self.queues.activity.pop() {
            if self.counters.is_constraint_still_active(constraint) {
                // Rules with higher priority are applied when a row or column counter equals 1.
                debug_assert!(self.counters.constraint[constraint] > 1, "was {}", self.counters.constraint[constraint]);
                return self.presolve_domain_propagation(constraint, direction);
            }
        }

        // TODO(ENHANCEMENT): Duplicate rows and columns.

        // No rule was applied
        Ok(Change::NotMeaningful)
    }
/// Apply a single presolve rule.
///
/// The order of the rules is an estimate of the ratio between how likely a rule yields a useful
/// result, and how expensive it is to apply the rule.
///
/// The following rules are applied:
///
/// 1. Substitute fixed variable
/// 2. Remove a bound constraint
/// 3. Eliminate slack variable
/// 4. Domain propagation (constraint activation bounds)
///
/// Generally, a constraint can only directly influence a variable, not another constraint. The
/// same holds true for variables. As such, we can view the constraints and variables as a
/// biparte graph.
///
/// TODO(ENHANCEMENT): What is the best order to apply the rules in?
/// TODO(ENHANCEMENT): Which element should be removed from the queue first?
///
/// # Arguments
///
/// * `&mut self`: A `PresolveIndex` that lives across repeated calls to this function. It is
/// used to store which constraints and variables need to be checked for which rules. After the
/// application of each rule, constraints and variables might be added to queues in this struct.
///
/// # Return value
///
/// `Ok` indicating whether a "meaningful change" was made. This could for example be a row or
/// column being removed, but also a constraint type being adapted. This is used to avoid
/// never-ending "improvements" of bounds that don't make the problem easier (but numerically
/// harder, unless the problem is rescaled). If the program is determined to be infeasible, an
/// `Err` type.
Apply a single presolve rule.
The order of the rules is an estimate of the ratio between how likely a rule yields a useful
result, and how expensive it is to apply the rule.

The following rules are applied.

1. Substitute fixed variable
2. Remove a bound constraint
3. Eliminate slack variable
4. Domain propagation (constraint activation bounds)

Generally, a constraint can only directly influence a variable, not another constraint. The
same holds true for variables. As such, we can view the constraints and variables as a
biparte graph.


Apply a single presolve rule . The order of the rules is an estimate of the ratio between how likely a rule yields a useful result and how expensive it is to apply the rule . The following rules are applied . 1 . Substitute fixed variable 2 . Remove a bound constraint 3 . Eliminate slack variable 4 . Domain propagation ( constraint activation bounds ) Generally a constraint can only directly influence a variable not another constraint . The same holds true for variables . As such we can view the constraints and variables as a biparte graph .
pub(super) fn presolve_step(&mut self) -> Result<Change, LinearProgramType<OF>> {
        // Rules that are guaranteed to make the problem smaller
        if let Some(variable) = self.queues.substitution.pop() {
            return self.presolve_fixed_variable(variable)
                // always removes a variable
                .map(|()| Change::Meaningful);
        }
        while let Some(constraint) = self.queues.bound.pop() {
            if self.counters.is_constraint_still_active(constraint) {
                return self.presolve_bound_constraint(constraint)
                    // always removes a constraint
                    .map(|()| Change::Meaningful);
            }
        }
        while let Some(variable) = self.queues.slack.pop() {
            if self.counters.is_variable_still_active(variable) {
                return self.presolve_slack(variable)
                    // always removes a variable
                    .map(|()| Change::Meaningful);
            }
        }
        // Rules not guaranteed to make the problem smaller
        while let Some((constraint, direction)) = self.queues.activity.pop() {
            if self.counters.is_constraint_still_active(constraint) {
                // Rules with higher priority are applied when a row or column counter equals 1.
                debug_assert!(self.counters.constraint[constraint] > 1, "was {}", self.counters.constraint[constraint]);
                return self.presolve_domain_propagation(constraint, direction);
            }
        }
        // TODO(ENHANCEMENT): Duplicate rows and columns.
        // No rule was applied
        Ok(Change::NotMeaningful)
    }
pub ( super ) fn presolve_step ( & mut self ) -> Result < Change , LinearProgramType < OF > > { // Rules that are guaranteed to make the problem smaller if let Some ( variable ) = self . queues . substitution . pop ( ) { return self . presolve_fixed_variable ( variable ) // always removes a variable . map ( | ( ) | Change :: Meaningful ) ; } while let Some ( constraint ) = self . queues . bound . pop ( ) { if self . counters . is_constraint_still_active ( constraint ) { return self . presolve_bound_constraint ( constraint ) // always removes a constraint . map ( | ( ) | Change :: Meaningful ) ; } } while let Some ( variable ) = self . queues . slack . pop ( ) { if self . counters . is_variable_still_active ( variable ) { return self . presolve_slack ( variable ) // always removes a variable . map ( | ( ) | Change :: Meaningful ) ; } } // Rules not guaranteed to make the problem smaller while let Some ( ( constraint , direction ) ) = self . queues . activity . pop ( ) { if self . counters . is_constraint_still_active ( constraint ) { // Rules with higher priority are applied when a row or column counter equals 1. debug_assert ! ( self counters constraint [ constraint ] 1 " " self counters constraint [ constraint ] ) ; return self . presolve_domain_propagation ( constraint , direction ) ; } } // TODO(ENHANCEMENT): Duplicate rows and columns. // No rule was applied Ok ( Change :: NotMeaningful ) }
Apply a single presolve rule.
Apply a single presolve rule .
&mut self
&mut self
return value
`Ok` indicating whether a "meaningful change" was made. This could for example be a row or
column being removed, but also a constraint type being adapted. This is used to avoid
never-ending "improvements" of bounds that don't make the problem easier (but numerically
harder, unless the problem is rescaled). If the program is determined to be infeasible, an
`Err` type.
` Ok ` indicating whether a " meaningful change " was made . This could for example be a row or column being removed but also a constraint type being adapted . This is used to avoid never - ending " improvements " of bounds that don ' t make the problem easier ( but numerically harder unless the problem is rescaled ) . If the program is determined to be infeasible an ` Err ` type .