Skip to content

Commit

Permalink
#566: Some coding.
Browse files Browse the repository at this point in the history
  • Loading branch information
jenetics committed Aug 22, 2019
1 parent e006572 commit e6425e8
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 103 deletions.
160 changes: 57 additions & 103 deletions jenetics/src/main/java/io/jenetics/engine/Engine.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import static java.lang.Math.round;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.CompletableFuture.failedFuture;
import static java.util.concurrent.CompletableFuture.supplyAsync;
import static java.util.concurrent.ForkJoinPool.commonPool;
import static io.jenetics.internal.util.require.probability;
Expand Down Expand Up @@ -133,13 +134,7 @@ public final class Engine<
private final Constraint<G, C> _constraint;

// Evolution parameters.
private final Selector<G, C> _survivorsSelector;
private final Selector<G, C> _offspringSelector;
private final Alterer<G, C> _alterer;
private final Optimize _optimize;
private final int _offspringCount;
private final int _survivorsCount;
private final long _maximalPhenotypeAge;
private final EvolutionParams<G, C> _evolutionParams;

// Execution context for concurrent execution of evolving steps.
private final Executor _executor;
Expand All @@ -157,13 +152,7 @@ public final class Engine<
* @param constraint phenotype constraint which can override the default
* implementation the {@link Phenotype#isValid()} method and repairs
* invalid phenotypes when needed.
* @param survivorsSelector the selector used for selecting the survivors
* @param offspringSelector the selector used for selecting the offspring
* @param alterer the alterer used for altering the offspring
* @param optimize the kind of optimization (minimize or maximize)
* @param offspringCount the number of the offspring individuals
* @param survivorsCount the number of the survivor individuals
* @param maximalPhenotypeAge the maximal age of an individual
* @param evolutionParams the evolution parameters
* @param executor the executor used for executing the single evolve steps
* @param clock the clock used for calculating the timing results
* @throws NullPointerException if one of the arguments is {@code null}
Expand All @@ -174,28 +163,16 @@ public final class Engine<
final Evaluator<G, C> evaluator,
final Factory<Genotype<G>> genotypeFactory,
final Constraint<G, C> constraint,
final Selector<G, C> survivorsSelector,
final Selector<G, C> offspringSelector,
final Alterer<G, C> alterer,
final Optimize optimize,
final int offspringCount,
final int survivorsCount,
final long maximalPhenotypeAge,
final EvolutionParams<G, C> evolutionParams,
final Executor executor,
final Clock clock,
final UnaryOperator<EvolutionResult<G, C>> mapper
) {
_evaluator = requireNonNull(evaluator);
_genotypeFactory = requireNonNull(genotypeFactory);
_survivorsSelector = requireNonNull(survivorsSelector);
_offspringSelector = requireNonNull(offspringSelector);
_alterer = requireNonNull(alterer);
_constraint = requireNonNull(constraint);
_optimize = requireNonNull(optimize);

_offspringCount = require.nonNegative(offspringCount);
_survivorsCount = require.nonNegative(survivorsCount);
_maximalPhenotypeAge = require.positive(maximalPhenotypeAge);
_evolutionParams = requireNonNull(evolutionParams);

_executor = requireNonNull(executor);
_clock = requireNonNull(clock);
Expand Down Expand Up @@ -265,7 +242,8 @@ public EvolutionResult<G, C> evolve(final EvolutionStart<G, C> start) {
final CompletableFuture<AltererResult<G, C>> alteredOffspring =
offspring.thenApplyAsync(off ->
timing.offspringAlter.timing(() ->
_alterer.alter(off, start.getGeneration())
_evolutionParams.getAlterer()
.alter(off, start.getGeneration())
),
_executor
);
Expand Down Expand Up @@ -313,7 +291,7 @@ public EvolutionResult<G, C> evolve(final EvolutionStart<G, C> start) {
final int alterationCount = alteredOffspring.join().getAlterations();

EvolutionResult<G, C> er = EvolutionResult.of(
_optimize,
_evolutionParams.getOptimize(),
result,
start.getGeneration(),
timing.toDurations(),
Expand All @@ -335,16 +313,22 @@ public EvolutionResult<G, C> evolve(final EvolutionStart<G, C> start) {
// Selects the survivors population. A new population object is returned.
private ISeq<Phenotype<G, C>>
selectSurvivors(final ISeq<Phenotype<G, C>> population) {
return _survivorsCount > 0
?_survivorsSelector.select(population, _survivorsCount, _optimize)
return _evolutionParams.getSurvivorsCount() > 0
? _evolutionParams.getSurvivorsSelector().select(
population,
_evolutionParams.getSurvivorsCount(),
_evolutionParams.getOptimize())
: ISeq.empty();
}

// Selects the offspring population. A new population object is returned.
private ISeq<Phenotype<G, C>>
selectOffspring(final ISeq<Phenotype<G, C>> population) {
return _offspringCount > 0
? _offspringSelector.select(population, _offspringCount, _optimize)
return _evolutionParams.getOffspringCount() > 0
? _evolutionParams.getOffspringSelector().select(
population,
_evolutionParams.getOffspringCount(),
_evolutionParams.getOptimize())
: ISeq.empty();
}

Expand All @@ -363,7 +347,9 @@ private FilterResult<G, C> filter(
if (!_constraint.test(individual)) {
pop.set(i, _constraint.repair(individual, generation));
++invalidCount;
} else if (individual.getAge(generation) > _maximalPhenotypeAge) {
} else if (individual.getAge(generation) >
_evolutionParams.getMaximalPhenotypeAge())
{
pop.set(i, Phenotype.of(_genotypeFactory.newInstance(), generation));
++killCount;
}
Expand Down Expand Up @@ -492,7 +478,7 @@ public Constraint<G, C> getConstraint() {
* @return the used survivor {@link Selector} of the GA.
*/
public Selector<G, C> getSurvivorsSelector() {
return _survivorsSelector;
return _evolutionParams.getSurvivorsSelector();
}

/**
Expand All @@ -501,7 +487,7 @@ public Selector<G, C> getSurvivorsSelector() {
* @return the used offspring {@link Selector} of the GA.
*/
public Selector<G, C> getOffspringSelector() {
return _offspringSelector;
return _evolutionParams.getOffspringSelector();
}

/**
Expand All @@ -510,7 +496,7 @@ public Selector<G, C> getOffspringSelector() {
* @return the used {@link Alterer} of the GA.
*/
public Alterer<G, C> getAlterer() {
return _alterer;
return _evolutionParams.getAlterer();
}

/**
Expand All @@ -519,7 +505,7 @@ public Alterer<G, C> getAlterer() {
* @return the number of selected offsprings
*/
public int getOffspringCount() {
return _offspringCount;
return _evolutionParams.getOffspringCount();
}

/**
Expand All @@ -528,7 +514,7 @@ public int getOffspringCount() {
* @return the number of selected survivors
*/
public int getSurvivorsCount() {
return _survivorsCount;
return _evolutionParams.getSurvivorsCount();
}

/**
Expand All @@ -537,7 +523,7 @@ public int getSurvivorsCount() {
* @return the number of individuals of a population
*/
public int getPopulationSize() {
return _offspringCount + _survivorsCount;
return _evolutionParams.getPopulationSize();
}

/**
Expand All @@ -546,7 +532,7 @@ public int getPopulationSize() {
* @return the maximal allowed phenotype age
*/
public long getMaximalPhenotypeAge() {
return _maximalPhenotypeAge;
return _evolutionParams.getMaximalPhenotypeAge();
}

/**
Expand All @@ -555,7 +541,7 @@ public long getMaximalPhenotypeAge() {
* @return the optimization strategy
*/
public Optimize getOptimize() {
return _optimize;
return _evolutionParams.getOptimize();
}

/**
Expand Down Expand Up @@ -748,16 +734,17 @@ public static final class Builder<
private Constraint<G, C> _constraint;

// This are the properties which default values.
private Selector<G, C> _survivorsSelector = new TournamentSelector<>(3);
private Selector<G, C> _offspringSelector = new TournamentSelector<>(3);
private Alterer<G, C> _alterer = Alterer.of(
new SinglePointCrossover<G, C>(0.2),
new Mutator<>(0.15)
);
private Optimize _optimize = Optimize.MAXIMUM;
private double _offspringFraction = 0.6;
private int _populationSize = 50;
private long _maximalPhenotypeAge = 70;
private final EvolutionParams.Builder<G, C> _evolutionParams = EvolutionParams.builder();
// private Selector<G, C> _survivorsSelector = new TournamentSelector<>(3);
// private Selector<G, C> _offspringSelector = new TournamentSelector<>(3);
// private Alterer<G, C> _alterer = Alterer.of(
// new SinglePointCrossover<G, C>(0.2),
// new Mutator<>(0.15)
// );
// private Optimize _optimize = Optimize.MAXIMUM;
// private double _offspringFraction = 0.6;
// private int _populationSize = 50;
// private long _maximalPhenotypeAge = 70;

// Engine execution environment.
private Executor _executor = commonPool();
Expand Down Expand Up @@ -796,10 +783,8 @@ public Builder(
* @param selector used for selecting the offspring population
* @return {@code this} builder, for command chaining
*/
public Builder<G, C> offspringSelector(
final Selector<G, C> selector
) {
_offspringSelector = requireNonNull(selector);
public Builder<G, C> offspringSelector(final Selector<G, C> selector) {
_evolutionParams.offspringSelector(selector);
return this;
}

Expand All @@ -810,10 +795,8 @@ public Builder<G, C> offspringSelector(
* @param selector used for selecting survivors population
* @return {@code this} builder, for command chaining
*/
public Builder<G, C> survivorsSelector(
final Selector<G, C> selector
) {
_survivorsSelector = requireNonNull(selector);
public Builder<G, C> survivorsSelector(final Selector<G, C> selector) {
_evolutionParams.survivorsSelector(selector);
return this;
}

Expand All @@ -826,8 +809,7 @@ public Builder<G, C> survivorsSelector(
* @return {@code this} builder, for command chaining
*/
public Builder<G, C> selector(final Selector<G, C> selector) {
_offspringSelector = requireNonNull(selector);
_survivorsSelector = requireNonNull(selector);
_evolutionParams.selector(selector);
return this;
}

Expand All @@ -849,13 +831,7 @@ public final Builder<G, C> alterers(
final Alterer<G, C> first,
final Alterer<G, C>... rest
) {
requireNonNull(first);
Stream.of(rest).forEach(Objects::requireNonNull);

_alterer = rest.length == 0
? first
: Alterer.of(rest).compose(first);

_evolutionParams.alterers(first, rest);
return this;
}

Expand Down Expand Up @@ -888,7 +864,7 @@ public Builder<G, C> constraint(final Constraint<G, C> constraint) {
* @return {@code this} builder, for command chaining
*/
public Builder<G, C> optimize(final Optimize optimize) {
_optimize = requireNonNull(optimize);
_evolutionParams.optimize(optimize);
return this;
}

Expand Down Expand Up @@ -928,7 +904,7 @@ public Builder<G, C> minimizing() {
* within the range [0, 1].
*/
public Builder<G, C> offspringFraction(final double fraction) {
_offspringFraction = probability(fraction);
_evolutionParams.offspringFraction(fraction);
return this;
}

Expand All @@ -948,7 +924,7 @@ public Builder<G, C> offspringFraction(final double fraction) {
* within the range [0, 1].
*/
public Builder<G, C> survivorsFraction(final double fraction) {
_offspringFraction = 1.0 - probability(fraction);
_evolutionParams.survivorsFraction(fraction);
return this;
}

Expand All @@ -963,14 +939,8 @@ public Builder<G, C> survivorsFraction(final double fraction) {
* within the range [0, population-size].
*/
public Builder<G, C> offspringSize(final int size) {
if (size < 0) {
throw new IllegalArgumentException(format(
"Offspring size must be greater or equal zero, but was %s.",
size
));
}

return offspringFraction((double)size/(double)_populationSize);
_evolutionParams.offspringSize(size);
return this;
}

/**
Expand All @@ -984,14 +954,8 @@ public Builder<G, C> offspringSize(final int size) {
* within the range [0, population-size].
*/
public Builder<G, C> survivorsSize(final int size) {
if (size < 0) {
throw new IllegalArgumentException(format(
"Survivors must be greater or equal zero, but was %s.",
size
));
}

return survivorsFraction((double)size/(double)_populationSize);
_evolutionParams.survivorsSize(size);
return this;
}

/**
Expand All @@ -1003,13 +967,7 @@ public Builder<G, C> survivorsSize(final int size) {
* @throws java.lang.IllegalArgumentException if {@code size < 1}
*/
public Builder<G, C> populationSize(final int size) {
if (size < 1) {
throw new IllegalArgumentException(format(
"Population size must be greater than zero, but was %s.",
size
));
}
_populationSize = size;
_evolutionParams.populationSize(size);
return this;
}

Expand All @@ -1022,12 +980,7 @@ public Builder<G, C> populationSize(final int size) {
* @throws java.lang.IllegalArgumentException if {@code age < 1}
*/
public Builder<G, C> maximalPhenotypeAge(final long age) {
if (age < 1) {
throw new IllegalArgumentException(format(
"Phenotype age must be greater than one, but was %s.", age
));
}
_maximalPhenotypeAge = age;
_evolutionParams.maximalPhenotypeAge(age);
return this;
}

Expand Down Expand Up @@ -1088,7 +1041,8 @@ public Engine<G, C> build() {
_genotypeFactory,
_constraint == null
? RetryConstraint.of(_genotypeFactory)
: _constraint, _survivorsSelector,
: _constraint,
_survivorsSelector,
_offspringSelector,
_alterer,
_optimize,
Expand Down
11 changes: 11 additions & 0 deletions jenetics/src/main/java/io/jenetics/engine/EvolutionParams.java
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,17 @@ public static final class Builder<
private Builder() {
}

public Builder<G, C> evolutionParams(final EvolutionParams<G, C> params) {
survivorsSelector(params.getSurvivorsSelector());
offspringSelector(params.getOffspringSelector());
alterers(params.getAlterer());
optimize(params.getOptimize());
offspringFraction(params.getS());
populationSize(params.getPopulationSize());
maximalPhenotypeAge(params.getMaximalPhenotypeAge());
return this;
}

/**
* The selector used for selecting the offspring population. <i>Default
* values is set to {@code TournamentSelector<>(3)}.</i>
Expand Down

0 comments on commit e6425e8

Please sign in to comment.