Panoramica
La risposta di Jeff Shattock è corretta che questo è equivalente (o isomorfo, come scrivono i matematici) a un problema di ottimizzazione combinatoria, ma equivale al problema dell'imballaggio del bidone monodimensionale , non al problema dello zaino .
Fortunatamente per te, ho del codice da condividere che risolverà questo problema per te o chiunque altro, con accesso a un computer Windows con almeno la versione 3.5 di .NET Framework installata.
Una soluzione approssimativa
Innanzitutto, scarica e installa LINQPad .
In secondo luogo, scarica la query LINQPad che ho appena scritto - ecco il linq (ha) nel file raw. Salvalo come file .linq e aprilo in LINQPad.
Modifica i parametri:
Ecco la parte nel codice di query LINQPad che dovresti modificare:
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";
Cambia binSizeMb
le dimensioni del tuo "cestino", ad es. CD, DVD, es. int binSizeMb = 650;
per un CD.
Nota : il binSizeMb
valore viene interpretato come ciò che a volte viene definito mebibyte . Contrariamente alla mia infanzia, quando tutti i multipli di byte erano "binari", a volte "MB" ora si riferisce a un "megabyte decimale" o esattamente 1.000.000 di byte, al contrario dei 1.048.576 byte di un mebibyte (MiB), che viene utilizzato nel mio codice . Se si desidera modificarlo, modificare la riga const int bytesPerMb = 1048576;
nel codice in const int bytesPerMb = 1000000;
.
Passare rootFileFolderPath
al percorso completo della cartella contenente i file che si desidera "impacchettare in bin", ad es. string rootFileFolderPath = @"C:\MySecretBinFilesFolder";
.
Esegui la query premendo F5o facendo clic sul pulsante Esegui nella parte superiore sinistra della scheda della query.
risultati
Il codice della query enumera rootFileFolderPath
ricorsivamente tutti i file nella cartella, il che significa che includerà anche i file in tutte le sottocartelle.
Quindi creerà "bin" per i file in modo tale che la dimensione totale di tutti i file in ciascun cestino sia inferiore o uguale alla dimensione del cestino specificata.
Nel riquadro dei risultati LINQPad vedrai due elenchi.
Il primo elenco è di tutti i file trovati, elencati in ordine decrescente per dimensione.
Il secondo elenco è costituito dai contenitori creati "impacchettando i file", con un elenco dei file e delle loro dimensioni, nonché le dimensioni rimanenti del cestino.
Ecco uno screenshot che mostra il secondo elenco e i primi due bin creati:
Analisi Cursoria
Secondo Wikipedia, l'algoritmo che ho usato - la strategia First Fit Decreasing (FFD) - non dovrebbe essere troppo male; Wikipedia afferma:
Nel 2007, è stato dimostrato che l'OPT 11/9 + 6/9 per FFD è limitato.
'OPT' si riferisce alla strategia ottimale (come qualcosa di potenzialmente irraggiungibile, non una particolare strategia reale).
Sulla base delle mie memorie un po 'sfocate dei termini matematici coinvolti, ciò dovrebbe significare che, nella peggiore delle ipotesi, la strategia FFD dovrebbe raggruppare gli oggetti in ~ 1,22 volte il numero di bin che una strategia ottimale avrebbe. Quindi, questa strategia potrebbe impacchettare gli oggetti in 5 contenitori anziché 4. Sospetto che le sue prestazioni siano probabilmente molto vicine all'ottimale tranne che per specifiche dimensioni "patologiche" degli oggetti.
Lo stesso articolo di Wikipedia afferma inoltre che esiste un "algoritmo esatto" . Potrei decidere di implementarlo anch'io. Dovrò leggere prima l'articolo che descrive l'algoritmo.