Class VectorIndividual
- All Implemented Interfaces:
Prototype,Setup,Serializable,Cloneable,Comparable<Individual>
- Direct Known Subclasses:
BitVectorIndividual,ByteVectorIndividual,DoubleVectorIndividual,FloatVectorIndividual,GeneVectorIndividual,IntegerVectorIndividual,LongVectorIndividual,ShortVectorIndividual
This class contains two methods, defaultCrossover and defaultMutate, which can be overridden if all you need is a simple crossover and a simple mutate mechanism. the VectorCrossoverPipeline and VectorMutationPipeline classes use these methods to do their handiwork. For more sophisticated crossover and mutation, you'll need to write a custom breeding pipeline.
The kind of default crossover and mutation, and associated information, is stored in the VectorIndividual's VectorSpecies object, which is obtained through the species variable. For example, VectorIndividual assumes three common types of crossover as defined in VectorSpecies which you should implement in your defaultCrossover method: one-point, two-point, and any-point (otherwise known as "uniform") crossover.
VectorIndividual is typically used for fixed-length vector representations; however, it can also be used with variable-length representations. Two methods have been provided in all subclasses of VectorIndividual to help you there: split and join, which you can use to break up and reconnect VectorIndividuals in a variety of ways. Note that you may want to override the reset() method to create individuals with different initial lengths.
VectorIndividuals must belong to the species VectorSpecies (or some subclass of it).
From ec.Individual:
In addition to serialization for checkpointing, Individuals may read and write themselves to streams in three ways.
- writeIndividual(...,DataOutput)/readIndividual(...,DataInput) This method transmits or receives an individual in binary. It is the most efficient approach to sending individuals over networks, etc. These methods write the evaluated flag and the fitness, then call readGenotype/writeGenotype, which you must implement to write those parts of your Individual special to your functions-- the default versions of readGenotype/writeGenotype throw errors. You don't need to implement them if you don't plan on using read/writeIndividual.
- printIndividual(...,PrintWriter)/readIndividual(...,LineNumberReader) This approach transmits or receives an indivdual in text encoded such that the individual is largely readable by humans but can be read back in 100% by ECJ as well. To do this, these methods will encode numbers using the ec.util.Code class. These methods are mostly used to write out populations to files for inspection, slight modification, then reading back in later on. readIndividual reads in the fitness and the evaluation flag, then calls parseGenotype to read in the remaining individual. You are responsible for implementing parseGenotype: the Code class is there to help you. printIndividual writes out the fitness and evaluation flag, then calls genotypeToString and printlns the resultant string. You are responsible for implementing the genotypeToString method in such a way that parseGenotype can read back in the individual println'd with genotypeToString. The default form of genotypeToString simply calls toString, which you may override instead if you like. The default form of parseGenotype throws an error. You are not required to implement these methods, but without them you will not be able to write individuals to files in a simultaneously computer- and human-readable fashion.
- printIndividualForHumans(...,PrintWriter) This approach prints an individual in a fashion intended for human consumption only. printIndividualForHumans writes out the fitness and evaluation flag, then calls genotypeToStringForHumans and printlns the resultant string. You are responsible for implementing the genotypeToStringForHumans method. The default form of genotypeToStringForHumans simply calls toString, which you may override instead if you like (though note that genotypeToString's default also calls toString). You should handle one of these methods properly to ensure individuals can be printed by ECJ.
In general, the various readers and writers do three things: they tell the Fitness to read/write itself, they read/write the evaluated flag, and they read/write the gene array. If you add instance variables to a VectorIndividual or subclass, you'll need to read/write those variables as well.
- See Also:
-
Field Summary
Fields inherited from class ec.Individual
evaluated, EVALUATED_PREAMBLE, fitness, P_INDIVIDUAL, species -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidcloneGenes(Object piece) Clones the genes in pieces, and replaces the genes with their copies.voiddefaultCrossover(EvolutionState state, int thread, VectorIndividual ind) Destructively crosses over the individual with another in some default manner.voiddefaultMutate(EvolutionState state, int thread) Destructively mutates the individual in some default manner.intReturns the length of the gene array.Returns the gene array.voidJoins the n pieces and sets the genome to their concatenation.abstract voidreset(EvolutionState state, int thread) Initializes the individual.voidreset(EvolutionState state, int thread, int newSize) Initializes the individual to a new size.voidSets the gene array.voidsetGenomeLength(int len) Sets the genome length.longsize()Returns the "size" of the individual.voidSplits the genome into n pieces, according to points, which *must* be sorted.Methods inherited from class ec.Individual
clone, compareTo, distanceTo, equals, genotypeToString, genotypeToStringForHumans, hashCode, merge, parseGenotype, printIndividual, printIndividual, printIndividual, printIndividualForHumans, printIndividualForHumans, readGenotype, readIndividual, readIndividual, setup, toString, writeGenotype, writeIndividualMethods inherited from class java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, waitMethods inherited from interface ec.Prototype
defaultBase
-
Constructor Details
-
VectorIndividual
public VectorIndividual()
-
-
Method Details
-
defaultCrossover
Destructively crosses over the individual with another in some default manner. In most implementations provided in ECJ, one-, two-, and any-point crossover is done with a for loop, rather than a possibly more efficient approach like arrayCopy(). The disadvantage is that arrayCopy() takes advantage of a CPU's bulk copying. The advantage is that arrayCopy() would require a scratch array, so you'd be allocing and GCing an array for every crossover. Dunno which is more efficient. -
defaultMutate
Destructively mutates the individual in some default manner. The default version calls reset() -
reset
Initializes the individual. -
getGenome
Returns the gene array. If you know the type of the array, you can cast it and work on it directly. Otherwise, you can still manipulate it in general, because arrays (like all objects) respond to clone() and can be manipulated with arrayCopy without bothering with their type. This might be useful in creating special generalized crossover operators -- we apologize in advance for the fact that Java doesn't have a template system. :-( The default version returns null. -
setGenome
Sets the gene array. See getGenome(). The default version does nothing. -
genomeLength
public int genomeLength()Returns the length of the gene array. By default, this method returns 0. -
reset
Initializes the individual to a new size. Only use this if you need to initialize variable-length individuals. -
setGenomeLength
public void setGenomeLength(int len) Sets the genome length. If the length is longer, then it is filled with a default value (likely 0 or false). This may or may not be a valid value -- you will need to set appropriate values here. The default implementation does nothing; but all subclasses in ECJ implement a subset of this. -
split
Splits the genome into n pieces, according to points, which *must* be sorted. pieces.length must be 1 + points.length. The default form does nothing -- be careful not to use this method if it's not implemented! It should be trivial to implement it for your genome -- just like at the other implementations. -
join
Joins the n pieces and sets the genome to their concatenation. The default form does nothing. It should be trivial to implement it for your genome -- just like at the other implementations. -
cloneGenes
Clones the genes in pieces, and replaces the genes with their copies. Does NOT copy the array, but modifies it in place. If the VectorIndividual holds numbers or booleans etc. instead of genes, nothing is cloned (why bother?). -
size
public long size()Description copied from class:IndividualReturns the "size" of the individual. This is used for things like parsimony pressure. The default form of this method returns 0 -- if you care about parsimony pressure, you'll need to override the default to provide a more descriptive measure of size.- Overrides:
sizein classIndividual
-