Visão geral
A resposta de Jeff Shattock está correta de que isso é equivalente (ou isomórfico, como os matemáticos escrevem) a um problema de otimização combinatória, mas é equivalente ao 1-dimensional problema de empacotamento de bin , não o problema de mochila .
Para sua sorte, eu tenho alguns códigos para compartilhar que resolverão este problema para você, ou qualquer outra pessoa, com acesso a um computador Windows com pelo menos a versão 3.5 do .NET Framework instalado.
Uma solução aproximada
-
Primeiro, baixe e instale o LINQPad .
-
Em segundo lugar, baixe a consulta LINQPad que acabei de escreveu - aqui está o linq (ha) para o arquivo raw. Salve como um arquivo .linq e abra-o no LINQPad.
-
Altere os parâmetros:
Aqui está a parte do código de consulta do LINQPad que você deve alterar:
int binSizeMb = 4476; // This is the (floor of the) total size of a DVD+R reported by CDBurnerXP.
string rootFileFolderPath = @"F:06 - Polyester Pimpstrap Intergalactic Extravaganza multicam";
Altere binSizeMb
para o tamanho do seu 'bin', por ex. CD, DVD, ex. int binSizeMb = 650;
para um CD.
Observação - o valor binSizeMb
é interpretado como o que às vezes é chamado de mebibyte . Ao contrário da minha infância, quando todos os múltiplos de byte eram 'binários', às vezes 'MB' agora se refere a 'megabyte decimal' ou exatamente 1.000.000 bytes, ao contrário dos 1.048.576 bytes de um mebibyte (MiB), que são usados no meu código . Se você quiser mudar isso, altere a linha const int bytesPerMb = 1048576;
no código para const int bytesPerMb = 1000000;
.
Altere rootFileFolderPath
para o caminho completo da pasta que contém os arquivos que você deseja 'empacotar em caixas', ex. string rootFileFolderPath = @"C:\MySecretBinFilesFolder";
.
-
Execute a consulta pressionando F5 ou clicando no botão Executar no canto superior esquerdo da guia de consulta.
Resultados
O código de consulta irá enumerar todos os arquivos na pasta rootFileFolderPath
, de forma recursiva, o que significa que incluirá arquivos em todas as subpastas também.
Em seguida, ele criará 'escaninhos' para os arquivos, de modo que o tamanho total de todos os arquivos em cada escaninho seja menor ou igual ao tamanho do escaninho especificado.
No painel de resultados do LINQPad, você verá duas listas.
A primeira lista é de todos os arquivos encontrados, listados em ordem decrescente de tamanho.
A segunda lista são os escaninhos criados por "empacotando os arquivos", com uma lista dos arquivos e seus tamanhos, bem como o tamanho restante do escaninho.
Aqui está uma captura de tela mostrando a segunda lista e as duas primeiras caixas criadas:
AnálisedeRastreio
DeacordocomaWikipedia,oalgoritmoqueusei-aestratégiaFirstFitDecreasing(FFD)-nãodeveriasertãoruim;EstadosdaWikipédia:
In2007,itwasproventhatthebound11/9OPT+6/9forFFDistight.
'OPT'refere-seàestratégiaótima(comoalgopotencialmenteinacessível,nãoumaestratégiarealemparticular).
Combasenasminhasmemóriasumtantoconfusasdostermosmatemáticosenvolvidos,issodevesignificarqueaestratégiaFFDdeve,napiordashipóteses,embalaritensem~1,22vezesonúmerodecaixasqueumaestratégiaótimafaria.Portanto,essaestratégiapodeagruparitensem5posiçõesaoinvésde4.Suspeitoqueodesempenhoprovavelmenteestejamuitopróximodoideal,excetoparatamanhosdeitens'patológicos'específicos.
OmesmoartigodaWikipediatambémafirmaqueexisteum "algoritmo exato" . Eu posso decidir implementar isso também. Vou ter que ler o artigo que descreve o algoritmo primeiro.