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 { ...@@ -7,20 +7,30 @@ class Breaker {
Breaker(CodeToolkit tk) { Breaker(CodeToolkit tk) {
this.tk = tk; this.tk = tk;
root = new Node(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.shrink();
root.triangleOpt(); root.triangleOpt();
computeFitness(); computeFitness();
} }
void train() { void train(Node p1, Node p2) {
boolean[] used = new boolean[tk.M]; boolean[] used = new boolean[tk.M];
int[] unused = new int[tk.M]; int[] unused = new int[tk.M];
for (int code = 0; code < tk.M; code++) { for (int code = 0; code < tk.M; code++) {
for (int k = 0; k < tk.M; k++) { for (int k = 0; k < tk.M; k++) {
used[k] = false; used[k] = false;
} }
root.followPath(code, used, unused); root.followPath(code, p1, p2, used, unused);
} }
} }
......
...@@ -4,21 +4,30 @@ class Node { ...@@ -4,21 +4,30 @@ class Node {
int guess; int guess;
boolean good; boolean good;
Node[] children; Node[] children;
// used for visualisation of crossover
// 0 = new, 1 = parent 1, 2 = parent2
int comesFrom;
Node(CodeToolkit tk) { Node(CodeToolkit tk) {
this.tk = tk; this.tk = tk;
guess = int(random(tk.M)); guess = int(random(tk.M));
good = false; good = false;
children = new Node[tk.F]; 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; used[guess] = true;
int f = tk.feedback(code, guess); int f = tk.feedback(code, guess);
if (f == 0) { if (f == 0) {
good = true; good = true;
} else if (children[f] != null) { return;
children[f].followPath(code, used, unused); }
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 { } else {
int count = 0; int count = 0;
for (int k = 0; k < tk.M; k++) { for (int k = 0; k < tk.M; k++) {
...@@ -31,6 +40,27 @@ class Node { ...@@ -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) { void buildPath(int code, int[] unused, int count) {
int k = int(random(count)); int k = int(random(count));
guess = unused[k]; guess = unused[k];
...@@ -43,7 +73,7 @@ class Node { ...@@ -43,7 +73,7 @@ class Node {
children[f].buildPath(code, unused, count - 1); children[f].buildPath(code, unused, count - 1);
} }
} }
Node shrink() { Node shrink() {
int childCount = 0; int childCount = 0;
Node lastChild = null; Node lastChild = null;
...@@ -56,7 +86,7 @@ class Node { ...@@ -56,7 +86,7 @@ class Node {
} }
return !good && childCount == 1 ? lastChild : this; return !good && childCount == 1 ? lastChild : this;
} }
int triangleOpt() { int triangleOpt() {
int count = 0; int count = 0;
int f1 = 0; int f1 = 0;
...@@ -90,7 +120,7 @@ class Node { ...@@ -90,7 +120,7 @@ class Node {
} }
return count; return count;
} }
int height() { int height() {
int h = 0; int h = 0;
for (Node child : children) { for (Node child : children) {
...@@ -98,7 +128,7 @@ class Node { ...@@ -98,7 +128,7 @@ class Node {
} }
return 1 + h; return 1 + h;
} }
void histogram(int level, int[] histo) { void histogram(int level, int[] histo) {
if (good) histo[level]++; if (good) histo[level]++;
for (Node child : children) { for (Node child : children) {
...@@ -134,6 +164,11 @@ class Node { ...@@ -134,6 +164,11 @@ class Node {
while (children[f] == null) f++; while (children[f] == null) f++;
int x1 = (xc.get(i - 1) + xc.get(i)) / 2; int x1 = (xc.get(i - 1) + xc.get(i)) / 2;
stroke(0); 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); line(x0, y + pegSize, x1, y + BRANCH_HEIGHT * pegSize);
displayLabel(f, (x0 + x1) / 2.0, y + (BRANCH_HEIGHT + 1) / 2.0 * pegSize, pegSize); displayLabel(f, (x0 + x1) / 2.0, y + (BRANCH_HEIGHT + 1) / 2.0 * pegSize, pegSize);
f++; 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