Effizienter Algorithmus zum 'Aufsummieren' einer Reihe von Summen


24

Berücksichtigen Sie bei einem Multiset von natürlichen Zahlen X die Menge aller möglichen Summen:

sums(X)={iAi|AX}

Zum Beispiel, während Summen ( { 1 , 1 } ) = { 0 , 1 , 2 } .sums({1,5})={0,1,5,6}sums({1,1})={0,1,2}

Was ist der effizienteste Algorithmus zur Berechnung der inversen Operation (gemessen an der Größe des eingegebenen Summensatzes)? Insbesondere ist es möglich, Folgendes effizient zu berechnen:

  1. Gibt an, ob eine bestimmte Menge eine gültige Menge von Summen ist. (Beispielsweise ist gültig, { 0 , 1 , 3 } jedoch nicht.){0,1,2}{0,1,3}
  2. Ein Multiset, das sich zu dem angegebenen Set summiert.
  3. Das kleinste Multiset, das sich zu dem angegebenen Set summiert. (Zum Beispiel ergeben und { 1 , 1 , 1 } beide { 0 , 1 , 2 , 3 } , ersteres ist jedoch kleiner.){1,2}{1,1,1}{0,1,2,3}

1
Könnten Sie uns möglicherweise den Mehrfachsatz von Beträgen anstelle des Satzes von Beträgen geben? Dies würde eine angenehme Symmetrie erzeugen (da Sie mit einer Vielzahl von Werten beginnen).
DW

1
Eine andere Frage: Interessieren Sie sich am meisten für theoretische Ergebnisse (z. B. asymptotische Komplexität) oder für praktische Lösungen (Schemata, die in der Praxis möglicherweise in Ordnung sind)? Wenn letzteres der Fall ist, haben Sie eine Vorstellung von typischen Werten für Parameter: z. B. der Größe des Multisets X, der Größe des größten Elements im Multiset X, der höchsten Multiplizität? Dies kann sich darauf auswirken, ob es sinnvoll ist, einen "großen Hammer" wie einen ILP-Solver oder einen SAT-Solver anzuwenden.
DW

@ DW Ich bin definitiv daran interessiert, den Summensatz anstelle des Multisets zu verwenden (obwohl das auch ein interessantes Problem sein kann). Außerdem war dies ursprünglich ein Freizeit-Mathematik-Problem, weshalb ich mich hauptsächlich für Komplexitätsgrenzen und nicht für eine praktische Lösung interessiere.
Uri Granta

3
Wenn Sie mehrere Summen erhalten, ist es ziemlich einfach, dies gierig zu tun (siehe zum Beispiel math.stackexchange.com/questions/201545/… ).
Schnei

@UriZarfaty die als Eingabe angegebene Menge ist bereits sortiert? Endlich ist dies gesetzt oder Multiset? Kommentar noch vorschlagen, dass Sie reines Set wollen.
Evil

Antworten:


9

Lösung

Lösung besteht aus zwei Teilen. Zuerst entdecken wir die minimale Menge, dann beweisen wir, dass sie die Potenzsummenmenge darstellen kann. Die Lösung ist auf die Implementierung der Programmierung abgestimmt.

Minimaler eingestellter Algorithmus

  1. Finden Sie das maximale Element aus der Summenmenge (Multi). P , die mögliche minimale (Multi) Menge ist anfänglich leer.amP

  2. Wenn es nicht nur eine Gruppe gibt, repräsentiere auf alle möglichen Arten als ein Paar von Summen, die sich zu einem m summieren , S i j = { ( a i , a j ) | a i + a j = a m }amamSij={(ai,aj)|ai+aj=am}

  3. Überprüfen Sie, ob alle Elemente aus dem Summensatz enthalten sind.

  4. Finden Sie das maximale Element aus allen S i j (Bedeutung zusammen) mit der folgenden Eigenschaft: Für jedes S i j ist a s entweder in S i j , oder wir können ein p aus der Menge der Summen finden, so dass ein p + a s ist in S i j .asSijSijasSijapap+asSij

  5. Wenn dies der Fall ist , die enthält nicht ein s , nur die Summe a s + a p , entfernen Sie ein p + a s von S i j (oder einem Satz nur eine Marke , es zu ignorieren) , und legen Sie ein p und eine s in S i j statt.Sijaseins+einpeinp+einsSichjeinpeinsSichj

  6. Wenn in jedem ein Element vorhanden ist, entfernen Sie es einmal aus allen S i j (oder setzen Sie einfach eine Markierung, um es zu ignorieren und nicht mehr zu berühren) und fügen Sie es der Liste der Elemente der potenziellen minimalen Menge P hinzu .SichjSichjP

  7. Wiederholen, bis alle leer sindSichj

  8. Wenn ein Teil von nicht leer bleibt und wir nicht weitermachen können, versuchen Sie es erneut mit dem Maximalwert von allen S i j .SichjSichj

  9. Erstellen Sie die rekursiven Schritte erneut, ohne sie zu entfernen, und fahren Sie mit dem Algorithmus zum Festlegen der Netzabdeckung über . (Zuvor können Sie sicher stellen, dass P alle Elemente enthält, die nicht als Summe von zwei Elementen dargestellt werden können. Sie müssen sich also auf jeden Fall in der zugrunde liegenden Menge befinden. Beispielsweise muss sich das minimale Element in P befinden .)PPP

(10. Beachten Sie, dass eine minimale Mengenlösung, die das Ziel des Algorithmus ist, nicht mehr als eine Wiederholung derselben Zahl enthalten kann.)

Beispiel:

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

Stellen Sie 15 auf alle möglichen Arten als Summe von zwei Zahlen aus dem Summensatz dar.

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

Versuchen Sie, die maximale Anzahl zu finden, die in allen Gruppen enthalten ist oder als Summe dargestellt werden kann. Offensichtlich können wir ab 8 anfangen, danach zu suchen, es macht keinen Sinn, darüber hinauszugehen.

13 aus der ersten Gruppe ist 13 = 8 + 5, also ist 13 in Ordnung, aber 12 aus der zweiten Gruppe ist nicht in Ordnung, da es keine 4 gibt, die 12 = 8 + 4 in der Summe ergibt. Als nächstes versuchen wir es mit 7. Aber sofort können 13 nicht abgedeckt werden, es gibt keine 6.

Als nächstes versuchen wir 5. 13 = 5 + 8, 12 = 5 + 7, 10 = 5 + 5 und für das letzte entweder 8 = 5 + 3 oder 7 = 5 + 2, aber nicht beide. Die Gruppen sind jetzt:

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

5 wird in allen Gruppen wiederholt, daher extrahieren wir es . Wir extrahieren 5 nur einmal aus jeder Gruppe.P={5}

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

Offensichtlich gibt es keinen Grund, mehr als 5 zu erreichen, also versuchen wir es erneut mit 5. 8 = 5 + 3, 7 = 5 + 2, also ist alles in Ordnung

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

Extrahieren Sie erneut eine 5 aus allen Gruppen, da diese wiederholt wird. (Dies ist nicht üblich, aber unser Fall wurde absichtlich erstellt, um anzuzeigen, was bei Wiederholungen zu tun ist.) P={5,5}

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

Jetzt versuchen wir es mit 3 und haben 5 = 3 + 2. Fügen Sie es der Gruppe hinzu.

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

Nun extrahiere 3 und 2, da sie sich überall wiederholen und es uns gut geht. und die Gruppen sind leer.P={5,5,3,2}

(),(),(),()

Jetzt müssen wir rekursive Schritte ohne Entfernungen neu erstellen. Dies bedeutet einfach, dass wir die obigen Schritte ausführen, ohne die Elemente wirklich aus entfernen, indem wir sie in P platzieren und markieren, um sie nicht mehr zu ändern.SichjP

( ( 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))

Netzgerätedeckung

Der Zweck dieses Teils besteht darin, zu überprüfen, ob die gefundene minimale Menge die eingestellte Leistungssumme abdecken kann. Es ist möglich, dass eine gefundene Lösung alle angegebenen Summen abdeckt, es sich jedoch nicht um Leistungssummen handelt. (Technisch gesehen können Sie einfach eine Potenzsummenmenge aus der gefundenen Minimalmenge erstellen und prüfen, ob jede Summe, wie es die Potenzmenge vorschreibt, in der Anfangssummenmenge enthalten ist. Dies ist alles, was nur mit dem zusammengeführt wird, was wir bereits haben, sodass nichts verschwendet wird Sie können diesen Teil ausführen, während Sie die Rekursion zurückspulen.)

  1. Kodieren Sie alle Elemente aus der minimalen Menge mit aufeinanderfolgenden Potenzen von 2. Die Reihenfolge ist nicht wichtig. Codieren Sie dasselbe Element so oft mit einem neuen Wert, wie es sich wiederholt. Beginnen Sie mit C = 1, jedes nächste Element hat C = 2C.

(2=[1],3=[2],5=[4],5=[8])
  1. Ersetzen Sie die Elemente in der wiederhergestellten Rekursionsliste.

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

mit der Kodierung: 2 mit 1, 3 mit 2, 5 mit 4 und weitere 5 mit 8. Beachten Sie, dass jedes Element eine andere Kodierung hat, obwohl sie wiederholt werden.

((4,(8,2)),1),((4,(8,1)),2),((4,(2,1)),8),((8,2),(4,1))
  1. Sammle alle Zwischensummen, die wir momentan haben (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. 2m-1mm=4

  2. 12m-1

(6,7,11,12)

  1. Begründen Sie ihre Abwesenheit folgendermaßen: Stellen Sie jede Zahl in binärer Form dar

(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}Also ist alles in Ordnung.

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

1112

Wenn eine binäre Darstellung der nicht gefundenen Summe entspricht, geben Sie an, dass es keine Lösung gibt.

(2,3,5,5)

Diskussion

Es musste der Algorithmus angegeben werden, mit dem überprüft werden soll, ob die Summen die Vervollständigung des Leistungssatzes abdecken, was in der binären Erweiterung verborgen ist. Wenn wir beispielsweise 8 und 7 vom ursprünglichen Beispiel ausschließen, liefert der erste Teil immer noch die Lösung, nur der zweite Teil meldet fehlende Summenkombinationen.

mnlOG(m)mLog2(m)mnLog(m)

mLogmmLog2(m)

mLog3(m)

Teile des Algorithmus gehen davon aus, dass wir das Summenpaar in linearer Zeit finden können und dies eine Sortierung erfordert.

Falscher Start

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

5,4,3,3

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

Der Zweck dieses Algorithmus ist es, eine Lösung bereitzustellen, sobald wir alles richtig gestartet haben.

Verbesserungen

Schritt 4. ist derjenige, der auf diese Weise aufgerüstet werden könnte: Statt maximal könnten wir jedes Element in absteigender Reihenfolge ausprobieren, das die gegebene Bedingung erfüllt. Wir erstellen für jeden eine eigene Filiale. Wenn ein Zweig keine Lösung liefert, brechen Sie sie ab.

2,3,4,5,6,7,8,9,10,11,12,13,157,6,5,4auf getrennte Weise, da alle den ersten Test bestehen. (Es gibt keinen Grund, 2 oder 3 zu verwenden, da wir wissen, dass sie sich in der zugrunde liegenden Menge befinden müssen.) Fahren Sie einfach so fort, bis wir alle Versionen gesammelt haben, die das Ende erreichen können. Dies würde eine flächendeckende Lösung schaffen, die mehr als eine zugrunde liegende Menge entdecken würde.

Eine andere Sache ist, dass wir wissen, dass wir nicht mehr als eine Wiederholung haben können, wenn der Fall minimal ist. Wir können dies in unseren Algorithmus integrieren.

Insgesamt ist die Bedingung in Schritt 4, dass sich eine Zahl in jeder Gruppe wiederholen muss oder die Fähigkeit hat, eine Summe zu erstellen, stark genug, um uns aus direkten exponentiellen Gewässern herauszuholen. Dies wäre ein Algorithmus, bei dem einfach jede Kombination ausprobiert und die Leistung erzeugt wird setze über jedes, bis wir eine Übereinstimmung finden.


1
Im weiteren Sinne: Ich sehe eine textuelle Beschreibung eines Algorithmus, aber (a) keinen Pseudocode und (b) keinen Beweis für die Richtigkeit. Warum liefert dieser Ansatz Ihrer Meinung nach einen Algorithmus, der bei allen möglichen Eingaben korrekt funktioniert? Was ist die Rechtfertigung? Haben Sie dafür einen Richtigkeitsnachweis?
DW

Ich denke, das Problem hat insgesamt rund 30 Stunden Arbeit gekostet (30-facher Stundensatz, na ja ...). Es gibt jedoch keine bezahlte Option.

Schließlich lesen Sie die Antwort in dem Detail, das sie verdient. Gute Arbeit!
Uri Granta

1

HINWEIS: Dies funktioniert im Allgemeinen nicht ganz, siehe das nachstehende Gegenbeispiel von Uri.

Y.Y.

  • 0Y.
  • yY.yXY.
  • z1<<znY.Y.Y.=Y.+{0,y}0Y.ich=1,,nzich+yY.zichY.zich-yY.zich+yY.zich+yY.zichY.
  • 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.{ein+ky}Y.Y.


Ist es offensichtlich, dass Y 'nicht zu einer Sackgasse führt? Immerhin kann es viele Ys geben, so dass Y = Y '+ {0, y}. Zum Beispiel {0,1,2,3,4} = {0,2,3} + {0,1} = {0,1,2,3} + {0,1}, aber die vorherige Zerlegung führt zu a Sackgasse.
Uri Granta

Das stimmt und ist ein echtes Problem. Ich muss sehen, ob es repariert werden kann. Vielen Dank!
Klaus Draeger

Y.kY.=Y.+{0,y,,y}{0,y,,y}kyY.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.