001: /*
002: * This file is part of JGAP.
003: *
004: * JGAP offers a dual license model containing the LGPL as well as the MPL.
005: *
006: * For licensing information please see the file license.txt included with JGAP
007: * or have a look at the top of class org.jgap.Chromosome which representatively
008: * includes the JGAP license policy applicable for any file delivered with JGAP.
009: */
010: package examples.gp;
011:
012: import org.jgap.gp.impl.*;
013: import org.jgap.gp.*;
014: import org.jgap.gp.function.*;
015: import org.jgap.gp.terminal.*;
016:
017: /**
018: * Validates evolved nodes for the Fibonacci problem. This is mainly to
019: * demonstrate how the node validator works.
020: *
021: * @author Klaus Meffert
022: * @since 3.0
023: */
024: public class FibonacciNodeValidator implements INodeValidator {
025: /**
026: * Validates a_node in the context of a_chrom during evolution. Considers the
027: * recursion level (a_recursLevel), the type needed (a_type) for the node, the
028: * functions available (a_functionSet) and the depth of the whole chromosome
029: * needed (a_depth), and whether grow mode is used (a_grow is true) or not.
030: *
031: * @param a_chrom the chromosome that will contain the node, if valid (ignored
032: * in this implementation)
033: * @param a_node the node selected and to be validated
034: * @param a_rootNode the root node of a_node, may be null for top nodes
035: * @param a_tries number of times the validator has been called, useful for
036: * stopping by returning true if the number exceeds a limit
037: * @param a_num the chromosome's index in the individual of this chromosome
038: * @param a_recurseLevel level of recursion
039: * @param a_type the return type of the node needed
040: * @param a_functionSet the array of available functions (ignored in this
041: * implementation)
042: * @param a_depth the needed depth of the program chromosome
043: * @param a_grow true: use grow mode, false: use full mode (ignored in this
044: * implementation)
045: * @param a_childIndex index of the child in the parent node to which it
046: * belongs (-1 if node is root node)
047: * @param a_fullProgram true: whole program is available in a_chrom
048: * @return true: node is valid; false: node is invalid
049: *
050: * @author Klaus Meffert
051: * @since 3.0
052: */
053: public boolean validate(ProgramChromosome a_chrom,
054: CommandGene a_node, CommandGene a_rootNode, int a_tries,
055: int a_num, int a_recurseLevel, Class a_type,
056: CommandGene[] a_functionSet, int a_depth, boolean a_grow,
057: int a_childIndex, boolean a_fullProgram) {
058: if (a_fullProgram) {
059: return true;
060: }
061: // Guard to avoid endless validation.
062: // ----------------------------------
063: if (a_tries > 10) {
064: return true;
065: }
066: // Chromosome 0.
067: // -------------
068: if (a_num == 0) {
069: // SubProgram forbidden other than as root.
070: // ----------------------------------------
071: if (a_recurseLevel > 0
072: && a_node.getClass() == SubProgram.class) {
073: return false;
074: }
075: // SubProgram wanted as root.
076: // --------------------------
077: if (a_recurseLevel == 0
078: && a_node.getClass() != SubProgram.class) {
079: return false;
080: }
081: if (a_recurseLevel == 1
082: && a_node.getClass() != StoreTerminal.class) {
083: return false;
084: }
085: }
086: // Chromosome 1.
087: // -------------
088: if (a_num == 1) {
089: // ForLoop forbidden under root node
090: if (a_recurseLevel > 0
091: && a_node.getClass() == ForLoop.class) {
092: return false;
093: }
094: // ForLoop needed as root
095: if (a_recurseLevel == 0
096: && a_node.getClass() != ForLoop.class) {
097: return false;
098: }
099: // Variable forbidden other than directly under root
100: if (a_recurseLevel > 1
101: && a_node.getClass() == Variable.class) {
102: return false;
103: }
104: // Variable needed directly under root
105: if (a_recurseLevel == 1 && a_depth == 1
106: && a_node.getClass() != Variable.class) {
107: return false;
108: }
109: // SubProgram forbidden other than directly under root
110: if (a_recurseLevel > 1 && a_depth > 1
111: && a_node.getClass() == SubProgram.class) {
112: return false;
113: }
114: // SubProgram needed directly under root
115: if (a_recurseLevel == 1 && a_depth > 1
116: && a_type == CommandGene.VoidClass
117: && a_node.getClass() != SubProgram.class) {
118: return false;
119: }
120: // AddAndStore or TransferMemory needed 2 under root
121: if (a_recurseLevel == 2 && a_depth > 1
122: && a_type == CommandGene.VoidClass
123: && a_node.getClass() != AddAndStore.class
124: && a_node.getClass() != TransferMemory.class) {
125: return false;
126: }
127: // AddAndStore or TransferMemory forbidden other than 2 under root
128: if (a_recurseLevel != 2
129: && a_depth > 1
130: && a_type == CommandGene.VoidClass
131: && (a_node.getClass() == AddAndStore.class || a_node
132: .getClass() == TransferMemory.class)) {
133: return false;
134: }
135: }
136: return true;
137: }
138: }
|