I believe that you could use the strategy described by this answer. Your problem is not a direct Knapsack formulation, but it can be transoformed into one.
Set TotalW1 = ∑w1i - W1 and TotalW2 = ∑w2i - W2. Now you can solve a Mulitple Constraints Knapsack problem
- maximise ∑xivi
- constraint 1: ∑xjw1j ≤ TotalW1 - W1
- constraint 2: ∑xjw2j ≤ TotalW2 - W2
In order to get a solution for the minimisation problem statement for your question you simply take the complement of the Knapsack solution, i.e. the trucks which were not selected are the ones that minimise the gas consumption whilst carrying the minimum total weights expected.
According to the question the output should be the total value of the trucks that fulfil the weight conditions. Below is a recursive algorithm showing the example of your question:
#include <stdio.h>
int max(int a, int b)
{
return (a > b ? a : b);
}
int truck_knapsack(int W1, int W2, int w1[], int w2[], int v[], int n)
{
if (n == 0 || W1 == 0 || W2 == 0)
return 0;
if (w1[n - 1] > W1 || w2[n - 1] > W2)
return truck_knapsack(W1, W2, w1, w2, v, n - 1);
return max(
v[n - 1] + truck_knapsack(W1 - w1[n - 1], W2 - w2[n - 1], w1, w2, v, n - 1),
truck_knapsack(W1, W2, w1, w2, v, n - 1));
}
int main()
{
int W1 = 5;
int W2 = 60;
int w1[] = {3, 10, 5, 4, 1};
int w2[] = {36, 25, 50, 45, 20};
int v[] = {120, 129, 250, 130, 119};
int n = 5;
// the problem statement is a variation of Knapsack problem
// turn it into a classical Knapsack problem
// total1 = sum of w1 weights - W1
int total1 = 0;
for (int i = 0; i < n; i++)
total1 += w1[i];
total1 -= W1;
// total2 = sum of w2 weights - W2
int total2 = 0;
for (int i = 0; i < n; i++)
total2 += w2[i];
total2 -= W2;
// the result of the Knapsack algorithm is the max
// bounded by total1 and total2
// the result of the original problem statement is sum_of_values - result
int result = truck_knapsack(total1, total2, w1, w2, v, n);
int sum_values = 0;
for (int i = 0; i < n; i++)
sum_values += v[i];
printf("%d\n", sum_values - result);
return 0;
}
The output is 249.