给定大小的非相邻集的数量

Posted

技术标签:

【中文标题】给定大小的非相邻集的数量【英文标题】:Number of non-adjacent sets of a given size 【发布时间】:2012-02-15 20:04:08 【问题描述】:

如果给定集合L=1,2,3,...,N 和整数k,是否可以有效地计算大小为k 的“非相邻”子集的数量?如果S 中的每个x 不相邻,则子集S 不相邻,x-1x+1 都不在S 中。

例如,对于 L=1,2,3,4k=2,答案是 3,因为我们有 1,3,1,4,2,4。对于k=3,答案为零。

一种方法是生成所有大小为 2 的非相邻子集,然后尝试所有可能的并集(因为非相邻集具有其所有子集都不相邻的属性),但这让我很震惊浪费,并且可能有一个优雅而有效的解决方案。

【问题讨论】:

【参考方案1】:

这样想:如果您知道集合L'=1, 2, 3, ..., N - 1 的答案是什么,您能否使用该信息来构建集合L 的答案? 这个想法是,当您将N 添加到L' 时,新的解决方案由L' 可用的所有子集加上小于或等于@987654327 的L' 的每个元素的1 个新子集组成@,所以如果L' 的解决方案的大小为V',那么V L 的解决方案将是V = V' + (N - 2*(k - 1)) 如果你再计算一下,你会发现解可以表示为第一个N - 2k + 2自然整数之和。

关于小于或等于N - 2*(k - 1)部分,被添加的新数字N只会添加到最终数字小于或等于该表达式结果的子集中,因为其中必须有k元素正在构建的新子集(包括数字 N 本身,因此需要更多 k - 1)彼此之间至少间隔 2 个数字,这使得 2*(k - 1) 与数字 N 的距离为所以表达。

【讨论】:

感谢您的回复。我不遵循关于“小于或等于 N - 2*(k - 1)”的部分。但是您的最终公式似乎是错误的:N=4 和 k=2 的 N-k-1 等于 4-2-1=1,因此您将返回 1 而不是 3。 对不起,我在计算公式时出错了。应该是现在 我还添加了您不理解的解释。希望它有所帮助:) 感谢您添加的信息!不过,这对我来说似乎仍然不正确。取 N=6 和 k=3。那么我们应该有集合 135、136、146 和 246,即答案 4。但是公式 N-2k+2=2 得出 1+2=3。 您的回答启发我看到了一个看似正确且相当有效的解决方案。用 #(m,n) 表示 1,...,n 中大小为 m 的非相邻子集的数量。那么以下成立:#(m,n)=#(m,n-1)+#(m-1,n-1)。当然,像您这样的解决方案会更好,因为更容易计算。【参考方案2】:

这可能与 Win32 的解决方案相同,但我不确定。所以我单独发布。

取 S(n) 为大小为 n 的连续序列的非相邻子集的数量(即 S(n) 是您正在寻找的解决方案)。

让我们计算 S(n+1),当我们向序列中添加一个元素时的值。当我们添加一个元素 k 时,我们会增加该序列的非相邻子集的数量。我们可以将这些子集分为以下几类。

仅包含我们添加的新元素的子集。只有其中之一 (k)。 我们可以添加 k 并且仍然保留我们的非相邻标准(加上 k)的子集。我们可以将 k 添加到任何不包含 k-1 的子集,同时保持非邻接。另一种说法是,我们可以将 k 添加到最多包含 k-2 的子集中。最多包含 k-2 个子集的个数等于 S(n-1)。

所以当我们将 k 添加到我们的序列时,新的不相邻子集的数量是 1 + S(n-1)。换句话说,1 + S(n-1) = S(n+1) - S(n)。我们可以重新排列这个公式,得到 S(n+1) = 1 + S(n-1) + S(n)。

递归解决方案不是很有帮助,因此我们可以尝试对其进行概括。我不擅长这一步,但是Wolfram|Alpha is,我们发现通式等于以下。

S(n) = 1/2 * (3 * Fib(n) + Lucas(n) - 2)

以下是一些示例数据点。

n | S(n)
0 | 0
1 | 1
2 | 2
3 | 4
4 | 7
5 | 12
6 | 20
7 | 33
8 | 54
9 | 88

【讨论】:

我现在意识到我完全忘记了解决一组特定基数的问题。也许它仍然有用。 感谢您的回复和其他信息——我很难理解您为什么以这种方式使用 k :) 我同意您的推理,并认为总和是正确的基数。我不知道 WolframAlpha 解决了这样的系统。【参考方案3】:

S(m,n) 表示1,...,n 中大小为m 的不相邻子集的数量。那么以下成立:

S(m,n) = S(m,n-1) + S(m-1,n-2)

所以可以通过O(Nk)中的DP解决它,通过添加边界条件

S(1,n) = n
S(m,1) = I(m==1)
S(m,2) = 2*I(m==1)

其中I() 是指标函数。

【讨论】:

【参考方案4】:

让:

S(n,k) 是大小为k1,...n 的不相邻子集的集合

显然,S(n-1,k) 是一组大小为 k 的不相邻子集,它是 S(n,k) 的子集。

另外,S(n-2,k-1) 是一组大小为k-1 的不相邻子集,并且这些子集都不包括n-1。因此,我们可以安全地将n 添加到每个子集中,以获得大小为k 的子集。而且由于它们不包括n-1(与n 唯一相邻的元素),它们也是不相邻的。

因此:

S(n,k) = S(n-1,k) U (n X S(n-2,k-1))

使用一些实数,让我们尝试求解S(6,3)

S(6,3) = S(5,3) U (6 X S(4,2))
 S(5,3) = 1,3,5                   # Only one solution
  S(4,2) = S(3,2) U (4 X S(2,1))
   S(3,2) = 1,3                   # Only one solution
    S(2,1) = 1 2                # All sets of 1 element are non-adjacent
   4 X S(2,1) = 1,4 2,4       # Add 4 to each
  S(4,2) = 1,3 1,4 2,4
 6 X S(4,2) = 1,3,6 1,4,6 2,4,6
S(6,3) = 1,3,5 1,3,6 1,4,6 2,4,6

哪个符合你的答案。

现在,计算数字:

N(n,k)S(n,k)中的元素个数

然后:

N(n,k) = N(n-1,k) + N(n-2,k-1)

我还没有确定封闭形式,但这里有一些计算值:

 n    k=1   k=2   k=3   k=4   k=5   k=6   k=7   k=8   k=9  k=10  k=11  k=12  k=13
 1     1                                                                        
 2     2                                                                        
 3     3     1                                                                  
 4     4     3                                                                  
 5     5     6     1                                                            
 6     6    10     4                                                            
 7     7    15    10     1                                                      
 8     8    21    20     5                                                      
 9     9    28    35    15     1                                                
10    10    36    56    35     6                                                
11    11    45    84    70    21     1                                          
12    12    55   120   126    56     7                                          
13    13    66   165   210   126    28     1                                    
14    14    78   220   330   252    84     8                                    
15    15    91   286   495   462   210    36     1                              
16    16   105   364   715   792   462   120     9                              
17    17   120   455  1001  1287   924   330    45     1                        
18    18   136   560  1365  2002  1716   792   165    10                        
19    19   153   680  1820  3003  3003  1716   495    55     1                  
20    20   171   816  2380  4368  5005  3432  1287   220    11                  
21    21   190   969  3060  6188  8008  6435  3003   715    66     1            
22    22   210  1140  3876  8568 12376 11440  6435  2002   286    12            
23    23   231  1330  4845 11628 18564 19448 12870  5005  1001    78     1      
24    24   253  1540  5985 15504 27132 31824 24310 11440  3003   364    13      
25    25   276  1771  7315 20349 38760 50388 43758 24310  8008  1365    91     1
26    26   300  2024  8855 26334 54264 77520 75582 48620 19448  4368   455    14

【讨论】:

以上是关于给定大小的非相邻集的数量的主要内容,如果未能解决你的问题,请参考以下文章

jcl 查找给定 n 个数据集的整体大小

如何计算 OLAP 多维数据集的可能大小

Python:优化函数以查找给定候选项集的大小为 k 的频繁项集

在数组中找到两个总和最小的非后续元素

给定一个大小为 N*N 的矩阵。我们需要找出特定字符串的位置数量

(Neo4j 非托管扩展 API) 为啥查询的速度取决于 Neo4j 中数据集的大小?