无向图中的最大循环数

时间:2019-03-10 19:06:52

标签: algorithm graph

因此,我们得到了n个顶点的无向图G =(V,E)。

(| V | = n)

如何在指定图形G中找到简单循环的最大数量?

如果有人可以通过解释帮助我,我将感到非常高兴。

1 个答案:

答案 0 :(得分:2)

因此,我们想在图中找到所有可能的循环。假设每个顶点都已连接,因为这将生成所有可能的边。现在,让我们从简单的案例开始,逐步进行。

让我们从长度为3的循环开始。这是我们在图形中可以拥有的最小的简单循环。图中的任何三个顶点都可以构成这样一个循环。在这种情况下顺序无关紧要,因为我们三个一组中的每个顶点都将连接到其他两个。因此,长度为3的简单循环数将成为我们从一组V顶点中选择三个顶点而忽略顺序的方式的数量。这是“ n选择k”或nck(3, V),其中nck是:

function nck(k, n):
    return factorial(n) / (factorial(k) * factorial(n - k))

这为我们解决了长度为3的循环数。我们可以对长度4重复类似的逻辑,但是出现了一个新问题。对于一组四个顶点a, b, c, d,有一个以上的循环连接方式。我们可以将b连接到adaccd。简而言之,我们需要找到这些顶点k!的排列数量,并应用两次校正。首先,我们将除以二以说明“翻转”另一个排列顺序的排列(仍将连接相同的相邻顶点)。其次,我们将除以k,以说明仅旋转另一个置换的置换(同样,该置换不会更改相邻的顶点)。因此,k个顶点的循环的不同顺序数为:

function orderings(k):
    return factorial(k - 1) / 2

现在,我们可以通过nck(4, V) * orderings(4)计算长度为4的循环数。现在,该过程可以推广到所有长度的循环,直到V,并包括在内。

要获取周期总数,我们需要将所有长度为[3, V](含)的周期总数相加。请注意,我们可以通过取消两个函数中的项来进行一些简化。如果我们将factorial(k - 1)写为factorial(k) / k并内联这两个函数,则factorial(k)将取消。然后,我们只需要除以2 * k * factorial(n - k)。您也可以将factorial(n) / factorial(n - k)简化为[k + 1, n]中所有整数的乘积,以免被大阶乘除。

总的来说,这应该不会太昂贵。通过按升序计算factorial(n) / factorial(n - k),我们甚至可以避免重新计算部分乘积或任何阶乘。这意味着我们可以计算线性时间的总循环数。在python中:

def cycles(v):
    count = 0
    product = v * (v - 1) * (v - 2) // 2
    for k in range(3, v + 1):
            count += product // k
            product *= (v - k)
    return count

请注意,我确实试图找到一种没有任何运气的封闭式解决方案。如果我们不必乘以每个循环的顺序,则可以计算这些顶点的幂集的基数(减去大小为0..2的子集的数量)。我还尝试查看[wolfram alpha](https://www.wolframalpha.com/input/?i=sum+from+k%3D3+to+v+of+(v%5E2+%2F+2)+%2F+((v-k)%5E2+ * + k)是否可以简化它,但是它给了我更复杂的东西。