TheAlgorithms/Java · error · IllegalArgumentException

Weights must be positive.

Error message

Weights must be positive.

What it means

The Knapsack DP requires all item weights to be strictly positive (weight > 0). A zero or negative weight breaks the DP recurrence because the inner loop indexes dp[w - currentWeight], which can go out of bounds or cause an infinite-value cell. throwIfInvalidInput scans the weights array and rejects any w <= 0.

Source

Thrown at src/main/java/com/thealgorithms/dynamicprogramming/Knapsack.java:40

 * @see <a href="https://en.wikipedia.org/wiki/Knapsack_problem">Knapsack Problem</a>
 */
public final class Knapsack {

    private Knapsack() {
    }

    /**
     * Validates the input to ensure correct constraints.
     */
    private static void throwIfInvalidInput(final int weightCapacity, final int[] weights, final int[] values) {
        if (weightCapacity < 0) {
            throw new IllegalArgumentException("Weight capacity should not be negative.");
        }
        if (weights == null || values == null || weights.length != values.length) {
            throw new IllegalArgumentException("Weights and values must be non-null and of the same length.");
        }
        if (Arrays.stream(weights).anyMatch(w -> w <= 0)) {
            throw new IllegalArgumentException("Weights must be positive.");
        }
    }

    /**
     * Solves the 0/1 Knapsack problem using Dynamic Programming (bottom-up approach).
     *
     * @param weightCapacity The maximum weight capacity of the knapsack.
     * @param weights        The array of item weights.
     * @param values         The array of item values.
     * @return The maximum total value achievable without exceeding capacity.
     */
    public static int knapSack(final int weightCapacity, final int[] weights, final int[] values) {
        throwIfInvalidInput(weightCapacity, weights, values);

        int[] dp = new int[weightCapacity + 1];

        // Fill dp[] array iteratively
        for (int i = 0; i < values.length; i++) {

View on GitHub (pinned to fdfb9a395b)

Solutions

  1. Filter or replace any non-positive weights before calling knapSack.
  2. Validate that every weight > 0 at data-ingestion time.
  3. If zero-weight items are legitimate, assign them a minimum positive weight (e.g., 1) or handle them separately.

Example fix

// before
int best = Knapsack.knapSack(cap, new int[]{0, 3, 5}, values); // throws

// after
int[] weights = {0, 3, 5};
weights = Arrays.stream(weights).map(w -> Math.max(1, w)).toArray();
int best = Knapsack.knapSack(cap, weights, values);
Defensive patterns

Strategy: validation

Validate before calling

if (Arrays.stream(weights).anyMatch(w -> w <= 0)) {
    throw new IllegalArgumentException("All weights must be positive");
}
int best = Knapsack.knapSack(weightCapacity, weights, values);

Type guard

static boolean allWeightsPositive(int[] weights) {
    return weights != null && Arrays.stream(weights).allMatch(w -> w > 0);
}

Prevention

When it happens

Trigger: Passing a weights array that contains a zero or negative value — e.g., a placeholder 0 for items without a defined weight, or a negative weight from a data-entry error.

Common situations: Placeholder zeros in item master data; negative weights from subtracting a base offset; importing data where weight is optional and defaults to 0.

Related errors


AI-assisted analysis of TheAlgorithms/Java@fdfb9a395b (2026-08-13). Data as JSON: /api/errors/7e777ed90fa4070c. Report an issue: GitHub.