2013-10-02 3 views
5

Скажем, у меня есть массив значений:Numpy - группа данных в сумме значений

a = np.array([1,5,4,2,4,3,1,2,4]) 

и три «сумма» значения:

b = 10 
c = 9 
d = 7 

Есть ли способ, чтобы сгруппировать значения в a в группы множеств, где значения объединяются в равные b, c и d? Например:

b: [5,2,3] 
c: [4,4,1] 
d: [4,2,1] 

b: [5,4,1] 
c: [2,4,3] 
d: [4,2,1] 

b: [4,2,4] 
c: [5,4] 
d: [1,1,2,3] 

Примечание сумма b, c и d должен оставаться неизменным (== 26). Возможно, эта операция уже имеет имя?

+6

Похоже, вы пытаетесь решить «проблему ранца» (или его вариант): http://en.wikipedia.org/wiki/Knapsack_problem –

+3

Аналогично, да, я бы назвал это «множественным рюкзаком» проблема». Например. Сколько способов вы можете упаковать в три рюкзака (где стоимость не является проблемой). – atomh33ls

+3

Так что это проблема поиска, а не числовая (numpy). И как и в большинстве проблем поиска, существует решение грубой силы и различные стратегии (часто эвристические) для отсечения мертвых ветвей. – hpaulj

ответ

2

Вот наивная реализация с использованием itertools

from itertools import chain, combinations 

def group(n, iterable): 
    s = list(iterable) 
    return [c for c in chain.from_iterable(combinations(s, r) 
              for r in range(len(s)+1)) 
      if sum(c) == n] 

group(5, range(5)) 

Урожайность

[(1, 4), (2, 3), (0, 1, 4), (0, 2, 3)] 

Примечание, это, вероятно, будет очень медленным для больших списков, потому что мы по сути построения и фильтрации через набор мощности этого списка.


Вы можете использовать это для

sum_vals = [10, 9, 7] 
a = [1, 5, 4, 2, 4, 3, 1, 2, 4] 

map(lambda x: group(x, a), sum_vals) 

, а затем zip их вместе.

+3

Это не удовлетворяет неявному условию, что каждое значение в 'a' может быть помещено только в одну группу. – askewchan

+0

@askewchan, вы правы. Но я думаю, что это может быть хорошей отправной точкой. Я играл с использованием 'np.unique (group (b, a))', а затем как-то обрезал после тестирования с выводами из 'group (c, a)' и 'group (d, a)'. Пока не удалось. – atomh33ls

+0

Да, все, что ему не хватает, это фильтр в конце, который проверяет, что две коллекции равны. 'np.unique' недостаточно, потому что, хотя порядок не имеет значения, счетчик каждой записи делает. Вы можете сравнить их 'bincount'. – askewchan

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