Java 生成无冗余的所有对组合
我必须为开源锦标赛软件(java)解决一个问题。该软件可以根据不同的标准(参与者排名、已经进行的比赛?,…)找到最佳的比赛组合 目前,使用的算法不是最优的,因为它比较所有匹配组合(包括冗余组合)。通过这种方法,sotfware比较“参与者数量的阶乘”组合。我正在寻找一种算法,它可以生成所有匹配的组合,而不需要冗余 当前代码和4名参与者的示例:Java 生成无冗余的所有对组合,java,algorithm,combinations,Java,Algorithm,Combinations,我必须为开源锦标赛软件(java)解决一个问题。该软件可以根据不同的标准(参与者排名、已经进行的比赛?,…)找到最佳的比赛组合 目前,使用的算法不是最优的,因为它比较所有匹配组合(包括冗余组合)。通过这种方法,sotfware比较“参与者数量的阶乘”组合。我正在寻找一种算法,它可以生成所有匹配的组合,而不需要冗余 当前代码和4名参与者的示例: // Example with 4 participants public static void main (String[] args) { S
// Example with 4 participants
public static void main (String[] args) {
String[] participants = {"A","B","C","D"};
double factorial = factorial(participants.length);
for(double i=0;i<factorial;i++) {
String[] combination = permutation(i,participants);
System.out.println("Combination "+(int)i+" : "+combination[0]+" vs "+combination[1]+", "+combination[2]+" vs "+combination[3]);
}
}
// Current code
public static <K> K[] permutation (double k, K[] objects) {
K[] permutation = objects.clone();
for (int i = 2; i < permutation.length + 1; i++) {
k = k / (i - 1);
swap(permutation, (int)(k % i), i - 1);
}
return permutation;
}
public static <K> void swap (K[] objects, int indexA, int indexB) {
K temp = objects[indexA];
objects[indexA] = objects[indexB];
objects[indexB] = temp;
}
public static double factorial (int value) {
double result = value;
while (value != 2) {
result *= --value;
}
return result;
}
如您所见,存在大量冗余(“a对B,C对D”与“B对a,C对D”和“B对a,D对C”相同,并且……)。对于10名或10名以上的参与者(10!=3.628.800…),每种组合的比较损失的时间(目的是找到最佳组合)是相当大的
所需输出的示例(订单无关):
欢迎您的帮助。回答我的问题:
public void generate (int n) {
int[] covered = new int[n];
int[] list = new int[n];
for (int i = 0; i < n; i++) {
covered[i] = 0;
}
this.generate(n, covered, 0, list);
}
private void generate (int n, int[] covered, int i, int[] list) {
int j = 0;
while ((j < n) && (covered[j] == 1)) {
j++;
}
if (j == n) {
System.out.println(Arrays.toString(list));
return;
}
covered[j] = 1;
for (int k = 0; k < n; k++) {
if (covered[k] == 0) {
covered[k] = 1;
list[i++] = j;
list[i++] = k;
this.generate(n, covered, i, list);
i -= 2;
covered[k] = 0;
}
}
covered[j] = 0;
}
public void生成(int n){
int[]覆盖=新的int[n];
int[]列表=新的int[n];
对于(int i=0;i
找到。如果你想要组合,那么为什么要使用置换函数?这是我几年前发现的唯一一个算法。这不是完美的,但它的工作。现在我需要帮助来改进它。我做了很多研究,但我发现没有什么能解决我的问题……为什么
A vs D,C vs B
不是理想的输出?理想的输出是所有匹配的组合,没有冗余。在我举的一个有4名参赛者的锦标赛的例子中,两种组合足以涵盖所有的可能性(无论顺序如何)。你是对的,我犯了一个错误。三种组合是涵盖所有可能性所必需的。我通过添加一个组合来更正我的问题。非常感谢。
Combination 0 : A vs B, C vs D
Combination 1 : A vs C, B vs D
Combination 2 : A vs D, B vs C
public void generate (int n) {
int[] covered = new int[n];
int[] list = new int[n];
for (int i = 0; i < n; i++) {
covered[i] = 0;
}
this.generate(n, covered, 0, list);
}
private void generate (int n, int[] covered, int i, int[] list) {
int j = 0;
while ((j < n) && (covered[j] == 1)) {
j++;
}
if (j == n) {
System.out.println(Arrays.toString(list));
return;
}
covered[j] = 1;
for (int k = 0; k < n; k++) {
if (covered[k] == 0) {
covered[k] = 1;
list[i++] = j;
list[i++] = k;
this.generate(n, covered, i, list);
i -= 2;
covered[k] = 0;
}
}
covered[j] = 0;
}