簡體   English   中英

這是一個非多項式問題嗎? 如果不是,如何在多項式時間內解決?

[英]Is this a non-polynomial problem? If not, how can it be solved in polynomial time?

問題:

編寫一個具有 2 個輸入參數的 function:

  • items :2元組正整數的列表/向量(即> = 1)
  • target :正 integer(即 >= 1)

找到一個元組子集,使得:

  • 子集的第一個元組元素之和大於或等於輸入target
  • 子集的第二個元組元素的總和是最小的,我們稱該總和值為best

function 應該返回best 此外,保證有解決方案。 換句話說,所有第一個元組元素的總和總是大於或等於目標。

這是這樣一個 function 的偽代碼簽名:

 (items: List<(int, int)>, target: int) -> int

這里有一些例子......

示例 A:

  • 項目 = [(25,50), (49,51), (25,50), (1,100)]
  • 目標 = 50
  • 答案 = 100

示例 B:

  • 項目 = [(25,50), (49,51), (25,50), (1,5)]
  • 目標 = 50
  • 答案 = 56

這是我天真的指數時間解決方案:

  1. Go 通過所有可能的子集(因此是指數時間)
  2. 對於每個子集,計算第一個元組元素的總和
  3. 如果該總和大於或等於目標,則計算第二個元組元素的總和
  4. 如果該新總和是迄今為止找到的最小的,則更新最小值

我還嘗試確定問題的數學屬性是否允許使用捷徑,例如 go 通過最大的“第一個元素除以第二個元素”比率的項目(最划算)。 但是,如示例 A 所示,這並非對所有情況都有效。

這是一個非多項式問題嗎? 如果不是,如何在多項式時間內解決?

這是一個 0-1 背包問題: https://en.wikipedia.org/wiki/Knapsack_problem

元組是項目,第一個元組元素是項目值,第二個元組元素是項目權重。 經典的背包要求“ best小於某個特定的限制。

因此,這個問題是 NP 完全的,沒有多項式時間解。

有正常的動態規划解決方案可以適應在 O(items.length * best) 中工作。 最簡單的方法是使用正常的 DP 方法,首先對最佳值設置一個小的限制,然后將其加倍,直到可以實現目標值。

暫無
暫無

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

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