Skip to content

Level function returns different results depending on whether the iterator is iterating through a ProgramGene or TreeNode #475

Closed
@sachag678

Description

The following code displays my finding:

public class TestingLevel {

public static double fitness(final Genotype<ProgramGene<Double>> gene) {
	return 0.0;
}

public static void main(String [] args) {
	//functions
	final Op<Double> add2 = Op.of("add2",2, v-> v[0]+v[1]);
	final Op<Double> neg = Op.of("neg",1, v-> -v[0]);
	
	//terminals
	final Var<Double> x1 = Var.of("x1", 0);
	final Var<Double> x2 = Var.of("x2", 1);

	final ISeq<Op<Double>> Terminals = ISeq.of(x1, x2);
	final ISeq<Op<Double>> Operations = ISeq.of(add2, neg);
	
	//create tree
	TreeNode<Op<Double>> tree = TreeNode.of(add2)
			.attach(x1)
			.attach(TreeNode.of(neg).attach(x1));
	
	//create phenotype
	ProgramChromosome<Double> chromosome = ProgramChromosome.of(tree, ch->ch.getRoot().size()<=20, Operations, Terminals);
	Genotype<ProgramGene<Double>> mismatchTreeOneGenotype = Genotype.of(chromosome);
	Phenotype<ProgramGene<Double>, Double> p1 = Phenotype.of(mismatchTreeOneGenotype, 0, TestingLevel::fitness).withFitness(0.3);
	
	//convert back to traverse through
	System.out.println("------------------Convert to Program--------------------");
	ProgramGene<Double> program1 = (ProgramGene<Double>) p1.getGenotype().getChromosome().getGene();
	
	Iterator<ProgramGene<Double>> iterator1 = program1.breadthFirstIterator();
	
	while(iterator1.hasNext()) {
		ProgramGene<Double> node = iterator1.next();
		System.out.println(node.toParenthesesString().split("\\(")[0] + " | level: " + node.level());
	}
	
	System.out.println("------------------Convert to Tree--------------------");
	
	TreeNode<Op<Double>> convertedTree = TreeNode.ofTree(program1);
	
	Iterator<TreeNode<Op<Double>>> iterator = convertedTree.breadthFirstIterator();
	
	while(iterator.hasNext()) {
		TreeNode<Op<Double>> node = iterator.next();
		System.out.println(node.toParenthesesString().split("\\(")[0] + " | level: " + node.level());
	}
	
	
	
    }


}

The output is:

------------------Convert to Program--------------------
add2 | level: 0
x1 | level: 1
neg | level: 1
x1 | level: 1
------------------Convert to Tree--------------------
add2 | level: 0
x1 | level: 1
neg | level: 1
x1 | level: 2

As can be seen x1 in the ProgramGene structure is at level 1, whereas in TreeNode it is at level 2.

I'm wondering if this is expected behavior? It was causing some of my code to fail, until I looked into it to find this difference.

If I replace the Var in neg to x2, then the output is as follows:

------------------Convert to Program--------------------
add2 | level: 0
x1 | level: 1
neg | level: 1
x2 | level: 2
------------------Convert to Tree--------------------
add2 | level: 0
x1 | level: 1
neg | level: 1
x2 | level: 2

In this case because the x2 isn't used further up in the programGene, it's level is outputting correctly.

Metadata

Assignees

Labels

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions