Possible Bug in org.epochx.gr.op.init.RampedHalfAndHalfInitialiser?

28 views
Skip to first unread message

Grant Dick

unread,
Feb 4, 2011, 6:44:39 AM2/4/11
to EpochX
I am currently working with the XGR component of EpochX 1.3.2. Every
time that I try to run examples based upon GRModel, I have to
explicitly set the maximum start depth for the initialiser. Failing
to do so leads to a IllegalStateException being raised with the reason
"No possible programs within given max depth parameter for this
grammar."

The following class will produce the unexpected behaviour:
public class GEMUX6 {
public static void main(String[] args) {
final int noInputBits = 6;
//org.epochx.core.Model model = new
org.epochx.ge.model.epox.Multiplexer(noInputBits);
org.epochx.core.Model model = new
org.epochx.gr.model.epox.Multiplexer(noInputBits);
model.run();
}
}



I have looked into the source code for the ramped half-and-half
initialiser for this model, and I think that I have uncovered a bug;
line 211 of org.epochx.gr.op.init.RampedHalfAndHalfInitialiser (method
getInitialPopulation()) appears to override the starting depth for the
process when the current starting depth is less than the smallest
possible depth specified by the grammar. However, the variable
startDepth is not subsequently used in the rest of the method. I
suspect that it should be used at lines 222 and 227 (in place of
startMaxDepth). Changing these lines produces the behaviour that I
expected.

A "corrected" version of the method appears below.

/**
* Generates a population of new <code>GRCandidatePrograms</code>
* constructed
* from the <code>Grammar</code> attribute. The size of the
population will
* be equal to the population size attribute. All programs in the
population
* are only guarenteed to be unique (as defined by the <code>equals</
code>
* method on <code>GRCandidateProgram</code>) if the
* <code>isDuplicatesEnabled</code> method returns <code>true</code>.
* Each program will alternately be generated with the
* {@link FullInitialiser} and {@link GrowInitialiser}. If the
population
* size is odd then the extra individual will be initialised using
grow.
*
* @return A <code>List</code> of newly generated
* <code>GRCandidatePrograms</code>.
*/
@Override
public List<CandidateProgram> getInitialPopulation() {
if (popSize < 1) {
throw new IllegalStateException(
"Population size must be 1 or greater");
} else if (grammar == null) {
throw new IllegalStateException("No grammar has been set");
}

// Create population list to populate.
final List<CandidateProgram> firstGen = new
ArrayList<CandidateProgram>(
popSize);

int startDepth = startMaxDepth;
final int minDepthPossible = grammar.getMinimumDepth();
if (startMaxDepth < minDepthPossible) {
// Our start depth can only be as small as the grammars minimum
// depth.
startDepth = minDepthPossible;
}

if (endMaxDepth < startDepth) {
throw new IllegalStateException(
"End maximum depth must be greater than the minimum possible
depth.");
}

// Number of programs each depth SHOULD have. But won't unless
remainder
// is 0.
final double programsPerDepth = (double) popSize
/ (endMaxDepth - startDepth + 1);

for (int i = 0; i < popSize; i++) {
// Calculate depth
final int depth = (int) Math.floor((i / programsPerDepth)
+ startDepth);

// Grow on even numbers, full on odd.
GRCandidateProgram program;

do {
if ((i % 2) == 0) {
grow.setMaxDepth(depth);
program = grow.getInitialProgram();
} else {
full.setDepth(depth);
program = full.getInitialProgram();
}
} while (!acceptDuplicates && firstGen.contains(program));

firstGen.add(program);
}

return firstGen;
}

Tom Castle

unread,
Feb 4, 2011, 8:18:15 AM2/4/11
to EpochX
You are quite right, this is a bug. Thanks for the find (and fix)! The
fix you suggested is correct, so I've rolled a release (1.3.3) with
this update. This is the only change in the release, so there's no
need to update if you have compiled your own version already.
Reply all
Reply to author
Forward
0 new messages