博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javascript算法基础之01背包,完全背包,多重背包实现
阅读量:6581 次
发布时间:2019-06-24

本文共 3576 字,大约阅读时间需要 11 分钟。

01背包

给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。

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))

完全背包

  • 商品不限重复次数
  • 状态转移方程从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<k<j/w[i]
const bag = 61const 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.lengthconst 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 = 0function 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

多重背包

  • 商品限定重复次数
  • 只需要把重复的物品都看作一个不同的物品,然后转化成01背包即可

01背包带路径

const bag = 12const 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.lengthconst 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 = 0function 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

转载地址:http://xiino.baihongyu.com/

你可能感兴趣的文章
运筹学上机实验 - 单纯形方法的两阶段法
查看>>
CF294C Shaass and Lights
查看>>
oracle 11g 报错记录
查看>>
文件状态是否变化
查看>>
MongoDB的副本集Replica Set
查看>>
Maven项目中的配置文件找不到以及打包问题
查看>>
面向对象
查看>>
HDU 1058 Humble Numbers
查看>>
NYOJ The Triangle
查看>>
wps10.1中将txt转为excel
查看>>
并发同步知多少
查看>>
解决执行脚本报syntax error: unexpected end of file或syntax error near unexpected token `fi'错误的问题...
查看>>
[BZOJ3312][USACO]不找零(状压DP)
查看>>
gtp转换mbr
查看>>
django rest framework
查看>>
poj1985 求树的直径
查看>>
Python PyPI中国镜像
查看>>
centos 设置静态IP
查看>>
[Angularjs]系列——学习与实践
查看>>
js -- canvas img 封装
查看>>