高峰时间解算器禁忌列表的数据结构

时间:2013-11-01 16:29:14

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

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

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

我将我的电路板存储为汽车列表+宽度,高度和目标点(汽车最终应该在哪里)。汽车存储为2个点(左上角和右下角),完全描述汽车(因为它们只能水平或垂直放置)。

我能想到的一些事情:

  • A trie
  • 带有哈希码的东西
  • 巨大的词典(?)

我的问题有什么好/最好的数据结构?谢谢你的帮助。

编辑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。 (见下文)

2 个答案:

答案 0 :(得分:1)

感谢其他人的评论,找到了答案(或至少是答案)。我使用了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次移动的高峰时段电路板,并且内存使用量合理。

答案 1 :(得分:0)

这个效率低,但它对我有用,因为我的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();
}