我有一个定向的彩色图形(每个节点都有一个颜色),我想查找是否存在从节点A到节点B的路径,以便路径在MOST一次通过每种颜色。
我认为这个问题可以用网络流程来制定。不知何故,如果节点重复,可以对相同颜色的节点施加惩罚,使得流0或无穷大。
谢谢!
答案 0 :(得分:1)
只需执行普通的DFS,但也要保留颜色列表和每个的布尔值。如果您要访问具有某种颜色的节点,并且相应的布尔值为false,请将其设置为true并访问它;否则不要访问该节点并继续递归。如果你没有到达B就终止,那么显然没有路径。
编辑:如果某些选定的路径不起作用,并且递归回溯,重置与您回溯过去的节点颜色相关联的布尔值。
答案 1 :(得分:1)
假设您想使用搜索算法进行此操作,您最有可能使用深度优先回溯,从图表中删除(或标记已经访问过)您访问的每个节点
将为访问的颜色保留哈希表,以快速检查您找到的每种新颜色(如果已知或未知)(或检查图表上的访问路径,从A到C [=当前]或从C到A [无关紧要] ]如果您不能使用单独的结构,但只在图表上附加属性。)
对于回溯,您可以在从导致死端的传出链接回溯到节点(无法到达B)之后检查下一个传出链接。这假设链接有一些隐式排序(可以请求下一个链接 - 并检查它是否是一个外发链接或请求下一个链接,直到没有更多可用 - 当你有一个节点和一些其他外向链接时,你通过它回溯时回来))
然而,应该有更好的算法对图形进行一些(可并行化的)预处理,并在节点和/或链接上附加值,以帮助从给定颜色或任何颜色中搜索
答案 2 :(得分:1)
这是NP-hard通过减少特殊情况"路径与禁止对"所有禁止对都要求不相交的问题。只需为每个禁用对分配一些颜色。 "带有禁止对的路径"是一个众所周知的NP难问题(即使在不相交的情况下,它仍然是NP难的)。在Garey和Johnson的书中,它有标识符" GT54"。
但是如果非唯一颜色(k
)的数量是一个小常数,则可以应用具有时间复杂度O的修改后的BFS算法(| E | * 2 2 * k )
这里我解释一下这个BFS算法(从简化版开始):
路径访问的所有节点的颜色应编码为bitset,例如,如果我们有3种可用颜色(红色,绿色,蓝色)和访问绿色节点的路径,则编码为010
;在此路径也访问红色节点后,它被编码为011
。路径颜色与最后访问的节点一起存储在BFS队列中。
每个节点都应存储一些"访问过的"每种颜色组合的标志。假设有三种颜色的示例,每个未访问的节点将存储8个布尔值" false"值。用红色/绿色路径访问此节点后,其访问了#34;标志应更改为以下内容:
index.bool index.dec visited_flag
000 0 false
001 1 false
010 2 false
011 3 true
100 4 false
101 5 false
110 6 false
111 7 false
如果算法在处理具有相同颜色组合的路径时遇到相同的节点,则应该忽略它,因为" true"参观过国旗。
BFS算法主循环的伪代码可以改写为:
while Q is not empty:
(u, c) = Q.dequeue()
for each node n that is adjacent to u:
if (c & n.color) == 0 && n.visited[c] == false:
n.visited[c] = true
Q.enqueue((n, c | n.color))
算法像往常一样终止:到达目标(路径存在)或BFS队列变空(路径不存在)。
该算法的最坏情况时间复杂度为O(| E | * 2 k )。它还在做很多冗余的工作。由于在BFS算法中,较短(且较少彩色)的路径被认为比较长的路径更早,因此可能首先使用红色路径访问某个节点,然后通过绿色路径访问,然后通过红色/绿色路径访问。在这种情况下,处理此红色/绿色路径无法提供任何改进。这意味着我们可以通过将红色/绿色标记为"访问"来加速算法。早些时候,处理绿色路径。这种优化不是免费的:它需要在处理每个路径/节点组合时标记几个标志,并且它将最坏情况时间复杂度增加到O(| E | * 2 2 * k )。但是所有额外的工作都是在节点内部完成的。此外,如果所有2个 k 标志都适合单个CPU寄存器,则所有这些工作都可以并行完成,并采用按位逻辑运算。