Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package ea;
import java.util.Arrays;
import java.util.Random;
public class SimpleRandomHillClimber {
// Random mutation hill climber
// using a relative (hence co-evolutionary)
// fitness function
static Random random = new Random();
double[] bestYet;
Eval2 eval;
double stepFac = 0.1;
// set stepAdjust to 1.0 to keep the stepFac fixed
// on quadratic bowl 1.01 works much better than 1.0
// which increases the step size every time a mutation
// is successful and decreases it every time it fails
// to improve
// but be careful: could it make things worse in some cases?
double stepAdjust = 1.01;
// example ready for a minimal version of
// co-evolution
public static void main(String[] args) {
int nEvals = 1000;
int nDim = 10;
double[] init = randVec(nDim);
SimpleRandomHillClimber evo = new SimpleRandomHillClimber(init, new QuadraticBowl());
evo.run(nEvals);
System.out.println("Best Found: " + Arrays.toString(evo.bestYet));
System.out.println("Fitness: " + mag2(evo.bestYet));
}
public SimpleRandomHillClimber(double[] bestYet, Eval2 eval) {
this.bestYet = bestYet;
this.eval = eval;
}
public void run(int nEvals) {
for (int i=0; i<nEvals; i++) {
// randomly mutate the best yet
double[] mut = randMut(bestYet, stepFac);
double diff = eval.pointsDiff(bestYet, mut);
// if it's better then adopt the mutation as the new best
if (diff >= 0) {
bestYet = mut;
// try making it bigger - make even faster progress
} else {
// try making the step size smaller
stepFac /= stepAdjust;
}
System.out.println(i + "\t " + mag2(bestYet));
}
}
// to evolve a game playing agent inject a and b into
// game agent controllers and return the points difference
// ensure to interpret the sign correctly
// the example is set up to MINIMIZE a fitness score
static interface Eval2 {
double pointsDiff(double[] a, double[] b);
}
static double[] randVec(int n) {
double[] x = new double[n];
for (int i=0; i<n; i++) {
x[i] = random.nextGaussian();
}
return x;
}
static double[] randMut(double[] v, double stepFac) {
int n = v.length;
double[] x = new double[n];
for (int i=0; i<n; i++) {
x[i] = v[i] + stepFac * random.nextGaussian();
}
return x;
}
static class QuadraticBowl implements Eval2 {
@Override
public double pointsDiff(double[] a, double[] b) {
// simple example that evaluates quality as being
// the minimum squared magnitude of a vector
return mag2(a) - mag2(b);
}
}
static double mag2(double[] v) {
// square of the magnitude of the vector
double tot = 0;
for (double x : v) tot += x * x;
return tot;
}
}