0

The whole thing about this polynomial time is confusing to me for example: I want to write a program in a polynomial time algorithm that will just pick only 4 integers that sum to 0 from a set. For instance: Let assume I have the following set of integers {8, 20, 3, -2, 3, 7, 16, -9}. How can I pick only 4 distinct integers that sum to 0 from a set in polynomial time without having needed to check through every possible length other than 4? Note in the program I don’t need to search through any other possible length than 4. My expected solution is {8, 3, -2, -9} = 0. knowing fully well that i only need 4 integers from the set {8, 20, 3, -2, 3, 7, 16, -9}.

Edit: Will I found a polynomial time solution of {8, 3, -2, -9} even if I increase only the length of the original set from 8 to 100 integers while I will still have to pick my 4 elements that sum to 0 but from the set of 100 integers will it still be polynomial fast with respect to the size of the input (i.e the number of bits used to store the input)?

rosacart
  • 23
  • 5
  • 1
    Try all distinct quadruples. This takes at most `(N^4-6N³+11N²-6N)/24` attempts. –  Feb 02 '16 at 13:15

2 Answers2

0

Try all quadruples without repetitions. This takes at most (N^4-6N³+11N²-6N)/24 attempts each made in constant time.

8 + 20 + 3 - 2 = 29
8 + 20 + 3 + 3 = 34
8 + 20 + 3 + 7 = 38
8 + 20 + 3 + 16 = 47
8 + 20 + 3 - 9 = 22
8 + 20 - 2 + 3 = 29
8 + 20 - 2 + 7 = 33
8 + 20 - 2 + 16 = 42
8 + 20 - 2 - 9 = 17
8 + 20 + 3 + 7 = 38
8 + 20 + 3 + 16 = 47
8 + 20 + 3 - 9 = 22
8 + 20 + 7 + 16 = 51
8 + 20 + 7 - 9 = 26
8 + 20 + 16 - 9 = 35
8 + 3 - 2 + 3 = 12
8 + 3 - 2 + 7 = 16
8 + 3 - 2 + 16 = 25
8 + 3 - 2 - 9 = 0    <==
8 + 3 + 3 + 7 = 21
8 + 3 + 3 + 16 = 30
8 + 3 + 3 - 9 = 5
8 + 3 + 7 + 16 = 34
8 + 3 + 7 - 9 = 9
8 + 3 + 16 - 9 = 18
8 - 2 + 3 + 7 = 16
8 - 2 + 3 + 16 = 25
8 - 2 + 3 - 9 = 0    <==
8 - 2 + 7 + 16 = 29
8 - 2 + 7 - 9 = 4
8 - 2 + 16 - 9 = 13
8 + 3 + 7 + 16 = 34
8 + 3 + 7 - 9 = 9
8 + 3 + 16 - 9 = 18
8 + 7 + 16 - 9 = 22
20 + 3 - 2 + 3 = 24
20 + 3 - 2 + 7 = 28
20 + 3 - 2 + 16 = 37
20 + 3 - 2 - 9 = 12
20 + 3 + 3 + 7 = 33
20 + 3 + 3 + 16 = 42
20 + 3 + 3 - 9 = 17
20 + 3 + 7 + 16 = 46
20 + 3 + 7 - 9 = 21
20 + 3 + 16 - 9 = 30
20 - 2 + 3 + 7 = 28
20 - 2 + 3 + 16 = 37
20 - 2 + 3 - 9 = 12
20 - 2 + 7 + 16 = 41
20 - 2 + 7 - 9 = 16
20 - 2 + 16 - 9 = 25
20 + 3 + 7 + 16 = 46
20 + 3 + 7 - 9 = 21
20 + 3 + 16 - 9 = 30
20 + 7 + 16 - 9 = 34
3 - 2 + 3 + 7 = 11
3 - 2 + 3 + 16 = 20
3 - 2 + 3 - 9 = -5
3 - 2 + 7 + 16 = 24
3 - 2 + 7 - 9 = -1
3 - 2 + 16 - 9 = 8
3 + 3 + 7 + 16 = 29
3 + 3 + 7 - 9 = 4
3 + 3 + 16 - 9 = 13
3 + 7 + 16 - 9 = 17
- 2 + 3 + 7 + 16 = 24
- 2 + 3 + 7 - 9 = -1
- 2 + 3 + 16 - 9 = 8
- 2 + 7 + 16 - 9 = 12
3 + 7 + 16 - 9 = 17

Update:

At the request of the OP, stopped when a solution is found.

8 + 20 + 3 - 2 = 29
8 + 20 + 3 + 3 = 34
8 + 20 + 3 + 7 = 38
8 + 20 + 3 + 16 = 47
8 + 20 + 3 - 9 = 22
8 + 20 - 2 + 3 = 29
8 + 20 - 2 + 7 = 33
8 + 20 - 2 + 16 = 42
8 + 20 - 2 - 9 = 17
8 + 20 + 3 + 7 = 38
8 + 20 + 3 + 16 = 47
8 + 20 + 3 - 9 = 22
8 + 20 + 7 + 16 = 51
8 + 20 + 7 - 9 = 26
8 + 20 + 16 - 9 = 35
8 + 3 - 2 + 3 = 12
8 + 3 - 2 + 7 = 16
8 + 3 - 2 + 16 = 25
8 + 3 - 2 - 9 = 0    <==
  • Thanks, i would want it to stop immediately it found the first subset that sum to 0. Then it should terminate once {8+3-2-9} is found. – rosacart Feb 02 '16 at 14:25
0

The following algorithm runs in O(N^3 * logN).

#include <algorithm>
#include <iostream>
#include <tuple>
#include <vector>

using quadruple = std::tuple<int, int, int, int>;

std::vector<quadruple> find(std::vector<int> vec) {
  std::sort(vec.begin(), vec.end());
  vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
  std::vector<quadruple> ret;
  for (auto i = 0u; i + 3 < vec.size(); ++i) {
    for (auto j = i + 1; j + 2 < vec.size(); ++j) {
      for (auto k = j + 1; k + 1 < vec.size(); ++k) {
        auto target = 0 - vec[i] - vec[j] - vec[k];
        auto it = std::lower_bound(vec.begin() + k + 1,
            vec.end(),
            target);
        if (it != vec.end() && *it == target) {
          ret.push_back(std::make_tuple(
              vec[i], vec[j], vec[k], target));
        }
      }
    }
  }
  return ret;
}

int main() {
  std::vector<int> input = {8, 20, 3, -2, 3, 7, 16, -9};
  auto output = find(input);
  for (auto& quad : output) {
    std::cout << std::get<0>(quad) << ' '
              << std::get<1>(quad) << ' '
              << std::get<2>(quad) << ' '
              << std::get<3>(quad) << std::endl;
  }
}
Lingxi
  • 14,579
  • 2
  • 37
  • 93
  • Thanks, will I found a polynomial time solution of {8, 3, -2, -9} even if I increase only the length of the original set from 8 to 100 integers while I will still have to pick my 4 elements that sum to 0 but from the set of 100 integers will it still be polynomial fast with respect to the size of the input (i.e the number of bits used to store the input)? – rosacart Feb 02 '16 at 14:28
  • @rosacart The time complexity is polynomial to N - size of the total set. So, yes. – Lingxi Feb 02 '16 at 14:52
  • So what will be the implication in every subset sum problem if we can know or predict correctly the actual length of integers that sum to zero? Can this lead to a polynomial time algorithm for subset sum problem? – rosacart Feb 02 '16 at 15:07
  • @rosacart If the size of subset is constant. Yes. Otherwise, no. – Lingxi Feb 02 '16 at 15:13
  • Is the size of subset constant at least for the above examples that i gave? – rosacart Feb 02 '16 at 15:21
  • @rosacart If the subset is a variable M. The time complexity would then be O(N^(M-1) * logN). And that is not polynomial. – Lingxi Feb 02 '16 at 15:23
  • Do you mean the size of subset exist in the first example that i gave and should be constant for instance, for every other possible length of integers that could sum up to 0? – rosacart Feb 02 '16 at 15:47