有限重复排列算法

时间:2013-07-12 17:46:57

标签: java arrays algorithm math permutation

是否有算法列出重复次数有限的所有排列?如果有一个现有的Java库,那就太好了!

假设我们有3个项{A, B, C}。我们想要2个项目的排列。它将是 3 P 2

{A, B}
{A, C}
{B, A}
{B, C}
{C, A}
{C, B}

但是如果我们允许最多重复两次。怎么会这样? (我真的不知道。)

我尝试成像,我们从集合{A, A, B, B, C, C}得到2的排列。它将是 6 P 2 = 30.但是我们必须带走那些重复的东西。我已经手动完成它,它是9.我不知道如何从数学计算9。

{A, A}
{A, B}
{A, C}
{B, B}
{B, A}
{B, C}
{C, C}
{C, A}
{C, B}

(实际上 3 P 2 且重复为2不是一个好例子。这是因为排列中只有2个元素。因此,无限重复之间没有区别。重复2的 4 P 3 将是一个更好的例子。但是很难列出所有的排列。 )

更好的例子示例: 4 P 3 集合{A, B, C, D}

{A, B, C}
{A, B, D}
{A, C, B}
{A, C, D}
{A, D, B}
{A, D, C}
... repeat for permutations starting from {B, ... }
... repeat for permutations starting from {C, ... }
... repeat for permutations starting from {D, ... }

并且 4 P 3 集合{A, B, C, D},重复次数为2:

{A, A, B}
{A, A, C}
{A, A, D}

{A, B, A}
{A, B, B}
{A, B, C}
{A, B, D}

{A, C, A}
{A, C, B}
{A, C, C}
{A, C, D}

{A, D, A}
{A, D, B}
{A, D, C}
{A, D, D}

... repeat for permutations starting from {B, ... }
... repeat for permutations starting from {C, ... }
... repeat for permutations starting from {D, ... }

Here是一个谈论类似事情的网页。但它似乎需要 n P n (选择所有元素)。此外,我仍然需要一个算法来生成和列出排列。

感谢您的帮助!


对于编程实现,实际上存在“不智能”的方法。

对于set {A, B, C, D},保留一个互补数组int used[0, 0, 0, 0],这是每个元素的使用次数。每次选择元素时递增计数,并向前传递数组的副本(在调用树下)。然后使用受激励here的递归方法,将其更改为允许无限重复(通过从元素集中删除所选的一个),并在{{}之后添加if (used[i] <= LIMIT)检查语句{1}}。

这是“不聪明”而且不够好,因为我们需要一个互补的数组,并且每次都需要检查使用过的数字。

3 个答案:

答案 0 :(得分:1)

在生成集合的所有可能分区之前,我遇到了这个问题。这基本上与您尝试做的概念相同。 (给定大小的所有组合与该大小的分区集相同)我发现this论文提供了一种非常快速的非递归算法来生成这些组合而不需要重复以及c ++实现。

答案 1 :(得分:1)

嗯,这有点晚了,但我在GitHub上有一个Java Combinatorics库可以做到这一点。以下是基本用法:

在项目中包含依赖项:

<dependency>
  <groupId>com.xiantrimble.combinatorics</groupId>
  <artifactId>combinatorics</artifactId>
  <version>0.2.0</version>
<dependency>

然后通过从组合工厂获取虚拟集合来迭代排列:

import com.xiantrimble.combinatorics.CombinatoricFactory;
import com.xiantrimble.combinatorics.CombinatoricFactoryImpl;
import com.xiantrimble.combinatorics.Combinatoric;
...
int k = 6;
int[] domain = {1,1,1,1,2,2,2,3,3,4};
// create a factory.
CombinatoricFactory factory = new CombinatoricFactoryImpl();
Combinatoric<Integer> permutations = factory.createPermutations(k,  domain);

for( Integer[] permutation : permutations ) {
  System.out.println(Arrays.toString(permutation));
}

代码不执行字典顺序,而是试图最小化连续元素之间的变化,因此请记住这一点。此外,0.3.0-SNAPSHOT版本也有一些改进,可以在Sonatype的快照存储库中找到。

答案 2 :(得分:0)

请参阅this paper,找到答案数量的理论公式。 论文信息是:Roberto Frucht撰写的“重复有限的排列”,来自10.1016 / S0021-9800(66)80025-X的组合理论期刊

相关问题