Post-Tutorial Discussion: Other Stuff ECJ Has Built In

ECJ can do quite a lot of stuff not covered in the tutorials, but until more tutorials are written :-) you'll have to dig around to find it. Here are some such features.

Other Representations

Sets and Multisets (Bags) The ec.rule package has facilities for making individuals which consist of one or more multisets (bags) each. The notional idea is that individuals contain some fixed number of rulesets, each of which contains an arbitrary number of rules. A rule is left undefined. The notion of "rule" came from our original use for the package, which was to do Pitt-approach ruleset systems. This package comes with some simple breeding operators, though you'll probably want to make your own more specialized versions. The package is also a good jumping-off point for building bags with constraints, such as sets or abitrarily-sized graph structures (neural nets, FSAs, etc.). You'll need to build the constraints into the initialization and breeding operators.

Strings (Lists) The representations in the ec.vector package all have built-in methods (cut, join, etc.) for modifying arbitrary-length vectors (strings). However the package doesn't presently come with breeding operators which call these methods to manipulate arbitrary-length vectors; you'll need to make breeding operators appropriate for your problem.

Arbitrary Representations It's fairly easy to make arbitrary representations with ECJ. Just subclass Individual and add in your own representation. You may need to make your own BreedingPipelines which know how to cross over or mutate your representation.

Genetic Programming Gizmos

Breeding Operators In addition to standard subtree mutation and subtree crossover, ECJ comes with eight breeding operators, most of which :-) have been used in previous literature (the one exception, RehangPipeline, is very interesting but perhaps not all that useful). All operators but RehangPipeline work great with strong typing.

Tree Generation Functions Tired of GP's GROW, FULL, and RAMPED HALF-AND-HALF tree generators? ECJ has five more tree-generation functions, most of which can guarantee tree sizes and all of which work nicely with strong typing.

Forests, ADFs, ADMs, and ERCs ECJ's GP individuals can have multiple trees. ECJ's tree forests can support Automatically Defined Functions (ADFs) and Automatically Defined Macros (ADMs), among other things. At present ECJ does not have modification operators which permit Koza-style architecture-altering operations. The system also has built-in support for a variety of Ephemeral Random Constants (ERCs). The example shows one way of using ERCs.


ECJ's populations are broken into multiple subpopulations. Ordinarily you'd only use one subpopulation, but multiple subpopulations are particularly useful for coevolution. The ec.coevolve package has basic support for defining evaluation of an individual in the context of other individuals with both multi-population coevolution and single-population "competitive fitness" coevolution.

Spatially Distributed EAs

ECJ's ec.spatial package supports both spatially distributed and coevolved spatially distributed evolutionary algorithms. See the ec/app/spatial directory for examples.

Island Models

Another use of multiple subpopulations is to perform island models inside an ECJ run, essentially treating each subpopulation as its own evolutionary run, with occasional migrations from subpopulation to subpopulation. ECJ handles island models by plugging in Exchangers into the system. For multiple islands within one run, one uses the exchanger. Alternatively, one can build an island model consisting of many different processes running on different networked computers. ECJ supports such models with the exchanger. While InterPopulationExchange must be synchronous, IslandExchange can be either synchronous or asynchronous.

Some caveats. First, ECJ presently cannot support both InterPopulationExchange and IslandExchange simultaneously. Second, island models are best done with generational evolutionary methods. Third, an asynchronous IslandExchange cannot guarantee replicability (different computers run at different speeds).

Master-Slave Evaluation

ECJ supports master-slave evaluation, where a single master ECJ process sends Individuals to slave processes which evaluate them in parallel and return them with modified Fitnesses. Internally, ECJ does this by wrapping your Problem in an outer MasterProblem which ships individuals handed it (by the Evaluator) off to remote Slave evaluation processes. There are instructions for setting up the master and any number of slaves in ec/eval/ and some examples in ec/app/star. Master-slave evaluation can also be done in combination with island models: some N islands might each have their own set of slaves. The system is able to handle any number of slaves, and that number can increase or decrease at any time in the run.

Note that networks are inherently slow. At present the cost of sending indivdiuals over the network is high and so master-slave evaluation is only really helpful if it takes more than a fraction of a second or so to evaluate an individual. Also note that, like IslandExchange, Master-Slave evaluation cannot guarantee replicability between runds.


Maybe soon we'll have a tutorial for this. ECJ now has a GUI! You can use it to load and run jobs from parameter files and from checkpoint files, and to edit parameters. The GUI is in its early stages but we thought you'd like to play with it. We hope to extend the GUI to be more and more useful. You can fire up the GUI by running java ec.display.Console

The GUI can also do some nice statistics charting using the JFreeChart and iText libraries (which you must install yourself if you wish to take advantage of this feature). The aim is to provide both on-screen charts and publication-quality PDF output. Charting statistics are done using a subclass of ChartableStatistics. There are certain versions of the examples (in the gui) which, when loaded into the Console, will do charting for you. Like the GUI, charting is in its early stages and will see improvement as time goes by.

Multiobjective Fitnesses

ECJ has hooks for multiobjective fitness. These hooks come in the form of a custom Fitness subclass, MultiObjectiveFitness, which can be plugged into basic evolutionary systems.

ECJ's Fitnesses are separate classes from individuals: thus you can plug in your own customized Fitness class if you don't like the ones provided.

Robert Hubley donated the spea2 package consisting of classes which implement a simple version of the SPEA2 algorithm (a pareto-optimizing multiobjective algorithm for parsimony pressure).

Useful Breeding Operators and Selection Methods

In addition to tournament selection, ECJ's package supports Fitness Proportionate (Roulette) Selection, Koza-style Greedy Overselection, FirstSelection (returning the first individual in the population), BestSelection (picking uniformly from the best N individuals in the population), and a joint selection operator which picks from a variety of selection methods.

ECJ's ec.breed has various classes which allow one to glue different breeding operators together in different ways. For example, one can buffer results, force N individuals to be returned at a time, change the breeding operator after some N generations, and choose at random from N different breeding operators.

Steady State Evolution

ECJ supports steady-state evolution in the ec.steadystate package. This package contains special breeders, evaluators, and evolution states. Because steady state evolution isn't generational, there are certain things which are incompatable with it, or at least inappropriate for it. For example, Island Models are not compatible with it. And fitness proportionate selection and other statistics-based selection methods are inappropriate to use with steady state evolution because they need to be constantly updated every time a new individual is created. Last, steady state evolution cannot run multithreaded.

Differential Evolution and Particle Swarm Optimization

ECJ has packages for differential evolution (DE) and for particle swarm optimization (PSO). The differential evolution package implements several 'common' DE breeding mechanisms (standard, Best1Bin, Rand1EitherOr, Rand1Exp, etc.) via Breeders. The PSO package has its own Breeder and Subpopulation, as PSO requires much more information stored about individuals than ordinary population-based methods.

Parsimony Pressure

ECJ individuals have a size() method which they can overload to indicate their "size". This can be used in parsimony pressure methods. We have some built-in nonparametric parsimony pressure selection methods (lexicogaphic tournament, double tournament, ratio tournament) available in the ec.parsimony package.


The util package contains EC-independent utilities useful for all sorts of stuff. You've seen a few of them: ParameterDatabase, Output, Code, and the MersenneTwisterFast random number generator. You also used the checkpoint facility without accessing the Checkpoint class directly (and probably would never need to). But you ought to know what else is available in this package to avoid reinventing the wheel! Other utilities include: