繁体   English   中英

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

[英]Count the number of paths in DAG with length K

我有一个具有2 ^ N个节点的DAG,其值从0到2 ^ N-1。 如果x <y并且x(xor)y = 2 ^ p,则x到y之间有边,x和y是节点值,并且pa是非负整数。 由于N可以高达100000,因此生成图形并进行计数将需要大量的计算时间。 有什么方法可以计算具有一定长度K(K是两个节点之间的边数)的路径,换句话说,是否有某种方程式可以用于这种计数? 提前致谢

迈克尔(Michael)有一些很好的见解,但我不确定我是否会遵循他的全部论点。 这是我的解决方案。

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

现在让我们考虑节点2(0010 2 )。 因为2 <3且xor(2,3)= 1 = 2 0,所以存在2到3(0011 2 )的边。 还有一个从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相差一位的数字y。 所以从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 )的边缘,节点6具有7(0111 2 )和14(1110 2 )的边缘。 最后,节点2的边缘为节点10(1010 2 ),节点10的边缘为11(1011 2 )和14(1110 2 )。 节点2总共有6条2路径:2-3-7、2-3-11、2-6-7、2-6-14、2-10-11和2-10-14 。

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

当您要从一组n个项目中以特定顺序选择k个项目时,称为无替换的有序样本,并且有n个! /(nk)! 方法。 通常将其写为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!(nk)!)的方法。 这称为“ n select k”,通常以无法在堆栈溢出时重现的方式编写,因此将其写为C(n,k)。

对于我们的N = 4的示例,有C(4,2)= 6个节点,其中2位恰好设置为零。 这些节点是3(0011 2 ),5(0101 2 ),6(0110 2 ),9(1001 2 ),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条路径,因此,在正好三个0的节点中有C(4,3)* P(3,2)= 4 * 6 = 24条2条路径位。

最后,存在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}]

并将其简化为

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

陈述的问题似乎与此等效:

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

很容易看出,只要且仅当(x,y)是K可容许的,一个人才能通过一系列完全K的操作Fi从x获得y。 而且,如果我们固定x并对所有y求和,使得(x,y)是K可容许的,则得到(N- | x |)!

最后,我们需要用| x | <=(NK)对所有x求和。 对于| x |的给定选择 我们有N!/(N- | x |)!| x |! x的可能选择。 结合以上内容,即可得到给定的| x |。 有N!/ | x |! 可能的路径。

表示| x | = M,M从0到NK,而您的答案是N!/ M!的所有M之和。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM