Algorithm 无置换生成序列
我使用整数中的两个数字来表示一个元素。即Algorithm 无置换生成序列,algorithm,math,permutation,Algorithm,Math,Permutation,我使用整数中的两个数字来表示一个元素。即3345512表示四个元素[3,34,55,12]。接下来,我重复地将一个元素添加到整数中,以获得另一个元素序列。当生成这样的序列时,我得到相同序列的排列,即3341255=[3,34,12,55],在我的例子中,这相当于数字3345512=[3,34,55,12]。所以我想避免我已经遇到的序列的排列。我不想存储这些数字,因为它们变得非常大(10^30及更多)。我尝试使用布卢姆过滤器,但它无法处理元素的数量。有没有一个简单的解决方案来生成没有排列的序列 [
3345512
表示四个元素[3,34,55,12]
。接下来,我重复地将一个元素添加到整数中,以获得另一个元素序列。当生成这样的序列时,我得到相同序列的排列,即3341255=[3,34,12,55]
,在我的例子中,这相当于数字3345512=[3,34,55,12]
。所以我想避免我已经遇到的序列的排列。我不想存储这些数字,因为它们变得非常大(10^30
及更多)。我尝试使用布卢姆过滤器,但它无法处理元素的数量。有没有一个简单的解决方案来生成没有排列的序列
[编辑]这是一个很小的python脚本,应该可以运行。为了更好地理解,如果s[idx]==9:我使用带的一位数,而不是如果s[idx]==99:
如果你有一个更简单的解决方案,我会接受它作为一个答案
导入时间
s=[1]
尽管如此:
idx=0
而不是idx+1==len(s)和s[idx]
要检查给定序列是否已经生成并且可以跳过,您应该生成当前序列的“上一个”排列,如果从零开始计数,则会生成当前序列,并将其与起始编号进行比较
您可以通过以下方式找到此排列:
如果数字的排列顺序是递增的-例如[3][4][5][6]-您可以停止,因为这些数字没有更小的排列
如果序列有一些非递增部分-例如[3][5][4][8][6][7][8][9]。该序列有两个非递增部分。5-4和8-6
找到最后一个大于其后续编号的编号。这是前8次
[3] [5][4][8][6][7][8][9]
找出8后面的最大数字,实际上是更小的。现在是7点
[3] [5][4][8][6][7][8][9]
将7移动到8的位置,并按降序保留所有其他数字
[3] [5][4][7][9][8][6]
现在,如果这个序列小于起始数字,你知道它还没有生成。否则你可以跳过它。你要求的是组合而不是排列。看起来您正试图从100个项目的列表中获得4个项目的唯一组合。也就是说,可能的值是
00
到99
可以使用嵌套循环生成所有组合,如下所示:
for (i = 0 to 96)
for (j = i + 1 to 97)
for (k = j + 1 to 98)
for (l = k + 1 to 99)
write i, j, k, l
这保证了你不会得到相同的组合
您还将注意到,在生成的组合中:
i < j < k < l
有了这个,你可以增加一个整数,看看它是否设置了两个位,然后从设置的位转换成字母表中的字符
您可以从一组100个字符中选择4个组合来执行完全相同的操作。使用100位数字有点困难,但并非不可能。因为您只是在递增,所以可以使用一对64位数字来实现
确定设置了多少位很简单,这是一种简单的方法。该页面显示了几种更快的方法
有几种方法可以解决这个问题,所有这些方法都可以参数化,以便从n个项目的列表中选择唯一的k组合。如果要避免重复序列,它们是彼此的排列,请仅选择其中一种排列作为代表,例如,元素构成非递减序列的排列。如果从0开始计数,Chill的想法是好的。否则,您可能会错过一些序列。例如,如果您从
5050
开始计数,您将跳过5149
,即使您一开始从未遇到过4951
。您想要的是而不是排列。@Jim:“计数多个子集”部分似乎很合适,虽然没有关于如何实现它的建议,但我不想像这样硬编码这个问题,因为我不知道我需要多少个循环。虽然这看起来是一个非常简单且很好的解决方案。@hobic:循环只是展示了如何生成四个的组合。很容易想出一个通用方法,从m个列表中生成n个项目的组合。如果你能想出比我的脚本更可读的东西,我会接受你的答案。也许我可以使用递归和生成器来模拟无限嵌套的for循环。“我想不出其他的东西了。”@hobic:我想你贴的剧本和我想的很相似。我不是Python程序员,所以我不会尝试用Python编写代码。当我讨论如何增加时,我描述了我的算法。@恐惧症是一个C++中的算法,它使用这个精确的方法来解决这个问题。也许它会有些用处。对不起,我听不懂。您能否明确说明重新排序的目的是什么,以及您如何知道您的算法实现了它?也许您可以简单地对序列进行排序,而不是使用您的算法来获得“最小”排列并将其与当前序列进行比较?
0, 1 (0011)
0, 2 (0101)
0, 3 (1001)
1, 2 (0110)
1, 3 (1010)
2, 3 (1100)