#[non_exhaustive]pub struct Sensitivity {
pub basic_variables: Vec<String>,
pub from_final_tableau: bool,
pub constraints: Vec<ConstraintSensitivity>,
pub variables: Vec<VariableSensitivity>,
pub degenerate: bool,
pub alternative_optima: bool,
}Expand description
Sensitivity analysis of an optimal solution, read from its final basis.
Everything is expressed in terms of the original problem (its own sense, constraints and variables), whatever method produced the solution.
use simplex_trace::{solve, Method, Options, Problem, Relation, ratio};
// Wyndor Glass Co.: max 3x1 + 5x2
let problem = Problem::maximize([3, 5])
.subject_to([1, 0], Relation::Le, 4)
.subject_to([0, 2], Relation::Le, 12)
.subject_to([3, 2], Relation::Le, 18);
let solution = solve(&problem, Method::Simplex, &Options::default()).unwrap();
let s = solution.sensitivity.unwrap();
// One more unit of resource 2 is worth 3/2, as long as b2 stays within [6, 18].
assert_eq!(s.constraints[1].shadow_price, ratio(3, 2));
assert_eq!(s.constraints[1].rhs_range.lower, Some(ratio(6, 1)));
assert_eq!(s.constraints[1].rhs_range.upper, Some(ratio(18, 1)));
// (2, 6) stays optimal while c1 is within [0, 15/2].
assert_eq!(s.variables[0].cost_range.upper, Some(ratio(15, 2)));
print!("{s}");Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.basic_variables: Vec<String>Basic columns of the basis the analysis is read from, one per non-redundant row, by
name: a variable, a slack (s2), or a part of a free or non-positive variable (x1+,
x1-).
from_final_tableau: boolThe analysis is read from the final tableau of the trace (minus the rows of redundant
equalities), so every Source points at one of its cells.
false only with Big-M, when an artificial variable is left in the basis at zero in a
row that is not redundant: that is not a basis of the real problem. The artificial is
then pivoted out and the real objective re-optimized from there, which only takes
degenerate pivots (any other pivot would improve an optimal solution), so the
solution is the same but the basis differs, and no Source is given.
constraints: Vec<ConstraintSensitivity>One entry per constraint of the problem, in order.
variables: Vec<VariableSensitivity>One entry per original variable, in order.
degenerate: boolSome basic variable is zero. Shadow prices are then only valid in one direction (the right-hand-side range has an end at the current value) and may not be unique. A free variable at zero does not count: it can move both ways.
alternative_optima: boolSome nonbasic column (variable or slack) has a zero reduced cost: other optimal bases, and usually other optimal solutions, exist. The column of a free variable whose other column is basic does not count: it only splits the same value differently.