无向图转换为树
Posted
技术标签:
【中文标题】无向图转换为树【英文标题】:Undirected graph conversion to tree 【发布时间】:2011-12-22 22:40:52 【问题描述】:给定一个undirected graph,其中每个节点在空间中都有一个笛卡尔坐标,具有树的一般形状,是否有算法将图形转换为树,并找到合适的根节点?
请注意,我们对“树”的定义要求分支不能以锐角偏离父节点。
请参阅下面的示例图。我们如何找到红色节点?
【问题讨论】:
在这个例子中的无向图中,任何节点都可以作为根,你会得到一棵合适的树。如果我做对了,哪个节点将成为根取决于节点的空间排列。但我不清楚如何,以及“分支不会以锐角偏离父节点”的意思。你能澄清一下吗?你能解释一下吗?为什么最上面或最右边的节点不能成为您的应用程序的根? @paniwani:您的意思是说,将兄弟姐妹链接到其(公共)父节点的分支之间的角度一定不是锐角吗?除了坐标和图形结构之外,您还有什么数据结构可以处理吗?除了根节点的度数,你的树是二元的吗?二叉树会更容易处理,因为相邻边之间的 3 个角度中恰好有 1 个是锐角,因此可以在本地确定父/子关系。 @paniwani:请注意,您的问题似乎定义不明确:考虑任何 steiner 树;分支之间根本没有没有锐角。因此任何节点都可以被选为根节点而不会违反您的约束 不能每个节点都是树的根,这取决于您如何看待图表? 【参考方案1】:这里是关于如何解决您的问题的建议。
先决条件
符号:g
图,g.v
图顶点
v,w,z
:单个顶点
e
: 个人优势
n
: 顶点数
无向树 g 和给定节点 g.v 的任何组合唯一地确定具有根 g.v 的有向树(可通过归纳证明)
想法
通过g
隐含的有向树中的方向补足g
的边,并通过g
节点处的局部计算补足尚未找到的根节点。
这些方向将代表节点之间的子父关系(v -> w
:v
子,w
父)。
完全标记的树将包含一个出度为 0 的唯一节点,这是所需的根节点。您最终可能会得到 0 个或多个根节点。
算法
假定图/树结构的标准表示(例如邻接表)
g.v
中的所有顶点最初都标记为未访问,未完成。
以任意顺序访问所有顶点。跳过标记为“已完成”的节点。
让v
成为当前访问的顶点。
e_0
开始顺时针扫过链接v
的所有边,按照边与e_0
的角度顺序排列。
2.2。定向相邻的边缘e_1=(v,w_1), e_2(v,w_2)
,它们包围一个锐角。
相邻:wrt 根据它们与e_0
包围的角度进行排序。
[注意:不能保证这样一对的存在,请参阅第二条评论和最后一条评论。如果没有锐角,则从 2. 处理下一个节点。 ]
2.2.1 边e_1, e_2
的方向是已知的:
w_1 -> v -> w_2
: 不可能,因为祖父子段会包围一个锐角
w_1 <- v <- w_2
:不可能,同理
w_1 <- v -> w_2
:不可能,树中没有出度>1的节点
w_1 -> v <- w_2
:
只有可能的一对方向。 e_1, e_2
之前可能已经定位。如果先前的方向违反了当前的分配,则问题实例没有解决方案。
2.2.2 此分配意味着子图上的树结构由在不包含e_1 (
e_2`的路径上可从w_1
(w_2
) 到达的所有顶点诱导。将两个诱导子树中的所有顶点标记为已完成
[注意:子树结构可能违反角度约束。在这种情况下,问题没有解决方案。 ]
2.3 标记v
已访问。在顶点 v
完成步骤 2.2 后,检查尚未分配方向的连接边的数量 nc
。
nc = 0
:这是您一直在寻找的根目录 - 但您必须检查解决方案是否与您的约束兼容。
nc = 1
:让这条边为(v,z)
。
这条边的方向是 v->z,就像你在树上一样。将 v 标记为已完成。
z
是否标记为完成。
如果不是,请检查连接z
的无向边的数量nc2
。
nc2
= 1:重复步骤 2.3,将 z
替换为 v
。
如果您还没有找到根节点,则您的问题实例不明确: 随意定位剩余的未定向边。
备注
终止: 每个节点最多访问 4 次:
每步骤 2 一次 每步最多两次 2.2.2 每步 2.3 最多一次正确性:
所有包含锐角的边都按照步骤 2.2.1 进行定向复杂度(时间):
访问每个节点:O(n);顺时针扫过连接给定顶点的所有边需要对这些边进行排序。
因此,您需要O( sum_i=1..m ( k_i * lg k_i ) )
在约束sum_i=1..m k_i = n
下的m <= 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)
]
子树标记:
如果实现为 dfs,则此过程最多访问图中的每个节点 2 次。因此总共有O(n)
用于调用此子例程。
总计:O(n * lg n)
复杂度(空间):
O(n)
用于排序(顶点度数不固定)。
问题可能定义不明确:
多种解决方案:例如斯坦纳树 没有解决方案:例如图形形状像一个双尖箭头 ()【讨论】:
该死的..我一直在寻找与 OP 的问题相反的问题,但这很准确。很好解释,有据可查。很好的答案。 (旧帖,我知道)【参考方案2】:一个简单的解决方案是围绕红色节点或节点中心定义一个二维矩形,并使用摩尔曲线计算每个节点。摩尔曲线是一种空间填充曲线,更多的是希尔伯特曲线的特殊版本,其中起点和终点相同,坐标位于二维矩形的中间。一般来说,您的问题看起来像一个离散的寻址空间问题。
【讨论】:
以上是关于无向图转换为树的主要内容,如果未能解决你的问题,请参考以下文章