relp/algorithm/two_phase/
phase_two.rs1use crate::algorithm::OptimizationResult;
3use crate::algorithm::two_phase::matrix_provider::column::Column;
4use crate::algorithm::two_phase::matrix_provider::MatrixProvider;
5use crate::algorithm::two_phase::strategy::pivot_rule::PivotRule;
6use crate::algorithm::two_phase::tableau::{debug_assert_in_basic_feasible_solution_state, Tableau};
7use crate::algorithm::two_phase::tableau::inverse_maintenance::{ColumnComputationInfo, InverseMaintainer, ops as im_ops};
8use crate::algorithm::two_phase::tableau::kind::non_artificial::NonArtificial;
9
10pub fn primal<'provider, IM, MP, PR>(
23 tableau: &mut Tableau<IM, NonArtificial<'provider, MP>>,
24) -> OptimizationResult<IM::F>
25where
26 IM: InverseMaintainer<F:
27 im_ops::FieldHR +
28 im_ops::Column<<MP::Column as Column>::F> +
29 im_ops::Cost<MP::Cost<'provider>> +
30 >,
31 MP: MatrixProvider,
32 PR: PivotRule<IM::F>,
33{
34 let mut rule = PR::new(tableau);
35
36 loop {
37 debug_assert!({
38 debug_assert_in_basic_feasible_solution_state(&tableau);
39 true
40 });
41
42 match rule.select_primal_pivot_column(tableau) {
43 Some((pivot_column_index, cost)) => {
44 let column_with_info = tableau.generate_column(pivot_column_index);
45 match tableau.select_primal_pivot_row(column_with_info.column()) {
46 Some(pivot_row_index) => {
47 let basis_change_computation_info = tableau.bring_into_basis(
48 pivot_column_index, pivot_row_index,
49 column_with_info, cost,
50 );
51 rule.after_basis_update(basis_change_computation_info,&tableau);
52 }
53 None => break OptimizationResult::Unbounded,
54 }
55 }
56 None => break OptimizationResult::FiniteOptimum(tableau.current_bfs()),
57 }
58 }
59}