genel bakış
Jeff Shattock'un cevabı, bunun bir kombinatoryal optimizasyon problemine eşdeğer (veya matematikçilerin yazdığı gibi izomorfik) olduğu doğrudur, ancak sırt çantası problemine değil, 1 boyutlu çöp kutusu paketleme problemine eşdeğerdir .
Şanslıyız, .NET Framework'ün en az 3.5 sürümü yüklü bir Windows bilgisayara erişimi olan bu sorunu sizin için veya başka herhangi bir kişi için çözecek bazı kodlarım var.
Kaba Bir Çözüm
İlk olarak, LINQPad'i indirin ve yükleyin .
İkincisi, az önce yazdığım LINQPad sorgusunu indirin - işte ham dosyaya linq (ha). Bir .linq dosyası olarak kaydedin ve LINQPad'de açın.
Parametreleri değiştirin:
LINQPad sorgu kodunda değiştirmeniz gereken kısım:
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";
Değişim binSizeMb
için 'bin', örneğin CD, DVD, eski boyutuna. int binSizeMb = 650;
CD için.
Not - binSizeMb
değer, bazen mebibit olarak adlandırılan şey olarak yorumlanır . Çocukluğumun aksine, tüm bayt katları 'ikili' olduğunda, bazen 'MB' artık kodumda kullanılan 1.048.576 baytlık bir mebibitin (MiB) aksine, 'ondalık megabayt' veya tam olarak 1.000.000 bayt anlamına gelir. . Bunu değiştirmek isterseniz const int bytesPerMb = 1048576;
, koddaki satırı olarak değiştirin const int bytesPerMb = 1000000;
.
rootFileFolderPath
'Kutulara paketlemek' istediğiniz dosyaları içeren klasörün tam yolunu değiştirin , örn. string rootFileFolderPath = @"C:\MySecretBinFilesFolder";
.
Sorguyu, sekmenin sol üst tarafındaki Yürüt düğmesine basarak F5veya tıklayarak çalıştırın .
Sonuçlar
Sorgu kodu, rootFileFolderPath
klasördeki tüm dosyaları yinelemeli olarak numaralandıracaktır , yani tüm alt klasörlerde de dosyaları içerecektir.
Ardından, her bölmedeki tüm dosyaların toplam boyutu belirtilen bölme boyutundan küçük veya ona eşit olacak şekilde dosyalar için 'bölmeler' oluşturur.
LINQPad sonuçlar bölmesinde iki liste göreceksiniz.
İlk liste, boyutuna göre azalan sırada listelenen tüm dosyaları listeler.
İkinci liste 'dosyaların paketlenmesi' ile oluşturulan dosyaların, dosyaların ve boyutlarının yanı sıra çöp kutusunun kalan boyutu ile birlikte oluşturulan bölmelerdir.
İşte ikinci listeyi ve oluşturulan ilk iki kutuyu gösteren bir ekran görüntüsü:
Lanetli Analiz
Wikipedia'ya göre, kullandığım algoritma - İlk Uyum Azaltma (FFD) stratejisi - çok kötü olmamalı; Wikipedia belirtileri:
2007'de FFD için bağlı 11/9 OPT + 6/9'un sıkı olduğu kanıtlandı.
'OPT' optimal stratejiyi ifade eder (herhangi bir gerçek strateji değil, potansiyel olarak erişilemeyen bir şey olarak).
İlgili matematiksel terimlerdeki biraz bulanık anılarıma dayanarak, bu FFD stratejisinin en kötü ihtimalle, optimal bir stratejinin yapabileceği kutu sayısının ~ 1,22 katına kadar öğeleri paketlemesi gerektiği anlamına gelmelidir. Bu nedenle, bu strateji 4 yerine 5 kutuya ürün koyabilir. Performansın belirli 'patolojik' ürün boyutları hariç en uygun seviyeye yakın olduğundan şüpheleniyorum.
Aynı Wikipedia makalesi aynı zamanda bir "tam algoritma" olduğunu belirtir . Bunu da uygulamaya karar verebilirim. Önce algoritmayı tanımlayan makaleyi okumam gerekecek.