/*
* This file is part of JGAP.
*
* JGAP offers a dual license model containing the LGPL as well as the MPL.
*
* For licensing information please see the file license.txt included with JGAP
* or have a look at the top of class org.jgap.Chromosome which representatively
* includes the JGAP license policy applicable for any file delivered with JGAP.
*/
package org.jgap.gp;
import org.jgap.gp.terminal.*;
import org.jgap.gp.impl.*;
import org.jgap.*;
/**
* Abstract base class for all implementations of IGPChromosome.
*
* @author Klaus Meffert
* @since 3.01
*/
public abstract class BaseGPChromosome
implements IGPChromosome {
/** String containing the CVS revision. Read out via reflection!*/
private final static String CVS_REVISION = "$Revision: 1.8 $";
/**
* The configuration object to use.
*/
private GPConfiguration m_configuration;
/**
* The individual the chromosome belongs to.
*/
private IGPProgram m_ind;
public BaseGPChromosome(GPConfiguration a_configuration)
throws InvalidConfigurationException {
if (a_configuration == null) {
throw new InvalidConfigurationException(
"Configuration to be set must not"
+ " be null!");
}
m_configuration = a_configuration;
}
public BaseGPChromosome(GPConfiguration a_configuration, IGPProgram a_ind)
throws InvalidConfigurationException {
this(a_configuration);
m_ind = a_ind;
}
/**
* @return the individual containing this chromosome
*
* @author Klaus Meffert
* @since 3.01 (since 3.0 in ProgramChromosome)
*/
public IGPProgram getIndividual() {
return m_ind;
}
/**
* Sets the individual the chromosome belongs to.
*
* @param a_ind the individual containing this chromosome
*
* @author Klaus Meffert
* @since 3.01 (since 3.0 in ProgramChromosome)
*/
public void setIndividual(IGPProgram a_ind) {
if (a_ind == null) {
throw new IllegalArgumentException("Individual must not be null");
}
m_ind = a_ind;
}
/**
* Gets the i'th terminal in this chromosome. The nodes are counted in a
* depth-first manner, with node zero being the first terminal in this
* chromosome.
*
* @param a_index the i'th terminal to get
* @return the terminal
*
* @author Klaus Meffert
* @since 3.01 (since 3.0 in ProgramChromosome)
*/
public int getTerminal(int a_index) {
CommandGene[] functions = getFunctions();
int len = functions.length;
for (int j = 0; j < len && functions[j] != null; j++) {
if (functions[j].getArity(m_ind) == 0) {
if (--a_index < 0) {
return j;
}
}
}
return -1;
}
/**
* Gets the a_index'th function in this chromosome. The nodes are counted in a
* depth-first manner, with node zero being the first function in this
* chromosome.
*
* @param a_index the a_index'th function to get
* @return the function
*
* @author Klaus Meffert
* @since 3.01 (since 3.0 in ProgramChromosome)
*/
public int getFunction(int a_index) {
CommandGene[] functions = getFunctions();
int len = functions.length;
for (int j = 0; j < len && functions[j] != null; j++) {
if (functions[j].getArity(m_ind) != 0) {
if (--a_index < 0) {
return j;
}
}
}
return -1;
}
/**
* Gets the a_index'th terminal of the given type in this chromosome. The
* nodes are counted in a depth-first manner, with node zero being the first
* terminal of the given type in this chromosome.
*
* @param a_index the a_index'th terminal to get
* @param a_type the type of terminal to get
* @param a_subType the subtype to consider
* @return the index of the terminal found, or -1 if no appropriate terminal
* was found
*
* @author Klaus Meffert
* @since 3.01 (since 3.0 in ProgramChromosome)
*/
public int getTerminal(int a_index, Class a_type, int a_subType) {
CommandGene[] functions = getFunctions();
int len = functions.length;
for (int j = 0; j < len && functions[j] != null; j++) {
if ( (a_subType == 0 || functions[j].getSubReturnType() == a_subType)
&& functions[j].getReturnType() == a_type
&& functions[j].getArity(m_ind) == 0) {
if (--a_index < 0) {
return j;
}
}
}
return -1;
}
/**
* Gets the i'th function of the given return type in this chromosome. The
* nodes are counted in a depth-first manner, with node zero being the first
* function of the given type in this chromosome.
*
* @param a_index the i'th function to get
* @param a_type the type of function to get
* @param a_subType the subtype to consider
* @return the index of the function found, or -1 if no appropriate function
* was found
*
* @author Klaus Meffert
* @since 3.01 (since 3.0 in ProgramChromosome)
*/
public int getFunction(int a_index, Class a_type, int a_subType) {
CommandGene[] functions = getFunctions();
int len = functions.length;
for (int j = 0; j < len && functions[j] != null; j++) {
if (functions[j].getReturnType() == a_type
&& (a_subType == 0 || a_subType == functions[j].getSubReturnType())
&& functions[j].getArity(m_ind) != 0) {
if (--a_index < 0) {
return j;
}
}
}
return -1;
}
/**
* @return the number of terminals in this chromosome
*
* @author Klaus Meffert
* @since 3.0
*/
public int numTerminals() {
int count = 0;
CommandGene[] functions = getFunctions();
int len = functions.length;
for (int i = 0; i < len && functions[i] != null; i++) {
if (functions[i].getArity(m_ind) == 0) {
count++;
}
}
return count;
}
/**
* @return the number of functions in this chromosome
*
* @author Klaus Meffert
* @since 3.0
*/
public int numFunctions() {
int count = 0;
CommandGene[] functions = getFunctions();
int len = functions.length;
for (int i = 0; i < len && functions[i] != null; i++) {
if (functions[i].getArity(m_ind) != 0) {
count++;
}
}
return count;
}
/**
* Counts the number of terminals of the given type in this chromosome.
*
* @param a_type the type of terminal to count
* @param a_subType the subtype to consider
* @return the number of terminals in this chromosome
*
* @author Klaus Meffert
* @since 3.01 (since 3.0 in ProgramChromosome)
*/
public int numTerminals(Class a_type, int a_subType) {
int count = 0;
CommandGene[] functions = getFunctions();
int len = functions.length;
for (int i = 0; i < len && functions[i] != null; i++) {
if (functions[i].getArity(m_ind) == 0
&& functions[i].getReturnType() == a_type
&& (a_subType == 0 || functions[i].getSubReturnType() == a_subType)) {
count++;
}
}
return count;
}
/**
* Counts the number of functions of the given type in this chromosome.
*
* @param a_type the type of function to count
* @param a_subType the subtype to consider
* @return the number of functions in this chromosome.
*
* @author Klaus Meffert
* @since 3.01 (since 3.0 in ProgramChromosome)
*/
public int numFunctions(Class a_type, int a_subType) {
int count = 0;
CommandGene[] functions = getFunctions();
int len = functions.length;
for (int i = 0; i < len && functions[i] != null; i++) {
if (functions[i].getArity(m_ind) != 0
&& functions[i].getReturnType() == a_type
&& (a_subType == 0 || functions[i].getSubReturnType() == a_subType)) {
count++;
}
}
return count;
}
/**
* Gets the a_index'th node in this chromosome. The nodes are counted in a
* depth-first manner, with node zero being the root of this chromosome.
*
* @param a_index the node number to get
* @return the node
*
* @author Klaus Meffert
* @since 3.01
*/
public CommandGene getNode(int a_index) {
if (a_index >= getFunctions().length || getFunctions()[a_index] == null) {
return null;
}
return getFunctions()[a_index];
}
/**
* Helper: Find GP command with given class and return index of it.
*
* @param a_n return the n'th found command (starting at zero)
* @param a_class the class to find a command for
* @return index of first found matching GP command, or -1 if none found
*
* @author Klaus Meffert
* @since 3.01
*/
public int getCommandOfClass(int a_n, Class a_class) {
CommandGene[] functions = getFunctions();
int len = functions.length;
for (int j = 0; j < len && functions[j] != null; j++) {
if (functions[j].getClass() == a_class) {
if (--a_n < 0) {
return j;
}
}
}
return -1;
}
/**
* Helper: Find GP command being assignable from given class.
*
* @param a_n return the n'th found command (starting at zero)
* @param a_class the class to find a command for
* @return index of first found matching GP command, or -1 if none found
*
* @author Klaus Meffert
* @since 3.3
*/
public int getAssignableFromClass(int a_n, Class a_class) {
CommandGene[] functions = getFunctions();
int len = functions.length;
for (int j = 0; j < len && functions[j] != null; j++) {
if (a_class.isAssignableFrom(functions[j].getClass())) {
if (--a_n < 0) {
return j;
}
}
}
return -1;
}
/**
* Helper: Find GP Variable with given return type and return index of it.
*
* @param a_n return the n'th found command (starting at zero)
* @param a_returnType the return type to find a Variable for
* @return index of first found matching GP command, or -1 if none found
*
* @author Klaus Meffert
* @since 3.01 (since 3.0 in ProgramChromosome)
*/
public int getVariableWithReturnType(int a_n, Class a_returnType) {
CommandGene[] functions = getFunctions();
int len = functions.length;
for (int j = 0; j < len && functions[j] != null; j++) {
if (functions[j].getClass() == Variable.class) {
Variable v = (Variable) functions[j];
if (v.getReturnType() == a_returnType) {
if (--a_n < 0) {
return j;
}
}
}
}
return -1;
}
public GPConfiguration getGPConfiguration() {
return m_configuration;
}
}