当前位置: 首页 > news >正文

Javascript动态规划算法

JavaScript中的动态规划(Dynamic Programming,简称DP)是一种通过把原问题分解为相对简单的子问题的方式来求解复杂问题的方法。它主要致力于将“合适”的问题拆分成更小的子目标,并通过建立状态转移方程、缓存并复用以往结果以及按顺序从小往大算这三个步骤来解决问题。以下是对js动态规划算法的详细解析:

一、动态规划的基本概念

  1. 状态转移方程:动态规划的核心是找到一个能够描述问题状态转移的数学方程,即状态转移方程。这个方程描述了如何从较小的子问题的解推导出较大问题的解。
  2. 缓存并复用以往结果:为了避免重复计算,动态规划会将已经计算过的子问题的解存储起来,以便在后续的计算中直接引用。这通常通过一个数组或对象来实现,称为DP表。
  3. 按顺序从小往大算:动态规划通常按照某种顺序(如从小到大的子问题规模)来计算子问题的解,并最终得到原问题的解。

二、动态规划的应用示例

  1. 斐波那契数列

斐波那契数列是一个经典的动态规划问题。数列中的每个数字是前两个数字之和,通常以0和1开始。使用动态规划可以避免直接递归方法中的大量重复计算。

JavaScript代码示例:

function fibonacci(n, memo = []) {  // 初始化记忆数组  memo[0] = 0;  memo[1] = 1;  // 如果已经计算过该值,直接从记忆数组返回  if (memo[n] !== undefined) {  return memo[n];  }  // 递归计算斐波那契数,同时利用记忆化存储结果  memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo);  return memo[n];  
}  // 示例  
console.log(fibonacci(10)); // 输出第10个斐波那契数

在这个例子中,memo数组用于存储已经计算过的斐波那契数,从而避免了重复计算。

  1. 01背包问题

01背包问题是另一个经典的动态规划问题。它描述了一个背包可以装载的最大重量为W,有N件物品,每件物品有一个重量和一个价值。要求选择若干件物品装入背包,使得背包中物品的总价值最大,同时不超过背包的最大重量。

JavaScript代码示例:

const w = [1, 4, 3]; // 物品重量  
const value = [1500, 3000, 2000]; // 物品的价值  
const m = 4; // 背包容量  
const n = 3; // 物品的个数  // 二维数组v[i][j]表示在前i个物品中能够装入容量为j的背包中的最大价值  
let v = new Array(n + 1).fill(0).map(() => new Array(m + 1).fill(0));  // 遍历物品和背包容量  
for (let i = 1; i <= n; i++) {  for (let j = 1; j <= m; j++) {  if (w[i - 1] > j) {  v[i][j] = v[i - 1][j];  } else {  v[i][j] = Math.max(v[i - 1][j], value[i - 1] + v[i - 1][j - w[i - 1]]);  }  }  
}  console.log(v[n][m]); // 输出最大价值

核心:Math.max(v[i-1][j],  value[i - 1] + v[i - 1][j - w[i - 1]])

在这个例子中,二维数组v用于存储子问题的解。通过遍历物品和背包容量,可以逐步计算出在前i个物品中能够装入容量为j的背包中的最大价值。 

 

放了那些商品?【待思考】

function knapsack(weights, values, maxWeight) {  const n = weights.length;  // 创建一个二维数组dp,dp[i][w]表示前i个物品在重量不超过w的情况下的最大价值  const dp = Array.from({ length: n + 1 }, () => Array(maxWeight + 1).fill(0));  // 记录选择的物品  const selectedItems = Array.from({ length: n + 1 }, () => Array(maxWeight + 1).fill(false));  // 动态规划填表  for (let i = 1; i <= n; i++) {  for (let w = 0; w <= maxWeight; w++) {  if (weights[i - 1] <= w) {  if (dp[i - 1][w] + values[i - 1] > dp[i - 1][w]) {  dp[i][w] = dp[i - 1][w] + values[i - 1];  selectedItems[i][w] = true;  } else {  dp[i][w] = dp[i - 1][w];  }  } else {  dp[i][w] = dp[i - 1][w];  }  }  }  // 最大价值  const maxValue = dp[n][maxWeight];  // 追溯选择的物品  const selected = [];  let currentWeight = maxWeight;  for (let i = n; i > 0; i--) {  if (selectedItems[i][currentWeight] && dp[i][currentWeight] !== dp[i - 1][currentWeight]) {  selected.push(i - 1); // 物品索引从0开始,需要减1  currentWeight -= weights[i - 1];  }  }  return {  maxValue: maxValue,  selectedItems: selected  };  
}  // 示例  
const weights = [2, 3, 4, 5];  
const values = [3, 4, 5, 6];  
const maxWeight = 5;  const result = knapsack(weights, values, maxWeight);  
console.log(`最大价值: ${result.maxValue}`);  
console.log(`选择的物品索引: ${result.selectedItems}`);  
console.log(`选择的物品: ${result.selectedItems.map(index => `物品${index + 1}`).join(', ')}`);

三、动态规划的优点和局限性

  1. 优点

    • 能够高效地解决具有重叠子问题的问题。
    • 通过缓存和复用以往结果,避免了大量的重复计算。
  2. 局限性

    • 只适用于具有最优子结构和重叠子问题的问题。
    • 对于某些问题,可能需要大量的空间来存储子问题的解(即DP表)。

四、总结

JavaScript中的动态规划是一种强大的算法设计范式,适用于解决具有重叠子问题的问题。通过建立状态转移方程、缓存并复用以往结果以及按顺序从小往大算这三个步骤,可以高效地求解复杂问题。然而,动态规划也有一定的局限性,只适用于具有最优子结构和重叠子问题的问题。在实际应用中,需要根据问题的特点选择合适的算法设计范式来求解。

http://www.lryc.cn/news/457640.html

相关文章:

  • Java 循环里怎么删除元素才安全
  • LabVIEW晶体振荡器自动化测试系统
  • 3.6.xx版本SpringBoot创建基于Swagger接口文档
  • Oracle 12201非PDBS模式单机部署(静默安装)
  • Python 源码编译安装详解:跨平台指南及完整步骤解析
  • MQTT vs HTTP:谁更适合物联网?
  • 小北的技术博客:探索华为昇腾CANN训练营与AI技术创新——Ascend C算子开发能力认证考试(初级)
  • 鸿蒙next开发者第一课02.DevEcoStudio的使用-习题
  • 【vue】监听table水平滚动条切换tab后还原位置
  • C#使用PdfSharp生成PDF文件实例详解
  • 【软件系统架构设计师-案例-1】架构风格
  • 神经网络整体架构
  • 山西农业大学20241010
  • 小北的技术博客:探索华为昇腾CANN训练营与AI技术创新——Ascend C算子开发能力认证考试(中级)
  • Docker极速入门一文通
  • Unity网络开发基础 —— 实践小项目
  • 四、Spring Boot集成Spring Security之认证流程
  • Chromium 中chrome.bookmarks扩展接口c++实现
  • 编程思想:编程范式:响应式编程
  • Leetcode 颜色分类
  • ssh连接阿里云长连接
  • 栈的C实现
  • 【MySQL】入门篇—数据库基础:关系数据库概念
  • 不到千元的自动猫砂盆是智商税吗?这四大选购技巧不看就亏大了
  • 【图论】(二)图论基础与路径问题
  • Git常用命令(持续更新中)
  • 什么是PLM系统?PLM系统对制造业起到哪些作用?三品PLM系统对汽车制造业意义
  • Pr 视频效果:元数据和时间码刻录
  • 前端MD5加密
  • 仿IOS桌面悬浮球(支持拖拽、自动吸附、自动改变透明度与点击、兼容PC端与移动端)