计算DAG中长度为K的路径个数
Count the number of paths in DAG with length K
我有一个具有2^N个节点的DAG,其值从0到2^N-1。如果x
Michael有一些很好的见解,但我不确定我是否完全理解他的论点。这是我的解决方案。
假设N=4, K=2。因此节点的范围从0 (00002)到15 (11112)。
现在让我们考虑节点2 (00102)。从2到3有一条边(00112)因为2 <3 and xor(2,3) = 1 = 20从2到6也有一条边,因为2 <6 and (2,6) = 4 = 22从2到10有一条边,因为2 <3..概括:对于任何x,考虑x中的所有0位。通过将任何0位翻转为1,你得到一个比x大且与x相差1位的数字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 (01012)。节点5有一条到7的边(01112),节点7有一条到15的边(11112)。节点5也有一条到13的边(11012),节点13有一条到15的边(11112)。所以从节点5有两条路径:5-7-15和5-13-15。接下来让我们再次查看节点2 (00102)。节点2有一条边到3 (00112),它有一条边到7 (01112)和11 (10112)。节点2也有一条到节点6 (01102)的边,节点6有一条到7 (01112)和14 (11102)的边。最后,节点2有一条到节点10 (10102)的边,节点10有一条到11 (10112)和14 (11102)的边。总的来说,结点2有6条2-路径:2-3-7、2-3-11、2-6-7、2-6-14、2-10-11和2-10-14。
模式是,对于任意节点x,其中z位被设为0,且z≥K,存在一些从x出发的K路径。为了找到从x出发的K路径,你取任意K个0位。把这些位一个一个地换成1,就得到了路径。你可以按你想要的顺序翻转比特;每个顺序给出不同的路径。
当你想从n个物品中选取k个物品,以特定的顺序,这被称为无替换有序样本,有n个!/(n - k) !做这件事的方法。通常写为nPk,但这里更容易写P(n,k)。
所以,恰好有2个0位的节点有p (2,2) = 2!/(2 - 2) != 2个路径。(注意0!= 1)。恰好有3个0位的节点有P(3,2) = 3!/1 != 6个2-路径。恰好有4个0位的节点有P(4,2)= 4!/2 != 12条2-路径。(因为我在示例中使用N=4,所以只有一个节点恰好有4个零位,即节点0。)
然后我们需要知道,有多少节点恰好有2个0位?当有n个项目可供选择时,我们想从中选择k个,我们不关心所选项目的顺序,这就叫做无替换的无序样本,有n个!/(k !(n-k)!)这被称为"n选k",它通常以一种我无法在堆栈溢出时复制的方式写成,所以我把它写成C(n,k)。
对于我们的N=4的例子,有C(4,2) = 6个节点,正好有2位设置为零。这些节点3(0011 <子> )、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 (00012)、2 (00102)、4 (01002)和8 (10002)。每个节点都有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-路径。
2-paths总数当N = 4 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
很容易看出,一个人可以通过一系列恰好K个运算,从x得到y当且仅当(x,y) K可容许。此外,如果我们固定x并对所有y求和使得(x,y)是k可容许的,我们得到(N-|x|)!
最后,我们需要用|x|<=(N-K)对所有x求和。对于一个给定的选择|x|我们有N!/(N-|x|)!|x|!x的可能选择。结合上面的,你会得到对于给定的|x|有N!/|x|!可能的路径。
表示|x|=M, M从0到N- k,你的答案是对所有M求和N!/M!
- 如何将更多文件夹添加到c++include路径
- 带有特殊路径部分的"std::filesystem::weakly_canonical"失败
- C++A*算法并不总是在路径中具有目标节点
- 从函数角度看ID到文件路径的内部与外部映射
- boost xml parsingl将xml的路径作为变量发送
- 对于MacOS上的G++,如何添加默认的include目录/usr/local/include和默认的库搜索路径/usr
- 如何使用cppcheck处理半相对包含路径
- 在C++中设置基于操作系统的文件路径
- 基于编译器选项的编译二进制路径
- 按边长度递归搜索图中所有可行路径
- 使用变量值作为 PlaySound 中的路径
- 如何转换真实路径 CString c++
- 从 GUID 获取 USB 卷路径
- 查找 GCD:并非所有控制路径都返回值
- C++17 文件系统::remove_all 带有通配符路径
- 在带有尾部斜杠的路径上返回 std::filesystem::create_directories() 的值
- 获取当前正在运行的 exe 名称(不是路径)
- 如何从 Skia 路径几何体中获取网格?
- 需要算法的帮助来找到DAG中的最大路径
- 计算DAG中长度为K的路径个数