ECJ

Version		Change Log
----------------------------------------------------------------------------
1		Initial version

2		First prerelease, too many additions to mention

3		Second prerelease
		Race condition bug fixed in ec.gp.koza.Crossover
	     	Breeding trees can now be prespecified
		Crossover can throw away the second sibling
		Multiplexer sped up by a factor of 10!  I might do the
			same thing for Parity and Regression if I have time,
			though for Regression it won't make much of a 
			difference -- thanks to Poli and Langdon
		Lots of little additions and tweaks
		GPNode functions increased
		Regression's * operator no longer shortcuts (due to NaN/Inf)
		Documentation fixes
		Fitness.equivalentTo() now is ==, not >=
		ec.util.Version modified slightly
		Individuals can now be written out to streams, not just logs

4		Third prerelease
		Finisher and Exchanger now are told the run result 
			(success/failure) when they're cleaning up
		Protected Log (rlog) in ec.app.regression.func.Log now is:
				(if (= x 0) x (abs (log x)))
			It was incorrectly:
				(if (<= x 0) x (abs (log x)))
		Edge domain added, with basic function classes
		GPNode.readNode() and ERC.readNode() now check to 
			make sure that the character after the read node is 
			whitespace, (, ), or end of string
		GPTree's readTree() method now checks if a line is empty, 
			rather than bombing.  :-)
		Default population size is now 1024
		Koza FULL/GROW/HALF algorithms now ramp properly; before 
			they were fixed to maxDepth rather than ramping 
			between minDepth and maxDepth.
		ECJ now uses the following for its FULL/GROW/HALF algorithm
			parameter defaults:
				GROW:  	min-depth=5, max-depth=5 (Koza standard
					for mutation)
				FULL:	undefined
				HALF:	min-depth=2, max-depth=6 (Koza standard
					for new individuals)
			Unlike Koza, ECJ permits single-terminal trees/subtrees
		Fixed the documentation for FULL/GROW/HALF to describe the
			odd things that Koza and lil-gp do.
		MersenneTwister and MersenneTwisterFast implement the new, 
			official, improved Mersenne Twister seeding algorithm.
		MersenneFastest.c file deleted
		Three Classes Shortened to the 31 char Mac filename limit:
			ParameterClassNotFoundException ->
				ParameterClassLoadException
			FitnessProportionateSelection ->
				FitProportionateSelection
			SteadyStateBreedingSourceForm ->
				SteadyStateBSourceForm
		ec/params and ec/simple/params files now don't have overlapping
			stuff
		ec/gp/params no longer includes ec/multiobjective/params
		ec.gp.koza.KozaShortStatistics now splits up
			postEvaluationStatistics so that you can include
			stuff in an overriding class before a println 
			is issued.
		
5		Fourth prerelease
		Decided on a strategy to deal with (ARGH!!!) Sun's shift to
			incompatible floating point types across platforms.
			See the file "ABOUT.JDK13"
		ec.select.TournamentSelection can have a tournament of 1
		added README.MacOS
		minor fix to ec.util.ParameterDatabase
		removed the (commented out) populate(...) method from ec.Group
		ec.Evolve now allows <=0 as a seed (since we're using the new
			MersenneTwister seeding algorithm).
		minor fix to ec.gp.GPTreeConstraints
		Added the TwoBox problem
		Orphaned interface GPNodeBuilderHelper deleted
		Modified documentation eval.finish -> eval.problem parameter
		Added the PTC1 and PTC2 algorithms.  Slight addition to
			GPNodeConstraints to accommodate them.
		Added the es package, including (mu,lambda) and (mu+lambda)
			selection strategies.  Totally untested, use at
			your own risk.
		Modified ECJ's strong-typing claim.  ECJ does atomic and
			set-based typing, but will not handle polymorphic
			algorithms without some coding (which I may or
			may not get to -- set-based strong typing is
			pretty dang useful, and it's rare that you
			need more than that).
		Tweaked documentation of SteadyState stuff; as currently
			implemented, the steady state evolution only marks
			one individual per subpop for death each loop
			(not n individuals, as had previously suggested).
		Added elitism to ec.simple.SimpleBreeder
		Symbolic Regression training set size now a parameter
		Fixed ForceBreedingPipeline's claimed default parameter base
		Changed default parameter base for entire ec.breed package
			to "breed"
		Moved all params files to foo.params.  Updated parent 
			statements within params files to reflect this.
			Hope I got 'em all.
		ec.BreedingSource now has typicalIndsProduced() set to a
			default of 1, rather than forcing it to be abstract.
		MAJOR CHANGE: Species no longer has an array of breeding 
			pipelines. It now has a single pipeline.  If you 
			need to pick from among pipelines, use 
			ec.breed.MultiBreedingPipeline.  The various GP 
			params files have been updated to reflect this 
			(since Koza GP by default picks from among pipelines),
			but your params files may be broken because stuff like
				pop.subpop.0.species.pipe.0.blah.blah
			has now changed to
				pop.subpop.0.species.pipe.source.0.blah.blah
			with the insertion of the MultiBreedingPipeline.  
			This is a good thing overall though -- it 
			dramatically simplifies the breeding code with no net
			loss.
		Tweaked the documentation stating the purpose of 
			GPBreedingPipeline.
		Tweaked documentation for ec.Evolve
		Modified ec.util.ParameterDatabase to sort its listed parameters
		Fixed bugs (I hope) in ec.gp.breed.RandomBranch
		Modified RandomChoice (adding the exemptZeroes method) so that 
			it properly handles zero-probability values, and also
			added the ability to handle objects which return 
			doubles rather than floats (RandomChoiceChooserD).
		ec.gp.GPNodeBuilder.canPick() and ec.gp.GPNodeBuilder.pickSize()
			are no longer final
		ec.util.MersenneTwister[Fast].nextBoolean([float|double]) now
			checks to see if the probability is 0.0 or 1.0 and
			guarantees to return false or true in that case
        	Modified ec.Exchanger.runComplete(...) to return a String
        	Modified the various EvolutionState subclasses to consider
        	    ec.Exchanger.runComplete(...) properly in their decision
        	    to shut down prematurely
		ec.steadystate.SteadyStateEvolutionState now reports that it
		    found an ideal individual
		Docs updated

6	Fifth prerelease
	Island models, coevolution, and competitive fitness have been added.
		A bunch of big modifications were made in order to implement 
       	     	coevolution, competitive fitness, and island models.  Get
            	ready, here we go:
        Major change, not backward-compatible:  the thread parameter
		    has been removed from most print- and read- methods 
		    which operate on PrintWriters or LineNumberReaders for
		    individuals and subcomponents.  This is because reading
		    and writing might be done in a private thread (for 
		    asynchronous island model exchanges for example), and so
 		    no thread number is appropriate.  If you need to use a
		    random number generator,  you will need to create one
		    yourself.  Do not rely on random[0].  Affected methods:

			Species.newIndividual(...)
			Fitness.printFitness(...)
			Fitness.readFitness(...)
			Individual.printIndividual(...)
			Individual.readindividual(...)
			simple.SimpleFitness.printFitness(...)
			simple.SimpleFitness.readFitness(...)
			gp.GPSpecies.newIndividual(...)
			gp.GPIndividual.printIndividual(...)
			gp.GPIndividual.readIndividual(...)
			gp.GPTree.printTree(...)
			gp.GPTree.readTree(...)
			gp.GPNode.printRootedTree(...)
			gp.GPNode.readRootedTree(...)
			gp.GPNode.printNode(...)
			gp.koza.KozaFitness.printFitness(...)
			gp.kozalKozaFitness.readFitness(...)
			multiobjective.MultiObjectiveFitness.printFitness(...)
			multiobjective.MultiObjectiveFitness.readFitness(...)
        
        Bug fix in ParameterDatabase.getStringWithDefault() now always
            returns the default string if the string was not found for
            the given parameter (sometimes it was returning null)
        gp.GPTree.printTree* methods now make certain that a return is
            printed at the end.  Also gp.GPIndividual.printIndividual*
            does not make certain (it assumes that printTree will 
            do it). Fixed to make IslandModel exchanges work right.
        EvolutionState.restartFromCheckpoint() is no longer a hook -- 
            now it's the official mechanism that Checkpoint uses
            to get the whole evolution system to restart itself
            after a checkpoint.  Accordingly, output.restart() and
            Exchanger.reinitializeContacts() have been moved to this
            location, and removed from their previous locations in
            the various EvolutionState objects.
        EvolutionState.go() and EvolutionState.run() no longer throw
            IOExceptions, because they no longer call output.restart()
        Fixed checkpoint bug -- GPNodeConstraints wasn't writing out all
            of its static variables.
        Fixed another checkpoint bug -- various Clique objects weren't
            getting written out at all because we no longer reference
            them with pointers but instead with bytes.  This was fixed
            by sticking their static hashtables in a vector called
            "statics" maintained by EvolutionState, so *something*
            serializable is pointing to them.
        Major change, not backward-compatable: the mechanism behind
            the Problem class has been modified, in order to clean up
            stuff to make competitive fitness and coevolution methods more
            doable.  To whit:
                1. Problem is no longer an interface.  It is now an
                empty abstract class.  We may add stuff to this class in
                the future.
                2. Problem's methods have been moved into another
                interface, "SimpleProblemForm".  Problems will now have
                Problem Forms which they implement.  This permits us to
                have different kinds of evaluation methods (for single
                evolution, coevolution, etc.)  The Evaluator involved
                is responsible for checking to make certain that the
                correct Problem Form is being used.
                3. The evaluate(...) and describe(...) methods no longer
                pass in an array of individuals; instead they pass in a
                single individual.
                
            The net result of this is that you will have to modify your
                Problem subclasses so that they implement
                ec.simple.SimpleProblemForm, and so that they do not go
                through the individuals passed in one by one and evaluate
                them, but rather just evaluate a single individual.  This
                generally means you just remove an outer for-loop (at
                least that's what I had to do for all the demo examples).
                
            Affected classes (besides your own Problem subclasses):
                SimpleProblemForm (new)
                Problem
                GPProblem
                SimpleEvaluator
                SteadyStateEvaluator
                Ant
                Edge
                Lawnmower
                Multiplexer
                multiplexerslow.Multiplexer
                Parity
                Regression
                TwoBox
	
	And now for stuff that doesn't have to do with Island Models or
	Coevolution or Competitive Fitness:

	MersenneTwister and MersenneTwisterFast now have a new nextLong(long)
		method so you can get longs up to a certain size.  It's not
		nearly as efficient as the nextInt method, as you might guess.
	ParameterDatabase now has the methods getLongWithMax and 
		getLongWithDefault.  One set of getLong(...) methods has been
		deprecated.  This gets getLong...(...) in-line with the getInt
		methods.
	A new package, vector, has been added for simple GA individuals.
		This package may be modified heavily, don't rely on it to be
		forward-compatible with future versions.
	A new package, rule, has been added for simple rule-based individuals.
		This package may be modified heavily, don't rely on it to be
		forward-compatible with future versions.
	Individuals now have a size() method, which provides a hook for
		parsimony pressure techniques.
	The ParameterDatabase itself has a new global parameter,
		print-params,
		which if true will print parameters as they are grabbed
		from the database through the various get() methods.
		Printing is done through stderr, not logged.
	ec.Evolve has been updated to provide new parameters which list
		all the parameters NOT used or NOT accessed (so you
		can see if you misspelled something and it's being ignored,
		for example).
        Fitness has been tweaked a little bit to allow the fitness() function
                to return ANY value between 0.0 and infinity, rather than the
                previous form (between 0.0 and 1.0).  This isn't a problem
                for fitness-proportionate selection methods because they use
                the distribution mechanisms, which autonormalize.  However,
                it necessitates changing SimpleFitness so that you now have
                to *specify* whether or not something is the ideal fitness.
                This may require a tiny rewrite in those apps which use
                SimpleFitness.  KozaFitness isn't affected because it's defined
                to have the ideal at 0.0.  MultiObjectiveFitness still defines
                its fitnesses as arrays from 0.0 to 1.0 inclusive -- if you
                need them to go to infinity as well, let us know.
        KozaFitness has deprecated its setFitness() function -- now you should
                instead use the better-named setStandardizedFitness().
        Some changes in how breeding pipelines operate:
                1. if generateMax is true, then MultiBreedingPipeline will return
                    *exactly* the maximum typical number.  Previously the pipeline
                    returned a value between the maximum typical number and the
                    maximum requested.
                2.  The typicalIndsProduced() method has been modified in all the
                    breeding pipelines.  Instead of returning 1 (for mutation)
                    or 1 or 2 (for crossover), it now operates as follows:
                        A. Mutation and Reproduction pipelines return the typical number of
                           individuals returned by their sources.  Thus they no
                           longer force their sources to return 1 individual apiece.
                        B. Crossover pipelines return the minimum typical number
                           of individuals returned by their sources.   Thus they
                           no longer force their sources to return 1 or 2 individuals.
                    This change was made to make it easier to tack a mutation pipeline
                    onto a crossover pipeline without losing individuals.
		3. Buffered and Force Breeding pipelines still work as normal
		Hope this doesn't break anything! Most of this will not make any difference,
		because selection methods typically return 1 individual apiece anyway,
		which gets bubbled up through the pipelines.  
	Added the Uniform and RandTree tree-generation algorithms.
	A Makefile is now provided.
	Added the app/ecsuite and app/sum examples for the Vector package
