2011-09-12 167 views
6

對於我正在處理的應用程序,我需要類似Python see here for more details中實現的打包算法。基本思想是我有n不同尺寸的物體,我需要裝入n箱,箱的數量是有限的,物體和箱的尺寸是固定的。物體/箱可以是1d或2d,有興趣看到兩者。 (我認爲3D對象可能比我需要的更多。)包裝算法的Python實現

我知道有很多算法可以解決這個問題,比如最佳適合度下降和首次適應度下降,但我希望可能會有一個實現在Python中(或者PHP/C++/Java,真的我沒那麼挑剔)。有任何想法嗎?

+0

這是在2D?什麼樣的形狀?限於矩形? – jterrace

+0

如果你能回答這些問題,這將有所幫助 - 1.什麼是最大數量的對象? 2.什麼是垃圾箱的最大數量? 3.什麼是對象的最大寬度/高度? – pravin

+0

我不能給你一個確切數量的物體或箱子的最大數量,但我認爲最大值將在20-30左右(每個)。至於寬度/高度,現在不能給你最大值。 – tchaymore

回答

9

https://bitbucket.org/kent37/python-tutor-samples/src/f657aeba5328/BinPacking.py

""" Partition a list into sublists whose sums don't exceed a maximum 
    using a First Fit Decreasing algorithm. See 
    http://www.ams.org/new-in-math/cover/bins1.html 
    for a simple description of the method. 
""" 


class Bin(object): 
    """ Container for items that keeps a running sum """ 
    def __init__(self): 
     self.items = [] 
     self.sum = 0 

    def append(self, item): 
     self.items.append(item) 
     self.sum += item 

    def __str__(self): 
     """ Printable representation """ 
     return 'Bin(sum=%d, items=%s)' % (self.sum, str(self.items)) 


def pack(values, maxValue): 
    values = sorted(values, reverse=True) 
    bins = [] 

    for item in values: 
     # Try to fit item into a bin 
     for bin in bins: 
      if bin.sum + item <= maxValue: 
       #print 'Adding', item, 'to', bin 
       bin.append(item) 
       break 
     else: 
      # item didn't fit into any bin, start a new bin 
      #print 'Making new bin for', item 
      bin = Bin() 
      bin.append(item) 
      bins.append(bin) 

    return bins 


if __name__ == '__main__': 
    import random 

    def packAndShow(aList, maxValue): 
     """ Pack a list into bins and show the result """ 
     print 'List with sum', sum(aList), 'requires at least', (sum(aList)+maxValue-1)/maxValue, 'bins' 

     bins = pack(aList, maxValue) 

     print 'Solution using', len(bins), 'bins:' 
     for bin in bins: 
      print bin 

     print 


    aList = [10,9,8,7,6,5,4,3,2,1] 
    packAndShow(aList, 11) 

    aList = [ random.randint(1, 11) for i in range(100) ] 
    packAndShow(aList, 11) 
+2

呃,這是'aList = [5,4,4,3,2,2]'和'maxValue = 10'的錯誤。它給出了3個框的結果,但真正的答案應該是2([4,4,2],[5,3,2])。 – aemdy

+1

@aemdy說誰? FFD算法會給出[5 4],[4 3 2],[2 2]。最佳的容器裝箱是NP難的,確切的算法要更復雜。 – krapht

+1

這個效果很好;我修改了這個以簡化我的直線材料購買:https://github.com/ninowalker/linear-pack –