js實現01揹包問題

01揹包是動態規劃中比較簡單的一個問題,其中的關鍵在於找到狀態轉換方程。java

假設編號分別爲a,b,c,d,e的五件物品,重量分別是2,2,6,5,4,價值分別是6,3,5,4,6,如今有一個承重爲10的揹包,如何裝入物品具備最大價值?數組

思路分析

首先假設有一個國王且手下有大臣A和大臣B,聰明的國王將這個問題分爲放入物品a不放入物品a兩種狀況。而後國王告訴大臣A假如已經放了物品a, 那麼剩下b,c,d,e四件商品放入大小爲8的揹包中的最大價值(其中8來自於總重量10減去物品a的重量2),而後再告訴大臣B假如沒有放入物品a, 那麼在b,c,d,e四件商品中放入大小爲10的揹包中的最大價值。spa

而國王只須要比較兩個大臣的答案就能夠獲得最終答案。大臣A採用一樣方法把任務分給手下有A1和A2兩我的,大臣B同理。依次下去,便可獲得最終的答案。.net

以上能夠看出,關鍵步驟是將問題分解爲放入物品a與不放入物品a兩種狀況中的最大值,並推廣的全部的物品。這也是01的由來。code

用圖形表示出來就是下面這張表。blog

圖片描述

首先注意的是該表是從左下開始填的,左邊紫色列標示物品編號,並對應的有重量與價值,第一行標示揹包重量。(b, 5)表示b、c、d、e四個物品放入大小爲5的揹包中的最大值。(a, 10)就是abcde五種商品放入容量爲10的揹包中的最大價值,這正好就是題目的答案。圖片

如今咱們開始學怎麼填這張表,先隨便挑一個表格(a,9),此時揹包容量爲9,能夠選abcde五種物品,咱們要找出容量的最大值,根據上述思路分爲放入物品a和不放入物品a兩種狀況。ip

  • 狀況a: 假如放入物品a, 則揹包容量變爲9-2=7,還剩b,c,d,e四種物品。因此該狀況下的最大值 = (b,7) + 物品a的價值6,即9+6get

  • 狀況b: 假如不放入物品a, 揹包容量不變爲9,還剩b,c,d,e四種物品。因此該狀況下的最大值 = (b, 9),即10it

因此如今(a, 9) = max( (b,7)+6, b(9) ) = max(9+6,10) = 15。

一樣的步驟填滿其餘的表格便可。

代碼實現

下面是方法2的js實現

function packageMaxValue(weight, value, size){
    // 省略參數合法性校驗
    let bagMatrix = []
    for(let w = 0; w <= size; w++) {
        // js不能直接建立二維數組,因此在此初始化數組
        bagMatrix[w] = []
        for (let j = 0; j < 5; j++) {
            // 揹包的容量爲0,那麼一個東西也裝不下,此時的值確定也是爲0
            if(w === 0) {
                bagMatrix[w][j] = 0
                continue
            }
            // 揹包的容量小於物品j的重量,那麼就沒有上述狀況a了
            if(w < weight[j]){
                bagMatrix[w][j] = bagMatrix[w][j-1] || 0
                continue
            }
            bagMatrix[w][j] = Math.max((bagMatrix[w-weight[j]][j-1] || 0) + value[j], bagMatrix[w][j-1] || 0)
        }
    }
    return bagMatrix
}
    
let weight = [4, 5, 6, 2, 2]
let value = [6, 4, 5, 3, 6]
 
console.log(packageMaxValue(weight, value, 10))

參考:
動態規劃之01揹包問題(最易理解的講解)

相關文章
相關標籤/搜索