计算长度为K的DAG中的路径数

时间:2015-06-02 21:30:55

标签: c++ algorithm counting directed-acyclic-graphs

我有一个具有2 ^ N个节点的DAG,其值为0到2 ^ N-1。如果x

2 个答案:

答案 0 :(得分:1)

迈克尔有一些很好的见解,但我不确定我是否遵循了他的整个论点。这是我的解决方案。

假设N = 4,K = 2。所以节点范围从0(0000 2 )到15(1111 2 )。

现在让我们考虑节点2(0010 2 )。存在从2到3的边缘(0011 2 ),因为2< 3和xor(2,3)= 1 = 2 0 。还有从2到6的边缘,因为2< 6和xor(2,6)= 4 = 2 2 。并且存在从2到10的边缘,因为2< 10和xor(2,10)= 8 = 2 3

概括:对于任何x,考虑x中的所有0位。通过将0位中的任何一位翻转为1,您得到的数字y大于x并且与x相差一位。所以从x到y都存在边缘。

x中的1位数通常称为x的总体计数。我将使用pop(x)来表示x的人口数。

我们正在处理N位数(当我们包含前导零时),因此x中的0位数是N - pop(x)。

让我们使用术语“ j -path”来表示长度 j 的路径。我们想要计算K路径的数量。

每个节点x都有N - pop(x)传出边。这些边缘中的每一个都是1路径。

让我们考虑节点5(0101 2 )。节点5的边缘为7(0111 2 ),节点7的边缘为15(1111 2 )。节点5还具有到13的边(1101 2 ),并且节点13具有到15的边(1111 2 )。因此,节点5中有两条2路径:5-7-15和5-13-15。

接下来让我们再看一下节点2(0010 2 )。节点2的边缘为3(0011 2 ),其边缘为7(0111 2 )和11(1011 2 )。节点2还具有到节点6的边(0110 2 ),其边缘为7(0111 2 )和14(1110 2 ) 。最后,节点2具有到节点10的边(1010 2 ),其边缘为11(1011 2 )和14(1110 2 )。总之,节点2有六条2路:2-3-7,3-3-11,2-6-7,2-6-14,2-10-11和2-10-14

模式是,对于z比特设置为零的任何节点x,其中z≥K,x中有一些K路径。要找出x中的K路径,可以选择任何K的零位。将这些位逐个翻转为1,为您提供路径。您可以按任何顺序翻转位;每个订单都有不同的路径。

如果您想从一组n个项目中选择k个项目,按特定顺序,这些项目称为无需替换的有序样本,并且有n! / (n-k)!个方法可以执行此操作。这通常写成 n P k ,但这里输入P(n,k)更容易。

因此,具有正好2个零位的节点具有P(2,2)= 2! /(2-2)! = 2个2路径。 (注意0!= 1.)具有正好3个零位的节点具有P(3,2)= 3! / 1! = 6个2路径。恰好有4个零位的节点有P(4,2)= 4! / 2! = 12个2路径。 (因为我使用N = 4作为示例,所以只有一个节点恰好有4个零位,即节点0。)

但是我们需要知道,有多少节点正好有2个零位?那么,当有n个项目可供选择时,我们想要选择其中的k个,并且我们关心所选项目的顺序,这称为无序替换的无序样本,以及有n! /(k!(n-k)!)方法。这被称为“n选择k”,它通常以我无法在堆栈溢出时重现的方式编写,因此我将其写为C(n,k)。

对于N = 4的示例,有C(4,2)= 6个节点,正好2位设置为零。这些节点是3(0011 2 ),5(0101 2 ),6(0110 2 ),9(1001 2 < / sub>),10(1010 2 )和12(1100 2 )。这些节点中的每一个都有P(2,2)2路径,因此这意味着有C(4,2)* P(2,2)= 6 * 2 = 12个2路径的节点两个0位。

然后有C(4,3)= 4个节点,正好3位设置为零。这些节点为1(0001 2 ),2(0010 2 ),4(0100 2 )和8(1000 2 )。这些节点中的每一个都有P(3,2)2路径,所以有C(4,3)* P(3,2)= 4 * 6 = 24个2路径的节点正好有3个0位。

最后,有C(4,4)= 1节点,正好4位设置为零。该节点有P(4,2)= 12个2路径。

因此,当N = 4时,2路径的总数是C(4,2)* P(2,2)+ C(4,3)* P(3,2)+ C(4,4) * P(4,2)= 12 + 24 + 12 = 48。

对于一般N和K(其中K≤N),K路径的数量是K≤z≤N的C(N,z)* P(z,K)之和。

我可以像这样输入Wolfram Alpha(或Mathematica):

Sum[n!/(z! (n - z)!) z!/(z - k)!, {z, k, n}]

And it simplifies it to this

2^(n-k) n! / (n-k)!

答案 1 :(得分:0)

陈述的问题似乎与此相同:

考虑长度为N的所有可能二进制字符串的集合。考虑将第i位从0翻转到1的操作Fi。对于字符串x&amp; y表示| x |设定位数x

当且仅当(x,y)是K-可接受时,很容易看出可以通过一系列精确的K操作来从x获得y。而且,如果我们修正x并总结所有y使得(x,y)是K-允许的,我们得到(N | | x |)!

最后,我们需要用| x |&lt; =(N-K)来总结所有x。对于给定的| x |选择我们有N!/(N | | x |)!| x |!可能的x选择。结合上面的内容,你可以得到给定的| x |有N!/ | x |!可能的路径。

表示| x | = M,M从0到N-K,你的答案是N!/ M中所有M的总和!