Created
February 10, 2024 17:54
-
-
Save bnm3k/31a02eef88ba48557e43018f9b2553d4 to your computer and use it in GitHub Desktop.
Solve knapsack in rust
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct Input { | |
values: Vec<u32>, | |
weights: Vec<u32>, | |
num_items: usize, | |
capacity: u32, | |
} | |
// returns a vector containing the indices of items selected | |
fn solve_knapsack(ip: &Input) -> (u32, Vec<usize>) { | |
let mut table = Vec::with_capacity(ip.num_items + 1); | |
for i in 0..(ip.num_items + 1) { | |
table.push(vec![0; (ip.capacity as usize) + 1]); | |
} | |
for item in 1..(ip.num_items + 1) { | |
for capacity in 1..(ip.capacity + 1) { | |
let max_val_without_curr = table[item - 1][capacity as usize]; | |
let mut max_val_with_curr = 0; | |
let weight_of_curr = ip.weights[item - 1]; | |
if capacity >= weight_of_curr { | |
let val_of_curr = ip.values[item - 1]; | |
let remaining_capacity = capacity - weight_of_curr; | |
max_val_with_curr = val_of_curr + table[item - 1][remaining_capacity as usize]; | |
} | |
table[item][capacity as usize] = std::cmp::max(max_val_without_curr, max_val_with_curr); | |
} | |
} | |
let mut packed_items = Vec::new(); | |
let total_value = table[ip.num_items][ip.capacity as usize]; | |
let mut curr_item = ip.num_items as i64; | |
let mut curr_weight = ip.capacity; | |
while curr_item > 0 { | |
let curr_value = table[curr_item as usize][curr_weight as usize]; | |
let prev_value = table[(curr_item - 1) as usize][curr_weight as usize]; | |
if curr_value != prev_value { | |
packed_items.push((curr_item - 1) as usize); | |
curr_weight = curr_weight - ip.weights[(curr_item - 1) as usize]; | |
} | |
curr_item -= 1; | |
} | |
(total_value, packed_items) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment