簡體   English   中英

0-1 背包:在空間優化實施中尋找解決方案集

[英]0-1 Knapsack: Find Solution Set in Space-Optimised Implementation

我想解決一個 0-1 背包問題,最大重量為 ~ 200k 和超過 100k 元素,並最終確定項目集,而不僅僅是最佳重量。

研究 0-1 Knapsack,我讀到解決這個問題的常用方法是通過動態規划並創建一個包含子問題最優解的表格,從而將原始問題分成更小的部分,然后在表格上回溯以確定項目集. 最大的利潤,而不考慮所采取的項目,對於可以在存儲效率的方式來計算(如概述這里)。

這里明顯的問題是,對於我想到的維度,這種方法會消耗比可行更多的內存(需要O(n*W)空間, n是元素數, W是最大容量)。 進一步研究發現我提到( 這里例如,參見“背包問題”的Kellerer,Pferschy和Pisinger)的內存使用效率的方式來解決0-1背包。

我們首先將設置的項目分成大小大致相等的兩個子集。 給定原始最大權重W ,我們將兩個子集視為它們自己的背包問題,並以內存高效的方式(上文詳述)確定兩個子集的最大利潤計算的最后一行。

下一步是找出最佳分割兩個子集的位置。 為此,我們確定兩行重量w1w2的最大利潤。 據我了解,維護w1 + w2 = W至關重要,因此我遍歷第一行並獲取當前索引另一端的索引。 我目前對這一步的實現如下所示:

def split(weights, values, n, w, i):
    # s1 is the bigger subset size if n is not even
    s1 = n // 2 + (n&1)
    s2 = n // 2

    row1 = maximum_profit(weights, values, s1, w)
    row2 = maximum_profit(weights[s1:], values[s1:], s2, w)

    max_profits_for_capacity = [x + y for x, y in zip(row1, row2[::-1])]
    max_profits = max(max_profits_for_capacity)                           
    optimal_weight_index = max_profits_for_capacity.index(max_value)

    c1 = row1[optimal_weight_index]
    c2 = row2[w-optimal_weight_index-1]

c1c2是每個子集的最大利潤,然后保持c1 + c2 = W 使用這些值,我們遞歸到每個子集:

split(weights[:s1], values[:s1], s1, c1, i)      
split(weights[s1:], values[s1:], s2, c2, i+s1)

這就是描述讓我迷失的地方。 最終這段代碼將遞歸到n == 1 ,值為w 在給定項目索引i和最大(本地)容量w如何確定是否包含元素?

我可以提供一個小的示例數據集來詳細說明我的代碼的工作原理以及哪里出錯了。 非常感謝。

首先,我猜你有一個錯誤的說法是關於cw以及它們作為容量的關系,而是從利潤列表中獲取c1c2

對於問題,通過 split 函數的返回值,您可以定義要回答的問題類型。

當您將拆分直接到n == 1點並且您希望將拾取的物品的索引放入背包時,您可以簡單地在此步驟返回由[0][1]組成的值作為輸出:

if n == 1:
  if weights[0] < w:
    return [1]
  return [0]
  • [1]表示將項目挑選到結果集中
  • [0]否則

然后在split函數的其他遞歸步驟中將它們連接成一個,例如:

def split(..):
  ..
  # since it is lists concatenation
  return split(weights[:s1], values[:s1], s1, c1, i) + split(weights[s1:], values[s1:], s2, c2, i+s1)

結果,您將獲得大小為n (對於您進行拆分的項目數)的列表,其中包含零和一。

總復雜度為:

  • O(nWlogn)時間,因為我們進行拆分直到n == 1
  • O(W)用於內存,因為我們在遞歸時總是只存儲結果列表的一部分

暫無
暫無

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

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