我有图1中的图形(第一个图像),并希望连接红色节点以具有循环,但循环不必像图2和图{{ 3}}(最后两张图片)。这个问题比TSP有更大的搜索空间,因为我们可以访问节点两次。像TSP一样,不可能在大图中评估所有组合,我应该尝试启发式,但问题是,与TSP不同,周期或游览的长度在这里不固定。因为访问所有蓝色节点不是强制性的,并且这导致具有可变长度,包括一些蓝色节点。如何在每次评估时生成可能的“有效”组合?我的意思是,一个循环可以是{A,e,B,l,k,j,D,j,k,C,g,f,e}或{A,e,B,l,k,j,D, j,i,h,g,C,g,f,e},但不是{A,e,B,l,k,C,g,f,e}或{A,B,k,C,i, d}。
更新 最终目标是在考虑长度和风险的情况下评估哪个周期最佳/接近最佳(见下文)。因此,我不仅要缩短长度,还要尽量降低风险。这导致无法评估循环风险,除非您知道其所有节点序列。希望这澄清了为什么我无法在其生成过程中评估新循环。 我们可以:
风险的定义: 假设循环是一个环,它将主节点(红色节点之一)连接到所有其他红色节点。如果环的任何部分(边缘)发生故障,则不应从主节点断开红色节点(这是期望的)。然而,我们必须传递两次边缘(由于没有连接所有红色节点的哈密尔顿循环),并且在这些边缘发生故障的情况下,一些红色节点可能完全断开。因此,周期风险是风险边缘长度的总和(我们在环/巡回赛中有两次)乘以我们在削减每个风险边缘时丢失的红色节点数。
我正在研究的包含5个红色节点和95个蓝色节点的3D图形的真实示例如下:
并且3链接到包含上图的邻接矩阵的Excel工作表(前五个节点为红色,其余为蓝色)。
答案 0 :(得分:1)
经过多次反思,我认为重写我的解决方案可能更好,因为你可以使用红色节点两次,这使得我最初的想法是将红色节点之间的路径映射效率低下。但是,它并没有完全浪费,因为红色节点之间的蓝色节点很重要。
您实际上可以使用BFS的修改版本解决此问题,因为更多的是backtracking algorithm。对于每个独特的分支,存储以下信息,其中大部分仅允许以更多空间为代价更快地拒绝,实际上只需要前两个项目:
算法从单个节点开始,然后使用BFS或DFS扩展相邻节点,这将重复直到结果是有效的游览或者要扩展的节点被拒绝。所以基本的psudoish代码(当前路径和剩余的红点)看起来如下所示。其中rn是红色节点的集合,t是有效游览的列表,p / p2是节点的路径,r / r2是一组红色节点,v是要扩展的节点,a是可能的节点扩展到。
function PATHS2HOME(G,rn)
create a queue Q
create a list t
p = empty list
v ← rn.pop()
r ← rn
add v to p
Q.enqueue((p,r))
while Q is not empty
p, r ← Q.dequeue()
if r is empty and the first and last elements of p are the same:
add p to t
else
v ← last element of p
for all vertices a in G.adjacentVertices(v) do
if canExpand(p,a)
p2 ← copy(p)
r2 ← copy(r)
add a to the end of p2
if isRedNode(a) and a in r2
remove a from r2
Q.enqueue( (p2,r2) )
return t
以下条件可防止节点扩展。可能不是一个完整的清单。
可能的优化: