用于生成具有最大度数的所有节点的路径的无向图的算法?

时间:2013-04-13 01:06:11

标签: algorithm graph graph-algorithm

我正在尝试生成一个无向图,其中每个节点都有一个与之关联的最大度数。也就是说,如果节点的最大度数为2,则它最多可以连接两个节点(允许连接节点,但不允许为0)。我的问题是我正在尝试生成一个可以从一个节点到另一个节点的图形。目前,我可以让节点“随机”连接到另一个,但问题是它可以创建分割图,即如果你有10个节点,那么有时无意中有两个图形,每个节点形成5个节点。如果有人知道有效的解决方案,我很乐意听到它!

编辑:假设我有一个包含十个节点的图表,并且我指定了最大度数为2.在这种情况下,这是可取的:

Desirable Graph

而这正是我想要避免的:

Undesirable Graph

两个图的每个节点的最大度数为2,但在第二个图像中,不可能选择任意节点并且能够到达任何其他任意节点。

3 个答案:

答案 0 :(得分:6)

这个问题在图论中是一个非常着名的问题,可以解决多项式时间,我忘记了它的名字(可能是“找到给定度数序列的图形”)。无论如何,Király的解决方案是一个很好的方法,解释得比我更好here。该算法可以求解满足给定度数序列的精确图形,但是对于更宽松的约束应该很容易修改。

答案 1 :(得分:0)

显而易见的解决方案是将其构建为N路树 - 如果最大度数为2,则最终得到二叉树。

为了使其无向,您不仅可以指向“子”节点,还可以指向“父”节点的向后指针。至少据推测,一个不计入节点的程度(如果确实如此,你的两个程度基本上最终会变成一个双向链接的线性列表而不是一个树)。

编辑:后澄清,看来后者确实如此。虽然它们绘制不同(链接朝不同的方向),但是显示所需结果的第一张图片在拓扑上只是一个线性链表。如上所述,由于您需要一个无向图,它最终会成为一个双向链表。

答案 2 :(得分:0)

听起来你已经知道图形应该是什么样子了,所以我相信你是否可以使用深度优先搜索方法。虽然呼吸优先搜索可用于避免递归。

例如,如果您有节点1-5和k = 2,则可以通过从节点1开始构建图形,然后只需随机选择一个未访问的节点。像这样:

1 [Start at 1]
1-2 [expand 2, add edge(1,2) to graph]
1-2-3 [expand 3, add edge(2,3) to graph]
1-2-3-4 [expand 4, add edge(3,4) to graph]
1-2-3-4-5 [expand 5, add edge(4,5) to graph]
1-2-3-4-5-1 [expand 1, add edge(5,1) to graph] (this step may or may not be done)

如果边缘从未使用过两次,那么p路径将导致整体度为p * 2,开始和结束节点的程度取决于路径是否真的是巡视。为了避免重复工作,可能更容易将顶点标记为整数1到N,然后创建边,使得每个顶点v连接到顶点编号(v + j)mod(N + 1)其中j和(N + 1)是co-prime< N-1。最后一点让事情有点问题,因为如果N不是素数,则从1到N的共素数可以被限制。这意味着对于某些值不存在解决方案,至少以新哈密顿路径/巡回的形式存在。但是,如果忽略共素方面并简单地使j为1到p的整数,则遍历每个顶点并创建边(而不是使用路径方法),可以使所有顶点都具有度k,其中k是偶数> = 2.这可以在O(N * k)中实现,尽管如果使用共素方法,它可以被推回到O(N ^ 2)。

因此,如果从1开始,则k = 4的路径看起来像这样,j = 2:

1 [Start at 1]
1-3 [expand 3, add edge(1,3) to graph]
1-3-5 [expand 5, add edge(3,5) to graph]
1-3-5-2 [expand 2, add edge(5,2) to graph]
1-3-5-2-4 [expand 4, add edge(2,4) to graph]
1-3-5-2-4-1 [expand 1, add edge(4,1) to graph] (this step may or may not be done)

从| V |开始= 5且k = 4,得到的边形成一个完整的图,这是预期的。它也有用,因为2和5是共同素数。

获得奇怪的程度有点困难。首先获得度k-1,然后以这样的方式添加边缘,总体上获得奇数度。看起来很容易接近(有一两个例外)所有边都是奇数度,但奇数个顶点似乎不可能或至少非常困难,并且需要仔细选择具有偶数个顶点的边。其中的部分,不容易放入算法中。但是,可以通过简单地选取两个未使用的顶点并在它们之间创建边缘来近似,使得顶点不会被使用两次,并且边缘不会被使用两次。