在给定一些约束的情况下,我可以使用什么算法来验证节点列表是否可以连接?

时间:2016-04-02 22:59:15

标签: algorithm graph-theory

我正在构建一个游戏,其中玩家被给予一组随机节点,并尝试通过按特定顺序放置节点来构建最长的列表。每个节点在侧面上具有零个或多个连接,这些连接必须与列表中下一个节点侧的至少一个连接匹配。例如,节点可能如下所示:

                  +--+
left connections  A  B right connections
                  B  C
                  +--+

上述节点(示例节点)可以与任何这些节点连接:

+--+
C  |  This node can connect to the right side of the example node (matches C)
D  |
+--+

+--+
B  K  This node can connect to the left side of the example node (matches A)
L  A  This node can connect to the right side of the example node (matches B)
+--+

所以,给定这三个节点,玩家可以在列表中匹配它们:

+--+     +--+     +--+
B  K     A  B     C  |
L  A -A- B  C -C- D  |
+--+     +--+     +--+

我需要验证玩家的选择。玩家不必首先以正确的顺序选择节点,但最终的选择必须能够连接到连续的线性列表。

因此,给定一系列无序节点(玩家选择),我需要将节点组成上面的有效列表,或者向玩家显示错误。

我可以强制验证,但我希望找到一个更优雅的解决方案。

1 个答案:

答案 0 :(得分:1)

在哈希和一些预先计算之后,问题可能如下所示:

Given a graph determine whether it has a path traversing all nodes

正是the Hamiltonian problem。您可以阅读有关该主题的研究或分析图表的某些结构(对于某些特殊图表,它有简单的解决方案),但在一般情况下,我所知道的最佳解决方案是指数级的。

然而,直截了当的蛮力解决方案是通过所有排列(n!)并检查它是否形成正确的路径(*n)。这种方法导致O(n*n!)渐近。实际上,这意味着n最多应为12以进行亚秒检查,而n=15则需要几个小时才能检查最坏情况。

轻微优化 - 逐渐形成路径并检查每个新顶点 - 在最坏的情况下导致O(n!)时间,因此可以在几秒钟内检查n=13最坏的情况,甚至更快的平均值,因为很多假路径将在早期阶段被削减。

您可以更进一步,充分利用动态编程。让我们定义isProperPath[S][i](其中S是节点子集的位掩码,i是该子集的某个节点)作为对应于由对应于{的子集的节点构成的路径的存在的值{1}}与最后一个节点S。然后,根据i中包含较少元素的子集的所有值,可以轻松计算isProperPath[S][i]

S

isProperPath[S][i] = false; for (j in S) { if (isProperPath[S\i][j] && hasConnection(j, i)) isProperPath[S][i] = true; } 大小递增的顺序遍历所有Si对,我们将计算所有值。当且仅当S isProperPath[A][i] = true是整个给定集合和A - 任何节点时,答案才是真实的。

时间复杂度为i,空间复杂度为O(2^n*n^2),因为有O(2^n*n)个值,并且需要2^n*n根据以前的值计算值。该算法可以使用大约O(n)位或24在亚秒内检查大小为400M的大小集。