charlie 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. data/History.txt +3 -0
  2. data/Manifest.txt +53 -0
  3. data/README.txt +90 -0
  4. data/Rakefile +43 -0
  5. data/TODO.txt +28 -0
  6. data/data/BENCHMARK +53 -0
  7. data/data/CROSSOVER +49 -0
  8. data/data/GENOTYPE +49 -0
  9. data/data/MUTATION +43 -0
  10. data/data/SELECTION +48 -0
  11. data/data/template.html +34 -0
  12. data/examples/bit.rb +10 -0
  13. data/examples/function_opt_2peak.rb +24 -0
  14. data/examples/function_opt_sombero.rb +38 -0
  15. data/examples/gladiatorial_simple.rb +17 -0
  16. data/examples/gladiatorial_sunburn.rb +89 -0
  17. data/examples/gridwalk.rb +29 -0
  18. data/examples/output/flattened_sombero.html +6400 -0
  19. data/examples/output/flattened_sombero2_.html +3576 -0
  20. data/examples/output/fopt1_dblopt.html +2160 -0
  21. data/examples/output/hill10.html +5816 -0
  22. data/examples/output/hill2.csv +24 -0
  23. data/examples/output/hill2.html +384 -0
  24. data/examples/output/royalroad1_report.html +1076 -0
  25. data/examples/output/royalroad2_report.html +1076 -0
  26. data/examples/output/royalroadquick_report.html +504 -0
  27. data/examples/output/tsp.html +632 -0
  28. data/examples/output/weasel1_report.html +1076 -0
  29. data/examples/output/weasel2_report.html +240 -0
  30. data/examples/royalroad.rb +26 -0
  31. data/examples/royalroad2.rb +18 -0
  32. data/examples/simple_climb_hill2.rb +47 -0
  33. data/examples/tsp.rb +35 -0
  34. data/examples/weasel.rb +36 -0
  35. data/lib/charlie.rb +35 -0
  36. data/lib/charlie/crossover.rb +49 -0
  37. data/lib/charlie/etc/minireport.rb +45 -0
  38. data/lib/charlie/etc/monkey.rb +136 -0
  39. data/lib/charlie/genotype.rb +45 -0
  40. data/lib/charlie/list/list_crossover.rb +30 -0
  41. data/lib/charlie/list/list_genotype.rb +53 -0
  42. data/lib/charlie/list/list_mutate.rb +75 -0
  43. data/lib/charlie/mutate.rb +25 -0
  44. data/lib/charlie/permutation/permutation.rb +47 -0
  45. data/lib/charlie/population.rb +156 -0
  46. data/lib/charlie/selection.rb +162 -0
  47. data/test/t_common.rb +32 -0
  48. data/test/test_basic.rb +32 -0
  49. data/test/test_benchmark.rb +56 -0
  50. data/test/test_cross.rb +28 -0
  51. data/test/test_mutator.rb +44 -0
  52. data/test/test_permutation.rb +23 -0
  53. data/test/test_sel.rb +39 -0
  54. metadata +115 -0
@@ -0,0 +1,240 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+
3
+ <html xmlns="http://www.w3.org/1999/xhtml">
4
+ <head>
5
+ <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
6
+ <title>GA Benchmark Report</title>
7
+ <style type='text/css'>
8
+ table{
9
+ background: #ccc;
10
+ font-family: Verdana, Helvetica, sans-serif;
11
+ }
12
+ th {
13
+ background: #666;
14
+ color: white;
15
+ padding: 3px;
16
+ font-weight: bold;
17
+ }
18
+ td {
19
+ color: #333;
20
+ background: #e2e2e2;
21
+ padding: 2px;
22
+ text-align: center;
23
+ }
24
+ </style>
25
+
26
+ </script>
27
+ <script type="text/javascript">
28
+
29
+ </script>
30
+ </head>
31
+ <body>
32
+ <h1>Information</h1>
33
+
34
+ <table>
35
+ <tr><td>Genotype class</td><td>Weasel</td></tr>
36
+ <tr><td>Population size</td><td>20</td></tr>
37
+ <tr><td># of generations per run</td><td>100</td></tr>
38
+ <tr><td>Number of tests </td><td>12</td></tr>
39
+ <tr><td>Tests repeated </td><td>10 times</td></tr>
40
+ <tr><td>Number of runs </td><td>120</td></tr>
41
+ <tr><td>Total number of generations </td><td>12000</td></tr>
42
+ <tr><td>Total time</td><td>153.89 seconds</td></tr>
43
+ </table
44
+ <h1>Stats for all</h1><table>
45
+ <tr><th>.</th><th>min</th><th>max</th><th>avg</th><th>stddev</th><th>avg-time</th></tr>
46
+ <tr>
47
+ <td>All</td>
48
+ <td>18.00000</td>
49
+ <td>27.00000</td>
50
+ <td>23.21667</td>
51
+ <td>1.86719</td>
52
+ <td>1.28238</td>
53
+ </tr>
54
+ </table><h1>Stats for selection</h1><table>
55
+ <tr><th>selection</th><th>min</th><th>max</th><th>avg</th><th>stddev</th><th>avg-time</th></tr>
56
+ <tr>
57
+ <td>TruncationSelection(1)</td>
58
+ <td>18.00000</td>
59
+ <td>27.00000</td>
60
+ <td>23.28333</td>
61
+ <td>1.81743</td>
62
+ <td>1.29585</td>
63
+ </tr>
64
+ <tr>
65
+ <td>TruncationSelection(0.2)</td>
66
+ <td>19.00000</td>
67
+ <td>27.00000</td>
68
+ <td>23.15000</td>
69
+ <td>1.91333</td>
70
+ <td>1.26892</td>
71
+ </tr>
72
+ </table><h1>Stats for crossover</h1><table>
73
+ <tr><th>crossover</th><th>min</th><th>max</th><th>avg</th><th>stddev</th><th>avg-time</th></tr>
74
+ <tr>
75
+ <td>UniformCrossover</td>
76
+ <td>22.00000</td>
77
+ <td>27.00000</td>
78
+ <td>24.32500</td>
79
+ <td>1.27255</td>
80
+ <td>1.38479</td>
81
+ </tr>
82
+ <tr>
83
+ <td>SinglePointCrossover</td>
84
+ <td>21.00000</td>
85
+ <td>27.00000</td>
86
+ <td>23.52500</td>
87
+ <td>1.43156</td>
88
+ <td>1.25068</td>
89
+ </tr>
90
+ <tr>
91
+ <td>NullCrossover</td>
92
+ <td>18.00000</td>
93
+ <td>26.00000</td>
94
+ <td>21.80000</td>
95
+ <td>1.86011</td>
96
+ <td>1.21168</td>
97
+ </tr>
98
+ </table><h1>Stats for mutation</h1><table>
99
+ <tr><th>mutation</th><th>min</th><th>max</th><th>avg</th><th>stddev</th><th>avg-time</th></tr>
100
+ <tr>
101
+ <td>ListMutator(:single_point,[:replace, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", " "])</td>
102
+ <td>18.00000</td>
103
+ <td>27.00000</td>
104
+ <td>23.50000</td>
105
+ <td>1.82117</td>
106
+ <td>1.26157</td>
107
+ </tr>
108
+ <tr>
109
+ <td>ListMutator([:n_point, 2],[:replace, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", " "])</td>
110
+ <td>19.00000</td>
111
+ <td>27.00000</td>
112
+ <td>22.93333</td>
113
+ <td>1.86964</td>
114
+ <td>1.30320</td>
115
+ </tr>
116
+ </table><h1>Raw Stats</h1><table>
117
+ <tr><th>selection</th><th>crossover</th><th>mutation</th><th>min</th><th>max</th><th>avg</th><th>stddev</th><th>avg-time</th></tr>
118
+ <tr>
119
+ <td>TruncationSelection(0.2)</td>
120
+ <td>UniformCrossover</td>
121
+ <td>ListMutator(:single_point,[:replace, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", " "])</td>
122
+ <td>22.00000</td>
123
+ <td>27.00000</td>
124
+ <td>24.80000</td>
125
+ <td>1.46969</td>
126
+ <td>1.34398</td>
127
+ </tr>
128
+ <tr>
129
+ <td>TruncationSelection(1)</td>
130
+ <td>UniformCrossover</td>
131
+ <td>ListMutator([:n_point, 2],[:replace, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", " "])</td>
132
+ <td>22.00000</td>
133
+ <td>26.00000</td>
134
+ <td>24.30000</td>
135
+ <td>1.34536</td>
136
+ <td>1.41264</td>
137
+ </tr>
138
+ <tr>
139
+ <td>TruncationSelection(0.2)</td>
140
+ <td>UniformCrossover</td>
141
+ <td>ListMutator([:n_point, 2],[:replace, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", " "])</td>
142
+ <td>22.00000</td>
143
+ <td>26.00000</td>
144
+ <td>24.10000</td>
145
+ <td>1.13578</td>
146
+ <td>1.38662</td>
147
+ </tr>
148
+ <tr>
149
+ <td>TruncationSelection(1)</td>
150
+ <td>UniformCrossover</td>
151
+ <td>ListMutator(:single_point,[:replace, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", " "])</td>
152
+ <td>23.00000</td>
153
+ <td>26.00000</td>
154
+ <td>24.10000</td>
155
+ <td>0.94340</td>
156
+ <td>1.39592</td>
157
+ </tr>
158
+ <tr>
159
+ <td>TruncationSelection(1)</td>
160
+ <td>SinglePointCrossover</td>
161
+ <td>ListMutator([:n_point, 2],[:replace, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", " "])</td>
162
+ <td>22.00000</td>
163
+ <td>27.00000</td>
164
+ <td>23.90000</td>
165
+ <td>1.44568</td>
166
+ <td>1.27018</td>
167
+ </tr>
168
+ <tr>
169
+ <td>TruncationSelection(1)</td>
170
+ <td>SinglePointCrossover</td>
171
+ <td>ListMutator(:single_point,[:replace, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", " "])</td>
172
+ <td>21.00000</td>
173
+ <td>26.00000</td>
174
+ <td>23.80000</td>
175
+ <td>1.46969</td>
176
+ <td>1.21699</td>
177
+ </tr>
178
+ <tr>
179
+ <td>TruncationSelection(0.2)</td>
180
+ <td>SinglePointCrossover</td>
181
+ <td>ListMutator(:single_point,[:replace, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", " "])</td>
182
+ <td>21.00000</td>
183
+ <td>26.00000</td>
184
+ <td>23.50000</td>
185
+ <td>1.36015</td>
186
+ <td>1.23589</td>
187
+ </tr>
188
+ <tr>
189
+ <td>TruncationSelection(0.2)</td>
190
+ <td>SinglePointCrossover</td>
191
+ <td>ListMutator([:n_point, 2],[:replace, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", " "])</td>
192
+ <td>21.00000</td>
193
+ <td>24.00000</td>
194
+ <td>22.90000</td>
195
+ <td>1.22066</td>
196
+ <td>1.27966</td>
197
+ </tr>
198
+ <tr>
199
+ <td>TruncationSelection(0.2)</td>
200
+ <td>NullCrossover</td>
201
+ <td>ListMutator(:single_point,[:replace, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", " "])</td>
202
+ <td>19.00000</td>
203
+ <td>26.00000</td>
204
+ <td>22.90000</td>
205
+ <td>1.97231</td>
206
+ <td>1.14157</td>
207
+ </tr>
208
+ <tr>
209
+ <td>TruncationSelection(1)</td>
210
+ <td>NullCrossover</td>
211
+ <td>ListMutator(:single_point,[:replace, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", " "])</td>
212
+ <td>18.00000</td>
213
+ <td>25.00000</td>
214
+ <td>21.90000</td>
215
+ <td>1.97231</td>
216
+ <td>1.23506</td>
217
+ </tr>
218
+ <tr>
219
+ <td>TruncationSelection(1)</td>
220
+ <td>NullCrossover</td>
221
+ <td>ListMutator([:n_point, 2],[:replace, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", " "])</td>
222
+ <td>20.00000</td>
223
+ <td>25.00000</td>
224
+ <td>21.70000</td>
225
+ <td>1.48661</td>
226
+ <td>1.24429</td>
227
+ </tr>
228
+ <tr>
229
+ <td>TruncationSelection(0.2)</td>
230
+ <td>NullCrossover</td>
231
+ <td>ListMutator([:n_point, 2],[:replace, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", " "])</td>
232
+ <td>19.00000</td>
233
+ <td>23.00000</td>
234
+ <td>20.70000</td>
235
+ <td>1.18743</td>
236
+ <td>1.22578</td>
237
+ </tr>
238
+ </table>
239
+ </body>
240
+ </html>
@@ -0,0 +1,26 @@
1
+ require '../lib/charlie'
2
+
3
+ class RoyalRoad < BitStringGenotype(64) # Royal Road problem
4
+ def fitness
5
+ 1e-6 + genes.enum_slice(8).find_all{|e| e.all?{|x|x==1} }.size
6
+ end
7
+ #use TruncationSelection()
8
+ use RouletteSelection
9
+ end
10
+
11
+ Population.new(RoyalRoad).evolve_on_console(1000)
12
+
13
+ Population.benchmark(RoyalRoad,'output/royalroad1_report.html'){
14
+ selection TruncationSelection(), Elitism(ScaledRouletteSelection(),1), Elitism(RouletteSelection,1), BestOnlySelection, ScaledRouletteSelection()
15
+ crossover NullCrossover, SinglePointCrossover, UniformCrossover
16
+ mutator ListMutator(:single_point,:flip), ListMutator(:n_point[2],:flip),ListMutator(:n_point[3],:flip),
17
+ ListMutator(:expected_n[1],:flip), ListMutator(:expected_n[2],:flip), ListMutator(:expected_n[3],:flip)
18
+
19
+ }
20
+
21
+ Population.benchmark(RoyalRoad,'output/royalroad2_report.html'){
22
+ selection TruncationSelection(0.2), TruncationSelection(0.3), TruncationSelection(0.4), Elitism(ScaledRouletteSelection(),1), Elitism(RouletteSelection,1)
23
+ crossover NullCrossover, SinglePointCrossover, UniformCrossover
24
+ mutator *( (2..4).map{|n| [ListMutator(:n_point[n],:flip), ListMutator(:expected_n[n],:flip)] }.flatten)
25
+ }
26
+
@@ -0,0 +1,18 @@
1
+ require '../lib/charlie'
2
+
3
+ class RoyalRoad < BitStringGenotype(64) # Royal Road problem
4
+ def fitness
5
+ genes.enum_slice(8).find_all{|e| e.all?{|x|x==1} }.size
6
+ end
7
+
8
+ #use TruncationSelection(0.1)
9
+ #use PCross(0.75,SingleChild(UniformCrossover))
10
+ end
11
+
12
+ Population.benchmark(RoyalRoad,'output/royalroadquick_report.html'){
13
+ selection TruncationSelection(), Elitism(ScaledRouletteSelection(),1), TournamentSelection(4)
14
+
15
+ crossover SinglePointCrossover, UniformCrossover, PCross(0.75,UniformCrossover), SingleChild(UniformCrossover)
16
+ mutator ListMutator(:expected_n[1],:flip), ListMutator(:expected_n[2],:flip), ListMutator(:expected_n[3],:flip)
17
+ self.repeat = 50
18
+ }
@@ -0,0 +1,47 @@
1
+ require '../lib/charlie'
2
+
3
+ class Hill2 < FloatListGenotype(2,(-1..1)) # simple hill function
4
+
5
+ def fitness
6
+ x,y=genes
7
+ 1 / (1+x*x+y*y)
8
+ end
9
+ #use BestOnlySelection
10
+ use TournamentSelection(4)
11
+ use NullCrossover
12
+ end
13
+
14
+ Population.new(Hill2,10).evolve_on_console(20)
15
+
16
+
17
+ class Hill10 < FloatListGenotype(10,(-1..1)) # 10-dimensional simple hill function
18
+ def fitness
19
+ 1 / (1 + genes.inject(0){|s,x|s+x*x})
20
+ end
21
+ #use BestOnlySelection
22
+ #use TournamentSelection(4)
23
+ #use NullCrossover
24
+ end
25
+
26
+ Population.benchmark(Hill2,'output/hill2.html','output/hill2.csv') {
27
+ selection BestOnlySelection, TournamentSelection(4)
28
+ crossover NullCrossover,SinglePointCrossover
29
+
30
+ mt = [:expected_n[1],:expected_n[2]].map{|s|
31
+ [:uniform[0.1],:uniform[0.2],:gaussian[0.3]].map{|p| ListMutator(s,p) } }.flatten
32
+ mutator *mt
33
+ self.generations = 20
34
+ self.population_size = 10
35
+ }
36
+
37
+ Population.benchmark(Hill10,'output/hill10.html') {
38
+ selection BestOnlySelection, TournamentSelection(4), TournamentSelection(3), RouletteSelection, Elitism(RouletteSelection,1)
39
+ crossover NullCrossover,SinglePointCrossover,UniformCrossover
40
+
41
+ mt = [:expected_n[1],:expected_n[2],:expected_n[3],:single_point,:n_point[2],:n_point[3]].map{|s|
42
+ [:uniform[0.1],:uniform[0.2],:uniform[0.3],:gaussian[0.1],:gaussian[0.2],:gaussian[0.3]].map{|p| ListMutator(s,p) } }.flatten
43
+
44
+ mutator *mt
45
+ self.generations = 20
46
+ self.population_size = 10
47
+ }
data/examples/tsp.rb ADDED
@@ -0,0 +1,35 @@
1
+ require '../lib/charlie'
2
+ # Travelling salesperson problem
3
+
4
+ N=10
5
+ # N cities in a circle
6
+ CITIES = (0...N).map{|i| th = i * 2 * Math::PI / N; [Math.cos(th),Math.sin(th)] }
7
+ #CITIES = (0...N).map{|i| [0,i] } # on a line
8
+
9
+ #CITIES = (0...N).map{|i| (0...N).map{|j| [i,j] } }.inject{|a,b|a+b} # on a grid
10
+
11
+ class TSP < PermutationGenotype(CITIES.size)
12
+ def fitness
13
+ d=0
14
+ (genes + [genes[0]]).each_cons(2){|a,b|
15
+ a,b=CITIES[a],CITIES[b]
16
+ d += Math.sqrt( (a[0]-b[0])**2 + (a[1]-b[1])**2 )
17
+ }
18
+ -d # higher (less negative) fitness is better. This breaks RouletteSelection (use 1.0/d instead), but most other methods can handle this
19
+ end
20
+ end
21
+
22
+ pop = Population.new(TSP,20).evolve_on_console(50)
23
+ #p pop[-1].genes.map{|a| CITIES[a]}
24
+ # 49 -6.18033988749895 [2, 3, 4, 5, 6, 7, 8, 9, 0, 1]
25
+ exit
26
+
27
+ Population.benchmark(TSP,'output/tsp.html') {
28
+ selection ScaledRouletteSelection(), TruncationSelection(1), TruncationSelection(0.3)
29
+ crossover PermutationCrossover, PCross(0.5,PermutationCrossover), PCross(0.75,PermutationCrossover), NullCrossover
30
+ mutator PermutationMutator, PMutate(0.5,PermutationMutator), PMutate(0.75,PermutationMutator), NullMutator
31
+
32
+ self.generations = 30
33
+ self.repeat = 50
34
+ self.population_size = 20
35
+ }
@@ -0,0 +1,36 @@
1
+ require '../lib/charlie'
2
+
3
+ STR = 'methinks it is like a weasel'
4
+ Schars = ('a'..'z').to_a << ' '
5
+
6
+ class Weasel < StringGenotype(STR.size,Schars)
7
+ def fitness
8
+ genes.zip(STR.chars).find_all{|a,b|a==b}.size
9
+ end
10
+
11
+ def to_s
12
+ genes.join.inspect
13
+ end
14
+ use BestOnlySelection
15
+ use UniformCrossover
16
+ use ListMutator(:single_point,:replace[*Schars])
17
+ end
18
+
19
+ Population.new(Weasel).evolve_on_console(200)
20
+
21
+ Population.benchmark(Weasel,'output/weasel1_report.html'){
22
+ selection TruncationSelection(), Elitism(ScaledRouletteSelection(),1), Elitism(RouletteSelection,1), BestOnlySelection, ScaledRouletteSelection()
23
+ crossover NullCrossover, SinglePointCrossover, UniformCrossover
24
+ mutator ListMutator(:single_point,:replace[*Schars]), ListMutator(:n_point[2],:replace[*Schars]),ListMutator(:n_point[3],:replace[*Schars]),
25
+ ListMutator(:expected_n[1],:replace[*Schars]), ListMutator(:expected_n[2],:replace[*Schars]), ListMutator(:expected_n[3],:replace[*Schars])
26
+
27
+ }
28
+
29
+
30
+ Population.benchmark(Weasel,'output/weasel2_report.html'){
31
+ selection TruncationSelection(0.2), BestOnlySelection
32
+ crossover NullCrossover, SinglePointCrossover, UniformCrossover
33
+ mutator ListMutator(:single_point,:replace[*Schars]), ListMutator(:n_point[2],:replace[*Schars])
34
+ }
35
+
36
+
data/lib/charlie.rb ADDED
@@ -0,0 +1,35 @@
1
+ require 'enumerator'
2
+
3
+ $:.unshift File.dirname(__FILE__)
4
+
5
+ # This is just a dummy module to avoid making the VERSION constant a global.
6
+ module Charlie
7
+ VERSION = '0.5.0'
8
+ end
9
+
10
+ require 'charlie/etc/monkey'
11
+ require 'charlie/etc/minireport'
12
+
13
+
14
+ require 'charlie/population'
15
+
16
+ require 'charlie/selection'
17
+ require 'charlie/crossover'
18
+ require 'charlie/mutate'
19
+
20
+ require 'charlie/genotype'
21
+
22
+
23
+ require 'charlie/list/list_mutate'
24
+ require 'charlie/list/list_crossover'
25
+ require 'charlie/list/list_genotype'
26
+
27
+ require 'charlie/permutation/permutation'
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
@@ -0,0 +1,49 @@
1
+ # This file contains some generic crossovers and functions to generate crossovers
2
+
3
+ # Just returns the two parents.
4
+ module NullCrossover
5
+ def cross(parent1,parent2)
6
+ [parent1.dup,parent2.dup]
7
+ end
8
+ end
9
+
10
+
11
+
12
+ # Turns a two-children crossover module into a single-child crossover module.
13
+ # Usage: use SingleChild(UniformCrossover)
14
+ def SingleChild(crossover_module)
15
+ Module.new{
16
+ include crossover_module
17
+ def cross(parent1,parent2)
18
+ super(parent1,parent2).at_rand
19
+ end
20
+ self.name= "SingleChild(#{crossover_module})"
21
+ }
22
+ end
23
+
24
+ # Takes crossover c1 with probability p, and crossover c2 with probability 1-p
25
+ def PCross(p,c1,c2=NullCrossover)
26
+ Module.new{
27
+ @@p = p
28
+ include c2
29
+ alias :cross2 :cross
30
+ include c1
31
+ def cross(*args)
32
+ rand < @@p ? super(*args) : cross2(*args)
33
+ end
34
+ self.name= "PCross(#{p},#{c1},#{c2})"
35
+ }
36
+ end
37
+
38
+ =begin
39
+ #a bit nicer, but needs parent1.class.from_genes(x) everywhere instead of just from_genes(x)
40
+ def PCross(p,c1,c2=NullCrossover)
41
+ [c1,c2].each{|m| m.module_eval{extend self} }
42
+ Module.new{
43
+ define_method(:cross) {|*args|
44
+ (rand < p ? c1 : c2).cross(*args)
45
+ }
46
+ self.name= "PCross(#{p},#{c1},#{c2})"
47
+ }
48
+ end
49
+ =end