Change the sum of the sum of a subset

I have (many) lots of positive numbers, for example. {71.28, 82.62, 148.77, 85.05, 50.76, 103.41}

...

I want to find the subset that gives the smallest amount greater than or equal to a given number .

Eg. if the minimum was 270

, then the result would be {148.77, 71.28, 50.76}

, which is added to 270.81

.

Note. My guess is that the solution might be more knapsack-like than the sum of a subset.

+3


source to share


1 answer


The subset sum problem and the knapsack problem in their solutions are quite similar and you can use either to solve the problem. However, the knapsack problem has a dynamic programming solution that contributes slightly to solving this particular problem. Take a look at this link to see my starting point: http://www.geeksforgeeks.org/dynamic-programming-set-10-0-1-knapsack-problem/ The above solution is repeated for each permutation of the set recursively, subtracting the value of each given element from the initial sum, until the subtraction results in a negative sum value. This represents a situation where the subset in question has a value greater than the specified input number, or in your example, a situation where the subset has an additive value greater than 270. In the DP backpack solution, we simply skip that set element and move it to the next. In my solution, I check if this solution value is the smallest value that has been greater than the input number so far (270 in your example). If so, I am updating two arguments to the function. One of the arguments is the difference between the tracked amount and the item in the set in question.This argument gives us the closeness of the subset's added value to the input number without having to compute the additive value or remember the original input number. The other argument is the current set, whose additive value is closest to the number of input numbers. In C ++, this set is stored in a std :: vector reference (it can also use a set or multiset). If there is no collection that adds more than the input number to the value, this algorithm returns an empty vector.which adds more than the input number to the value, this algorithm returns an empty vector.which adds more than the input number to the value, this algorithm returns an empty vector.



#include<iostream>
#include<vector>
#include<climits>
template<typename T>
void print(std::vector<T> v)
{
        for(auto i : v)
                std::cout<<i<<" ";
        std::cout<<std::endl;
}
template<typename T>
T closestVal(T sum, std::vector<T>& set, size_t n, std::vector<T> curSet, int& minSum, std::vector<T>& ret)
{
        if(n == 0 || sum == 0)
                return 0;
        if(set[n-1] >= sum) {
                if(sum-set[n-1] > minSum) {
                        minSum = sum-set[n-1];
                        std::vector<T> newSet = curSet;
                        newSet.push_back(set[n-1]);
                        ret = newSet;
                }
                return closestVal(sum, set, n-1, curSet, minSum, ret);
        }
        else {
                std::vector<T> newSet = curSet;
                newSet.push_back(set[n-1]);
                return std::max(
                        set[n-1] + closestVal(sum-set[n-1],set,n-1, newSet, minSum, ret),
                        closestVal(sum, set, n-1, curSet, minSum, ret)
                        );
        }
}
int main()
{
        std::vector<double> ms{71.28, 82.62,148.77, 85.05, 50.76, 103.41};

        std::vector<double> ret; //ret is empty, will be filled with the return value
        int i = INT_MIN; //i is instantiated to the smallest possible number

        closestVal(270.81, ms, ms.size(), {}, i, ret);

        print(ret);
        return 0;
}

      

+3


source







All Articles