Commit b770baff authored by sbalev's avatar sbalev

Changed Node and Breaker to implement crossover.

Added crossover test sketch
parent 275eaf00
......@@ -7,20 +7,30 @@ class Breaker {
Breaker(CodeToolkit tk) {
this.tk = tk;
root = new Node(tk);
train();
train(null, null);
root.shrink();
root.triangleOpt();
computeFitness();
}
Breaker(CodeToolkit tk, Breaker parent1, Breaker parent2) {
this.tk = tk;
root = new Node(tk);
root.guess = (random(1) < 0.5 ? parent1 : parent2).root.guess;
train(parent1.root, parent2.root);
root.shrink();
root.triangleOpt();
computeFitness();
}
void train() {
void train(Node p1, Node p2) {
boolean[] used = new boolean[tk.M];
int[] unused = new int[tk.M];
for (int code = 0; code < tk.M; code++) {
for (int k = 0; k < tk.M; k++) {
used[k] = false;
}
root.followPath(code, used, unused);
root.followPath(code, p1, p2, used, unused);
}
}
......
......@@ -4,21 +4,30 @@ class Node {
int guess;
boolean good;
Node[] children;
// used for visualisation of crossover
// 0 = new, 1 = parent 1, 2 = parent2
int comesFrom;
Node(CodeToolkit tk) {
this.tk = tk;
guess = int(random(tk.M));
good = false;
children = new Node[tk.F];
comesFrom = 0;
}
void followPath(int code, boolean[] used, int[] unused) {
void followPath(int code, Node p1, Node p2, boolean[] used, int[] unused) {
used[guess] = true;
int f = tk.feedback(code, guess);
if (f == 0) {
good = true;
} else if (children[f] != null) {
children[f].followPath(code, used, unused);
return;
}
Node p1Child = p1 == null ? null : p1.children[f];
Node p2Child = p2 == null ? null : p2.children[f];
children[f] = chooseChild(children[f], p1Child, p2Child, used);
if (children[f] != null) {
children[f].followPath(code, p1Child, p2Child, used, unused);
} else {
int count = 0;
for (int k = 0; k < tk.M; k++) {
......@@ -31,6 +40,27 @@ class Node {
}
}
Node chooseChild(Node myChild, Node p1Child, Node p2Child, boolean[] used) {
if (myChild != null) return myChild;
boolean can1 = p1Child != null && !used[p1Child.guess];
boolean can2 = p2Child != null && !used[p2Child.guess];
if (can1 && can2) {
if (random(1) < 0.5) {
can1 = false;
} else {
can2 = false;
}
}
Node choice = null;
if (can1 || can2) {
choice = new Node(tk);
choice.guess = (can1 ? p1Child : p2Child).guess; // No way! ;)
choice.comesFrom = can1 ? 1 : 2;
return choice;
}
return choice;
}
void buildPath(int code, int[] unused, int count) {
int k = int(random(count));
guess = unused[k];
......@@ -43,7 +73,7 @@ class Node {
children[f].buildPath(code, unused, count - 1);
}
}
Node shrink() {
int childCount = 0;
Node lastChild = null;
......@@ -56,7 +86,7 @@ class Node {
}
return !good && childCount == 1 ? lastChild : this;
}
int triangleOpt() {
int count = 0;
int f1 = 0;
......@@ -90,7 +120,7 @@ class Node {
}
return count;
}
int height() {
int h = 0;
for (Node child : children) {
......@@ -98,7 +128,7 @@ class Node {
}
return 1 + h;
}
void histogram(int level, int[] histo) {
if (good) histo[level]++;
for (Node child : children) {
......@@ -134,6 +164,11 @@ class Node {
while (children[f] == null) f++;
int x1 = (xc.get(i - 1) + xc.get(i)) / 2;
stroke(0);
if (children[f].comesFrom == 1) {
stroke(255, 64, 0);
} else if (children[f].comesFrom == 2) {
stroke(0, 64, 255);
}
line(x0, y + pegSize, x1, y + BRANCH_HEIGHT * pegSize);
displayLabel(f, (x0 + x1) / 2.0, y + (BRANCH_HEIGHT + 1) / 2.0 * pegSize, pegSize);
f++;
......
../../lib/Breaker.pde
\ No newline at end of file
../../lib/CodeToolkit.pde
\ No newline at end of file
../../lib/Node.pde
\ No newline at end of file
CodeToolkit tk = new CodeToolkit(3, 3);
void setup() {
size(1540, 660);
background(255);
randomSeed(1972);
Breaker parent1 = new Breaker(tk);
parent1.display(0, 10, 10);
stroke(0);
line(0, 330, width, 330);
line(730, 0, 730, 330);
Breaker parent2 = new Breaker(tk);
parent2.display(740, 10, 10);
Breaker child1 = new Breaker(tk, parent1, parent2);
child1.display(0, 340, 10);
stroke(0);
line(770, 330, 770, 660);
Breaker child2 = new Breaker(tk, parent1, parent2);
child2.display(780, 340, 10);
textSize(20);
textAlign(LEFT, TOP);
fill(255, 64, 0);
text(String.format("Parent1: %.2f", parent1.getAvg()), 10, 10);
fill(0, 64, 255);
text(String.format("Parent2: %.2f", parent2.getAvg()), 740, 10);
fill(0);
text(String.format("Child1: %.2f", child1.getAvg()), 10, 340);
text(String.format("Child2: %.2f", child2.getAvg()), 780, 340);
println("parent1:", parent1.getAvg());
println("parent2:", parent2.getAvg());
println("child1 :", child1.getAvg());
println("child2 :", child2.getAvg());
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment