【问题标题】:Having trouble optimizing Iterative Deepening Rush Hour algorithm in JavaScript在 JavaScript 中优化迭代深化高峰时间算法时遇到问题
【发布时间】:2016-07-06 02:22:26
【问题描述】:

我有一个学校作业,要做一个迭代深化算法来解决一个 6x6 的高峰时间难题。我选择使用 JavaScript 是因为我需要练习。但是,我在优化算法时遇到了麻烦。

我试图解决一个难题,它的解决方案在树中的 8 个级别中,我发现我访问了 7,350,669 个节点,我的计算机花了将近 13 分钟来解决。

我正在寻找有关理解算法本身的提示和帮助。

我做了 2 个类 - 节点和车辆。这些的实现可能是问题的一部分:

class Vehicle {
  constructor(x,y,length,horizontal){
    this.x = x; //X position of the upper/left block of the vehicle
    this.y = y; //y postion
    this.length = length; //length of the vehicle
    this.horizontal = horizontal; //boolean - false if vertical
  }
}

class Node {
  constructor(grid,vehicles,moved,depth){
    this.grid = grid; //A 6x6 char array grid
    this.vehicles = vehicles; //array of vehicles on the game board
    this.moved = moved; //index of vehicle moved in last turn
    this.depth = depth; //Depth of this node
  }
}

我是否正确地假设,同时拥有一个用于网格的“二维”数组以及一个车辆数组是一种矫枉过正的做法?在检查可能的运动时,我会遍历车辆数组,但使用网格来快速检查车辆是否有空路。我会回到我看到的问题。

我不能公开发布该算法的代码,但这是我理解 IDDFS 并实现该算法的方式:

  1. 检查当前节点是否为最终状态,如果是则将其添加到解决方案数组中并返回true。
  2. 否则检查是否达到 maxDepth,如果达到则返回 false。
  3. 如果不是,则为处于此状态的每辆车创建新节点,用于它们可以进行的所有移动(除了在最后移动中移动的那些)
  4. 访问您刚刚创建的所有孩子(返回第 1 步),如果它们返回 false,则将其删除。
  5. 如果没有子节点显示为最终状态,则返回父节点并探索其邻居。否则返回真正的连锁反应。
  6. 重复直到找到最终状态。如果回到顶部,则将 maxDepth 增加 1 并重复整个过程。

我看到的一个问题是我的数据结构可能有点复杂。由于 JavaScript 将对象和对象数组作为引用传递,因此必须使用以下方法对其进行深度复制:

JSON.parse(JSON.stringify(node))

这里的主要问题是 - 我错过了什么吗?删除“坏”子节点并在迭代深化算法中一次又一次地遍历整个树是否正确,还是我误解了这一点?它们是否只是应该被标记为“已检查”,然后返回,然后稍后再通过它们,以便不必再次生成整个树?

【问题讨论】:

    标签: javascript arrays algorithm iterative-deepening


    【解决方案1】:

    首先,您必须分析您的代码执行情况。否则,这只是猜测,您可能会花费大量时间更改代码以获得 0.1% 的收益。

    牢记上述内容,当您知道对象的结构(如此处所示)时,您可以通过手动复制每个属性而不是使用stringify 来更快地克隆对象。

    【讨论】:

    • 哇,我不知道!我们刚刚下降到 47 秒!!!这大约减少了 95% 的时间。你太棒了,谢谢你:)
    • @PeterTheLobster 不客气!但正如我所说,这是一个没有分析的幸运猜测。您还在寻找其他改进吗?
    • 是的,当然 :) 但是我今天还没睡,我仍然需要弄清楚如何确定一个谜题是否完全没有解决方案。所以我想我会先睡觉。你帮了很多忙,再次感谢你:)
    • 我仍然无法弄清楚如何确定一个谜题没有解决方案。我想我能弄清楚的唯一方法是,每次我生成一个新的状态节点时,我都必须以某种方式检查所有以前生成的节点,以确定该状态是否已经生成并重复直到没有新的状态可以生成。然而,这对我来说似乎非常昂贵。有没有更有效的解决方案?
    • 如果你碰巧回到顶部没有达到最大深度,它不能自然停止吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多