Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.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
Algorithm 在给定一些约束的情况下,我可以使用什么算法来验证节点列表是否可以连接?_Algorithm_Graph Theory - Fatal编程技术网

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

Algorithm 在给定一些约束的情况下,我可以使用什么算法来验证节点列表是否可以连接?,algorithm,graph-theory,Algorithm,Graph Theory,我正在构建一个游戏,在这个游戏中,玩家被赋予一组随机的节点,并试图通过按一定顺序放置节点来构建最长的列表。每个节点的两侧都有零个或多个连接,这些连接必须与列表中下一个节点一侧的至少一个连接相匹配。例如,节点可能如下所示: +--+ left connections A B right connections B C +--+ Given a graph determine whet

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

                  +--+
left connections  A  B right connections
                  B  C
                  +--+
Given a graph determine whether it has a path traversing all nodes
上述节点(示例节点)可以与以下任何节点连接:

+--+
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  |
+--+     +--+     +--+
我需要确认玩家的选择。玩家不必首先以正确的顺序选择节点,但最终选择的节点必须能够连接到连续的线性列表中

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


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

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

                  +--+
left connections  A  B right connections
                  B  C
                  +--+
Given a graph determine whether it has a path traversing all nodes
确实如此。你可以阅读关于这个主题的研究,或者分析你的图的某些结构(对于一些特殊的图,它有简单的解),但在一般情况下,我知道的最好的解是指数解

然而,简单的暴力解决方案是遍历所有排列(
n!
)并检查它是否形成正确的路径(
*n
)。这种方法导致
O(n*n!)
渐近。实际上,这意味着对于亚秒检查,
n
的最大值应为
12
,对于
n=15
,在最坏的情况下检查需要几个小时

轻微的优化-逐渐形成路径并检查每个新顶点-在最坏的情况下会导致
O(n!)
时间,因此在最坏的情况下可以在几秒钟内检查
n=13
,平均速度更快,因为在早期阶段会切割大量错误路径

您可以进一步利用动态规划。让我们将
ispropertpath[S][i]
(其中
S
是节点子集的位掩码,
i
是该子集的某个节点)定义为与存在路径相对应的值,该路径由与最后一个节点
i
相对应的子集的节点构成。然后,根据元素少于
S
的子集的所有值,很容易计算
ispropertpath[S][i]

isProperPath[S][i] = false;
for (j in S) {
    if (isProperPath[S\i][j] && hasConnection(j, i))
        isProperPath[S][i] = true;
}
通过按
S
的升序遍历所有
S
i
对,我们将计算所有值。当且仅当
ispropertpath[A][i]=true
时,答案为true,其中
A
是整个给定集,
i
是任何节点


时间复杂度是
O(2^n*n^2)
,空间复杂度是
O(2^n*n)
,因为存在
2^n*n
值,并且需要
O(n)
根据以前的值计算值。该算法可以在亚秒的时间内利用大约400M的位或50Mb的位来检查小于等于24的集合,这些集合有多大?如果不是很复杂,那么比暴力更复杂的东西可能不值得费心。对于大的集合,动态规划可能是合适的。@ScottHunter玩家的选择可能有5或6个节点长。从左到右追踪一条没有循环的路径难道还不够吗?i、 e.在链接
-a-
上只能向一个方向(右)移动,并且只能向上/向下/向右移动。如果您担心用户构建的多条路径可能会死胡同,那么您实际上是在寻找一个树的深度优先遍历,其中至少有一片叶子到达目标“侧”。如果您想要最短路径,我想dykstra的算法可能在这里工作(但我对它有点模糊)。