Skip to content
Snippets Groups Projects
Commit b770baff authored by sbalev's avatar sbalev
Browse files

Changed Node and Breaker to implement crossover.

Added crossover test sketch
parent 275eaf00
Branches master
No related merge requests found
......@@ -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());
}
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