JS動態(tài)規(guī)劃算法--01背包問題

動態(tài)規(guī)劃

動態(tài)規(guī)劃算法是通過拆分問題在刺,定義問題狀態(tài)和狀態(tài)之間的關系,使得問題能夠以遞推(或者說分治)的方式去解決诚欠。

01 背包問題

有 N 件物品和一個容量為 V 的背包紫皇。第 i 件物品的體積是 c[i],價值是 w[i]盆耽。求解將哪些物品裝入背包可使價值總和最大(每一種物品只能放一次)

分析解答

也不多扯皮蹋砚,直入正題。

先看一個簡單的問題摄杂,斐波那契數(shù)列:

dynFib(n) {
  let arr = new Array(n).fill(0);
  arr[0] = 1;
  arr[1] = 1;
  for (let i = 2; i < n; i++) {
    arr[i] = arr[i - 1] + arr[i - 2];
  }
  // 返回最后一個
  return arr[n - 1];
}

該問題就是一個簡單的動態(tài)規(guī)劃問題,關鍵點在于找到狀態(tài)關系: f(n) = f(n-1) + f(n-2);

回到背包問題坝咐,可以參考上面斐波那契數(shù)列的遞推關系,

假設現(xiàn)在背包容量為 10析恢,有一個物品數(shù)組:

const product = [
  { weight: 2, value: 3},
  { weight: 2, value: 6 },
  { weight: 6, value: 5 },
  { weight: 5, value: 4 },
  { weight: 4, value: 6 },
];

如果背包容量為 0墨坚,那么什么也放不下

如果背包容量為 1,還是什么也放不下

如果背包容量為 2映挂,有兩個物品都為質(zhì)量都為 2泽篮,該放哪一個呢盗尸?

這時需要做一個決策,先放物品 1帽撑,此時價值為 3泼各;此時比較 上一個決策的價值 - 物品 1 的價值 + 放物品 2 的價值 和物品 1 的價值比,取大的當做該容量下的最優(yōu)解

用狀態(tài)方程描述為: f[i][j]= Math.max(f[i-1][j],f[i-1][j]-c[i]]+w[i]); 其中 i 為第 i 件物品(0 開始), j 為當前背包容量

如果背包容量為 3亏拉,.......

......

直到背包容量為 10扣蜻,得到此時的最優(yōu)解


初始化一個二維矩陣來記錄背包和價值的關系:

this.result = [];

const row = this.product.length;
const col = this.capacity;
for (let i = 0; i < row; i++) {
  this.result[i] = new Array(col + 1).fill(0);
}

我們會發(fā)現(xiàn),每一個狀態(tài)都依賴于上一個狀態(tài)及塘,第一個物品需要比較沒有物品的狀態(tài)做比較莽使,我們需要對 i=0 時做特殊處理,還有一個更巧妙的方法笙僚,初始化一個 -1 的狀態(tài):

this.result[-1] = new Array(col + 1).fill(0);

如下圖吮旅,我們發(fā)現(xiàn)類似于填表的方式,右下角即為背包最大容量時的價值;

觀察下表可以發(fā)現(xiàn)味咳,該矩陣記錄了每一個容量即狀態(tài)的最優(yōu)解庇勃,比如容量 7 時的最優(yōu)解,我們可以找到 7 那一列最下面即 12;

主函數(shù)部分,利用狀態(tài)方程進行最優(yōu)決策槽驶,

calculate() {
  const row = this.product.length;
  const col = this.capacity;
  let product;
  for (let i = 0; i < row; i++) {
    for (let j = 0; j < col + 1; j++) {
      product = this.product[i];
      if (j < product.weight) {
        this.result[i][j] = this.result[i - 1][j];
      } else {
        this.result[i][j] = Math.max(
          this.result[i - 1][j],
          this.result[i - 1][j - product.weight] + product.value
        );
      }
    }
  }
  delete this.result[-1];
  return this.result[row - 1][col];
}

動態(tài)規(guī)劃解決問題主要是兩個:

  • 拆分责嚷、劃分問題到某個顆度時,我們可以很輕易的做出決策
  • 確定狀態(tài)方程掂铐,比如上面的: f[i][j]= Math.max(f[i-1][j],f[i-1][j]-c[i]]+w[i])

源碼

源碼


END

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末罕拂,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子全陨,更是在濱河造成了極大的恐慌爆班,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辱姨,死亡現(xiàn)場離奇詭異柿菩,居然都是意外死亡,警方通過查閱死者的電腦和手機雨涛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門枢舶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人替久,你說我怎么就攤上這事凉泄。” “怎么了蚯根?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵后众,是天一觀的道長。 經(jīng)常有香客問我,道長蒂誉,這世上最難降的妖魔是什么教藻? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮拗盒,結果婚禮上,老公的妹妹穿的比我還像新娘锥债。我一直安慰自己陡蝇,他們只是感情好,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布哮肚。 她就那樣靜靜地躺著登夫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪允趟。 梳的紋絲不亂的頭發(fā)上恼策,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音潮剪,去河邊找鬼涣楷。 笑死,一個胖子當著我的面吹牛抗碰,可吹牛的內(nèi)容都是我干的狮斗。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼弧蝇,長吁一口氣:“原來是場噩夢啊……” “哼碳褒!你這毒婦竟也來了?” 一聲冷哼從身側響起看疗,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤沙峻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后两芳,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體摔寨,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年怖辆,在試婚紗的時候發(fā)現(xiàn)自己被綠了祷肯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡疗隶,死狀恐怖佑笋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情斑鼻,我是刑警寧澤蒋纬,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響蜀备,放射性物質(zhì)發(fā)生泄漏关摇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一碾阁、第九天 我趴在偏房一處隱蔽的房頂上張望输虱。 院中可真熱鬧,春花似錦脂凶、人聲如沸宪睹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽亭病。三九已至,卻和暖如春嘶居,著一層夾襖步出監(jiān)牢的瞬間罪帖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工邮屁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留整袁,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓佑吝,卻偏偏與公主長得像葬项,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子迹蛤,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344