pub(crate) fn new(provider: &'provider MP) -> Self
    where
        MP: PartialInitialBasis
    {
        let m = provider.nr_rows();

        // (row index, column index) coordinate tuples of suitable pivots in a slack column.
        let real = provider.pivot_element_indices();
        debug_assert!(real.is_sorted_by_key(|&(row, _column)| row));
        // Amount of slack variables that can be used for the initial artificial basis.
        let nr_real = real.len();
        // Amount of artificial variables that are still needed. Could be zero.
        let nr_artificial = m - nr_real;

        // Collect the rows that are not in the `real` value. Simple complement of the `real` set.
        let mut artificial = Vec::with_capacity(nr_artificial);
        let mut i = 0;
        for ith_artificial in 0..nr_artificial {
            while i < nr_real && ith_artificial + i == real[i].0 {
                i += 1;
            }
            artificial.push(ith_artificial + i);
            debug_assert!(!real.iter().any(|&(row, _)| row == ith_artificial + i));
        }
        debug_assert!(artificial.iter().all(|&row| row < m));

        // Create the map from the row to column indices where the initial basis elements are.
        //
        // Neither the artificial variables nor the real initial basis variables are necessarily in
        // a uninterrupted range, which is why this block is needed.
        debug_assert!(artificial.is_sorted() && real.is_sorted_by_key(|&(row, _column)| row));
        let mut artificial_counter = 0;
        let basis_indices = (0..m).map(|i| {
            let artificial_column = artificial_counter;
            let real_column = || nr_artificial + real[i - artificial_counter].1;

            let can_take_from_artificial = artificial_counter < nr_artificial;
            let can_take_from_real = i - artificial_counter < nr_real;

            match (can_take_from_artificial, can_take_from_real) {
                (true, true) => {
                    // Which index row is lower?
                    if artificial[artificial_column] < real[i - artificial_counter].0 {
                        artificial_counter += 1;
                        artificial_column
                    } else {
                        real_column()
                    }
                },
                (true, false) => {
                    artificial_counter += 1;
                    artificial_column
                },
                (false, true) => {
                    real_column()
                },
                (false, false) => {
                    unreachable!("If both `ac == nr_a` and `i - ac == nr_r`, loop should have ended")
                },
            }
        }).collect::<Vec<_>>();
        let basis_columns = basis_indices.iter().copied().collect();

        let inverse_maintainer = IM::create_for_partially_artificial(
            &artificial,
            &real,
            provider.right_hand_side(),
            basis_indices,
        );

        Tableau {
            inverse_maintainer,
            basis_columns,

            kind: Partially {
                column_to_row: artificial,

                provider,
            },
        }
    }
/// Create a `Tableau` augmented with artificial variables.
///
/// The tableau is then in a basic feasible solution having only the artificial variables in the
/// basis.
///
/// # Arguments
///
/// * `provider`: Provides the problem to find a basic feasible solution for.
///
/// # Return value
///
/// The tableau.
Create a `Tableau` augmented with artificial variables.
The tableau is then in a basic feasible solution having only the artificial variables in the
basis.
Create a ` Tableau ` augmented with artificial variables . The tableau is then in a basic feasible solution having only the artificial variables in the basis .
pub(crate) fn new(provider: &'provider MP) -> Self
    where
        MP: PartialInitialBasis
    {
        let m = provider.nr_rows();
        // (row index, column index) coordinate tuples of suitable pivots in a slack column.
        let real = provider.pivot_element_indices();
        debug_assert!(real.is_sorted_by_key(|&(row, _column)| row));
        // Amount of slack variables that can be used for the initial artificial basis.
        let nr_real = real.len();
        // Amount of artificial variables that are still needed. Could be zero.
        let nr_artificial = m - nr_real;
        // Collect the rows that are not in the `real` value. Simple complement of the `real` set.
        let mut artificial = Vec::with_capacity(nr_artificial);
        let mut i = 0;
        for ith_artificial in 0..nr_artificial {
            while i < nr_real && ith_artificial + i == real[i].0 {
                i += 1;
            }
            artificial.push(ith_artificial + i);
            debug_assert!(!real.iter().any(|&(row, _)| row == ith_artificial + i));
        }
        debug_assert!(artificial.iter().all(|&row| row < m));
        // Create the map from the row to column indices where the initial basis elements are.
        //
        // Neither the artificial variables nor the real initial basis variables are necessarily in
        // a uninterrupted range, which is why this block is needed.
        debug_assert!(artificial.is_sorted() && real.is_sorted_by_key(|&(row, _column)| row));
        let mut artificial_counter = 0;
        let basis_indices = (0..m).map(|i| {
            let artificial_column = artificial_counter;
            let real_column = || nr_artificial + real[i - artificial_counter].1;
            let can_take_from_artificial = artificial_counter < nr_artificial;
            let can_take_from_real = i - artificial_counter < nr_real;
            match (can_take_from_artificial, can_take_from_real) {
                (true, true) => {
                    // Which index row is lower?
                    if artificial[artificial_column] < real[i - artificial_counter].0 {
                        artificial_counter += 1;
                        artificial_column
                    } else {
                        real_column()
                    }
                },
                (true, false) => {
                    artificial_counter += 1;
                    artificial_column
                },
                (false, true) => {
                    real_column()
                },
                (false, false) => {
                    unreachable!("If both `ac == nr_a` and `i - ac == nr_r`, loop should have ended")
                },
            }
        }).collect::<Vec<_>>();
        let basis_columns = basis_indices.iter().copied().collect();
        let inverse_maintainer = IM::create_for_partially_artificial(
            &artificial,
            &real,
            provider.right_hand_side(),
            basis_indices,
        );
        Tableau {
            inverse_maintainer,
            basis_columns,
            kind: Partially {
                column_to_row: artificial,
                provider,
            },
        }
    }
pub ( crate ) fn new ( provider : & ' provider MP ) -> Self where MP : PartialInitialBasis { let m = provider . nr_rows ( ) ; // (row index, column index) coordinate tuples of suitable pivots in a slack column. let real = provider . pivot_element_indices ( ) ; debug_assert ! ( real is_sorted_by_key ( ( row _column ) row ) ) ; // Amount of slack variables that can be used for the initial artificial basis. let nr_real = real . len ( ) ; // Amount of artificial variables that are still needed. Could be zero. let nr_artificial = m - nr_real ; // Collect the rows that are not in the `real` value. Simple complement of the `real` set. let mut artificial = Vec :: with_capacity ( nr_artificial ) ; let mut i = 0 ; for ith_artificial in 0 .. nr_artificial { while i < nr_real && ith_artificial + i == real [ i ] . 0 { i += 1 ; } artificial . push ( ith_artificial + i ) ; debug_assert ! ( real iter ( ) any ( ( row ) row ith_artificial i ) ) ; } debug_assert ! ( artificial iter ( ) all ( row row m ) ) ; // Create the map from the row to column indices where the initial basis elements are. // // Neither the artificial variables nor the real initial basis variables are necessarily in // a uninterrupted range, which is why this block is needed. debug_assert ! ( artificial is_sorted ( ) real is_sorted_by_key ( ( row _column ) row ) ) ; let mut artificial_counter = 0 ; let basis_indices = ( 0 .. m ) . map ( | i | { let artificial_column = artificial_counter ; let real_column = | | nr_artificial + real [ i - artificial_counter ] . 1 ; let can_take_from_artificial = artificial_counter < nr_artificial ; let can_take_from_real = i - artificial_counter < nr_real ; match ( can_take_from_artificial , can_take_from_real ) { ( true , true ) => { // Which index row is lower? if artificial [ artificial_column ] < real [ i - artificial_counter ] . 0 { artificial_counter += 1 ; artificial_column } else { real_column ( ) } } , ( true , false ) => { artificial_counter += 1 ; artificial_column } , ( false , true ) => { real_column ( ) } , ( false , false ) => { unreachable ! ( " " ) } , } } ) . collect :: < Vec < _ > > ( ) ; let basis_columns = basis_indices . iter ( ) . copied ( ) . collect ( ) ; let inverse_maintainer = IM :: create_for_partially_artificial ( & artificial , & real , provider . right_hand_side ( ) , basis_indices , ) ; Tableau { inverse_maintainer , basis_columns , kind : Partially { column_to_row : artificial , provider , } , } }
Create a `Tableau` augmented with artificial variables.
Create a ` Tableau ` augmented with artificial variables .
provider
&'provider MP
provider
&'provider MP
return value
None