Überblick
Jeff Shattocks Antwort ist richtig, dass dies einem kombinatorischen Optimierungsproblem entspricht (oder isomorph ist, wie Mathematiker schreiben), aber es entspricht dem Problem der eindimensionalen Behälterverpackung , nicht dem Rucksackproblem .
Zum Glück muss ich Code freigeben, der dieses Problem für Sie oder andere Personen mit Zugriff auf einen Windows-Computer mit mindestens Version 3.5 von .NET Framework löst.
Eine grobe Lösung
Laden Sie zunächst LINQPad herunter und installieren Sie es .
Laden Sie zweitens die LINQPad-Abfrage herunter, die ich gerade geschrieben habe - hier ist der Linq (ha) zur Rohdatei. Speichern Sie es als .linq- Datei und öffnen Sie es in LINQPad.
Ändern Sie die Parameter:
Hier ist der Teil im LINQPad-Abfragecode, den Sie ändern sollten:
int binSizeMb = 4476; // This is the (floor of the) total size of a DVD+R reported by CDBurnerXP.
string rootFileFolderPath = @"F:\2006 - Polyester Pimpstrap Intergalactic Extravaganza multicam";
Ändern Sie binSizeMb
die Größe Ihres 'Fachs', z. B. CD, DVD, z. int binSizeMb = 650;
für eine CD.
Hinweis - Der binSizeMb
Wert wird als das interpretiert, was manchmal als Mebibyte bezeichnet wird . Im Gegensatz zu meiner Kindheit, als alle Byte-Vielfachen "binär" waren, bezieht sich "MB" manchmal auf ein "dezimales Megabyte" oder genau 1.000.000 Bytes, im Gegensatz zu den 1.048.576 Bytes eines Mebibytes (MiB), die in meinem Code verwendet werden . Wenn Sie dies ändern möchten, ändern Sie die Zeile const int bytesPerMb = 1048576;
im Code in const int bytesPerMb = 1000000;
.
Wechseln Sie rootFileFolderPath
in den vollständigen Pfad des Ordners mit den Dateien, die Sie in Bins packen möchten, z. string rootFileFolderPath = @"C:\MySecretBinFilesFolder";
.
Führen Sie die Abfrage aus, indem F5Sie oben links auf der Registerkarte "Abfrage" auf die Schaltfläche " Ausführen" klicken oder darauf klicken .
Ergebnisse
Der Abfragecode listet rootFileFolderPath
rekursiv alle Dateien im Ordner auf, dh er enthält auch Dateien in allen Unterordnern.
Anschließend werden "Bins" für die Dateien erstellt, sodass die Gesamtgröße aller Dateien in jedem Bin kleiner oder gleich der angegebenen Bin-Größe ist.
Im LINQPad-Ergebnisbereich werden zwei Listen angezeigt.
Die erste Liste enthält alle gefundenen Dateien, die in absteigender Reihenfolge nach Größe aufgelistet sind.
Die zweite Liste enthält die durch "Packen der Dateien" erstellten Fächer mit einer Liste der Dateien und ihrer Größe sowie der verbleibenden Größe des Fachs.
Hier ist ein Screenshot mit der zweiten Liste und den ersten beiden erstellten Behältern:
Flüchtige Analyse
Laut Wikipedia sollte der von mir verwendete Algorithmus - die FFD-Strategie (First Fit Decreasing) - nicht schlecht sein. Wikipedia sagt:
Im Jahr 2007 wurde nachgewiesen, dass der gebundene 11/9 OPT + 6/9 für FFD eng ist.
'OPT' bezieht sich auf die optimale Strategie (als etwas, das möglicherweise nicht erreichbar ist, nicht als eine bestimmte tatsächliche Strategie).
Basierend auf meinen etwas unscharfen Erinnerungen an die beteiligten mathematischen Begriffe sollte dies bedeuten, dass die FFD-Strategie im schlimmsten Fall Elemente in das 1,22-fache der Anzahl von Behältern packen sollte, die eine optimale Strategie bieten würde. Diese Strategie könnte also Artikel in 5 statt in 4 Fächer packen. Ich vermute, dass die Leistung mit Ausnahme bestimmter „pathologischer“ Artikelgrößen wahrscheinlich nahezu optimal ist.
Der gleiche Wikipedia-Artikel besagt auch, dass es einen "exakten Algorithmus" gibt . Ich kann mich auch dafür entscheiden, dies umzusetzen. Ich muss zuerst das Papier lesen, das den Algorithmus beschreibt.