2015-06-17 1 views
-1

У меня есть массив целых чисел и вам нужно применить вариант subset sum algorithm, за исключением того, что вместо поиска набора целых чисел, сумма которых равна 0, я пытаюсь найти набор целых чисел, сумма которых равна n. Непонятно, как адаптировать один из стандартных алгоритмов суммирования к этому варианту и надеялся на какое-либо понимание проблемы.Вариант суммы подмножества с ненулевой суммой цели

+0

В чем вопрос? – Jarod42

+0

Проверить, есть ли какие-либо числа в массиве, которые могут быть добавлены, чтобы они были равны другому номеру :) – Kuker

+0

Это вариант проблемы суммирования подмножества; удаленный код, потому что он не был релевантным –

ответ

1

Это subset sum problem, который NP-Complete (не известно эффективное решение для NP-полных задач), но если ваши номера относительно небольшие целые числа - существует эффективный псевдо полиномиальное решение ему, что следует повторение:

D(x,i) = false x<0 
D(0,i) = true 
D(x,0) = false x != 0 
D(x,i) = D(x,i-1) OR D(x-arr[i],i-1) 

Позже вам необходимо вернуться к своим выборам, посмотреть, где вы решили «уменьшить» (взять элемент), и где вы решили не «уменьшать» (не принимать элемент), на сгенерированную матрицу ,

This thread и this thread обсудить, как получить элементы для подобных проблем.

Вот код python (взятый из связанного с нитью), который делает трюк.
Если вы не знакомы с python - прочитайте его как псевдокод, это довольно легко понять python !.

arr = [1,2,4,5] 
n = len(arr) 
SUM = 6 
#pre processing: 
D = [[True] * (n+1)] 
for x in range(1,SUM+1): 
    D.append([False]*(n+1)) 
#DP solution to populate D: 
for x in range(1,SUM+1): 
    for i in range(1,n+1): 
     D[x][i] = D[x][i-1] 
     if x >= arr[i-1]: 
      D[x][i] = D[x][i] or D[x-arr[i-1]][i-1] 
print D 

#get a random solution: 

if D[SUM][n] == False: 
    print 'no solution' 
else: 
    sol = [] 
    x = SUM 
    i = n 
    while x != 0: 
     possibleVals = [] 
     if D[x][i-1] == True: 
      possibleVals.append(x) 
     if x >= arr[i-1] and D[x-arr[i-1]][i-1] == True: 
      possibleVals.append(x-arr[i-1]) 
     #by here possibleVals contains 1/2 solutions, depending on how many choices we have. 
     #chose randomly one of them 
     from random import randint 
     r = possibleVals[randint(0,len(possibleVals)-1)] 
     #if decided to add element: 
     if r != x: 
      sol.append(x-r) 
     #modify i and x accordingly 
     x = r 
     i = i-1 
    print sol 
+0

Я действительно не могу понять, что я могу сказать, что я начинаю, когда он приходит к этим передовым алгоритмам :) – Kuker

+0

@Kuker См. edit, я добавил код python. Довольно легко следить за python, так как это очень читаемый язык, поэтому вы, скорее всего, поймете код, даже если вы не знаете python. – amit

+0

спасибо за помощь. Я все еще не могу понять python, но вы дали мне некоторые идеи! Это было действительно полезно :) – Kuker

0

Вы можете решить эту проблему с помощью динамического программирования.

Давайте предположим, что:

  • N - это сумма, которая требуется (ваш первый вход).
  • M - это количество слагаемых, доступных (ваш второй вход).
  • a ... a M - это сгенерируемые слагаемые.
  • f[x] является true, когда вы можете достигнуть суммы в x и false иначе

Теперь решение:

Первоначально f[0] = true и f[1..N] = false - мы можем достичь только сумму нуля без принятия каких-либо слагаемым.

Теперь вы можете перебрать все в я, где i в [1..m], и с каждым из них выполнить следующую операцию:

F [х + а я] = F [ x + a i] || f [x], для каждого x из [M..a i] - порядок обработки имеет значение!

Наконец, вы выводите f [N].

Это решение имеет сложность O (N * M), поэтому оно не очень полезно, когда вы либо имеете большие входные числа, либо большое количество слагаемых.

+0

Спасибо, что ответили. Я не буду лгать, я не могу понять, что означает «а» и «f». Что это за слагаемые? – Kuker

+0

@Kuker, 'a' или 'summands' - это элементы массива из вашего утверждения. 'f' - массив, который я представил для хранения результата. Если вам трудно понять - попробуйте прочитать некоторые статьи о «Динамическом программировании» - я узнал об этом некоторое время назад, поэтому, к сожалению, не могу предложить вам хороший ресурс. – user3707125

+0

Я до сих пор не могу понять, как его реализовать. Это до тех пор, пока я не получил: 'int a, b, sum, temp; \t vector c; \t в то время (CIN >> A >> б) { \t \t для (INT I = 0; я > темп; \t \t \t c.push_back (temp); \t \t} \t \t int * f = new int [a]; \t \t f [0] = true; \t \t для (INT = 1; я с [I]; х -) { \t \t \t \t F [х + с [i]] = f [x + c [i]] || Р [х]; \t \t \t} \t \t \t соиЬ << е [а]; ' – Kuker

Смежные вопросы