【问题标题】:Data structure for Rush Hour solver taboo listRush Hour求解器禁忌列表的数据结构
【发布时间】:2013-11-01 16:29:14
【问题描述】:

我正在使用广度优先搜索来解决rush hour game。它工作正常,但在困难的板上需要很长时间。我使用禁忌列表来避免我已经发现的状态,以避免疯狂的内存使用并提高运行时间。

我认为这个禁忌清单是长期运行的主要原因。与普通 BFS 相比,它确实大大缩短了时间,但它仍然太慢了。目前我使用的是普通列表(C# 的ListList.Contains 方法)。我相信还有更好的选择。

我将我的电路板存储为汽车列表 + 宽度、高度和目标点(您的汽车应该结束的位置)。 a Car 存储为完全描述汽车的 2 个点(左上角和右下角)(因为它们只能水平或垂直放置)。

我能想到的一些事情:

  • 试一试
  • 带有哈希码的东西
  • 庞大的字典 (?)

对于我的问题,什么是好的/最好的数据结构?感谢您的帮助。

编辑 1: 伪代码(X为禁忌列表类型):

void Solve(Board b)
    Queue q = {b};
    X taboo = {b};
    while (q not empty)
        Board next = q.Dequeue();
        foreach (Board succ in next.Successors)
            if (succ.IsSolved)
                PrintSolution();
                return;
            if (!taboo.Contains(succ))
                q.Enqueue(succ);
                taboo.Add(succ);
    WriteLine("No solution found");

编辑 2: 解决方案是使用 HashSet。 (见下文)

【问题讨论】:

  • 我即将建议您使用 HashSet,但实际上并不知道我是否回答了正确的问题。您能否通过发布一些示例代码来阐明禁忌列表的使用方式?
  • 我已经添加了我的 BFS 算法的伪代码。我认为 HashSet 确实是最好的解决方案,但问题是我不知道一个好的哈希函数。你能推荐一个吗?
  • 愚蠢的答案,但你确定禁忌列表真的提高了性能吗?你试过没有它吗?
  • 更新:找到一个有效的哈希函数真的很容易,因为汽车总是以相同的顺序存储。对于那些感兴趣的人,我将把这个功能添加到我的问题中。 @PerLundberg:是的,我在没有禁忌列表的情况下尝试过它,它炸毁了我的笔记本电脑(内存错误和很长的运行时间)。
  • @WouterFlorijn - 您可以在答案中发布您的解决方案。

标签: c# data-structures breadth-first-search solver hour


【解决方案1】:

感谢其他人的 cmets,找到了答案(或至少是一个答案)。我使用了 C# 的 HashSet 数据结构和下面的板哈希函数:

public override int GetHashCode()
{
    int hash = 0;
    int mul = 1;
    foreach (Car c in Cars.Values)
    {
        hash += (c.P1.X + c.P1.Y * W) * mul;
        mul += W * H;
    }
    return hash;
}

这似乎工作正常,并为每个板提供唯一的哈希码(如果我错了,请纠正我),假设汽车总是以相同的顺序存储并且 P1 代表汽车的左上角。

有了这个解决方案,我现在可以解决需要在 0.5 秒内完成 50 次移动的高峰时段棋盘,并且内存使用量合理。

【讨论】:

    【解决方案2】:

    这个效率很低,但它对我有用,因为我的 RushHour 总体上非常快。

    public string HashCode()
    {
        StringBuilder str = new StringBuilder();
        foreach (Car car in this.Positions)
        {
            //#yolo
            str.Append(string.Format("#{0}({1},{2})#", car.Original, car.Vector.X, car.Vector.Y));
        }
        return str.ToString();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-16
      • 2017-01-10
      • 2019-02-11
      相关资源
      最近更新 更多