Skip to main content

bounded_knapsack

Function bounded_knapsack 

Source
pub fn bounded_knapsack(
    values: &[f64],
    weights: &[f64],
    counts: &[usize],
    capacity: f64,
) -> OptimizeResult<(f64, Vec<usize>)>
Expand description

Solve the bounded knapsack problem.

Maximizes sum(values[i] * x[i]) subject to:

  • sum(weights[i] * x[i]) <= capacity
  • 0 <= x[i] <= counts[i] (integer)

Uses binary splitting: each item i with bound b_i is split into O(log b_i) virtual 0-1 items representing multiples 1, 2, 4, …, remainder. The resulting 0-1 DP finds the exact optimum.

§Arguments

  • values – per-unit values
  • weights – per-unit weights
  • counts – maximum number of units of each item
  • capacity – knapsack capacity

§Returns

(optimal_value, selection) where selection[i] is the number of units of item i in the solution.

§Errors

Returns OptimizeError::InvalidInput on dimension mismatch or negative inputs.

§Example

use scirs2_optimize::integer::knapsack::bounded_knapsack;

let values  = vec![3.0, 4.0, 5.0];
let weights = vec![1.0, 2.0, 3.0];
let counts  = vec![4usize, 3, 2];
let (val, sel) = bounded_knapsack(&values, &weights, &counts, 7.0).expect("valid input");
// Optimal is 17: e.g. 4×item0 (v=12,w=4) + 1×item2 (v=5,w=3)
let total_w: f64 = weights.iter().zip(sel.iter()).map(|(&w, &c)| w * c as f64).sum();
assert!(total_w <= 7.0 + 1e-9);
assert!(val >= 17.0 - 1e-6);