0/1 背包問題計算機使用精確的動態規劃而非貪婪近似法,從一組不可分割的物品中,找出在單一整數容量限制內能放入且總價值最高的子集合。它接收一個容量上限以及一份帶有標籤、重量與價值的物品清單,然後回傳每個被選中物品的標籤,連同總價值、已使用的總重量,以及剩餘容量。由於每個物品都視為不可分割且最多只能選一次,「每個物品不是放入就是不放入」這個經典限制會被精確保留,這與 Google OR-Tools 以及多數演算法教科書所描述的標準 0/1 背包問題表述相符。背包問題計算機會在你的瀏覽器中執行整個運算,因此輸入內容永遠不會離開頁面,且相同的輸入會重現相同的選擇。在出現並列最佳值時,會保留較早出現的解而非任意切換,這在審核作業答案或重現採購範例時非常實用。

0 1 knapsack problem calculator
0 1 knapsack problem calculator

0/1 背包問題究竟是什麼

0/1 背包問題問的是一個單一的問題:給定一個具有單一容量上限的容器,以及一組固定的物品,每個物品都有各自的重量與價值,你應該放入哪些物品,才能在不超過總重量上限的情況下,讓總價值盡可能最高?「0/1」這個限定詞是關鍵約束 —— 每個物品都是單一不可分割的單位,你要嘛將其納入,要嘛排除,無法將一列拆成兩半,也無法將同一列重複放入兩次。這就是史丹佛 CS161 關於 0/1 背包動態規劃的講義以及Google OR-Tools 背包問題文件中所描述的版本,其中目標敘述為:在不超過容量的前提下,選擇總價值最大化的子集合。

由於每個物品的選擇是二元性的,問題規模會隨物品數量快速成長 —— 對於 n 個物品,可能的子集合數量為 2n —— 但精確的動態規劃會將這種暴力方式轉化為一張大小取決於容量而非 2n 的表格。整數容量的要求並非虛飾:它讓求解程式能為每單位容量編列一個索引儲存格,並在與 n × 容量成正比的時間內產出答案,這也是讓互動式工具在課堂規模的案例中仍可處理的原因。

計算機如何建模 0/1 背包問題

背包問題計算機實作了那個精確的表格導向方法。對於每個物品 i 以及從零到所輸入上限的每個容量 u,它會保留兩個候選狀態:在不放入 i 的情況下,容量 u 所能達到的最佳價值;以及放入 i(當 i 的重量 ≤ u 時)再加上容量 u − weight(i) 之前的最佳價值。兩者中較大者會被儲存,因此每個儲存格都承載了截至目前為止所見的最佳值。

一旦表格填滿,求解器會沿著決策路徑回溯,以重建被選中的標籤。在出現並列的情況下 —— 兩個不同的子集合達到相同的最大價值 —— 實作會保留較早出現的解而非任意切換,這就是為什麼相同的輸入每次都能重現相同的選擇。這與教科書逐步講解中使用的確定性平手決勝規則一致:保留較大的價值,而非隨機抽樣,也非啟發式猜測。

實作還會在求解前驗證輸入。空白欄位、重複的標籤、非正值的重量、超過容量的重量、非有限的數值,以及格式錯誤的以逗號分隔的列,都會被拒絕;而重量超過容量的物品會直接被拒絕,而非悄悄略過。這能確保結果的忠實性:如果計算機回傳了一組選擇,那麼每個被選中的物品都確實符合你所設定的容量,沒有任何一列出現兩次,並且在你輸入的有界模型下,總價值是可證明為最佳的。

逐步使用背包計算機

  1. 開啟背包問題計算機,並在容量欄位中輸入介於 1 到 10,000 之間的整數容量。
  2. 將每個物品新增為一列,包含標籤、正整數重量以及一個價值。如有需要可使用帶小數的數值,但請將重量保持為整數,以確保動態規劃表格正確無誤。
  3. 仔細確認沒有任何標籤包含逗號,因為逗號是用來分隔三個欄位的,並確認清單中所有標籤都不重複。
  4. 確認每個重量都是正值,且沒有任何重量超過你的容量 —— 過重的物品會一開始就被拒絕,而非默默忽略。
  5. 求解模型,並從結果面板讀出被選中的標籤、總價值、總重量以及未使用的容量。
  6. 將每個被選中的標籤與你的輸入進行核對,確認「不可分割、至多使用一次」的假設符合你實際要建模的決策;接著如有需要,可將該選擇以純文字格式複製,以便貼入報告、簡報或作業中。

輸入、限制以及結果包含什麼

在開始輸入列之前,最好先確切了解這個工具接受哪些輸入以及會回傳哪些結果。下方表格摘要列出已驗證的約束條件以及你所取得的報告。由於限制條件明確且運算在本機端進行,相同的輸入每次都會產生相同的選擇,這使得該工具適用於課程作業、可重現的採購範例,以及候選物品清單之間的快速比較。

輸入或輸出格式 / 範圍違反時的行為
容量整數,1–10,000若為空白、非整數或超出範圍則拒絕
物品數量最多 100 個不重複的標籤若清單超過上限或包含重複項則拒絕
物品重量正整數若非正值、為空白或大於容量則拒絕
物品價值非負數,允許帶小數若為空白或非有限數值則拒絕
物品標籤任意文字,不得包含逗號若包含逗號則拒絕,因為逗號是欄位的分隔符
運算精確的 0/1 動態規劃,在瀏覽器本機執行
輸出選中的標籤、總價值、已使用重量、未使用容量;可複製為純文字

範例演練:容量 10 搭配四個物品

為了讓機制更具體,讓我們執行一個小型案例:容量為 10,四個物品分別為 —— 重量 4 價值 40、重量 3 價值 50、重量 5 價值 30,以及重量 6 價值 35。一個天真的依價值重量比進行的貪婪選擇會單獨偏好重量 3、價值 50 的物品,但檢視每個可行的配對會發現,將重量 4、價值 40 的物品與重量 3、價值 50 的物品組合起來才是最佳的:4 + 3 = 7 ≤ 10,總價值 = 40 + 50 = 90,未使用容量 = 10 − 7 = 3。

另一個可行配對 {3, 5} 可達到價值 80,而 {4, 6} 雖然剛好等於容量上限,但總價值僅有 75;沒有任何三個物品的子集合可行,因為 4 + 3 + 5 = 12 已超過 10。將這些數字輸入背包問題計算機,會重現該選擇而非依照輸入順序,這符合此實作所測試的、可手動稽核的黃金案例。

0/1 背包問題與相關裝填問題的比較

背包問題屬於一組相關裝填與選擇問題的家族,模型之間的選擇至關重要。下方表格對比了最常見的變體,讓你在輸入資料前能選對模型。關鍵結論是:「最佳」完全取決於你正在求解哪個模型,因為同一組重量與價值,在允許多個容器、允許分割,或將目標改為最小化所用容器數量而非最大化價值時,可能會產生不同的贏家。

變體容器數每類型的物品數允許分割嗎?典型目標
0/1 背包問題(本工具)一個每個物品最多一次在單一容量下最大化總價值
分數背包問題一個任何數量是 —— 允許取部分最大化價值;依比例貪婪即為最佳
多重背包問題多個,各有容量每個物品最多一次跨所有容器最大化總價值
裝箱問題視需要使用等大的箱子每個物品最多一次最小化所用箱子的數量

當純量模型不敷使用時

純量 0/1 模型會根據你所輸入的資料給出數學上的最佳答案,因此它非常適合課堂問題、具有明確投入預算的有界功能優先排序、小型的投資組合草案,以及每個物品都有單一重量與單一價值的配置練習。它無法看見實體尺寸、平衡性、易碎性、必要群組、不相容的配對、截止期限或不確定性,因此當上述任何因素具有影響力時,它就是不適合的工具。對於安全關鍵性的裝載、醫療資源分配或高風險財務,請使用特定領域的模型並交由可負責的審核者驗證目標、相依性與約束,而非單純信任純量最佳解。

第二個常見陷阱是單位漂移。由於動態規劃表格為每個容量單位編列一個索引儲存格,重量必須是整數;如果你的測量單位帶有固定的小數位,請在輸入前一致地進行縮放 —— 例如,將 2.5 公斤視為 25 個十分之一公斤 —— 並記住更高的解析度會讓表格變大。容量上限為 10,000,物品清單上限為 100,以確保瀏覽器記憶體與回應時間受到控制,因此任何超過這些限制的案例都需要使用不同的求解器。對於帶小數的重量,常見的作法是在輸入前進行縮放;對於較大的案例,常見的作法是事先將物品按容量乾淨地加總回原始上限的方式手動預先分割為獨立的群組。這兩種應急方式都不會改變背後的 0/1 模型,它們只是將輸入調整為實作所接受的邊界。

延伸閱讀:如何求解最小生成樹問題

延伸閱讀:旅行銷售員問題:最佳解路徑產生器