基因表达编程[Java]:如何查看种群成员
Gene expression programming [Java]: How to view the members of the population
我正在使用基因表达编程library demo to obtain alternative mathematical expressions. I downloaded all the class files for uncommons.watchmaker framework and created a new project that runs without jar files. Java Project (full source code) is attached here。
我稍微修改了 demo 以生成给定数字的替代数学表达式。例如,假设我想得到 2 - 11 之间的所有数字组合,它们相乘得到 12。我会得到 6 * 2、3 * 4、3 * 2 * 2、2 * 6、4 * 3、2 * 2 * 3.主程序是TestMainProg.java
我很想知道如何打印最后一代的人口。
调查结果:
在制表师API中它说evolvePopulation() in EvolutionEngine interface可以用来获取最终的人口数据。但是我不确定如何调用该方法并打印数据。查看 EvolutionEngine.java、EvaluatedCandidate.java 和摘要EvolutionEngine.java 将很有用。
下面是我使用的代码:
import java.util.ArrayList;
import java.util.List;
import org.gep4j.GeneFactory;
import org.gep4j.INode;
import org.gep4j.INodeFactory;
import org.gep4j.IntegerConstantFactory;
import org.gep4j.KarvaEvaluator;
import org.gep4j.MutationOperator;
import org.gep4j.RecombinationOperator;
import org.gep4j.SimpleNodeFactory;
import org.gep4j.math.Multiply;
import org.uncommons.maths.random.MersenneTwisterRNG;
import org.uncommons.maths.random.Probability;
import org.uncommons.watchmaker.framework.EvolutionEngine;
import org.uncommons.watchmaker.framework.EvolutionObserver;
import org.uncommons.watchmaker.framework.EvolutionaryOperator;
import org.uncommons.watchmaker.framework.FitnessEvaluator;
import org.uncommons.watchmaker.framework.GenerationalEvolutionEngine;
import org.uncommons.watchmaker.framework.PopulationData;
import org.uncommons.watchmaker.framework.operators.EvolutionPipeline;
import org.uncommons.watchmaker.framework.selection.RouletteWheelSelection;
import org.uncommons.watchmaker.framework.termination.TargetFitness;
public class TestMainProg {
final KarvaEvaluator karvaEvaluator = new KarvaEvaluator();
public INode[] bestIndividual=null;
public void go() {
List<INodeFactory> factories = new ArrayList<INodeFactory>();
// init the GeneFactory that will create the individuals
//factories.add(new SimpleNodeFactory(new Add()));
factories.add(new SimpleNodeFactory(new Multiply()));
factories.add(new IntegerConstantFactory(2, 35)); //12,60,1 and the target number
double num = 36.0;
GeneFactory factory = new GeneFactory(factories, 20); //20 is the gene size
List<EvolutionaryOperator<INode[]>> operators = new ArrayList<EvolutionaryOperator<INode[]>>();
operators.add(new MutationOperator<INode[]>(factory, new Probability(0.01d)));
operators.add(new RecombinationOperator<INode[]>(factory, new Probability(0.5d)));
EvolutionaryOperator<INode[]> pipeline = new EvolutionPipeline<INode[]>(operators);
FitnessEvaluator<INode[]> evaluator = new FitnessEvaluator<INode[]>() {
@Override
public double getFitness(INode[] candidate, List<? extends INode[]> population) {
double result = (Double) karvaEvaluator.evaluate(candidate);
double error = Math.abs(num - result);
return error;
}
@Override
public boolean isNatural() {
return false;
}
};
EvolutionEngine<INode[]> engine = new GenerationalEvolutionEngine<INode[]>(factory, pipeline, evaluator,
new RouletteWheelSelection(), new MersenneTwisterRNG());
// add an EvolutionObserver so we can print out the status.
EvolutionObserver<INode[]> observer = new EvolutionObserver<INode[]>() {
@Override
public void populationUpdate(PopulationData<? extends INode[]> data) {
bestIndividual = data.getBestCandidate();
System.out.printf("Generation %d, PopulationSize = %d, error = %.1f, value = %.1f, %s\n",
data.getGenerationNumber(), data.getPopulationSize(),
Math.abs(/*Math.PI*/ num - (Double)karvaEvaluator.evaluate(bestIndividual)),
(Double)karvaEvaluator.evaluate(bestIndividual),
karvaEvaluator.print(bestIndividual));
}
};
engine.addEvolutionObserver(observer);
//to get the total population
engine.evolvePopulation(100,10,new TargetFitness(0.0001, false));
}
public static final void main(String args[]) {
new TestMainProg().go();
}
}
打印最终总体中所有正确的候选人很简单:
engine.evolvePopulation(100,10,new TargetFitness(0, false)).stream()
.filter( e -> e.getFitness() == 0 ) // Find all survivors
.map( e -> karvaEvaluator.print( e.getCandidate() ) ) // Convert to String
.forEach( System.out::println ); // Print
然而,获得多个两个数字组合更加棘手:
GeneFactory
基因长度为 5 或以上 可能 产生 A x B x C
,例如2 x 2 x 9 = 36
- 每次进化只保证一个正确的结果
第一点应该很容易解决。
第二,我们可以运行演化几次,巩固成果。
无法保证您会获得所有组合,但您 运行 获得的次数越多,获得该组合的机会就越高。
Optimisation tips:
1. Number range should be as small as possible, i.e. 2 to (target/2).
2. Recombination is unnecessary since there is only multiplication.
3. That leaves only (numeric) mutation, which can have a higher chance to occur.
我的解决方案:
import java.util.*;
import java.util.stream.Collectors;
import org.gep4j.*;
import org.gep4j.math.Multiply;
import org.uncommons.maths.random.MersenneTwisterRNG;
import org.uncommons.maths.random.Probability;
import org.uncommons.watchmaker.framework.*;
import org.uncommons.watchmaker.framework.operators.EvolutionPipeline;
import org.uncommons.watchmaker.framework.selection.RouletteWheelSelection;
import org.uncommons.watchmaker.framework.termination.TargetFitness;
public class TestMainProg {
private static final double NUM = 36.0;
private static final int RUN = 50;
public void go() {
KarvaEvaluator karvaEvaluator = new KarvaEvaluator();
GeneFactory factory = new GeneFactory( Arrays.asList(
new SimpleNodeFactory(new Multiply()),
new IntegerConstantFactory( 2, (int)(NUM/2) )
), 3 );
EvolutionaryOperator<INode[]> pipeline = new EvolutionPipeline<>( Arrays.asList(
new MutationOperator<>(factory, new Probability(0.5d))
) );
FitnessEvaluator<INode[]> evaluator = new FitnessEvaluator<INode[]>() {
@Override public double getFitness(INode[] candidate, List<? extends INode[]> population) {
return Math.abs( NUM - (Double) karvaEvaluator.evaluate(candidate) );
}
@Override public boolean isNatural() {
return false;
}
};
EvolutionEngine<INode[]> engine = new GenerationalEvolutionEngine<>(factory, pipeline, evaluator,
new RouletteWheelSelection(), new MersenneTwisterRNG());
Set<String> results = new HashSet<>();
for ( int i = 0 ; i < RUN ; i ++ ) {
List<EvaluatedCandidate<INode[]>> finalPopulation =
engine.evolvePopulation(100,10, new TargetFitness(0, false));
// Add all survivors to result
finalPopulation.stream().filter( e -> e.getFitness() == 0 )
.map( e -> karvaEvaluator.print( e.getCandidate() ) )
.forEach( results::add );
}
new TreeSet( results ).stream().forEach( System.out::println );
}
public static final void main(String args[]) {
new TestMainProg().go();
}
}
我正在使用基因表达编程library demo to obtain alternative mathematical expressions. I downloaded all the class files for uncommons.watchmaker framework and created a new project that runs without jar files. Java Project (full source code) is attached here。
我稍微修改了 demo 以生成给定数字的替代数学表达式。例如,假设我想得到 2 - 11 之间的所有数字组合,它们相乘得到 12。我会得到 6 * 2、3 * 4、3 * 2 * 2、2 * 6、4 * 3、2 * 2 * 3.主程序是TestMainProg.java
我很想知道如何打印最后一代的人口。
调查结果:
在制表师API中它说evolvePopulation() in EvolutionEngine interface可以用来获取最终的人口数据。但是我不确定如何调用该方法并打印数据。查看 EvolutionEngine.java、EvaluatedCandidate.java 和摘要EvolutionEngine.java 将很有用。
下面是我使用的代码:
import java.util.ArrayList;
import java.util.List;
import org.gep4j.GeneFactory;
import org.gep4j.INode;
import org.gep4j.INodeFactory;
import org.gep4j.IntegerConstantFactory;
import org.gep4j.KarvaEvaluator;
import org.gep4j.MutationOperator;
import org.gep4j.RecombinationOperator;
import org.gep4j.SimpleNodeFactory;
import org.gep4j.math.Multiply;
import org.uncommons.maths.random.MersenneTwisterRNG;
import org.uncommons.maths.random.Probability;
import org.uncommons.watchmaker.framework.EvolutionEngine;
import org.uncommons.watchmaker.framework.EvolutionObserver;
import org.uncommons.watchmaker.framework.EvolutionaryOperator;
import org.uncommons.watchmaker.framework.FitnessEvaluator;
import org.uncommons.watchmaker.framework.GenerationalEvolutionEngine;
import org.uncommons.watchmaker.framework.PopulationData;
import org.uncommons.watchmaker.framework.operators.EvolutionPipeline;
import org.uncommons.watchmaker.framework.selection.RouletteWheelSelection;
import org.uncommons.watchmaker.framework.termination.TargetFitness;
public class TestMainProg {
final KarvaEvaluator karvaEvaluator = new KarvaEvaluator();
public INode[] bestIndividual=null;
public void go() {
List<INodeFactory> factories = new ArrayList<INodeFactory>();
// init the GeneFactory that will create the individuals
//factories.add(new SimpleNodeFactory(new Add()));
factories.add(new SimpleNodeFactory(new Multiply()));
factories.add(new IntegerConstantFactory(2, 35)); //12,60,1 and the target number
double num = 36.0;
GeneFactory factory = new GeneFactory(factories, 20); //20 is the gene size
List<EvolutionaryOperator<INode[]>> operators = new ArrayList<EvolutionaryOperator<INode[]>>();
operators.add(new MutationOperator<INode[]>(factory, new Probability(0.01d)));
operators.add(new RecombinationOperator<INode[]>(factory, new Probability(0.5d)));
EvolutionaryOperator<INode[]> pipeline = new EvolutionPipeline<INode[]>(operators);
FitnessEvaluator<INode[]> evaluator = new FitnessEvaluator<INode[]>() {
@Override
public double getFitness(INode[] candidate, List<? extends INode[]> population) {
double result = (Double) karvaEvaluator.evaluate(candidate);
double error = Math.abs(num - result);
return error;
}
@Override
public boolean isNatural() {
return false;
}
};
EvolutionEngine<INode[]> engine = new GenerationalEvolutionEngine<INode[]>(factory, pipeline, evaluator,
new RouletteWheelSelection(), new MersenneTwisterRNG());
// add an EvolutionObserver so we can print out the status.
EvolutionObserver<INode[]> observer = new EvolutionObserver<INode[]>() {
@Override
public void populationUpdate(PopulationData<? extends INode[]> data) {
bestIndividual = data.getBestCandidate();
System.out.printf("Generation %d, PopulationSize = %d, error = %.1f, value = %.1f, %s\n",
data.getGenerationNumber(), data.getPopulationSize(),
Math.abs(/*Math.PI*/ num - (Double)karvaEvaluator.evaluate(bestIndividual)),
(Double)karvaEvaluator.evaluate(bestIndividual),
karvaEvaluator.print(bestIndividual));
}
};
engine.addEvolutionObserver(observer);
//to get the total population
engine.evolvePopulation(100,10,new TargetFitness(0.0001, false));
}
public static final void main(String args[]) {
new TestMainProg().go();
}
}
打印最终总体中所有正确的候选人很简单:
engine.evolvePopulation(100,10,new TargetFitness(0, false)).stream()
.filter( e -> e.getFitness() == 0 ) // Find all survivors
.map( e -> karvaEvaluator.print( e.getCandidate() ) ) // Convert to String
.forEach( System.out::println ); // Print
然而,获得多个两个数字组合更加棘手:
GeneFactory
基因长度为 5 或以上 可能 产生A x B x C
,例如2 x 2 x 9 = 36- 每次进化只保证一个正确的结果
第一点应该很容易解决。 第二,我们可以运行演化几次,巩固成果。 无法保证您会获得所有组合,但您 运行 获得的次数越多,获得该组合的机会就越高。
Optimisation tips:
1. Number range should be as small as possible, i.e. 2 to (target/2).
2. Recombination is unnecessary since there is only multiplication.
3. That leaves only (numeric) mutation, which can have a higher chance to occur.
我的解决方案:
import java.util.*;
import java.util.stream.Collectors;
import org.gep4j.*;
import org.gep4j.math.Multiply;
import org.uncommons.maths.random.MersenneTwisterRNG;
import org.uncommons.maths.random.Probability;
import org.uncommons.watchmaker.framework.*;
import org.uncommons.watchmaker.framework.operators.EvolutionPipeline;
import org.uncommons.watchmaker.framework.selection.RouletteWheelSelection;
import org.uncommons.watchmaker.framework.termination.TargetFitness;
public class TestMainProg {
private static final double NUM = 36.0;
private static final int RUN = 50;
public void go() {
KarvaEvaluator karvaEvaluator = new KarvaEvaluator();
GeneFactory factory = new GeneFactory( Arrays.asList(
new SimpleNodeFactory(new Multiply()),
new IntegerConstantFactory( 2, (int)(NUM/2) )
), 3 );
EvolutionaryOperator<INode[]> pipeline = new EvolutionPipeline<>( Arrays.asList(
new MutationOperator<>(factory, new Probability(0.5d))
) );
FitnessEvaluator<INode[]> evaluator = new FitnessEvaluator<INode[]>() {
@Override public double getFitness(INode[] candidate, List<? extends INode[]> population) {
return Math.abs( NUM - (Double) karvaEvaluator.evaluate(candidate) );
}
@Override public boolean isNatural() {
return false;
}
};
EvolutionEngine<INode[]> engine = new GenerationalEvolutionEngine<>(factory, pipeline, evaluator,
new RouletteWheelSelection(), new MersenneTwisterRNG());
Set<String> results = new HashSet<>();
for ( int i = 0 ; i < RUN ; i ++ ) {
List<EvaluatedCandidate<INode[]>> finalPopulation =
engine.evolvePopulation(100,10, new TargetFitness(0, false));
// Add all survivors to result
finalPopulation.stream().filter( e -> e.getFitness() == 0 )
.map( e -> karvaEvaluator.print( e.getCandidate() ) )
.forEach( results::add );
}
new TreeSet( results ).stream().forEach( System.out::println );
}
public static final void main(String args[]) {
new TestMainProg().go();
}
}