Skip to content

Commit efcd557

Browse files
avijit-basakGilles Sadowski
avijit-basak
authored and
Gilles Sadowski
committed
MATH-1563: Introducing new implementation of GA functionality (WIP).
Closes #209.
1 parent 99ca991 commit efcd557

29 files changed

+36
-152
lines changed

commons-math-examples/examples-ga/examples-ga-tsp/src/main/java/org/apache/commons/math4/examples/ga/tsp/TSPOptimizer.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,15 @@ public void optimize(List<City> cities,
7676
final RealValuedChromosome<List<City>> bestFinal = (RealValuedChromosome<List<City>>) finalPopulation
7777
.getFittestChromosome();
7878

79-
logger.info(bestFinal.decode().toString());
79+
StringBuilder schedule = new StringBuilder();
80+
schedule.append("Travel Shcedule: " + System.lineSeparator());
81+
List<City> bestCities = bestFinal.decode();
82+
for (City city : bestCities) {
83+
schedule.append("City - " + city.getIndex() + System.lineSeparator());
84+
}
85+
schedule.append("Total distance - " + Math.abs(bestFinal.evaluate()));
86+
87+
logger.info(schedule.toString());
8088
}
8189

8290
private static Population<List<City>> getInitialPopulation(List<City> cities, int populationSize) {
@@ -87,12 +95,9 @@ private static Population<List<City>> getInitialPopulation(List<City> cities, in
8795
ChromosomeRepresentationUtils.randomPermutation(cities.size()), decodedChromosome -> {
8896
final DistanceMatrix distanceMatrix = DistanceMatrix.getInstance(cities);
8997
double totalDistance = 0.0;
90-
int index1 = 0;
91-
int index2 = 0;
9298
for (int j = 0; j < cities.size(); j++) {
93-
index1 = j;
94-
index2 = (j == cities.size() - 1) ? 0 : j + 1;
95-
totalDistance += distanceMatrix.getDistance(cities.get(index1), cities.get(index2));
99+
totalDistance += distanceMatrix.getDistance(decodedChromosome.get(j),
100+
decodedChromosome.get((j == cities.size() - 1) ? 0 : j + 1));
96101
}
97102
return -totalDistance;
98103
}, new RandomKeyDecoder<City>(cities)));

commons-math-examples/examples-ga/examples-ga-tsp/src/main/java/org/apache/commons/math4/examples/ga/tsp/legacy/LegacyTSPOptimizer.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,18 @@
2727
import org.apache.commons.math3.genetics.StoppingCondition;
2828
import org.apache.commons.math3.genetics.TournamentSelection;
2929
import org.apache.commons.math4.examples.ga.tsp.City;
30+
import org.slf4j.Logger;
31+
import org.slf4j.LoggerFactory;
3032

3133
/**
3234
* This class represents the tsp optimizer based on legacy implementation of
3335
* Genetic Algorithm.
3436
*/
3537
public class LegacyTSPOptimizer {
38+
39+
/** instance of logger. **/
40+
private final Logger logger = LoggerFactory.getLogger(LegacyTSPOptimizer.class);
41+
3642
/**
3743
* Optimizes the TSP problem.
3844
* @param cities list of cities
@@ -67,9 +73,13 @@ public void optimize(List<City> cities,
6773
@SuppressWarnings("unchecked")
6874
final RandomKey<City> bestFinal = (RandomKey<City>) finalPopulation.getFittestChromosome();
6975

70-
//CHECKSTYLE: stop all
71-
System.out.println("best=" + bestFinal.toString());
72-
//CHECKSTYLE: resume all
76+
StringBuilder schedule = new StringBuilder("Travel Shcedule: " + System.lineSeparator());
77+
List<City> bestCities = bestFinal.decode(cities);
78+
for (City city : bestCities) {
79+
schedule.append("City - " + city.getIndex() + System.lineSeparator());
80+
}
81+
schedule.append("Total distance - " + Math.abs(bestFinal.fitness()));
82+
logger.info(schedule.toString());
7383
}
7484

7585
private static Population getInitialPopulation(List<City> cities, int populationSize, double elitismRate) {

commons-math-ga/src/main/java/org/apache/commons/math4/ga/AbstractGeneticAlgorithm.java

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -42,46 +42,22 @@ public abstract class AbstractGeneticAlgorithm<P> {
4242

4343
/** instance of logger. **/
4444
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractGeneticAlgorithm.class);
45-
4645
/** the crossover policy used by the algorithm. */
4746
private final CrossoverPolicy<P> crossoverPolicy;
48-
4947
/** the mutation policy used by the algorithm. */
5048
private final MutationPolicy<P> mutationPolicy;
51-
5249
/** the selection policy used by the algorithm. */
5350
private final SelectionPolicy<P> selectionPolicy;
54-
51+
/** the elitism rate having default value of .25. */
52+
private final double elitismRate;
5553
/**
5654
* the number of generations evolved to reach {@link StoppingCondition} in the
5755
* last run.
5856
*/
5957
private int generationsEvolved;
60-
61-
/** The elitism rate having default value of .25. */
62-
private double elitismRate = .25;
63-
64-
/** The registry for all interested convergence listeners. **/
58+
/** the registry for all interested convergence listeners. **/
6559
private ConvergenceListenerRegistry<P> convergenceListenerRegistry = new ConvergenceListenerRegistry<>();
6660

67-
/**
68-
* @param crossoverPolicy The {@link CrossoverPolicy}
69-
* @param mutationPolicy The {@link MutationPolicy}
70-
* @param selectionPolicy The {@link SelectionPolicy}
71-
* @param convergenceListeners An optional collection of
72-
* {@link ConvergenceListener} with variable arity
73-
*/
74-
@SafeVarargs
75-
protected AbstractGeneticAlgorithm(final CrossoverPolicy<P> crossoverPolicy,
76-
final MutationPolicy<P> mutationPolicy,
77-
final SelectionPolicy<P> selectionPolicy,
78-
ConvergenceListener<P>... convergenceListeners) {
79-
this.crossoverPolicy = crossoverPolicy;
80-
this.mutationPolicy = mutationPolicy;
81-
this.selectionPolicy = selectionPolicy;
82-
updateListenerRigistry(convergenceListeners);
83-
}
84-
8561
/**
8662
* @param crossoverPolicy The {@link CrossoverPolicy}
8763
* @param mutationPolicy The {@link MutationPolicy}
@@ -100,13 +76,7 @@ protected AbstractGeneticAlgorithm(final CrossoverPolicy<P> crossoverPolicy,
10076
this.mutationPolicy = mutationPolicy;
10177
this.selectionPolicy = selectionPolicy;
10278
this.elitismRate = elitismRate;
103-
updateListenerRigistry(convergenceListeners);
104-
}
10579

106-
// suppressed warnings as the parameter is annotated as @SafeVarargs in
107-
// constructor.
108-
@SuppressWarnings("unchecked")
109-
private void updateListenerRigistry(ConvergenceListener<P>... convergenceListeners) {
11080
if (convergenceListeners.length > 0) {
11181
for (ConvergenceListener<P> convergenceListener : convergenceListeners) {
11282
convergenceListenerRegistry.addConvergenceListener(convergenceListener);

commons-math-ga/src/main/java/org/apache/commons/math4/ga/AdaptiveGeneticAlgorithm.java

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -53,35 +53,11 @@ public class AdaptiveGeneticAlgorithm<P> extends AbstractGeneticAlgorithm<P> {
5353

5454
/** instance of logger. **/
5555
private static final Logger LOGGER = LoggerFactory.getLogger(AdaptiveGeneticAlgorithm.class);
56-
5756
/** The crossover rate generator. **/
5857
private final CrossoverRateGenerator<P> crossoverRateGenerator;
59-
6058
/** The mutation rate generator. **/
6159
private final MutationRateGenerator<P> mutationRateGenerator;
6260

63-
/**
64-
* @param crossoverPolicy crossover policy
65-
* @param crossoverProbabilityGenerator crossover probability generator
66-
* @param mutationPolicy mutation policy
67-
* @param mutationProbabilityGenerator mutation probability generator
68-
* @param selectionPolicy selection policy
69-
* @param convergenceListeners An optional collection of
70-
* {@link ConvergenceListener} with
71-
* variable arity
72-
*/
73-
@SafeVarargs
74-
public AdaptiveGeneticAlgorithm(CrossoverPolicy<P> crossoverPolicy,
75-
CrossoverRateGenerator<P> crossoverProbabilityGenerator,
76-
MutationPolicy<P> mutationPolicy,
77-
MutationRateGenerator<P> mutationProbabilityGenerator,
78-
SelectionPolicy<P> selectionPolicy,
79-
ConvergenceListener<P>... convergenceListeners) {
80-
super(crossoverPolicy, mutationPolicy, selectionPolicy, convergenceListeners);
81-
this.crossoverRateGenerator = crossoverProbabilityGenerator;
82-
this.mutationRateGenerator = mutationProbabilityGenerator;
83-
}
84-
8561
/**
8662
* @param crossoverPolicy crossover policy
8763
* @param crossoverProbabilityGenerator crossover probability generator
@@ -123,8 +99,7 @@ protected Population<P> nextGeneration(final Population<P> current, final Execut
12399

124100
final int maxOffspringCount = nextGeneration.getPopulationLimit() - nextGeneration.getPopulationSize();
125101

126-
final Population<P> offsprings = reproduceOffsprings(current, executorService,
127-
maxOffspringCount);
102+
final Population<P> offsprings = reproduceOffsprings(current, executorService, maxOffspringCount);
128103

129104
LOGGER.debug("Performing adaptive mutation of offsprings.");
130105

@@ -139,9 +114,10 @@ private List<Chromosome<P>> mutateChromosomes(final ExecutorService executorServ
139114
final Population<P> offspringPopulation) {
140115

141116
// recompute the statistics of the offspring population.
142-
final PopulationStatisticalSummary<P> offspringPopulationStats = ConstantMutationRateGenerator.class
143-
.isAssignableFrom(this.mutationRateGenerator.getClass()) ? null :
144-
new PopulationStatisticalSummaryImpl<>(offspringPopulation);
117+
final PopulationStatisticalSummary<P> offspringPopulationStats =
118+
mutationRateGenerator instanceof ConstantMutationRateGenerator ?
119+
null :
120+
new PopulationStatisticalSummaryImpl<>(offspringPopulation);
145121

146122
List<Future<Chromosome<P>>> mutatedChromosomes = new ArrayList<>();
147123

commons-math-ga/src/main/java/org/apache/commons/math4/ga/GeneticAlgorithm.java

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -43,44 +43,15 @@ public class GeneticAlgorithm<P> extends AbstractGeneticAlgorithm<P> {
4343

4444
/** instance of logger. **/
4545
private static final Logger LOGGER = LoggerFactory.getLogger(GeneticAlgorithm.class);
46-
4746
/** crossover rate string. **/
4847
private static final String CROSSOVER_RATE = "CROSSOVER_RATE";
49-
5048
/** mutation rate string. **/
5149
private static final String MUTATION_RATE = "MUTATION_RATE";
52-
5350
/** the rate of crossover for the algorithm. */
5451
private final double crossoverRate;
55-
5652
/** the rate of mutation for the algorithm. */
5753
private final double mutationRate;
5854

59-
/**
60-
* Create a new genetic algorithm.
61-
* @param crossoverPolicy The {@link CrossoverPolicy}
62-
* @param crossoverRate The crossover rate as a percentage (0-1
63-
* inclusive)
64-
* @param mutationPolicy The {@link MutationPolicy}
65-
* @param mutationRate The mutation rate as a percentage (0-1 inclusive)
66-
* @param selectionPolicy The {@link SelectionPolicy}
67-
* @param convergenceListeners An optional collection of
68-
* {@link ConvergenceListener} with variable arity
69-
*/
70-
@SafeVarargs
71-
public GeneticAlgorithm(final CrossoverPolicy<P> crossoverPolicy,
72-
final double crossoverRate,
73-
final MutationPolicy<P> mutationPolicy,
74-
final double mutationRate,
75-
final SelectionPolicy<P> selectionPolicy,
76-
ConvergenceListener<P>... convergenceListeners) {
77-
super(crossoverPolicy, mutationPolicy, selectionPolicy, convergenceListeners);
78-
79-
checkValidity(crossoverRate, mutationRate);
80-
this.crossoverRate = crossoverRate;
81-
this.mutationRate = mutationRate;
82-
}
83-
8455
/**
8556
* Create a new genetic algorithm.
8657
* @param crossoverPolicy The {@link CrossoverPolicy}

commons-math-ga/src/main/java/org/apache/commons/math4/ga/ParallelGeneticAlgorithm.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ public class ParallelGeneticAlgorithm<P> {
4242

4343
/** instance of logger. **/
4444
private static final Logger LOGGER = LoggerFactory.getLogger(ParallelGeneticAlgorithm.class);
45-
4645
/** List of algorithm execution configurations to be executed in parallel. **/
4746
private List<AlgorithmExecutionConfig> algorithmConfigParams = new ArrayList<>();
4847

@@ -99,18 +98,15 @@ private List<Population<P>> evolve(ExecutorService executorService) {
9998
} catch (InterruptedException | ExecutionException e) {
10099
throw new GeneticIllegalArgumentException(e);
101100
}
102-
103101
return convergedPopulations;
104102
}
105103

106104
private final class AlgorithmExecutionConfig {
107105

108106
/** instance of genetic algorithm. **/
109107
private AbstractGeneticAlgorithm<P> algorithm;
110-
111108
/** initial population to converge. **/
112109
private Population<P> initialPopulation;
113-
114110
/** stopping condition to decide convergence. **/
115111
private StoppingCondition<P> stoppingCondition;
116112

@@ -121,7 +117,5 @@ private AlgorithmExecutionConfig(AbstractGeneticAlgorithm<P> algorithm,
121117
this.initialPopulation = initialPopulation;
122118
this.stoppingCondition = stoppingCondition;
123119
}
124-
125120
}
126-
127121
}

commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/AbstractChromosome.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,12 @@ public abstract class AbstractChromosome<P> implements Chromosome<P> {
3636

3737
/** Value assigned when no fitness has been computed yet. */
3838
private static final double NO_FITNESS = Double.NEGATIVE_INFINITY;
39-
4039
/** Cached value of the fitness of this chromosome. */
4140
private double fitness = NO_FITNESS;
42-
4341
/** Fitness function to evaluate fitness of chromosome. **/
4442
private final FitnessFunction<P> fitnessFunction;
45-
4643
/** decoder to deode the chromosome's genotype representation. **/
4744
private final Decoder<P> decoder;
48-
4945
/** Id of chromosome. **/
5046
private final String id;
5147

commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/BinaryChromosome.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,10 @@ public class BinaryChromosome<P> extends AbstractChromosome<P> {
3535
* maximum allowed length of binary chromosome.
3636
*/
3737
public static final long MAX_LENGTH = Integer.MAX_VALUE;
38-
3938
/**
4039
* length of binary chromosome.
4140
*/
4241
private final long length;
43-
4442
/**
4543
* binary representation of chromosome.
4644
*/

commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/ChromosomePair.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ public class ChromosomePair<P> {
2525

2626
/** the first chromosome in the pair. */
2727
private final Chromosome<P> first;
28-
2928
/** the second chromosome in the pair. */
3029
private final Chromosome<P> second;
3130

commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/IntegralValuedChromosome.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ public class IntegralValuedChromosome<P> extends AbstractListChromosome<Integer,
3333

3434
/** minimum acceptable value of allele. **/
3535
private final int min;
36-
3736
/** maximum acceptable value of allele. **/
3837
private final int max;
3938

commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/RealValuedChromosome.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ public class RealValuedChromosome<P> extends AbstractListChromosome<Double, P> {
3636

3737
/** minimum acceptable value of allele. **/
3838
private final double min;
39-
4039
/** maximum acceptable value of allele. **/
4140
private final double max;
4241

commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/FixedElapsedTime.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ public class FixedElapsedTime<P> implements StoppingCondition<P> {
3636

3737
/** Maximum allowed time period (in nanoseconds). */
3838
private final long maxTimePeriod;
39-
4039
/** The predetermined termination time (stopping condition). */
4140
private long endTime = -1;
4241

@@ -73,7 +72,6 @@ public boolean isSatisfied(Population<P> population) {
7372
if (endTime < 0) {
7473
endTime = System.nanoTime() + maxTimePeriod;
7574
}
76-
7775
return System.nanoTime() >= endTime;
7876
}
7977

commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/FixedGenerationCount.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@
3030
* @since 2.0
3131
*/
3232
public class FixedGenerationCount<P> implements StoppingCondition<P> {
33+
3334
/** Number of generations that have passed. */
3435
private int numGenerations;
35-
3636
/** Maximum number of generations (stopping criteria). */
3737
private final int maxGenerations;
3838

commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/UnchangedBestFitness.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,11 @@ public class UnchangedBestFitness<P> implements StoppingCondition<P> {
3030

3131
/** best fitness of previous generation. **/
3232
private double lastBestFitness = Double.MIN_VALUE;
33-
3433
/**
3534
* The configured number of generations for which optimization process will
3635
* continue with unchanged best fitness value.
3736
**/
3837
private final int maxGenerationsWithUnchangedBestFitness;
39-
4038
/** Number of generations the best fitness value has not been changed. **/
4139
private int generationsHavingUnchangedBestFitness;
4240

commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/UnchangedMeanFitness.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,11 @@ public class UnchangedMeanFitness<P> implements StoppingCondition<P> {
3131

3232
/** Mean fitness of previous generation. **/
3333
private double lastMeanFitness = Double.MIN_VALUE;
34-
3534
/**
3635
* The configured number of generations for which optimization process will
3736
* continue with unchanged best fitness value.
3837
**/
3938
private final int maxGenerationsWithUnchangedMeanFitness;
40-
4139
/** Number of generations the mean fitness value has not been changed. **/
4240
private int generationsHavingUnchangedMeanFitness;
4341

@@ -66,7 +64,6 @@ public boolean isSatisfied(Population<P> population) {
6664
this.generationsHavingUnchangedMeanFitness = 0;
6765
lastMeanFitness = currentMeanFitness;
6866
}
69-
7067
return false;
7168
}
7269

commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/AbstractListChromosomeCrossoverPolicy.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ private void checkValidity(final Chromosome<P> first, final Chromosome<P> second
6565
throw new GeneticIllegalArgumentException(GeneticIllegalArgumentException.SIZE_MISMATCH,
6666
secondListChromosome.getLength(), length);
6767
}
68-
6968
}
7069

7170
/**

0 commit comments

Comments
 (0)