com.github.chen0040.gp.treegp.program.Program Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of java-genetic-programming Show documentation
Show all versions of java-genetic-programming Show documentation
Genetic Programming in Java, including packages on Linear Genetic Programming
package com.github.chen0040.gp.treegp.program;
import com.github.chen0040.data.utils.TupleTwo;
import com.github.chen0040.gp.commons.Observation;
import com.github.chen0040.gp.services.RandEngine;
import com.github.chen0040.gp.treegp.TreeGP;
import com.github.chen0040.gp.treegp.enums.TGPInitializationStrategy;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* Created by xschen on 14/5/2017.
*/
public class Program implements Serializable, Comparable {
///
/// Function Set contains the operators which are the internal nodes of the GP tree, as specified in the Section 3.2 of "A Field Guide to Genetic Programming"
///
private final OperatorSet operatorSet = new OperatorSet();
///
/// Variable Set contains program's external inputs, which typically takes the form of named variables, as specified in Section 3.1 of "A Field Guide to Genetic Programming"
///
private final VariableSet variableSet = new VariableSet();
///
/// Constant Set contains two type of terminals: constant value and function with no arguments, as specified in Section 3.1 of "A Field Guide to Genetic Programming"
///
private final ConstantSet constantSet = new ConstantSet();
private TreeNode root;
private int depth;
private int length;
public OperatorSet getOperatorSet(){
return operatorSet;
}
public VariableSet getVariableSet(){
return variableSet;
}
public ConstantSet getConstantSet(){
return constantSet;
}
public String mathExpression(){
if(root == null) return "";
return root.mathExpression();
}
public TreeNode getRoot(){
return root;
}
public void setRoot(TreeNode node){
root = node;
}
///
/// Method that performs deep copy of another GP
///
/// The GP to copy
public void copy(Program that) {
operatorSet.copy(that.operatorSet);
variableSet.copy(that.variableSet);
constantSet.copy(that.constantSet);
depth = that.depth;
length = that.length;
if(that.root != null) {
root = that.root.makeCopy(operatorSet, variableSet, constantSet);
} else {
root = null;
}
}
public Program makeCopy(){
Program clone = new Program();
clone.copy(this);
return clone;
}
public double execute(Object... tags){
return root.execute(tags);
}
public void read(Observation observation){
int inputCount = observation.inputCount();
for(int i=0; i < variableSet.size(); ++i){
int j = i % inputCount;
variableSet.set(j, observation.getInput(j));
}
}
///
/// Method that randomly select and returns a terminal primitive
///
/// The randomly selected terminal primitive
public Terminal anyTerminal(RandEngine randEngine)
{
int variable_count = variableSet.size();
int constant_count = constantSet.size();
int r = randEngine.nextInt(variable_count + constant_count);
if (r < variable_count)
{
return (Terminal)variableSet.get(r);
}
else
{
return (Terminal)constantSet.get(r - variable_count);
}
}
public boolean isBetterThan(Program rhs)
{
return compareTo(rhs) < 0;
}
/**
* The method return -1 if this program is better than that program
* @param that
* @return
*/
@Override public int compareTo(Program that) {
int cmp = Integer.compare(depth, that.depth);
if (cmp == 0)
{
return Integer.compare(length, that.length);
} else {
return cmp;
}
}
///
/// Method that creates a GP tree with a maximum tree depth
///
/// TreeGP config
/// Method that calculates the size of the tree
///
/// The tree size
public int calcLength()
{
return length = root.length();
}
///
/// Method that calculates the tree depth
///
/// The tree depth
public int calcDepth()
{
return depth = root.depth();
}
public Primitive anyOperatorWithArityLessThan(int s, RandEngine randEngine) {
return operatorSet.anyWithArityLessThan(s, randEngine);
}
public Primitive anyOperator(RandEngine randEngine) {
return operatorSet.any(randEngine);
}
///
/// Method that returns a random primitive based on the weight associated with each primitive
/// The method is similar to roulette wheel
///
/// The randomly selected primitive
public Primitive anyPrimitive(RandEngine randEngine)
{
double r = randEngine.uniform();
if(r < 0.3333) {
return constantSet.any(randEngine);
} else if(r < 0.6666) {
return variableSet.any(randEngine);
} else {
return anyOperator(randEngine);
}
}
public TupleTwo anyNode(RandEngine randEngine){ return anyNode(false, randEngine); }
///
/// Method that returns a randomly selected node from the current tree
/// The tree is first flatten into a list from which a node is randomly selected
///
///
public TupleTwo anyNode(boolean bias, RandEngine randEngine)
{
List> nodes = flattenNodes();
if (bias)
{
if (randEngine.uniform() <= 0.1) // As specified by Koza, 90% select function node, 10% select terminal node
{
List> terminal_nodes = new ArrayList<>();
for (TupleTwo tuple : nodes)
{
TreeNode node = tuple._1();
if (node.isTerminal())
{
terminal_nodes.add(tuple);
}
}
if (terminal_nodes.size() > 0)
{
return terminal_nodes.get(randEngine.nextInt(terminal_nodes.size()));
}
else
{
return nodes.get(randEngine.nextInt(nodes.size()));
}
}
else
{
List> function_nodes = new ArrayList<>();
for (TupleTwo tuple : nodes)
{
TreeNode node = tuple._1();
if (!node.isTerminal())
{
function_nodes.add(tuple);
}
}
if (function_nodes.size() > 0)
{
return function_nodes.get(randEngine.nextInt(function_nodes.size()));
}
else
{
return nodes.get(randEngine.nextInt(nodes.size()));
}
}
}
else
{
return nodes.get(randEngine.nextInt(nodes.size()));
}
}
///
/// Method that flattens the tree and then stores all the nodes of the tree in a list
///
/// The list of nodes in the tree
public List> flattenNodes()
{
List> list = new ArrayList<>();
collectNodes(root, null, list);
return list;
}
private void collectNodes(TreeNode node, TreeNode parent_node, List> list) {
if(node == null) return;
if(parent_node != null){
assert parent_node.getChildren().contains(node);
}
list.add(new TupleTwo<>(node, parent_node));
for(TreeNode child : node.getChildren()){
collectNodes(child, node, list);
}
}
public Primitive matchPrimitive(Primitive that) {
int index = that.getIndex();
if(that.isTerminal()){
if(that.isReadOnly()){
return constantSet.get(index);
} else {
return variableSet.get(index);
}
} else {
return operatorSet.get(index);
}
}
public int getDepth() {
return depth;
}
public int getLength() {
return length;
}
@Override
public String toString(){
return root.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy