The subset-sum problem is a classic computational challenge in computer science. The task is to find a subset of a set of integers that sums up to a specified value. Even though determining if such a subset exists is classified as an NP-complete problem, there are various algorithms to approach it, including backtracking.

Table of Contents

This article presents a solution for the subset-sum problem using backtracking in the C programming language. Specifically, it will find all possible subsets from a set of integers that sum up to the target value.

typedef void(*subset_sumfn)(const unsigned int *, size_t);
 
static unsigned int promising(int i, size_t len, unsigned int weight, unsigned int total,
        unsigned int target, const unsigned int *weights)
{
    return (weight + total >= target) && (weight == target || weight + weights[i + 1] <= target);
}
 
static unsigned int sum(const unsigned int *weights, size_t len)
{
    unsigned int total = 0;
    unsigned int i;
    for (i = 0; i < len; i++) {
        total += weights[i];
    }
    return total;
}
 
static void subset_sum_recursive(const unsigned int *weights, size_t len, unsigned int target,
        int i, unsigned int weight, unsigned int total, unsigned int *include, subset_sumfn fun)
{
    if (promising(i, len, weight, total, target, weights)) {
        if (weight == target) {
            fun(include, i + 1);
        }
        else if (i < (int)len - 1){
            include[i + 1] = 1;
            subset_sum_recursive(weights, len, target, i + 1, weight + weights[i + 1],
                   total - weights[i + 1], include, fun);
            include[i + 1] = 0;
            subset_sum_recursive(weights, len, target, i + 1, weight,
                    total - weights[i + 1], include, fun);
        }
    }
}
 
void subset_sum(const unsigned int *weights, size_t len, unsigned int target, subset_sumfn fun)
{
    const unsigned int total = sum(weights, len);
    unsigned int *include = calloc(len, sizeof(unsigned int));
    if (include == NULL) {
        return;
    }
    subset_sum_recursive(weights, len, target, -1, 0, total, include, fun);
    free(include);
}
 
int main(void)
{
    unsigned int weights[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    const unsigned int len = sizeof(weights) / sizeof(unsigned int);
    const unsigned int target = 7;
    subset_sum(weights, len, target, print_vector);
    return 0;
}
man pointing at floating code snippets from languages like JavaScript, Python, C++, PHP, and C#

Sample Output:

The result is represented as binary strings that indicate which elements from the initial set belong to the subset. For instance, the initial binary string corresponds to 1 + 2 + 4, resulting in a sum of 7.

The example provided in the code yields the following results:

1 1 0 1
1 0 0 0 0 1
0 1 0 0 1
0 0 1 1
0 0 0 0 0 0 1

Conclusion

The subset-sum problem, though computationally complex, can be tackled using algorithms like backtracking. The provided C code offers a comprehensive approach to finding all subsets that meet a given target sum. On a related note, for those interested in web automation, another article dives into how to execute JavaScript in Python using Selenium.

Leave a Reply