当前位置: 动力学知识库 > 问答 > 编程问答 >

java - Every combination of object array

问题描述:

Basically, I have an array containing 25 different people, I need to select 5 of these people and have every single combination possible, without using duplicates of the same person.

The only logical way I can think of doing it is by having 5 for loops and checking if person has already been used, although this seems like there's probably a better method involving recursion.

If anyone can help I'd be very appreciated.

Here's an example of my class;

public class Calculator {

final Person[] people = new Person[25]; //Pretend we have filled in this info already

public List<Group> generateList()

{

final List<Group> possible = new ArrayList<>();

for (int a = 0; a < 25; a++)

{

for (int b = 0; b < 25; b++)

{

for (int c = 0; c < 25; c++)

{

for (int d = 0; d < 25; d++)

{

for (int e = 0; e < 25; e++)

{

final Group next = new Group();

next.set = new Person[] {

people[a],

people[b],

people[c],

people[d],

people[e]

};

possible.add(next);

}

}

}

}

}

return possible;

}

class Group {

Person[] set = new Person[5];

}

class Person {

String name;

int age;

}

}

However I'm not sure the best way to do this and if that would even get every combination. I also know there's no duplicate checking here, which I'd do by checking;

if(b == a) continue;

Etc.

I would appreciate any help.

网友答案:

There are many options.

(1)

you can improve your algoritghm by using

for a = 0 to 25 
  for b = a+1 to 25  // use ascending-order rule 
    for c = b+1 to 25

etc - this eliminates duplicate checking, taking advantage of the factorial nature of the problem

(2)

you can alternatively implement these as a single for loop over the whole N^R items (if you chose R items from N), and discard permutations that are not in full ascending order. This is good if you don't know R beforehand. Imagine you are counting in base N

for i = 0 to N^R // count in base N
  for digit = 0 to R 
    value[digit] = (i/N^digit) mod (N^(digit+1)) // extract the required digit
    if digit>0 && value[digit]<value[digit-1], SKIP  

In other words, you count sequentially on these R indexes.

(3)

The final option, which is longer to code but more efficient for large R and N, is to use a set of indices:

// i is an array size R, with items ranging from 0 to N
i = int[]{ 0, 1, 2, 3, 4 }; // each is an index of the items in N

while !finished
    j=0; // index to start incrementing at
    i[j] ++;

then if you go above N on any index, increase j, increment i[j], and set all the i[k<j] to [0 1 2 ... j-1], and start counting again! this cycles most efficiently through all combinations.

网友答案:

One possibility would be to use a combinatorics library like: http://code.google.com/p/combinatoricslib/.

// Create the initial vector
   ICombinatoricsVector<String> initialVector = Factory.createVector(
      new String[] { "red", "black", "white", "green", "blue" } );

   // Create a simple combination generator to generate 3-combinations of the initial vector
   Generator<String> gen = Factory.createSimpleCombinationGenerator(initialVector, 3);

   // Print all possible combinations
   for (ICombinatoricsVector<String> combination : gen) {
      System.out.println(combination);
   }

The example is from the project page (see link). It should be pretty easy to transfer it to your use case.

分享给朋友:
您可能感兴趣的文章:
随机阅读: