我有一个锯齿状的数组,20比20。我尝试匹配700个不同的模式,这些模式就像较小的锯齿状数组一样。匹配的值(字节OR:ed在一起)可以是“播放器”,“对手”,“空”或“不关心”或这些的混合。图案尺寸范围为4x4到7x7。
我怎样才能加快速度?我相信有更好的方法可以做到这一点。现在需要大约一秒钟来检查所有模式。我需要知道所有的比赛,而不是每个模式一次。
// Iterate through all patterns
for( int patNum = 0; patNum < whitePatterns.Length; patNum++)
{
// Get current pattern
pat = whitePatterns[patNum];
col = pat.pattern.Length;
row = pat.pattern[0].Length;
for (int x = 0; x < myBoard.Size - col + 1; ++x)
{
for (int y = 0; y < myBoard.Size - row + 1; ++y)
{
for (int xx = 0; xx < col; ++xx)
for (int yy = 0; yy < row; ++yy)
{
count++;
if ((myBoard.board[x + xx][y + yy] & pat.pattern[xx][yy]) == 0)
{
goto loopY;
}
}
// Found a match!
loopY: ;
}
}
}
答案 0 :(得分:2)
有时蛮力是最好的方法。但是,您不太可能利用您的CPU。作为一个非常基本的开始,使用并行化来充分利用您的机器处理能力。
Parallel.ForEach(whitePatterns, wp =>
{
int col = wp.pattern.Length;
int row = wp.pattern[0].Length;
for (int x = 0; x < myBoard.Size - col + 1; ++x)
{
for (int y = 0; y < myBoard.Size - row + 1; ++y)
{
for (int xx = 0; xx < col; ++xx)
for (int yy = 0; yy < row; ++yy)
{
count++;
if ((myBoard.board[x + xx][y + yy] & wp.pattern[xx][yy]) == 0)
{
goto loopY;
}
}
// Found a match!
loopY: ;
}
}
});
答案 1 :(得分:1)
所以你有一套固定的模式,你想在游戏板上搜索所有这些模式。
这听起来很像是想要在大量文本中找到一组固定的搜索字符串。
我并不是说它会 easy ,但你可以从固定的模式集构建一个状态机,然后运行基本上修改了它的Aho-Corasick算法。
实际上,你要做的是每个模式的每一行被认为是一个“字符串”,你从这些模式构建Aho-Corasick树结构。然后,您将浏览整个游戏板以查找所有匹配的字符串。您的结果将是一组模式行及其起始地址(行,列)和模式编号。
按照模式编号,行编号(模式中的行编号),起始列和起始行对这些结果进行排序。然后,您可以按顺序浏览排序列表并选择匹配模式。如果第一行在游戏板位置(行,列)开始,下一行从游戏板位置(行+ 1,列)开始,则匹配模式
生成状态机需要一些(小)时间,但您只需要执行一次。之后,搜索速度非常快。对结果进行排序并选出匹配将非常快。
我在C#中构建了一个Aho-Corasick模式匹配器,可能会帮助您入门。请参阅我的文章Aho-Corasick Revisited。