-
Notifications
You must be signed in to change notification settings - Fork 0
/
fitness.js
97 lines (85 loc) · 2.19 KB
/
fitness.js
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
/*
* The fitness function is used to quantify how well a program performed over a given dataset
*
* In our case, we want the result to be negative, and we assume the program is perfect when its
* fitness reach 0. This convention will allow to use diferent types of fitnesses for different types
* of problems
*/
/*
* The Levenshtein Edit Distance is used to calculate the distance between 2 strings
*
* s1 => {String}
* s2 => {String}
*
* return => {Number}
*/
const levenshtein = (s, t) => {
if (!s.length) { return t.length }
if (!t.length) { return s.length }
return Math.min(
levenshtein(s.substr(1), t) + 1,
levenshtein(t.substr(1), s) + 1,
levenshtein(s.substr(1), t.substr(1)) + (s[0] !== t[0] ? 1 : 0)
)
}
/*
* Returns a fitness function that returns the overall program's performance,
*
* dataset => {Array<{ input, output }>}
* definition => {Function}
* error => {Function} used to calculate the distance between the expected value and the actual result
* evaluate => {Function} takes an array representing the program and turn it into a javascript function
*
* program => {Program}
*
* return => {Number} the program's performance
*/
export const createFitness = ({
dataset,
definition,
error,
evaluate,
}) => program => {
const evaluated = evaluate(program)
return dataset.map(e => error(e.output, evaluated(e.input)))
.reduce((p, c) => p + c, 0)
}
/*
* Create a fitness for math problems
*/
export const createMathFitness = ({
definition,
minDataset,
maxDataset,
evaluate,
}) =>
createFitness({
dataset: createMathDataset(definition, minDataset, maxDataset),
definition,
error: (expected, got) => Math.abs(expected - got) * -1,
evaluate,
})
/*
* Create a fitness for string problems
*/
export const createLevenshteinFitness = ({
definition,
dataset,
evaluate,
}) =>
createFitness({
dataset,
definition,
evaluate,
error: (expected, got) => levenshtein(expected, got) * -1,
})
/*
* Create a dataset for math problems
*/
export const createMathDataset = (fn, min = -10, max = 100) => {
const ret = []
while (min++ < max) {
ret.push({ input: { x: min }, output: fn(min) })
}
return ret
}