Skip to content

Instantly share code, notes, and snippets.

@bnm3k
Created February 10, 2024 17:54
Show Gist options
  • Save bnm3k/31a02eef88ba48557e43018f9b2553d4 to your computer and use it in GitHub Desktop.
Save bnm3k/31a02eef88ba48557e43018f9b2553d4 to your computer and use it in GitHub Desktop.
Solve knapsack in rust
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