给定一个undirected graph,其中每个节点在空间中具有一般树形状的笛卡尔坐标,是否有算法将图形转换为树,并找到合适的根节点?
请注意,我们对“树”的定义要求分支在锐角处不会偏离父节点。
请参阅下面的示例图表。我们如何找到红色节点?
答案 0 :(得分:10)
这是一个关于如何解决问题的建议。
g
图表,g.v
图顶点v,w,z
:个别顶点e
:个人优势n
:顶点数g
隐含的有向树中的方向补充g
的边缘,并通过g
节点处的本地计算补充尚未找到的根节点。 / LI>
v -> w
:v
子级,w
父级。假设图形/树结构的标准表示(例如邻接列表)
g.v
中的所有顶点最初都标记为未访问,未完成。以任意顺序访问所有顶点。跳过标记为“已完成”的节点
让v
成为当前访问的顶点。
v
的所有边缘,从边缘角度e_0
的随机选择的e_0
开始。 2.2。定向相邻边e_1=(v,w_1), e_2(v,w_2)
,包围锐角
相邻:wrt根据它们与e_0
包围的角度进行排序。
[注意:不保证存在这样的一对,见第2条评论和最后评论。如果没有锐角,请在2.下一个节点处继续。 ]
2.2.1已知边e_1, e_2
的方向:
w_1 -> v -> w_2
:不可能,因为祖父母 - 儿童片段会包含锐角w_1 <- v <- w_2
:不可能,同样的原因 w_1 <- v -> w_2
:不可能,树中没有outdegree&gt; 1的节点
w_1 -> v <- w_2
:
只有可能的一对方向。 e_1, e_2
之前可能已被定位。如果先前的方向违反了当前的分配,则问题实例没有解决方案。
2.2.2此赋值意味着子图上的树结构由w_1
(w_2
)在不包含e_1 (
e_2`的路径上可到达的所有顶点引起。将两个诱导子树中的所有顶点标记为已完成
[注意:子树结构可能违反了角度约束。在这种情况下,问题没有解决方案。 ]
2.3标记v
已访问过。在顶点v
完成步骤2.2后,检查连接尚未指定方向的边的数量nc
。
nc = 0
:这是您一直在寻找的根 - 但您必须检查解决方案是否与您的约束兼容。 nc = 1
:将此边缘设为(v,z)
当你在树中时,这条边的方向是v-> z。将v标记为已完成。
z
是否标记为已完成。
如果不是,请检查连接nc2
的无定向边的数量z
。
nc2
= 1:将z
用于v
,重复步骤2.3。 如果您还没有找到根节点,则您的问题实例不明确: 随意定向剩余的无定向边缘。
终止: 每个节点最多访问4次:
正确性:
复杂性(时间):
顺时针扫过连接给定顶点的所有边需要对这些边进行排序
因此,您需要在约束O( sum_i=1..m ( k_i * lg k_i ) )
下的m <= n
个顶点sum_i=1..m k_i = n
O ( n * lg n)
。
总共需要sum_i=1..m ( k_i * lg k_i ) <= n * lg n
,sum_i=1..m k_i = n
为m <= n
O(n)
任意O(n)
(可通过应用拉格朗日优化来证明)。
[注意:如果你的树有一个由常数限定的度数,理论上你会在每个受影响的节点上按时间排序;在这种情况下的总计:O(n * lg n)
]
子树标记:
如果实现为dfs,则通过此过程最多访问图中的每个节点2次。因此,调用此子例程的总计为O(n)
。
总计:{{1}}
复杂性(空间):
问题可能不明确:
答案 1 :(得分:0)
一个简单的解决方案是在红色节点或节点中心周围定义一个2d矩形,并用摩尔曲线计算每个节点。摩尔曲线是一个空间填充曲线,更多的是希尔伯特曲线的特殊版本,其中起点和终点相同,坐标位于2d矩形的中间。在一般情况下,您的问题看起来像是一个离散的寻址空间问题。