2013-10-02 10 views
5

Dire che ho una matrice di valori:Numpy - i dati di gruppo in somma Valori

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

e tre valori 'somma':

b = 10 
c = 9 
d = 7 

c'è un modo per raggruppare i valori in a in gruppi di insiemi in cui i valori si combinano con b, ced e d? Per esempio:

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] 

nota la somma di b, c e d dovrebbe rimanere lo stesso (== 26). Forse questa operazione ha già un nome?

+6

Sembra che tu stia cercando di risolvere il "problema dello zaino" (o una sua variante): http://en.wikipedia.org/wiki/Knapsack_problem –

+3

Simile sì, lo chiamerei lo "zaino multiplo" problema". Per esempio. In quanti modi puoi mettere le tue cose in tre zaini (dove il costo non è un problema). – atomh33ls

+3

Quindi è un problema di ricerca, non numerico (insipido). E come con la maggior parte dei problemi di ricerca, c'è una soluzione di forza bruta e varie strategie (spesso euristiche) per la potatura dei rami morti. – hpaulj

risposta

2

Ecco un'implementazione ingenuo utilizzando 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)) 

rendimenti

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

Nota, questo probabilmente sarà molto lento per grandi liste perché stiamo essenzialmente costruendo e filtraggio attraverso il power set di quella lista.


Si potrebbe utilizzare questo per

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

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

e poi zip insieme.

+3

Questo non soddisfa la condizione implicita che ogni valore in 'a' può essere inserito in un solo gruppo. – askewchan

+0

@askewchan, hai ragione. Ma penso che potrebbe essere un buon punto di partenza. Mi sono divertito a usare 'np.unique (group (b, a))' e poi in qualche modo potare dopo aver testato con uscite da 'group (c, a)' e 'group (d, a)'. Non ci sono ancora riuscito. – atomh33ls

+0

Sì, tutto ciò che manca è un filtro alla fine che controlla che le due raccolte siano uguali. 'np.unique' non è sufficiente perché mentre l'ordine non è importante, il conteggio di ciascuna voce lo fa. Si potrebbe confrontare il loro 'bincount's. – askewchan