View Javadoc
1   package net.bmahe.genetics4j.core.combination;
2   
3   import java.util.ArrayList;
4   import java.util.Collections;
5   import java.util.List;
6   import java.util.Objects;
7   
8   import org.apache.commons.lang3.Validate;
9   
10  import net.bmahe.genetics4j.core.Genotype;
11  import net.bmahe.genetics4j.core.chromosomes.Chromosome;
12  import net.bmahe.genetics4j.core.spec.AbstractEAConfiguration;
13  import net.bmahe.genetics4j.core.util.MultiIntCounter;
14  
15  /**
16   * Produces the cartesian product of all chromosome combinations across all chromosome positions.
17   *
18   * @author bruno
19   *
20   */
21  public class AllCasesGenotypeCombinator implements GenotypeCombinator {
22  
23  	@Override
24  	public List<Genotype> combine(final AbstractEAConfiguration eaConfiguration,
25  			final List<List<Chromosome>> chromosomes) {
26  		Objects.requireNonNull(eaConfiguration);
27  		Objects.requireNonNull(chromosomes);
28  		Validate.isTrue(eaConfiguration.chromosomeSpecs().size() == chromosomes.size());
29  
30  		boolean hasChild = true;
31  		for (int i = 0; i < chromosomes.size() && hasChild; i++) {
32  			final List<Chromosome> list = chromosomes.get(i);
33  
34  			if (list.isEmpty()) {
35  				hasChild = false;
36  			}
37  		}
38  		if (hasChild == false) {
39  			return Collections.emptyList();
40  		}
41  
42  		final int[] maxIndices = chromosomes.stream().mapToInt(List::size).toArray();
43  
44  		final MultiIntCounter multiIntCounter = new MultiIntCounter(maxIndices);
45  
46  		boolean done = false;
47  		final List<Genotype> combined = new ArrayList<>();
48  		while (done == false) {
49  
50  			final List<Chromosome> currentGenotype = new ArrayList<>();
51  
52  			for (int i = 0; i < chromosomes.size(); i++) {
53  				final int index = multiIntCounter.getIndex(i);
54  				currentGenotype.add(chromosomes.get(i).get(index));
55  			}
56  			combined.add(new Genotype(currentGenotype));
57  
58  			multiIntCounter.next();
59  			if (multiIntCounter.hasNext() == false) {
60  				done = true;
61  			}
62  		}
63  
64  		return combined;
65  	}
66  }