/*
Copyright 2006 by Sean Luke
Licensed under the Academic Free License version 3.0
See the file "LICENSE" for more information
*/
package ec.rule;
import ec.*;
import ec.util.*;
import java.io.*;
/*
* RuleIndividual.java
*
* Created: Tue May 29 18:20:20 EDT 2001
* By: Sean Luke
*/
/**
* RuleIndividual is an Individual with an array of RuleSets, each of which
* is a set of Rules. RuleIndividuals belong to some subclass of RuleSpecies
* (or just RuleSpecies itself).
*
*
RuleIndividuals really have basically one parameter: the number
* of RuleSets to use. This is determined by the num-rulesets
* parameter.
*
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. readIndividualreads
* 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 Rulesets. If you add instance variables to
* a RuleIndividual or subclass, you'll need to read/write those variables as well.
Parameters
base.num-rulesets
int >= 1 |
(number of rulesets used) |
base.ruleset.n
Classname, subclass of or = ec.rule.RuleSet |
(class of ruleset n) |
Parameter bases
Default Base
rule.individual
* @author Sean Luke
* @version 1.0
*/
public class RuleIndividual extends Individual
{
public static final String P_RULESET = "ruleset";
public static final String P_NUMRULESETS = "num-rulesets";
/** The individual's rulesets. */
public RuleSet[] rulesets;
public Parameter defaultBase()
{
return RuleDefaults.base().push(P_INDIVIDUAL);
}
public Object clone()
{
RuleIndividual myobj = (RuleIndividual) (super.clone());
myobj.rulesets = new RuleSet[rulesets.length];
for(int x=0;x>> 31 ) ^ rulesets[x].hashCode();
return hash;
}
public void setup(final EvolutionState state, final Parameter base)
{
super.setup(state,base); // actually unnecessary (Individual.setup() is empty)
// I'm the top-level setup, I guess
int numrulesets = state.parameters.getInt(
base.push(P_NUMRULESETS), defaultBase().push(P_NUMRULESETS),
1); // need at least 1 ruleset!
if (numrulesets == 0)
state.output.fatal("RuleIndividual needs at least one RuleSet!",
base.push(P_NUMRULESETS), defaultBase().push(P_NUMRULESETS));
rulesets = new RuleSet[numrulesets];
for(int x=0;x