Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 需要加快锯齿阵列中的模式匹配_C#_Unity3d_Pattern Matching_Jagged Arrays - Fatal编程技术网

C# 需要加快锯齿阵列中的模式匹配

C# 需要加快锯齿阵列中的模式匹配,c#,unity3d,pattern-matching,jagged-arrays,C#,Unity3d,Pattern Matching,Jagged Arrays,我有一个锯齿阵列,20乘20。我尝试匹配700种不同的模式,这些模式构建得像较小的锯齿状阵列。匹配的值(字节或:ed在一起)可以是“player”、“对手”、“empty”或“don't care”,也可以是这些值的组合。图案大小从4x4到7x7不等 我怎样才能加快速度?我相信有更好的方法可以做到这一点。现在,检查所有模式大约需要一秒钟的时间。我需要知道所有的匹配项,而不是每个模式一次 // Iterate through all patterns for( int patNum = 0; pa

我有一个锯齿阵列,20乘20。我尝试匹配700种不同的模式,这些模式构建得像较小的锯齿状阵列。匹配的值(字节或:ed在一起)可以是“player”、“对手”、“empty”或“don't care”,也可以是这些值的组合。图案大小从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: ;
        }
    }
}
//遍历所有模式
for(int patNum=0;patNum
有时候暴力是最好的方法。但是,您不太可能利用您的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: ;
    }       
}
});
Parallel.ForEach(whitePatterns,wp=>
{
int col=wp.pattern.Length;
int row=wp.pattern[0]。长度;
对于(int x=0;x
因此,您有一组固定的模式,并且希望在游戏板上搜索所有出现的模式

这听起来很可疑,就像有一组固定的搜索字符串,您希望在大量文本中查找这些字符串

我并不是说这很容易,但是你可以从固定的模式集合中构建一个状态机,然后在它上面运行一个经过修改的Aho-Corasick算法

实际上,您要做的是将每个模式的每一行都视为一个“字符串”,然后根据这些模式构建Aho-Corasick树结构。然后,在整个游戏板中查找所有匹配的字符串。您的结果将是一组模式行及其起始地址(行、列)和模式编号

按模式编号、行编号(即模式中的行编号)、起始列和起始行对这些结果进行排序。然后,您可以按顺序浏览已排序的列表并选择匹配的模式。如果模式的第一行开始于游戏板位置(行,列),下一行开始于游戏板位置(行+1,列),则模式匹配

生成状态机需要一些(少量)时间,但您只需执行一次。在那之后,搜索速度惊人地快。对结果进行排序并找出匹配项将非常快


我用C#构建了一个Aho-Corasick模式匹配器,它可能会帮助您开始。请参阅我的文章。

您是否尝试过用Parallel.ForEach()替换模式迭代器?暴力攻击没有神奇的解决方法。但它似乎非常适合并行化。你可以使用4x4组合的字典。这将使全部或部分查找非常快速,但是创建这样的字典并提供查找将增加复杂性并需要一些时间。我使用的Unity使用Mono 2.6,看起来它不支持Parallel.ForEach。将找到一种尝试并行化模式循环的方法。根据要做的工作量,您可能希望更改
for
并行。ForEach
Parallel.for
。对于700个测试项目来说,这个答案可能是正确的。我强烈建议您查看Microsoft“”提供的免费书籍。特别是查看反模式“太细粒度,太粗粒度”,以了解更多关于为循环并行嵌套的
。@ScottChamberlain对此表示感谢。我以前从未遇到过这种情况。我真的会喜欢这本书的。:-)使用不支持Parallel.ForEach的Unity。我将检查如何在Unity中实现它。嗨,Jon,我不确定你是否得到了这个,我发现了一个与.NET3.5兼容的版本。这是一个并行程序。例如,当迭代whitepatterns的长度并打印索引时,它就像一个符咒,但是如果我在上面的代码中尝试它,我会得到一个超出范围的数组。有什么线索能导致这种情况吗?我需要某种密码锁吗?@Andreas太好了。你不需要锁。当数组超出边界时,在某个地方生成的数字超出了一个数组的范围,但是如果没有完整的代码,我无法确定在哪里。我只能建议您在Parallel.For循环之外放置一些全局变量来捕获col、row、x、y、xx和wp。然后并行包装。对于每个循环,在一次尝试中,将当前变量的值写入全局变量,在异常点设置断点,全局变量会让您了解其失败的原因。感谢您的建议,我将阅读您的文章。这需要对模式进行一些处理,但最终可能是值得的:)