簡體   English   中英

電源設置太慢 python

[英]Power Sets too slow python

我正在使用以下 function 來查找列表 L 的子集。但是,當將 function powerset 的output轉換為長列表時,它需要的方式太長了。 有什么建議嗎?

為澄清起見,此powerset function 不 output 空子集和子集 L 本身(這是故意的)。

我的清單 L:

L = [0, 3, 5, 6, 8, 9, 11, 13, 16, 18, 19, 20, 23, 25, 28, 29, 30, 32, 33, 35, 36, 38, 42, 43, 44, 45, 49, 50, 51, 53, 54, 56, 57, 62, 63, 64, 65, 66, 67, 71, 76, 78, 79, 81, 82, 84, 86, 87, 90, 92, 96, 97, 98, 100, 107]

編碼:

def powerset(s):
    x = len(s)
    masks = [1 << i for i in range(x)]
    for i in range(1, (1 << x)-1):
        yield [ss for mask, ss in zip(masks, s) if i & mask]

my_Subsets = list(powerset(L)) # <--- THIS TAKES WAY TOO LONG

你的集合有 55 個元素。 意思是 2^55=36028797018963968 個子集。

在任何語言中,任何算法都無法做到這一點。 因為對於每個子集,您至少需要一個分配,並且重復 2^55 次的單個操作將永遠運行。 例如,如果我們要每納秒運行一次分配(實際上這要慢幾個數量級),我們正在研究一年多的事情(如果我的計算是正確的)。 在 Python 大概 100 年。 :P

更不用說最終結果不太可能適合目前可用的整個世界數據存儲(ram + 硬盤驅動器)。 而且絕對不在一台機器的存儲中。 所以最終list(...)轉換將以 100% 的概率失敗,即使你等待那些年。

無論您試圖實現什么(這可能是一個 XY 問題),您都以錯誤的方式進行操作。

您可以做的是創建一個 class ,它的行為類似於列表,但只會根據需要計算項目而不實際存儲它們:

class Powerset:

    def __init__(self,base):
        self.base = base

    def __len__(self):
        return 2**len(self.base)-2 # - 2 you're excluding empty and full sets

    def __getitem__(self,index):
        if isinstance(index,slice):
            return [ self.__getitem__(i) for i in range(len(self))[index] ]
        else:
            return [ss for bit,ss in enumerate(self.base) if (1<<bit) & (index+1)]


L = [0, 3, 5, 6, 8, 9, 11, 13, 16, 18, 19, 20, 23, 25, 28, 29, 30, 32, 33, 35, 36, 38, 42, 43, 44, 45, 49, 50, 51, 53, 54, 56, 57, 62, 63, 64, 65, 66, 67, 71, 76, 78, 79, 81, 82, 84, 86, 87, 90, 92, 96, 97, 98, 100, 107]


P = Powerset(L)

print(len(P)) # 36028797018963966
print(P[:10]) # [[0], [3], [0, 3], [5], [0, 5], [3, 5], [0, 3, 5], [6], [0, 6], [3, 6]]
print(P[3:6]) # [[5], [0, 5], [3, 5]]
print(P[-3:]) # [[5, 6, 8, 9, 11, 13, 16, 18, 19, 20, 23, 25, 28, 29, 30, 32, 33, 35, 36, 38, 42, 43, 44, 45, 49, 50, 51, 53, 54, 56, 57, 62, 63, 64, 65, 66, 67, 71, 76, 78, 79, 81, 82, 84, 86, 87, 90, 92, 96, 97, 98, 100, 107], [0, 5, 6, 8, 9, 11, 13, 16, 18, 19, 20, 23, 25, 28, 29, 30, 32, 33, 35, 36, 38, 42, 43, 44, 45, 49, 50, 51, 53, 54, 56, 57, 62, 63, 64, 65, 66, 67, 71, 76, 78, 79, 81, 82, 84, 86, 87, 90, 92, 96, 97, 98, 100, 107], [3, 5, 6, 8, 9, 11, 13, 16, 18, 19, 20, 23, 25, 28, 29, 30, 32, 33, 35, 36, 38, 42, 43, 44, 45, 49, 50, 51, 53, 54, 56, 57, 62, 63, 64, 65, 66, 67, 71, 76, 78, 79, 81, 82, 84, 86, 87, 90, 92, 96, 97, 98, 100, 107]]

顯然,如果你接下來要做的是順序搜索或遍歷 powerset,它仍然需要很長時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM