commit f844f5db591e02f11276a648503d6193210ba624 Author: Zastian Pretorius Date: Tue Jul 19 22:34:18 2022 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..132337a --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "lpr_project" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..f50b5ab --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "lpr_project" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..db6b999 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,230 @@ +use std::io::{self, Write}; +use std::vec::Vec; +struct Coll { + restriction: Vec, + sign: String, + rhs: f64, +} +fn main() { + let amount_restrictions = int_input("Enter amount of restrictions: "); + let amount_variables = int_input("Enter amount of variables: "); + let mut max_z: Vec = vec![]; + for z in 0..amount_variables { + let input = float_input(&format!("{}x{}:","Enter max value of variable ",z)); + max_z.push(input); + } + let all_colls = fill_coll(amount_restrictions, amount_variables); + let mut table: Vec> = vec![]; + //fill in max_z with 0 for the rest of the table till size amount_restrictions + for _i in 0..amount_restrictions { + max_z.push(0.0); + } + table.push(max_z); + + let mut count = 0; + for mut coll in all_colls{ + for i in 0..amount_restrictions { + //push 1 if i = count + if i == count { + coll.restriction.push(1.0); + } else { + coll.restriction.push(0.0); + } + } + coll.restriction.push(coll.rhs); + count += 1; + table.push(coll.restriction); + } + + println!("t*"); + print_table(&table); + println!(""); + println!("ti"); + let mut table = flip_z(&mut table); + print_table(&table); + //pivot table until table is optimal + // table is optimal when z has no negative values + println!(""); + let mut optimal = false; + while !optimal { + let pivot_col = find_pivot_col(&table); + let ratio = ratio_test(&table, pivot_col); + let pivot_row = find_pivot_row(&ratio); + table = pivot_table(&mut table, pivot_row, pivot_col); + print_table(&table); + println!(""); + if check_optimal(&table){ + optimal = true; + } + } + // + // + //println!("{}",find_pivot_col(&table)); + //let pivot_col = find_pivot_col(&table); + //let ratios = ratio_test(&table, pivot_col); + //// print all ratios + //for ratio in &ratios { + // println!(""); + // println!("{}",ratio); + //} + //let pivot_row = find_pivot_row(&ratios); + //let mut table = pivot_table(&mut table, pivot_row, pivot_col); + //println!(""); + //print_table(&table); +} + +fn check_optimal(table: &Vec>) -> bool { +// tebale is optimal when z has no negative values + let mut z_index = 0; + for i in 0..table[0].len() { + if table[0][i] < 0.0 { + z_index = i; + } + } + if z_index == 0 { + return true; + } else { + return false; + } +} + + +fn print_table(table: &Vec>) { + for i in 0..table.len() { + for j in 0..table[i].len() { + print!("{:.1$}\t", table[i][j],2); + } + println!(""); + } +} + +fn pivot_table(table: &mut Vec>, pivot_row: usize, pivot_col: usize) -> Vec> { + // firnd the pivot point + let mut new_table = table.clone(); + let pivot_point = table[pivot_row+1][pivot_col]; + // divide pivot row by pivot point + for i in 0..table[pivot_row+1].len() { + new_table[pivot_row+1][i] = table[pivot_row+1][i] / pivot_point; + }; + // current possition-(pivot_row*new_table pivot_point) + for i in 0..table.len() { + if i != pivot_row+1 { + let current_possition = table[i][pivot_col]; + for j in 0..table[i].len() { + new_table[i][j] = table[i][j] - (current_possition * new_table[pivot_row+1][j]); + } + } + } + return new_table; +} + + +fn flip_z(table: &mut Vec>) -> Vec>{ + for i in 0..table[0].len(){ + if table[0][i] > 0.0 { + table[0][i] = -table[0][i]; + } + } + table[0].push(0.0); + return table.to_vec(); +} + +fn find_pivot_col(table: &Vec>) -> usize { + let mut largest = 0.0; + let mut largest_index = 0; + for i in 0..table[0].len() { + if table[0][i] < largest{ + largest = table[0][i]; + largest_index = i; + } + } + return largest_index; +} + +fn ratio_test(table: &Vec>, test_col: usize) -> Vec { + let mut ratios: Vec = vec![]; + for i in 1..table.len() { + if table[i][test_col] != 0.0 { + ratios.push(table[i][table[i].len() - 1] / table[i][test_col]); + } else { + ratios.push(std::f64::MAX); + } + } + return ratios; +} + +fn find_pivot_row(ratios: &Vec) -> usize { + //find the index of the smallest ratio + let mut smallest = std::f64::MAX; + let mut smallest_index = 0; + for i in 0..ratios.len() { + if ratios[i] < smallest && ratios[i] > 0.0 { + smallest = ratios[i]; + smallest_index = i; + } + } + return smallest_index; +} + + +fn fill_coll(amount_restrictions: usize, amount_vars: usize) -> Vec { + let mut colls : Vec = vec![]; + for _restriction in 0..amount_restrictions { + let mut restrictions:Vec = vec![]; + let mut count = 1; + for _var in 0..amount_vars { + let input = float_input(&format!("{}x{}:","Enter restriction ",count)); + restrictions.push(input.clone()); + count += 1; + } + let sign_local = string_input("Enter sign: "); + let rhs_local = float_input("Enter rhs: "); + let coll_local = Coll { + restriction: restrictions, + sign: sign_local, + rhs: rhs_local, + }; + colls.push(coll_local); + } + colls +} + + + +pub fn string_input(prompt: &str) -> String { + print!("{}", prompt); + let mut input = String::new(); + let _ = io::stdout().flush(); + io::stdin() + .read_line(&mut input) + .expect("Error reading from STDIN"); + input.trim().to_string() +} + +pub fn int_input(prompt: &str) -> usize { + print!("{}", prompt); + let mut input = String::new(); + let _ = io::stdout().flush(); + io::stdin() + .read_line(&mut input) + .expect("Error reading from STDIN"); + //try to parse the input as usize else return max usize + match input.trim().parse::() { + Ok(i) => i, + Err(_) => { + usize::max_value() + } + } +} + +pub fn float_input(prompt: &str) -> f64 { + print!("{}", prompt); + let mut input = String::new(); + let _ = io::stdout().flush(); + io::stdin() + .read_line(&mut input) + .expect("Error reading from STDIN"); + //try to parse the input as f64 else return max f64 + let output = input.trim().parse::().unwrap(); + output +}