Author: Chris Warburton <chriswarbo@gmail.com>
Date: Sat 19 Mar 17:08:22 UTC 2016
Parent: 6cea3562c0f84c096b2a78e8355a0f5a813a7d2a
Log message:
Merge branch 'master' of /home/chris/Programming/repos/search-optimisation-streams
1: diff --git a/search.js b/search.js
2: index f87fbd8..addcd26 100755
3: --- a/search.js
4: +++ b/search.js
5: @@ -30,7 +30,7 @@
6: // and state, but they must be curried into the
7: // stream functions. This minimises shared state
8: // and other such nastiness.
9: -//
10: +//
11: // As a consequence of this currying, we generally
12: // don't ending up define streams directly, but
13: // rather curryable functions (combinators, or
14: @@ -195,6 +195,130 @@ var array_compare = c(function(a, b) {
15:
16: var identity = function(x) { return x; };
17:
18: +var n_point_crossover = c(function(points, first, second) {
19: + // Takes two array-like solutions (first and
20: + // second) and swaps their elements at n points,
21: + // chosen by rand.
22: + var new_first = first.slice(0);
23: + var new_second = second.slice(0);
24: + points.forEach(function(n) {
25: + var chunk1 = new_first.splice(n * new_first.length);
26: + var chunk2 = new_second.splice(n * new_second.length);
27: + new_first = new_first.concat(chunk1);
28: + new_second = new_second.concat(chunk2);
29: + });
30: + return [new_first, new_second];
31: +});
32: +
33: +var flip_bit = c(function(rand, string) {
34: + // Takes an array of booleans and a random number
35: + // between 0 and 1. Indexes the array using the
36: + // random number and flips the bit.
37: + if (string.length === 0) return string;
38: + var index = Math.floor(rand * string.length - 1);
39: + var copy = string.slice(0, index);
40: + copy.push(!string[index]);
41: + return copy.concat(string.slice(index));
42: +});
43: +
44: +/////////////////////////////
45: +// Streams and combinators //
46: +/////////////////////////////
47: +
48: +var constant = function(val) {
49: + // A constant stream always gives the same
50: + // value. This combinator makes constant
51: + // streams.
52: + return function() {
53: + return val;
54: + };
55: +};
56: +
57: +var zeros = function() {
58: + // A stream of 0s
59: + return constant(0);
60: +};
61: +
62: +var ones = function() {
63: + // A stream of 1s
64: + return constant(1);
65: +};
66: +
67: +var reduce = c(function(init, f, stream) {
68: + // Reduce combines the results of a
69: + // stream using a reduction function.
70: + // For function f, initial value init
71: + // and stream values a, b, c, ...
72: + // reduce returns:
73: + // f(init, a)
74: + // f(f(init, a), b)
75: + // f(f(f(init, a), b), c)
76: + // ...
77: + var comb = function() {
78: + comb = function() {
79: + init = f(init, stream());
80: + return init;
81: + };
82: + return init;
83: + };
84: + return function() {
85: + return comb();
86: + };
87: +});
88: +
89: +var counter = function() {
90: + // A useful example of a reduction.
91: + // Produces a stream of the Naturals
92: + return reduce(0, plus, ones());
93: +};
94: +
95: +var hoard = function(comb) {
96: + // A reducer which appends all results to an
97: + // array
98: + return reduce([], catenate, comb);
99: +};
100: +
101: +var delayer = c(function(vals, stream) {
102: + // Returns each element of the given
103: + // array, then becomes the given stream
104: + var index = 0;
105: + return function() {
106: + if (index < vals.length) return vals[index++];
107: + else return stream();
108: + };
109: +});
110: +
111: +var delay = c(function(val, stream) {
112: + // Returns the given value, then becomes
113: + // the given stream
114: + return delayer([val], stream);
115: +});
116: +
117: +var map = c(function(f, comb) {
118: + // Maps the given function over the given
119: + // stream.
120: + return function() {
121: + return f(comb());
122: + };
123: +});
124: +
125: +var iterate = c(function(f, val) {
126: + // Takes a function f and a value x, returns
127: + // the stream f(x), f(f(x)), f(f(f(x))), ...
128: + var result = val;
129: + return function() {
130: + result = f(result);
131: + return result;
132: + };
133: +});
134: +
135: +var simple = function() {
136: + // SIMPLE, as defined by Jurgen Schmidhuber.
137: + // Returns every binary sequence in ascending
138: + // order.
139: + return enumerate([0, 1]);
140: +};
141: +
142: var bbj = c(function(i, o, inc, input, n) {
143: // A simple, potentially Turing Complete language,
144: // BitBitJump. We have an unbounded memory full of
145: @@ -945,6 +1069,15 @@ var make_fittest = function(comb) {
146: };
147: };
148:
149: +var mutate = c(function(choices, step) {
150: + return map(function(a) {
151: + if (choices()) {
152: + return step(a);
153: + }
154: + return a;
155: + });
156: +});
157: +
158: var extremal_optimiser = c(function(source, fitness, size) {
159: // Performs extremal optimisation. This is similar
160: // to a genetic algorithm but rather than finding
161: @@ -1073,7 +1206,7 @@ var exhaustive = c(function(stream, symbols) {
162: // Makes the given search stream exhaustive by
163: // taking every other result from a brute-force
164: // enumeration of the given symbols
165: - return interleave(stream, enumerate(symbols));
166: + return interleave([stream, enumerate(symbols)]);
167: });
168:
169: var tabu = c(function(ns, stream) {
170: @@ -1117,4 +1250,4 @@ var aixi = function(predictor, experimentor, inputs, rewards) {
171: // Once we have a good model, we find
172: // a good output for the model using
173: // experimentor.
174: -}
175: \ No newline at end of file
176: +}