Algoritmo efficiente per "non riassumere" un insieme di somme


24

Dato un multiset di numeri naturali X, considera l'insieme di tutte le possibili somme:

sums(X)={iAi|AX}

Ad esempio, mentre .sums({1,5})={0,1,5,6}sums({1,1})={0,1,2}

Qual è l'algoritmo più efficiente per calcolare l'operazione inversa (misurata in termini di dimensioni del set di input di somme)? In particolare è possibile calcolare in modo efficiente uno dei seguenti:

  1. Se un determinato set è un insieme valido di somme. (Ad esempio, è valido ma non lo è.){0,1,2}{0,1,3}
  2. Un multiset che si somma al set specificato.
  3. Il più piccolo multiset che si somma al set dato. (Ad esempio, e sommano entrambi a ma il primo è più piccolo.){1,2}{1,1,1}{0,1,2,3}

1
Si potrebbe forse darci la multinsieme delle somme piuttosto che l' insieme delle somme? Ciò creerebbe una piacevole simmetria (visto che inizi con una serie multipla di valori).
DW

1
Un'altra domanda: sei più interessato ai risultati teorici (ad esempio, complessità asintotica) o soluzioni pratiche (schemi che potrebbero funzionare bene nella pratica)? In quest'ultimo caso, hai un'idea dei valori tipici per i parametri: ad esempio, la dimensione del multiset X, la dimensione dell'elemento più grande nel multiset X, la massima molteplicità? Ciò potrebbe influire sul fatto che sia ragionevole applicare un "grosso martello" come un risolutore ILP o un risolutore SAT.
DW

@DW Sono decisamente interessato a usare il set di somme piuttosto che il multiset (anche se potrebbe essere un problema interessante). Inoltre, questo era originariamente un problema di matematica ricreativa, quindi sono principalmente interessato ai limiti di complessità piuttosto che a una soluzione pratica.
Uri Granta,

3
Se ti viene dato il multiset di somme, è abbastanza semplice farlo avidamente (vedi ad esempio math.stackexchange.com/questions/201545/… ).
jschnei,

@UriZarfaty il set dato come input è già ordinato? Finalmente questo è impostato o multiset? Il commento suggerisce ancora che desideri un set puro.
Evil

Risposte:


9

Soluzione

La soluzione ha due parti. Prima scopriamo un set minimo, quindi dimostriamo che può rappresentare il set di somma di potenza. La soluzione è adattata per l'implementazione della programmazione.

Algoritmo del set minimo

  1. Trova l'elemento massimo dal set somma (multi). P , il potenziale minimo (multi) set è inizialmente vuoto.amP

  2. A meno che non vi sia un solo gruppo, rappresenta in tutti i modi possibili come una coppia di somme che si sommano a una m , S i j = { ( a i , a j ) | a i + a j = a m }amamSij={(ai,aj)|ai+aj=am}

  3. Verificare che siano inclusi tutti gli elementi dell'insieme di somme.

  4. Trova l'elemento massimo da tutti S i j (che significa insieme) con la seguente proprietà: per ogni S i j , a s è in S i j , oppure possiamo trovare una p dall'insieme delle somme in modo che a p + a s è in S i j .asSijSijasSijapun'p+un'SSioj

  5. Se è il caso che non contiene un s , solo la somma di una s + un p , rimuovere un p + a s da S i j (o semplicemente impostare un contrassegno di ignorarlo) e inserire un p e un s in S i j invece.Siojun'Sun'S+un'pun'p+un'SSiojun'pun'SSioj

  6. Se un elemento è presente in ogni elimina da tutti S i j una volta (o semplicemente impostare un contrassegno di ignorarlo e di non toccarlo più) e aggiungerlo alla lista di elementi di potenziale set minimo P .SiojSiojP

  7. Ripetere fino a quando tutti i sono vuotiSioj

  8. Se alcuni di rimangono non vuoti e non possiamo continuare, riprovare con il valore massimo di tutti i S j .SiojSioj

  9. Ricreare le operazioni ricorsive senza rimozioni e continuare con l'algoritmo di copertura set potere su . (Prima di ciò, è possibile verificare con sicurezza che P includa tutti gli elementi che non possono essere rappresentati come una somma di due elementi, quindi devono essere sicuramente nel set sottostante. Ad esempio, l'elemento minimo deve essere in P. )PPP

(10. Si noti che una soluzione minima impostata che è l'obiettivo dell'algoritmo non può contenere più di una ripetizione dello stesso numero.)

Esempio:

{2,3,5,7,8,10,12,13,15}

Rappresenta 15 in tutti i modi possibili come somma di due numeri dall'insieme delle somme.

(13,2),(12,3),(10,5),(8,7)

Prova a trovare il numero massimo che è in tutti i gruppi o che può essere rappresentato come somma. Ovviamente possiamo iniziare a cercarlo da 8, non ha senso andare oltre.

13 dal primo gruppo è 13 = 8 + 5, quindi 13 va bene, ma 12 dal secondo gruppo non va bene poiché non ci sono 4 per fare 12 = 8 + 4 nell'insieme delle somme. Quindi proviamo con 7. Ma immediatamente 13 non possono essere coperti, non ce ne sono 6.

Quindi proviamo 5. 13 = 5 + 8, 12 = 5 + 7, 10 = 5 + 5 e per l'ultimo 8 = 5 + 3 o 7 = 5 + 2 ma non entrambi. I gruppi sono ora:

((5,8),2),((5,7),3),((5,5),5),((5,3),7)

5 si ripete in tutti i gruppi, quindi lo estraiamo . Ne estraiamo 5 solo una volta da ciascun gruppo.P={5}

(8,2),(7,3),(5,5),(3,7)

Ovviamente non ha senso andare oltre 5, quindi proviamo di nuovo 5. 8 = 5 + 3, 7 = 5 + 2, quindi tutto va bene

((5,3),2),((5,2),3),(5,5),(3,(5,2))

Estrai di nuovo un 5 da tutti i gruppi poiché si sta ripetendo. (Questo non è comune ma il nostro caso è stato creato deliberatamente per mostrare cosa fare in caso di ripetizioni.) P={5,5}

(3,2),(2,3),(5),(3,2)

Ora proviamo con 3 e abbiamo 5 = 3 + 2. Aggiungilo al gruppo.

(3,2),(2,3),(3,2),(3,2)

Ora estrai 3 e 2 poiché si ripetono ovunque e stiamo bene e i gruppi sono vuoti.P={5,5,3,2}

(),(),(),()

Ora, abbiamo bisogno di ricreare passaggi ricorsivi senza rimozioni, questo significa semplicemente fare quanto sopra senza rimuovere realmente gli elementi da semplicemente posizionandoli in P e segnando di non modificarli più.SiojP

( ( 5 , 8 ) , 2 ) , ( ( 5 , 7 ) , 3 ) , ( ( 5 , 5 ) , 5 ) , ( ( 5 , 3 ) , 7

(13,2),(12,3),(10,5),(8,7)
( ( 5 , ( 5 , 3 ) ) , 2 ) , ( ( 5 , ( 5 , 2 ) ) , 3 ) , ( ( 5 , ( 3 , 2 ) ) , 5 ) , ( ( 5 , 3 ) , ( 5 , 2 ) )
((5,8),2),((5,7),3),((5,5),5),((5,3),7)
((5,(5,3)),2),((5,(5,2)),3),((5,(3,2)),5),((5,3),(5,2))

Copertura del set di potenza

Lo scopo di questa parte è verificare se il set minimo trovato è in grado di coprire il set di somma di potenza. È possibile che una soluzione trovata possa coprire tutte le somme indicate, ma che non siano somme di potenza. (Tecnicamente, potresti semplicemente creare un set di somma di potenza dal set minimo trovato e verificare se ogni somma, come impone il set di potenza, è nel set di somma iniziale. Questo è tutto ciò che è appena unito a ciò che già abbiamo, quindi nulla è sprecato Puoi fare questa parte mentre riavvolgi la ricorsione.)

  1. Codifica tutti gli elementi dell'insieme minimo usando potenze successive di 2. L'ordine non è importante. Codifica lo stesso elemento con un nuovo valore tante volte quante si ripete. Inizia da C = 1, ogni elemento successivo ha C = 2C.

(2=[1],3=[2],5=[4],5=[8])
  1. Sostituisci gli elementi nell'elenco di ricorsione ripristinato,

((5,(5,3)),2),((5,(5,2)),3),((5,(3,2)),5),((5,3),(5,2))

con la codifica: 2 con 1, 3 con 2, 5 con 4 e un altro 5 con 8. Osservare che ogni elemento ha una codifica diversa anche se vengono ripetuti.

((4,(8,2)),1),((4,(8,1)),2),((4,(2,1)),8),((8,2),(4,1))
  1. Raccogli tutte le somme intermedie, al momento abbiamo (1,2,4,8)

((4,(10)),1),((4,(9)),2),((4,(3)),8),((10),(5))

(1,2,3,4,5,8,9,10)

((14),1),((13),2),((7),8),(15)

(1,2,3,4,5,8,9,10,13,14,15)

{(15),(15),(15),(15)}
  1. 2m1mm=4

  2. 12m1

(6,7,11,12)

  1. Giustificare la loro assenza nel modo seguente: rappresentare ogni numero in forma binaria

(6=01102) (7=01112) (11=10112) (12=10102)

601102(2=[1],3=[2],5=[4],5=[8]){2,3,5,7,8,10,12,13,15}, quindi va tutto bene.

701112(2=[1],3=[2],5=[4],5=[8])

1112

Se una rappresentazione binaria corrisponde alla somma che non è possibile trovare, segnalare che non esiste soluzione.

(2,3,5,5)

Discussione

Era necessario fornire l'algoritmo che controllerà se le somme coprono il completamento del gruppo di potenza, che è ciò che è nascosto nell'espansione binaria. Ad esempio se escludiamo 8 e 7 dall'esempio iniziale, la prima parte fornirebbe comunque la soluzione, solo la seconda parte riporterebbe combinazioni mancanti di somme.

mnlog(m)mlog2(m)mnlog(m)

mlogmmlog2(m)

mlog3(m)

Alcune parti dell'algoritmo presuppongono che possiamo trovare la coppia di somme in tempo lineare e questo richiede un ordinamento.

Inizio errato

2,3,4,5,6,7,8,9,10,11,12,13,152,3,4,6Sij

5,4,3,3

2,2,3,4,42,3,4,6

Lo scopo di questo algoritmo è di fornire una soluzione una volta avviato tutto correttamente.

miglioramenti

Il passaggio 4. è quello che potrebbe essere aggiornato in questo modo: invece del massimo potremmo provare ogni elemento in ordine decrescente che soddisfi la condizione data. Creiamo un ramo separato per ciascuno. Se un ramo non fornisce una soluzione, annullarla.

2,3,4,5,6,7,8,9,10,11,12,13,157,6,5,4in modi separati poiché tutti stanno superando il primo test. (Non c'è motivo di usare 2 o 3 poiché sappiamo che devono essere nel set sottostante.) E continuare semplicemente così fino a quando non raccogliamo tutte le versioni che possono raggiungere la fine. Ciò creerebbe una soluzione a copertura totale che scoprirebbe più di un insieme sottostante.

Un'altra cosa, poiché sappiamo che non possiamo avere più di una ripetizione se il caso è minimo, possiamo incorporarlo nel nostro algoritmo.

Nel complesso, la condizione al punto 4. che un numero debba ripetersi in ogni gruppo o avere la capacità di creare una somma è abbastanza forte da farci uscire dalle acque esponenziali dirette, che sarebbe un algoritmo di provare semplicemente ogni combinazione e creare il potere impostare su ciascuno fino a quando non troviamo una corrispondenza.


1
Più in generale: vedo una descrizione testuale di un algoritmo, ma (a) nessuno pseudocodice e (b) nessuna prova di correttezza. Perché pensi che questo approccio fornisca un algoritmo che funzionerà correttamente su tutti i possibili input? Qual è la giustificazione? Hai una prova di correttezza per questo?
DW

Penso che il problema abbia richiesto circa 30 ore di lavoro tutti insieme (30 volte la tariffa oraria, beh ...). Ma non esiste un'opzione a pagamento.

Finalmente leggi la risposta nei dettagli che meritava. Ottimo lavoro!
Uri Granta,

1

NOTA: Questo non funziona in generale, vedi il controesempio di Uri di seguito.

YY

  • 0Y
  • yYyXY
  • z1<<znYYY=Y+{0,y}0Yio=1,...,nzio+yYzioY'zio-yYzio+yYzio+yYzioY'
  • Y'y,y',...

1yO(n)O(n2)

Y={0,1,3,4,5,6,7}{0,1,3,4,6}{0,1,3,5,6}yY{a+ky}YY


È ovvio che Y 'non porta a un vicolo cieco? Dopotutto ci possono essere molti Y tali che Y = Y '+ {0, y}. Ad esempio {0,1,2,3,4} = {0,2,3} + {0,1} = {0,1,2,3} + {0,1} ma la precedente decomposizione porta a un senza uscita.
Uri Granta,

Questo è vero ed è un vero problema. Dovrò vedere se può essere risolto. Grazie!
Klaus Draeger,

@UriZarfaty, mi chiedo se l'algoritmo di Klaus potrebbe essere corretto per il caso speciale in cui si inizia con un set anziché un multiset (ovvero, nessun elemento nel multiset ha una molteplicità superiore a 1). Hai un controesempio? Forse è interessante cercare prima un algoritmo per il caso speciale in cui inizi con un set anziché con un multiset. Se funziona per quel caso, potremmo essere in grado di generalizzarlo per funzionare per un multiset, ad esempio, cercando di trovare un setY' e un numero massimo K tale che Y=Y'+{0,y,...,y} dove {0,y,...,y} contiene K copie di y, quindi ricorrere Y'.
DW
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.