【问题标题】:How can I code this problem? (C++)我该如何编码这个问题? (C++)
【发布时间】:2009-10-07 09:35:59
【问题描述】:

我正在编写一个简单的游戏,它将数据集存储在 2D 网格中(如棋盘)。网格中的每个单元格可能包含一个整数(0 表示单元格为空)。如果单元格包含一个大于 0 的数字,则称其为“已填充”。网格上的一组“填充”单元称为“配置”。

我的问题是能够“识别”特定的配置,而不管单元格的配置在 MxN 网格中的什么位置。

这个问题(在我看来),分解为以下 2 个子问题:

  1. 以某种方式“规范化”配置的位置(例如,将其位置“重新定位”为 (0,0),这样包含配置中所有单元格的最小矩形的左顶点位于 (0,0 ) 在 MxN 网格中

  2. 计算某种相似性度量(或者可能只是设置差异?),以确定当前“标准化”配置是否是已知配置之一(即“已识别”)

我怀疑我将需要使用 std::set (迄今为止,我作为 C++ 编码员这么多年没有使用过的少数 STL 容器之一!)。我将不胜感激之前解决过此类问题的任何人的任何想法/提示。任何代码 sn-ps、伪代码和/或链接都会非常有用。

【问题讨论】:

  • 你想要达到的目标让我想到了 HashLife,一种用于计算元胞自动机的记忆算法。它使用四叉树表示网格,并将计算的配置存储到哈希图中,以避免多次执行相同的计算。
  • 您的问题未完全说明 - 当您希望识别一个 blob 时,板上是否有其他已归档的单元格与 blob 分开?您还谈到“相似性”——但您是在精确模式匹配还是近似模式匹配?
  • Mick:它不是我想要识别的 blob,它是网格上的整个 blob 集(即“配置”)关于相似度度量 - 相似度度量也适用于两个精确匹配作为那些仅仅“相似”的 - 通过返回适当的信息(例如,它与识别的配置有何不同)与已知配置
  • 这个问题的标题里面几乎没有信息。如果您使用描述的第二段作为标题,则更能激励人们阅读和回答问题。比如:“我如何'识别' MxN 网格中的单元格配置?”这个问题的标题要好得多。

标签: c++ matrix pattern-matching set


【解决方案1】:

相似度指标是一个庞大的学术研究领域。您需要确定您的任务所需的复杂程度。可能您可以简单地将“模板图案”拖过您的棋盘,光栅样式,并且对于每个位置得分 +1 表示命中,-1 表示未命中,然后将得分相加。然后找到模板得分最高的位置。然后这个 score_max 就是该模板的相似度指标。如果这种方法不合适,那么您可能需要更详细地了解游戏的确切性质。

【讨论】:

  • 这(得分“命中”)似乎是一个易于处理的解决方案。实际上,它给了我另一个想法——从配置中计算哈希。忽略“规范化”问题(即将配置的最左边的顶点放置在(0,0) - 你能建议一种编码配置的方法,以便可以唯一地识别它们吗?(我想这现在变成了一个编码问题)
  • 使用哈希系统。为模式模板中的每个坐标分配一个 32 位随机数。从称为种子的固定随机数开始。光栅扫描您的图案,并为每个“on”像素“XOR”对应的随机数与种子。生成的数字很可能是该模式唯一的。
  • Mick:我不确定我明白你在说什么(这听起来很复杂)。在配置上计算某种 CRC 不是更简单且同样有效吗?
  • 一目了然,CRC 的工作原理与我提出的相同(一系列 XOR 与模式中的数字)——它可能工作得很好。
【解决方案2】:

也许您可以使用一些哈希函数来识别配置。由于即使模式不在棋盘上的同一位置,您也需要识别模式,因此此哈希不应取决于单元格的位置,而应取决于它们的组织方式。

如果将二维网格存储在一维数组中,则需要找到第一个填充的单元格并从这里开始计算哈希,直到最后一个填充的单元格。

例如:

-----------------
|   |   |   |   |
-----------------
|   | X | X |   |
-----------------
|   |   | X |   |
-----------------
|   |   |   |   |
-----------------

----------------+---------------+---------------+----------------
|   |   |   |   |   | X | X |   |   |   | X |   |   |   |   |   |
----------------+---------------+---------------+----------------
                    |_______________________|
                                |
               Compute hash based on this part of the array

但是,在某些情况下这不起作用,例如当图案跨线移动时:

-----------------
|   |   |   | X |
-----------------
| X |   |   |   |
-----------------              Different configuration in 2D.
| X |   |   |   |
-----------------
|   |   |   |   |
-----------------

----------------+---------------+---------------+----------------
|   |   |   | X | X |   |   |   | X |   |   |   |   |   |   |   |
----------------+---------------+---------------+----------------
            |_______________________|
               Seems similar in 1D

因此,您需要一些方法来处理这些情况。我还没有任何解决方案,但如果我的日程安排允许,我会尝试找到一些东西!

经过一番思考,也许您可​​以对网格使用两种不同的表示形式:一种是将线附加到一维数组中,另一种是将列附加到一维数组中。哈希将使用这两种表示来计算,这将(我认为)解决上述问题。

【讨论】:

    【解决方案3】:

    这对于一个小型应用程序来说可能是多余的,但 OpenCV 有一些出色的图像识别和 blob 查找例程。如果您将 2D 板视为图像,将整数视为亮度,则应该可以使用该库中的函数。

    还有链接: http://opencv.willowgarage.com/documentation/index.html

    【讨论】:

      【解决方案4】:

      你可以使用神经网络来完成这项工作。

      如果您寻找神经网络形状识别,我认为您可以找到一些有用的东西。您可以找到大量可以帮助您的库,但是如果您没有使用 NN 的经验,这可能会有点困难,但我认为这是最简单的方法

      【讨论】:

        【解决方案5】:

        听起来您想将棋盘输入经过训练以识别配置的神经网络。

        这与图像分类的经典示例非常相似,唯一的复杂之处在于您不知道您的配置内容将出现在网格中的确切位置,除非您始终考虑整个网格 - 在这种情况下,经典的 2 层网络应该可以工作。

        HTM 神经网络实现开箱即用地解决了偏移问题。从here 开始,您可以找到大量现成的实现。显然,您将不得不调整您将找到的实现,但您应该能够准确地实现您所要求的我的理解。

        如果您想进一步调查这条路线,Numenta forum 将是一个很好的起点。

        【讨论】:

        • HTM 网络很棒,但对于 scoobydoo 的问题,它们几乎可以肯定太复杂了。我个人对 numenta 的工作很感兴趣,你可以在这里看到:www.reiss.demon.co.uk/neural/neural.htm
        • 我同意,这可能是矫枉过正。如果要始终将网格视为一个整体,那么应该很容易提出一个 NN 来对该网格上的配置进行分类。如果偏移量是 HTM 网络会遇到的问题,但您提出的模板模式解决方案无疑是一个更可行的解决方案。感谢您的链接顺便说一句
        【解决方案6】:

        这让我想起了使用 QuadTrees 的 HashLife。查看有关 HashLife 和 Quadtrees 的维基百科页面。

        在 Wikipedia 页面底部还有一个链接,指向 DrDobbs 关于实际实现这种算法的文章:http://www.ddj.com/hpc-high-performance-computing/184406478

        我希望这些链接有所帮助。如果没有别的,它们很有趣。

        【讨论】:

        • 另请注意此链接:tomas.rokicki.com/hlife 他提供了哈希生命的源代码。也许你可以从中汲取一些灵感。
        【解决方案7】:

        至于问题的第一部分,即贬低试试这个:

        用 2 个整数创建一个结构。声明该结构类型的指针。输入(或计算活细胞数量)并分配那么多存储空间(使用 calloc 等例程)。输入结构中的坐标。计算最小 x 坐标和最小 y 坐标。在宇宙中,将 [x][y](用户给定的值或当前坐标)分配给 [x-minx][y-miny] 虽然从已经填充的网格中读取时很昂贵,但可以工作并且有帮助在问题的后续部分。

        【讨论】:

          猜你喜欢
          • 2016-04-18
          • 1970-01-01
          • 1970-01-01
          • 2020-03-25
          • 2020-02-14
          • 1970-01-01
          相关资源
          最近更新 更多