我正在尝试用简单的K来计算简单连接图的数量 边和N个明显标记的顶点。我在下面编写了这段代码,但似乎没有用。
这个想法是这种图形没有孤立的顶点,所以我 对N个顶点和K个边缘执行此操作。
Connected(N,K):
1) Total = all possible graphs, including disconnected ones.
2) Disconnected = Sum from i=1 to i=N-1 [(Connected(i,K)*(number of ways to
choose i vertices from all N vertices)]
3) return Total-Disconnected
Python代码:
#c dict just stores previous combinations
c = {}
def answer(N, K):
ways = connected(N, K)
return str(ways)
#number of simple graphs using exactly n vertices and k edges. no isolated vertices
def connected(n, k):
if k < n-1:
return 0
edges = n*(n-1)/2
if k > edges:
return 0
#number of all possible graphs with n vertices and k edges
ways = choose(edges, k)
#subtract number of graphs that are not connected
for i in range(1, n):
ways -= connected(i, k)*choose(n, i)
return ways
#calculates nCk
def choose(n, k):
key = str(n)+","+str(min([k,n-k]))+"/"+str(max([k,n-k]))
if key in c:
return c[key]
else:
top = fact(n)
bottom = fact(k)*fact(n-k)
ans = top/bottom
c[key] = ans
return ans
#factorial
def fact(num):
ret = 1
for i in range(2,num+1):
ret *= i
return ret
答案 0 :(得分:0)
您的Disconnected公式实际上不正确。
让我们标记顶点1,2,...,N。在公式中,术语:
[(连接(i,K)*(从所有N个顶点中选择i顶点的方式数)]
应该计算图形的数量,使得顶点1的连通分量包含i个顶点。但该产品仅提供可能连接组件的数量。对于每个这样的连通分量选择,仍然有很多方法可以在其余(N - i)个顶点之间排列边缘。
为了获得正确的公式,您还应考虑连通组件中的边数。
设Conn(i,j)是连接图的数量,其中i标记了顶点并且恰好是j个边。然后我们有:
选择(N *(N-1)/ 2,K)= sum(i = 1到N,j = 0到K)选择(N-1,i-1)* Conn(i,j)*选择((N - i)*(N - i - 1)/ 2,K - j)
左侧是具有N个顶点和K个边的图的总数。右侧的加数是具有N个顶点,K个边缘的图形的数量,并且顶点1的连通分量具有i个顶点和j个边缘。
对于加数的进一步说明:首先从除顶点1之外的N-1个顶点中选择i-1个顶点,然后乘以形成具有i个顶点和j个边的连通图的方式的数量,最后添加来自剩余N - i个顶点的任何K - j边。
根据这个公式,您应该能够编写DP算法来计算所有数字Conn(i,j)。
虽然这可能很慢,但它会为您提供正确的答案。您可以稍后考虑更好的算法。