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.
- data/History.txt +3 -0
- data/Manifest.txt +53 -0
- data/README.txt +90 -0
- data/Rakefile +43 -0
- data/TODO.txt +28 -0
- data/data/BENCHMARK +53 -0
- data/data/CROSSOVER +49 -0
- data/data/GENOTYPE +49 -0
- data/data/MUTATION +43 -0
- data/data/SELECTION +48 -0
- data/data/template.html +34 -0
- data/examples/bit.rb +10 -0
- data/examples/function_opt_2peak.rb +24 -0
- data/examples/function_opt_sombero.rb +38 -0
- data/examples/gladiatorial_simple.rb +17 -0
- data/examples/gladiatorial_sunburn.rb +89 -0
- data/examples/gridwalk.rb +29 -0
- data/examples/output/flattened_sombero.html +6400 -0
- data/examples/output/flattened_sombero2_.html +3576 -0
- data/examples/output/fopt1_dblopt.html +2160 -0
- data/examples/output/hill10.html +5816 -0
- data/examples/output/hill2.csv +24 -0
- data/examples/output/hill2.html +384 -0
- data/examples/output/royalroad1_report.html +1076 -0
- data/examples/output/royalroad2_report.html +1076 -0
- data/examples/output/royalroadquick_report.html +504 -0
- data/examples/output/tsp.html +632 -0
- data/examples/output/weasel1_report.html +1076 -0
- data/examples/output/weasel2_report.html +240 -0
- data/examples/royalroad.rb +26 -0
- data/examples/royalroad2.rb +18 -0
- data/examples/simple_climb_hill2.rb +47 -0
- data/examples/tsp.rb +35 -0
- data/examples/weasel.rb +36 -0
- data/lib/charlie.rb +35 -0
- data/lib/charlie/crossover.rb +49 -0
- data/lib/charlie/etc/minireport.rb +45 -0
- data/lib/charlie/etc/monkey.rb +136 -0
- data/lib/charlie/genotype.rb +45 -0
- data/lib/charlie/list/list_crossover.rb +30 -0
- data/lib/charlie/list/list_genotype.rb +53 -0
- data/lib/charlie/list/list_mutate.rb +75 -0
- data/lib/charlie/mutate.rb +25 -0
- data/lib/charlie/permutation/permutation.rb +47 -0
- data/lib/charlie/population.rb +156 -0
- data/lib/charlie/selection.rb +162 -0
- data/test/t_common.rb +32 -0
- data/test/test_basic.rb +32 -0
- data/test/test_benchmark.rb +56 -0
- data/test/test_cross.rb +28 -0
- data/test/test_mutator.rb +44 -0
- data/test/test_permutation.rb +23 -0
- data/test/test_sel.rb +39 -0
- 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
|
+
}
|
data/examples/weasel.rb
ADDED
@@ -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
|