/* Copyright 2009-2016 David Hadka * * This file is part of the MOEA Framework. * * The MOEA Framework is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * The MOEA Framework is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the MOEA Framework. If not, see <http://www.gnu.org/licenses/>. */ package org.moeaframework.core.variable; import org.moeaframework.core.PRNG; import org.moeaframework.core.Variable; import org.moeaframework.util.tree.Environment; import org.moeaframework.util.tree.Node; import org.moeaframework.util.tree.Rules; /** * A decision variable for programs. The program is represented as a * strongly-typed expression tree. * <p> * <b>Note: Although {@code Program} extends {@link Node}, the {@code Program} * object must never be altered by the optimization algorithm.</b> Only * its arguments can undergo variation. */ public class Program extends Node implements Variable { private static final long serialVersionUID = -2621361322042428290L; /** * The rules defining the program syntax. */ private final Rules rules; /** * Constructs a new program variable with the specified syntax rules. * * @param rules the rules defining the program syntax */ public Program(Rules rules) { super(rules.getReturnType(), rules.getReturnType()); this.rules = rules; } /** * Returns the rules defining the program syntax. * * @return the rules defining the program syntax */ public Rules getRules() { return rules; } @Override public Program copy() { return (Program)copyTree(); } @Override public Program copyNode() { return new Program(rules); } @Override public Object evaluate(Environment environment) { return getArgument(0).evaluate(environment); } /** * Initializes the program tree using ramped half-and-half initialization. */ @Override public void randomize() { Rules rules = getRules(); int depth = PRNG.nextInt(2, rules.getMaxInitializationDepth()); boolean isFull = PRNG.nextBoolean(); Node root = null; if (isFull) { if (rules.getScaffolding() == null) { root = rules.buildTreeFull(rules.getReturnType(), depth); } else { root = rules.buildTreeFull(rules.getScaffolding(), depth); } } else { if (rules.getScaffolding() == null) { root = rules.buildTreeGrow(rules.getReturnType(), depth); } else { root = rules.buildTreeGrow(rules.getScaffolding(), depth); } } setArgument(0, root); } }