摘要:背包給定一組物品,每種物品都有自己的重量和價格,在限定的總重量內(nèi),我們?nèi)绾芜x擇,才能使得物品的總價格最高。
01背包
給定一組物品,每種物品都有自己的重量和價格,在限定的總重量內(nèi),我們?nèi)绾芜x擇,才能使得物品的總價格最高。
const tList = [1, 2, 3, 4, 5] // 物品體積 const vList = [3, 4, 10, 7, 4] // 物品價值 const map = {} function getbag (i, v) { if (i === 0) { if (tList[0] > v) { return 0 } else { return vList[0] } } if (v >= tList[i]) { // 放與不放 取最大值 return Math.max(getbag(i - 1, v), vList[i] + getbag(i - 1, v - tList[i])) } else { return getbag(i - 1, v) } } console.log(getbag(5, 3))完全背包
商品不限重復(fù)次數(shù)
狀態(tài)轉(zhuǎn)移方程從01背包的f[i][j] = max(f[i-1][j], f[i-1][j-w[i] + v[i])變成f[i][j] = max(f[i-1][j], f[i-1][j-k*w[i]]+k*v[i])且0 商品限定重復(fù)次數(shù) 只需要把重復(fù)的物品都看作一個不同的物品,然后轉(zhuǎn)化成01背包即可const bag = 61
const goodList = [{
name: "apple",
w: 2,
v: 2
}, {
name: "book",
w: 3,
v: 7
}, {
name: "iphone",
w: 5,
v: 40
}, {
name: "mac",
w: 20,
v: 70
}]
const goodLen = goodList.length
const wList = goodList.map(item => {
return item.w
})
const vList = goodList.map(item => {
return item.v
})
const nList = goodList.map(item => {
return item.name
})
const map = {}
function getMax(i, j) {
let count = Math.floor(j/wList[i])
if (i === 0) {
map[i] = map[i] || {}
map[i][j] = count
return count * vList[i]
}
if (count === 0) {
map[i] = map[i] || {}
map[i][j] = 0
return getMax(i-1, j)
} else {
let maxIdx = 0
let maxVal = 0
for (let k = 1; k < count + 1; k++) {
let kr = getMax(i - 1, j - wList[i] * k) + vList[i] * k
if (kr > maxVal) {
maxVal = kr
maxIdx = k
}
}
map[i] = map[i] || {}
map[i][j] = maxIdx
return maxVal
}
}
const val = getMax(goodLen - 1, bag)
let bagCost = 0
function getSelect(i, j) {
if (i < 0) {
return
}
let count = 0
if (map[i] && map[i][j]) {
count = map[i][j]
}
bagCost += wList[i] * count
console.log(`物品${nList[i]} x ${count}`)
getSelect(i - 1, j - count * wList[i])
}
getSelect(goodLen - 1, bag)
console.log(`總價值${val}`)
console.log(`背包負載${bagCost}/${bag}`)
// 物品mac x 1
// 物品iphone x 8
// 物品book x 0
// 物品apple x 0
// 總價值390
// 背包負載60/61
多重背包
const bag = 12
const goodList = [{
name: "apple",
w: 1,
v: 2
}, {
name: "book",
w: 2,
v: 10
}, {
name: "iphone",
w: 5,
v: 40
}, {
name: "mac",
w: 10,
v: 100
}]
const goodLen = goodList.length
const wList = goodList.map(item => {
return item.w
})
const vList = goodList.map(item => {
return item.v
})
const nList = goodList.map(item => {
return item.name
})
const map = {}
const path = {}
function setMap(i, w, v) {
map[i] = map[i] || {}
map[i][w] = v
}
function setPath(i, w) {
path[i] = path[i] || {}
// 在重量為w的包里,是否放置第i個物品以達到最大價值
path[i][w] = true
}
function getMax(i, w) {
if (i === 0) {
if (wList[i] > w) {
setMap(i, w, 0)
return 0
} else {
setMap(i, w, vList[i])
setPath(i, w)
return vList[i]
}
}
if (wList[i] > w) {
let plan = getMax(i-1,w)
setMap(i, w, plan)
return plan
} else {
let planA = getMax(i-1, w)
let planB = getMax(i-1, w-wList[i]) + vList[i]
if (planB > planA) {
setMap(i, w, planB)
setPath(i, w)
return planB
} else {
setMap(i, w, planA)
return planA
}
}
}
const val = getMax(goodLen - 1, bag)
let bagCost = 0
function getSelect(i, j) {
if (i < 0) {
return []
}
let arr = []
if (path[i] && path[i][j]) {
arr.push(i)
bagCost += wList[i]
console.log(`物品${nList[i]} x 1`)
return arr.concat(getSelect(i-1, j-wList[i]))
} else {
console.log(`物品${nList[i]} x 0`)
return arr.concat(getSelect(i-1, j))
}
}
getSelect(goodLen - 1, bag)
console.log(`物品總價值${val}`)
console.log(`背包負重${bagCost}/${bag}`)
// 物品mac x 1
// 物品iphone x 0
// 物品book x 1
// 物品apple x 0
// 物品總價值110
// 背包負重12/12
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/100587.html
摘要:狀態(tài)轉(zhuǎn)移方程背包問題的狀態(tài)轉(zhuǎn)移方程是其中即表示前件物品恰放入一個容量為的背包可以獲得的最大價值。求解將哪些物品裝入背包可使這些物品的體積總和不超過背包容量,且價值總和最大。 01背包 01背包的概念 有N件物品和一個容量為V的背包。第i件物品的費用是c[i],價值是w[i]。求解將哪些物品裝入背包可使價值總和最大。從這個題目中可以看出,01背包的特點就是:每種物品僅有一件,可以選擇放或...
摘要:背包問題題目給定種物品和一個容量為的背包,物品的體積是,其價值為。用子問題定義狀態(tài)其狀態(tài)轉(zhuǎn)移方程是。 P01: 01背包問題 題目 給定 N 種物品和一個容量為 V 的背包,物品 i 的體積是 wi,其價值為 ci 。(每種物品只有一個)問:如何選擇裝入背包的物品,使得裝入背包中的物品的總價值最大? 面對每個物品,我們只有選擇放入或者不放入兩種選擇,每種物品只能放入一次。 我們用之前同...
摘要:背包問題具體例子假設(shè)現(xiàn)有容量的背包,另外有個物品,分別為,,。最后,就是動態(tài)規(guī)劃的思路了。而前個物體放入容量為的背包,又可以轉(zhuǎn)化成前個物體放入背包的問題。 背包問題具體例子:假設(shè)現(xiàn)有容量10kg的背包,另外有3個物品,分別為a1,a2,a3。物品a1重量為3kg,價值為4;物品a2重量為4kg,價值為5;物品a3重量為5kg,價值為6。將哪些物品放入背包可使得背包中的總價值最大? 首先...
摘要:動態(tài)規(guī)劃概念動態(tài)規(guī)劃過程每次決策依賴于當(dāng)前狀態(tài),又隨即引起狀態(tài)的轉(zhuǎn)移。相關(guān)文章王者編程大賽之一王者編程大賽之二蓄水池王者編程大賽之四約瑟夫環(huán)王者編程大賽之五最短路徑 首發(fā)于 樊浩柏科學(xué)院 服務(wù)目前每月會對搬家?guī)煾颠M行評級,根據(jù)師傅的評級排名結(jié)果,我們將優(yōu)先保證最優(yōu)師傅的全天訂單。 showImg(https://img3.fanhaobai.com/2017/12/2017-ziro...
摘要:遺傳算法物競天擇,適者生存,遺傳算法就是借鑒生物體自然選擇和自然遺傳機制的隨機搜索算法。隨機生成的基因適應(yīng)度的最大值隨機生成,適應(yīng)度函數(shù)計算種群中所有對象的適應(yīng)度及總和,并對超出的基因進行懲罰。 此為《算法的樂趣》讀書筆記,我用javascript(ES6)重新實現(xiàn)算法。 遺傳算法 物競天擇,適者生存,遺傳算法就是借鑒生物體自然選擇和自然遺傳機制的隨機搜索算法。算法的關(guān)鍵點有:基因的選...
閱讀 661·2019-08-30 15:44
閱讀 1383·2019-08-30 11:02
閱讀 2987·2019-08-29 18:42
閱讀 3514·2019-08-29 16:16
閱讀 1723·2019-08-26 13:55
閱讀 1773·2019-08-26 13:45
閱讀 2388·2019-08-26 11:43
閱讀 3254·2019-08-26 10:32