- Java 21 is used for building and using the library.
- #878: Allow Virtual-Threads evaluating the fitness function.
final Engine<DoubleGene, Double> engine = Engine.builder(ff)
.fitnessExecutor(BatchExecutor.ofVirtualThreads())
.build();
- #880: Replace code examples in Javadoc with JEP 413.
- #886: Improve
CharStore
sort.
- #894: New genetic operators:
ShiftMutator
, ShuffleMutator
and UniformOrderBasedCrossover
.
- #895: Improve default
RandomGenerator
selection. The used RandomGenerator
is selected in the following order:
- Check if the
io.jenetics.util.defaultRandomGenerator
start parameter is set. If so, take this generator.
- Check if the
L64X256MixRandom
generator is available. If so, take this generator.
- Find the best available random generator according to the
RandomGeneratorFactory.stateBits()
value.
- Use the
Random
generator if no best generator can be found. This generator is guaranteed to be available on every platform.
- #862: Add a method, which allows to create a sliced (chromosome) view onto a given Genotype.
- #866: Allow specifying the default
RandomGenerator
used by the library.
java -Dio.jenetics.util.defaultRandomGenerator=L64X1024MixRandom\
-cp jenetics-@__version__@.jar:app.jar\
com.foo.bar.MyJeneticsAppjava
- #872: Improve generic type parameters for some argument types in
io.jenetics.prog
module.
- #876: Fix compiler warnings with Java 21-
- #865, #867: Fixing typos in documentation.
- #868: Fix execution script
./jrun.cmd
- #857: Make library compile with Java 20.
- #853: Improve error message for
Codecs::ofSubSet::encode
method.
- #842:
BitChromosone::bitCount
returns wrong results for chromosome lengths <= 8.
- #813: Re-implementation of
MathExpr
class. Replace ad-hoc parsing implementation.
- #815: Implement Grammatical-Evolution.
- #820: Additional
BitChromosome
methods: and
, or
, xor
, not
, shiftRight
, shiftLeft
.
- #833: Implement
Tree::reduce
function. Allows to write code as follows:
final Tree<String, ?> formula = TreeNode.parse(
"add(sub(6, div(230, 10)), mul(5, 6))",
String::trim
);
final double result = formula.reduce(new Double[0], (op, args) ->
switch (op) {
case "add" -> args[0] + args[1];
case "sub" -> args[0] - args[1];
case "mul" -> args[0] * args[1];
case "div" -> args[0] / args[1];
default -> Double.parseDouble(op);
}
);
- #831: Error while parsing parentheses trees.
- #836: Fix
BitChromosome
(Test
).
- #632: Convert data classes to
records
.
- #696: Convert libraries to JPMS modules.
- #715: Improve
BitChromosome
.
- #762: Apply new Java17 construct where useful.
- #767: Incubator - Grammar-based evolution.
- #773: Incubator - Simplify and unify parsing code for
MathExpr
class.
- #785: Using
RandomGenerator
instead of Random
class.
- #787: Breaking change - Change upper limit of
Integer
/LongeGenes
from inclusively to exclusively.
- #789: Make
AbstractChromosome
non-Serializable
.
- #796: Use
InstantSource
instead of Clock
for measuring evolution durations.
- #798: Performance improve of subset creation method.
- #801: Introduce
Self
interface.
- #816: Add Sudoku example (by alex-cornejo).
- #791: Fix possible overflow in Integer/LongGene mean method.
- #794: Fix possible underflow in DoubleGene mean method.
- #803: Bug checking Sample arity in class SampleList.
- #763:
ProxySorter
is now able to sort array slices.
- #768: Implement
Ordered
class. Currently, it is required that the return value of the fitness function to be Comparable
. But sometimes you might want to change the order of a given type or add some order to a type. The Ordered
class makes this possible.
- #754: Make
Optimize.best
method null
friendly
- #742: Fix compile error with Java 15.
- #746:
Const<Double>
equals doesn't conform with Double.compare
.
- #748: Fix broken formulas in Javadoc.
- #752:
StreamPublisher
doesn't close underlying Stream
on close.
- #323: Fix leaky abstraction of
CompositeCodec
.
- #434: Rewrite build scripts using Kotlin.
- #695: Simplify MOEA for continious optimization.
- #704: Add
FlatTreeNode.ofTree
factory method, for cleaner Tree
API.
- #706: The
Constraint
is now part of the Problem
interface. If defined, it will automatically be part of the created Engine
.
default Optional<Constraint<G, C>> constraint() {
return Optional.empty();
}
- #708: Additional
Chromosome.map(Function)
methods. This allows a more efficient mapping of chromosomes.
- #731: Improve creation of constrained individuals, as defined in the
Constraint
interface.
- #739: Add
jenetics.incubator
module. This module will contain classes which might be part of one of the main module.
- #701: Invalid
DoubleGene.isValid
method.
- #713: Fix numeric instability of
RouletteWheleSelector
class.
- #718:
IntermediateCrossover
is not terminating for invalid genes.
- #403: Converting library to Java 11.
- #581: Minimize the required evaluation calls per generation.
- #587: Fix Javadoc for Java 11.
- #590: Improve serialization of
Seq
implementations.
- #591: Remove deprecated classes and methods.
- #606: Improve serialization of
*Range
classes.
- #630: Fix inconsistency in
Codec.of
factory methods.
- #659: Additional factory methods for
VecFactory
interface in the moea
package.
- #661: Allow the re-evaluation of the population fitness value
- #665: Implement
CombineAlterer
, which is a generalization of th MeanAlterer
class.
- #669: Regression analysis with dynamically chaning sample points.
final var scheduler = Executors.newScheduledThreadPool(1);
final var nullifier = new FitnessNullifier<ProgramGene<Double>, Double>();
final var sampling = new SampleBuffer<Double>(100);
scheduler.scheduleWithFixedDelay(
() -> {
// Adding a new sample point every second to the ring buffer.
sampling.add(nextSamplePoint());
// Force re-evaluation of populations fitness values.
nullifier.nullifyFitness();
},
1, 1, TimeUnit.SECONDS
);
final Codec<Tree<Op<Double>, ?>, ProgramGene<Double>> codec =
Regression.codecOf(OPS, TMS, 5, t -> t.gene().size() < 30);
final Regression<Double> regression = Regression.of(
codec,
Error.of(LossFunction::mse),
sampling
);
final Engine<ProgramGene<Double>, Double> engine = Engine
.builder(regression)
.interceptor(nullifier)
.build();
engine.stream()
.flatMap(Streams.toIntervalMax(Duration.ofSeconds(30)))
.map(program -> program.bestPhenotype()
.genotype().gene()
.toParenthesesString())
// Printing the best program found so far every 30 seconds.
.forEach(System.out::println);
- #671: Adding helper methods in
Streams
class, which allows to emit the best evolution result of every n generation.
final ISeq<Integer> values = IntStream.range(0, streamSize).boxed()
.flatMap(Streams.toIntervalMax(sliceSize))
.collect(ISeq.toISeq());
- #672: Introduce the
StreamPublisher
class, which allows to use a normal Java Stream in a reactive way.
final var publisher = new StreamPublisher<EvolutionResult<IntegerGene, Integer>>();
try (publisher) {
final var stream= engine.stream();
publisher.subscribe(new Subscriber<>() { ... });
publisher.attach(stream);
...
}
- #679: Additional constructor for the
TournamentSelector
, which allows to define own Phenotype
comparator.
- #685: Add
Engine.Setup
interface, which allows combining different dependent engine configurations.
- #687: Add engien setup for (μ,λ)- and (μ+λ)-Evolution Strategy.
- #663:
PartialAlterer
uses fitness of unaltered phenotype.
- #667: Fix
Concurrency.close()
method.
- #542: Introduce
InvertibleCodec
interface. This interface extends the the current Codec
interface.
public interface InvertibleCodec<T, G extends Gene<?, G>> extends Codec<T, G> {
Function<T, Genotype<G>> encoder();
default Genotype<G> encode(final T value) {
return encoder().apply(value);
}
}
- #543: Simplified
Constraint
factory methods.
- #566: New parameter class,
EvolutionParams
, contains all Engine
parameters which influence the evolution performance.
- #607: More flexible MOEA optimization. It is now possible to do minimization/maximization on every dimension independently.
- #614: Generalize the
ConstExprRewriter
class. It can no be used with every type, not only with Double
values.
- #635: Mark the
Chromosome.toSeq()
and Genotype.toSeq()
methods as deprecated. This methods are no longer needed, because the Chromosome
and Genotype
itself will implement the new BaseSeq
interfaces and are now sequences itself.
- #645: Mark all bean-like getter methods as deprecated. This methods will be replaced by simple accessor-methods, and is a preparation step for using the new Java records.
- #621:
ìo.jenetics.prog.op.Program.arity()
returns the wrong value.
- #522: Replace
io.jenetics.ext.engine.AdaptiveEngine
with io.jenetics.ext.engine.UpdatableEngine
. The AdaptiveEngine
has been marked as deprecated.
- #557: Implementation
io.jenetics.util.ProxySorter
class, which sorts a proxy array instead of an sequence itself.
- #563: Introduction of
Evolution
interface, which makes the concept of an evolution function more explicit.
- #579: Improve internal
RingBuffer
implementation.
- #585: Improve
EphemeralConst
serialization.
- #592: Add
Tree.path()
and Tree.pathElements()
methods.
- #539: Fix JHM tests.
- #599:
Recombinator
performs recombine
on an individual with itself.
- #600: Duplicates in Pareto set owing to the
equals
method in Phenotype
class.
- #550: Erroneous index check for
Sample.argAt(int)
method in io.jenetics.prog.regression
package.
- #554:
ClassCastException
in io.jenetics.prog.regression.Regression
class.
- #534: Generify
Regression
classes so it can be used for regression analysis of arbitrary types.
- #529: Implementation of Hybridizing PSM and RSM mutation operator (HPRM)
- #518: Implementation of Symbolic Regression classes. This makes it easier to solve such optimization problems.
- #515: Rename
Tree.getIndex(Tree)
to Tree.indexOf(Tree)
.
- #509: Allow to collect the nth best optimization results.
final ISeq<EvolutionResult<DoubleGene, Double>> best = engine.stream()
.limit(Limits.bySteadyFitness(50))
.flatMap(MinMax.toStrictlyIncreasing())
.collect(ISeq.toISeq(10));
- #504: Rename
Tree.getChild(int)
to Tree.childAt(int)
.
- #500: Implementation of Reverse Sequence mutation operator (RSM).
- #497: Implement Boolean operators for GP.
- #496: Implement
GT
operator for GP.
- #493: Add dotty tree formatter
- #488: Implement new tree formatter
TreeFormatter.LISP
. This allows to create a Lisp string representation from a given Tree
.
- #487: Re-implementation of 'MathTreePruneAlterer'. The new implementation uses the newly introduced Tree Rewriting API, implemented in #442.
- #486: Implement
TreeRewriteAlterer
, based on the new Tree Rewriting API.
- #485: Cleanup of
MathExpr
class.
- #484: The
Tree.toString()
now returns a parentheses string.
- #481: The parentheses tree representation now only escapes "protected" characters.
- #469: Implementation of additional
Evaluator
factory methods.
- #465: Remove fitness scaler classes. The fitness scaler doesn't carry its weight.
- #455: Implementation of
CompletableFutureEvaluator
.
- #450: Improvement of
FutureEvaluator
class.
- #449: The
Engine.Builder
constructor is now public and is the most generic way for creating engine builder instances. All other builder factory methods are calling this primary constructor.
- #447: Remove evolution iterators. The whole evolution is no performed via streams.
- #442: Introduce Tree Rewriting API, which allows to define own rewrite rules/system. This is very helpful when solving GP related problems.
final TRS<String> trs = TRS.parse(
"add(0,$x) -> $x",
"add(S($x),$y) -> S(add($x,$y))",
"mul(0,$x) -> 0",
"mul(S($x),$y) -> add(mul($x,$y),$y)"
);
// Converting the input tree into its normal form.
final TreeNode<String> tree = TreeNode.parse("add(S(0),S(mul(S(0),S(S(0)))))");
trs.rewrite(tree);
assert tree.equals(TreeNode.parse("S(S(S(S(0))))"));
- #372: Allow to define the chromosome index an
Alterer
is allowed to change. This allows to define alterers for specific chromosomes in a genotype.
// The genotype prototype, consisting of 4 chromosomes
final Genotype<DoubleGene> gtf = Genotype.of(
DoubleChromosome.of(0, 1),
DoubleChromosome.of(1, 2),
DoubleChromosome.of(2, 3),
DoubleChromosome.of(3, 4)
);
// Define the GA engine.
final Engine<DoubleGene, Double> engine = Engine
.builder(gt -> gt.getGene().doubleValue(), gtf)
.selector(new RouletteWheelSelector<>())
.alterers(
// The `Mutator` is used on chromosome with index 0 and 2.
SectionAlterer.of(new Mutator<DoubleGene, Double>(), 0, 2),
// The `MeanAlterer` is used on chromosome 3.
SectionAlterer.of(new MeanAlterer<DoubleGene, Double>(), 3),
// The `GaussianMutator` is used on all chromosomes.
new GaussianMutator<>()
)
.build();
- #368: Remove deprecated code.
- #364: Clean implementation of async fitness functions.
- #342: The
Tree
accessor names are no longer in a Java Bean style: getChild(int)
-> childAt(int)
. This corresponds to the childAtPath(path)
methods.
- #331: Remove
hashCode
and equals
method from Selector
and Alterer
.
- #314: Add factory method for
AdaptiveEngine
, which simplifies its creation.
- #308: General improvement of object serialization.
- #50: Improve Genotype validation. The new
Constraint
interface, and its implementation RetryConstraint
, now allows a finer control of the validation and recreation of individuals.
- #520: Fix tree-rewriting for
Const
values. This leads to non-matching nodes when trying to simplify the GP tree.
- #475: Level function returns different results depending on whether the iterator is iterating through a
ProgramGene
or TreeNode
.
- #473:
DynamicGenotype
example causes IllegalArgumentException
.
- #316: Improve implementation of tree rewriting. This is a preparations tep for #442.
- #414: Use Gradle 'implementation' instead of 'compile' dependency
- #426: Relax
final
restriction on some Alterer
implementations. All alterers can now be sub-classed.
- #430: Codec for numeric 2d matrices.
- #433: Upgrade Gradle to 5.x.
- #443: Precondition check for
XXXChromosome.of(Gene...)
factory methods.
- #445: Mark
Phenotype.newInstance
methods as deprecated.
- #457: Add
<A> A[] Seq.toArray(IntFunction<A[]> generator)
method.
- #347: Improve
hashCode
and equals
methods.
- #349: Cleanup of chromosome constructors. Make the constructors more regular.
- #355: Simplify implementation of numeric genes.
- #361: Add
NumericChromosome.primitiveStream()
methods.
- #366: Deprecate reference to fitness function property from
Phenotype
. Preparation step for generalizing the fitness evaluation.
- #377: Add
Tree.childAt
method. Lets you fetch deeply nested child nodes.
- #378: Convert tree to parentheses tree string.
- #379: Parse parentheses tree string to tree object.
- #380: Add
TreeNode.map
method.
- #400: Codec for mapping source- and target objects.
- #406: Make the library compilable under Java 11.
- #411: Improve the behaviour of the
MathExpr.format
method.
- #357: Invalid length of selected population in
MonteCarloSelector
.
- #420:
Limits.byFitnessThreshold
termination strategy is missing best generation.
- 416: Method internal
comb.subset
doesn't create all possible combinations. The PermutationChromosome
is therefore not able to create solutions for the whole search space.
- #325: Allow customization of fitness evaluation execution for bundling calculations
- #327: Improve CPU utilization during fitness evaluation.
- #335: Seq view wrapper for List and T[] types.
- #317: Fix links of Javadoc images.
- #318: NULL result from engine.stream() after upgrade from 4.0.0 to 4.1.0.
- #336: Errornous default implementation of 'Seq.indexWhere'.
- #341: Error in internal 'bit.increment' method.
- #345: Assumption for 'Genotype.newInstance(ISeq)' no longer holds.
- #223: Implementation of Multi-Objective Optimization.
- #259: Pruning GP program tree.
- #285: Population exchange between different Engines.
- #294: Cleanup of Jenetics examples.
- #295: Upgrade Gradle version 4.5.
- #297: Compile JMH test on test execution.
- #306: Improve Javadoc on how to extend chromosomes.
- #307: Enable @apiNote, @implSpec and @implNote Javadoc tag.
- #290: User's manual fixes.
- #298: Fix GP load/save of generated tree.
- #28: Immutable population class. The original
Population
class has been replaced by Seq<Phenotype<G, C>>
. This points to a more functional implementation of the library.
- #119:
Chromosome
implementations are now fully immutable. This is an internal change only.
- #121:
Mutator
class is easier now to extend. It has been extended with additional mutate
methods which serves as extension points for onw Mutator
implementations.
- #123:
Chromosome
with variable number of genes: Most chromosomes can now be created with a variable number of genes. DoubleChromosome.of(0.0, 1.0, IntRange.of(5, 16))
.
- #172:
io.jenetics.prngine
library replaces the existing PRNG implementations in the io.jenetics.base
module.
- #175: Align random int range generation with
io.jenetics.prngine
library. This is an internal change only.
- #180: Change library namespace from
org.jenetics
to io.jenetics
. This is the most invasive change of this release. Users have to adopt the imports in all their code.
- #183: Change copyright email address to ...@gmail.com
- #200: Implementation of gene convergence termination: A termination method that stops the evolution when a user-specified percentage of the genes that make up a
Genotype
are deemed as converged. A gene is deemed as converged when the average value of that gene across all of the genotypes in the current population is less than a user-specified percentage away from the maximum gene value across the genotypes.
- #253: Removal of deprecated code and classes: mainly
JAXB
marshalling and the LCG64ShiftRandom
class.
- #260: Clean room implementation of internal
subset
function. This method was a port from the C++ source written by John Burkardt. The original source has been published under the LGPL licence, which is not compatible to tha Apache 2 licence. To avoid legal issues, the affected method has been reimplemented using the Clean Room method, based on the original book, Combinatorial Algorithms for Computers and Calculators, by Albert Nijenhuis and Herbert Wilf. The io.jenetics.internal.math.comb.subset
method is now fully compatible with the Apache 2 licence.
- #262: Filter for duplicate individuals: It is now possible to intercept the stream of
EvolutionResult
s of the evolution Engine
:
final Engine<DoubleGene, Integer> engine = Engine.builder(problem)
.mapping(EvolutionResult.toUniquePopulation())
.build();
- #264: Upgrade Gradle to version 4.3.
- #266: The
Seq
serialization should be more robust in the case of implementation changes.
- #268: Implementation of an
EliteSelector
.
- #269: Cleanup of internal, mathematical helper functions.
- #272: Obey Java naming convention. Two helper classes have been renamed to obey the Java naming conventions.
codecs
-> Codecs
and limits
-> Limits
.
- #279: Additional
MSeq.swap
method.
- #247: Fix the classpath of the
jrun
helper script.
- #256: Buggy type signature of
AnyChromosome.of
method.
- #26: Extend Gradle scripts for multi-module releases.
- #27: Parallel
EvolutionStream
.
- #64: Implementation of
TreeGene
/Chromosome
.
- #181: XML marshaling module:
org.jenetics.xml
.
- #199: Termination: Population convergence.
- #201: Simplify Gradle build scripts.
- #204: Remove internal 'Stack' container class.
- #207: Add missing
BitChromosome
factory methods.
- #216: Restructuring of User's Manual.
- #218: Mark
LCG64ShiftRandom
class as deprecated.
- #219: Mark
JAXB
marshaling as deprecated.
- #227: Genetic Programming module:
org.jenetics.prog
.
- #228: Upgrade Gradle to 4.0.2.
- #229: Define stable module names.
- #236: Rename module
jenetix
to org.jenetics.ext
- #238: Align project directories with maven artifact names.
- #212: Fix
Seq.toArray(Object[])
method.
- #226: Incorrect
MinMax.toString()
output.
- #233:
Engine.java
Comment Grammar Fix.
- #234:
Population.empty()
isn't empty
- #157: Add
LineCrossover
class.
- #158: Add
IntermediateCrossover
class.
- #168: Remove dependency to
java.desktop
module.
- #169: Describe how to configure (μ, λ) and (μ + λ) Evolution Strategies in manual.
- #177: Additional 'Seq' conversion functions:
- #182: Rename build script to default names. All build scripts are now named
build.gradle
.
- #188: Additional
Engine.Builder
methods
- #189:
TruncationSelector
is now able to globally limit best selected individuals. This is used for (μ, λ) and (μ + λ) Evolution Strategies.
- #197: Improve CPU utilization for long running fitness functions. The original concurrent fitness function evaluation where assumed to be quite fast.
- #127: Change the maven group and artifact ID from
org.bitbucket:org.jenetics
to io.jenetics:jenetics
.
- #142: Jenetics now compiles without warnings with Java 9 EA.
- #145: Add additional
Engine.stream(...)
and Engine.iterator(...)
methods:
- #150: Implement fitness convergence termination strategy.
- #152: Remove
hashCode
and replace equals
method with sameState(T)
for mutable objects.
- #156: Implementation of an UniformCrossover.
- #162: Update and improve User's Manual.
- #143: Fix serialization of
EvolutionResult
class.
- #146: NPE in
EvolutionResult.toBestEvolutionResult()
when collecting empty EvolutionStream
s.
- #159: The User's Manual build fails for Lyx version 2.2.2.
- #103: Add
MSeq.sort
method.
- #114:
Alterer
implementations are now able to handle Chromosome
s of different length.
- #135: Add
Codec.decode(Genotype)
default method.
- #140: Additional
EvolutionResult.toBestResult
collectors.
- #129: Fix Javadoc encoding.
- #134: Update Gradle to 3.1.
- #138: Update TestNG to 6.9.13.
- #111: Dead lock for single-threaded executors.
- #81: It is now easier to register user-defined JAXB marshallings --
org.jenetics.util.IO.JAXB.register
- #90, #91: The manual contains now a section where the performance of the
MonteCarloSelector
and an evolutionary Selector
is compared (fig. 6.8, page 52).
- #96: Merge branch with incubation module
org.jenetix
, which contains experimental classes.
- #101: Add manual example for solving the Rastrigin function.
- #92: Fix example code in user manual.
- #94: Inconsistent pre-condition check of
Engine.Builder.build
method.
- #99:
EvolutionResult
was not completely immutable.
- #68: Improve implementations of
Seq
interfaces. Note: The changes of this issue changes the Java serialization of the Genes
and Chromosomes
. Gene
/Chromosomes
which has been serialized with version 3.3 can't be loaded with version 3.4. As a workaround, it is still possible to write the Genes
/Chromosomes
in XML format and load it with version 3.4.
- #73: Add additional methods to
Seq
interface: Seq.append
and Seq.prepend
.
- #79: Improve evolution performance measuring. Code resides now in (experimental)
org.jenetics.tool
module.
- #85: Add support for fixed-sized subsets in
PermutationChromosome
class. See also codecs.ofSubSet(ISeq, int).
- #43: Add Evolving images example.
- #62: Two or more
Codec
interfaces can be combined into a single one.
- #66: Add
AnyGene
and AnyChromosome
for arbitrary allele types.
- #52: Immutability of ISeq violated.
- #55: Fixing example-run script for Mac.
- #24: Stabilize statistical selector tests.
- #25: Remove
testng.xml
file. The test classes are now determined automatically.
- #40: Introduce
Codec
interface for defining problem encodings.
- Add Internal section in manual, which describes implementation details.
- #33: Selectors must not change the input population. This occasionally caused
ConcurrentModificationException
. Such selectors are now creating a defensive copy of the input population.
- #34:
IndexOutOfBoundsException
when selecting populations which are too short.
- #35:
IndexOutOfBoundsException
when altering populations which are too short.
- #39: Numerical instabilities of
ProbabilitySelector
.
- #47:
Engine
deadlock for long running fitness functions.
- Additional termination strategies in
org.jenetics.engine.limit
class.
- Add
EvolutionStream.of
factory method. This allows to use other evolution functions than the Engine
class.
org.jenetics.stat.Quantile
has now a combine
method which lets them use in a parallel stream.
- #12: Fix typos in user manual.
- #13: Add link to Javadoc and manual to README file.
- #14: Remove
Serializable
interface from Gene
and Chromosome
.
- #16: Make code examples in Javadoc standard conform.
- #17: Improve recombination section in manual.
- #20: Advance
Genotype
validity checks.
- Rewrite of engine classes to make use of Java 8 Stream API.