GEP(基因表达式程序算法)是遗传算法的一个分支。由于该算法尚处于研究阶段。所以除了发明者本人,没有其他作者写过相关的书籍。
本人用c#语言。改写了四川大学唐教授的GEP程序(java语言描述)。希望有相同爱好的朋友指点。
GEP程序的流程:
由流程我们知道:我们首先要做的事情是
1、给出函数集合和终止符号集合。
2、给出基因结构和种群结构。
3、适应性函数。
我们先做这三件事情。
在此我们使用工厂模式写这个程序。首先定义几个通用接口。
public interface Expression
{
/**
* 返回代码
* @return
*/
char getCode();
/**
* 返回表达式的目数(即有几个操作数)
*/
int getArity();
/**
* 添加子表达式(操作数)。按从左到右的顺序
*/
void addChild(Expression child);
/**
* 返回该节点的所有子节点
* @return
*/
ArrayList getChildren();
}
/**
* 表达式工厂
*/
public interface ExpressionFactory
{
/**
* 返回表达式
* @return
*/
Expression get(char code);
}
/**
/**
* 绝对值函数表达式
*/
/**
* 表达式
*/
public interface NExpression : Expression
{
/**
* 计算表达式的值
*/
double evaluate();
}
/**
* 表达式工厂(工厂方法模式)
*/
public interface FunctionFactory : ExpressionFactory
{
/**
* 返回表达式的代码
*/
char getCode();
/**
* 返回表达式的目数(即有几个操作数)
*/
int getArity();
}
在这些接口中,给出了一些基本的方法。这些方法方便我们以后把函数代码与表达式类或者表达式对应起来。
以下是具体的一个函数和函数工厂类:
public class Abs : NExpression
{
public static char code = 'A';//代码
public static int arity = 1;//操作数
private NExpression left; //左操作项
public char getCode()
{
return code;
}
public int getArity()
{
return arity;
}
public void addChild(Expression child)
{
if (left == null)
{
left = (NExpression)child;
return;
}
// throw new IllegalStateException("ADD_CHILD_ERROR");
}
public double evaluate()
{
return System.Math.Abs(left.evaluate());
}
public String toString()
{
return "Abs[" + left + "]";
}
public ArrayList getChildren()
{
ArrayList children = new ArrayList();
children.Add(left);
return children;
}
}
/**
* 绝对值函数表达式工厂
*/
public class AbsFactory : FunctionFactory
{
public char getCode()
{
return Abs.code;
}
public int getArity()
{
return Abs.arity;
}
public Expression get(char code)
{
return new Abs();
}
}
这两个类给出了绝对值函数,和绝对值函数工厂,并在类中对一些接口的方法做了实现。其他函数与函数工厂的定义方式类同。这里不再赘述。以下是常量表达式及常量表达式工厂的定义:
/**
* 数值常量表达式
*/
public class NConstant : NExpression
{
private char code;
private double value;
public NConstant(char code, double value)
{
this.code = code;
this.value = value;
}
public char getCode()
{
return code;
}
public int getArity()
{
return 0;
}
public void addChild(Expression child)
{
// throw new IllegalStateException("ADD_CHILD_ERROR");
}
public double evaluate()
{
return value;
}
public String toString()
{
return "" + value;
}
public ArrayList getChildren()
{
ArrayList children = new ArrayList();
return children;
}
}
/**
* 数值变量表达式工厂
*/
public class NConstantFactory : ExpressionFactory
{
private double[] constantValues; // 常数的值
private NConstant[] constants; // 常数
public Expression get(char code)
{
int index = code - '0';
if (constants[index] == null)
{
constants[index] = new NConstant(code, constantValues[index]);
}
return constants[index];
}
}
以下是数值变量的定义方式:
/**
* 变量
*/
public class NVariable : NExpression
{
public static int arity = 0;
private char code;
private double value;
public NVariable(char code)
{
this.code = code;
}
public char getCode()
{
return code;
}
public int getArity()
{
return arity;
}
public void addChild(Expression child)
{
MessageBox.Show("ADD_CHILD_ERROR");//报错
}
public void setValue(double value)
{
this.value = value;
}
public double evaluate()
{
return value;
}
public String toString()
{
return "" + code;
}
public ArrayList getChildren()
{
ArrayList children = new ArrayList();
return children;
}
}
/**
* 数值变量工厂
*/
public class NVariableFactory : ExpressionFactory
{
private NVariable[] variables; // 变量列表
public Expression get(char code)
{
int index = code - '0';
if (variables[index] == null)
{
variables[index] = new NVariable(code);
}
return variables[index];
}
}
这样我们完成了第一步。