保持有关访问状态的信息的想法

时间:2011-04-14 09:49:14

标签: c++ algorithm data-structures map hash-function

我现在制作了15个拼图解算器(用c ++编写),但是我的程序必须解决3x4拼图,8x8拼图等问题,而不仅仅是15拼图... - > X x Y拼图。我必须以某种方式保存有关访问状态的信息,我的第一个想法是制作树,例如:
拼图:

  

国家1   1 2
  3 0
  
国2   1 3
  0 2

我留在树上:

  

根 - > 1→2→3→0
        \ _
            \ - 将3-→0→2

对于所有谜题,这也适用于拼图5x3,6x6等

这个想法有效,但它浪费了大量内存,而且要添加节点,需要一些时间:/所以效率非常低。

接下来的想法是在stl的std :: map<中保持访问状态。 > ,但我不知道如何制作好的哈希函数 - 从拼图状态制作快捷方式(beacouse我不必存储拼图状态,我只需要访问信息。你有任何想法,对于std的关键::地图,或其他关于保持信息的想法已被国家访问过?

3 个答案:

答案 0 :(得分:2)

假设您只对解决X * Y的问题感兴趣,其中X,Y <= 16.我用X * Y字节数组表示拼图的状态,其中每个字节给出a的值拼图中的方块。在奇怪的基础中使用字节而不是BigInteger可能会给你更快的访问和修改时间,因为位运算往往很慢,并且在内存/速度权衡方面可能不是一个好的整体方法。

template<unsigned X, unsigned Y>
class PuzzleState {
    unsigned char state[X*Y];
    public:
    void set(unsigned x, unsigned y, unsigned char v) {
        state[x+X*y] = v;
    }
    unsigned get(unsigned x, unsigned y) {
        return state[x+X*y];
    }
    bool operator<(const PuzzleState<X, Y>& other) const {
        return memcmp(state, other.state, X*Y) < 0;
    }
};

然后只需使用std::set<PuzzleState<8,8 >insert方法find。在测试性能是否仍然不合适之后,您可以使用简单的哈希函数(例如Rolling hash)抛出哈希表而不是std::set

答案 1 :(得分:1)

我将单个状态表示为BigInteger数字(可用的c ++实现here,或者如果您想实现自己的here也是一个线程)。< / p>

假设你有一个带有(X,Y)尺寸的拼图,你可以用base = X * Y创建一个数字,这个数字的数字代表拼成一个尺寸的拼图。

例如:

State 1
1 2
3 0

这将被夷为平地

1 2 3 0

然后转换为基数为4的数字,如:

state = (1 * (4^3)) + (2 * (4^2)) + (3 * 4) + 0;

这将唯一地识别任何难题的任何给定状态。

答案 2 :(得分:1)

Zobrist hashing在玩抽象游戏的程序中几乎无处不在。