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
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.txt
|
4
|
+
Rakefile
|
5
|
+
TODO.txt
|
6
|
+
data/BENCHMARK
|
7
|
+
data/CROSSOVER
|
8
|
+
data/GENOTYPE
|
9
|
+
data/MUTATION
|
10
|
+
data/SELECTION
|
11
|
+
data/template.html
|
12
|
+
examples/bit.rb
|
13
|
+
examples/function_opt_2peak.rb
|
14
|
+
examples/function_opt_sombero.rb
|
15
|
+
examples/gladiatorial_simple.rb
|
16
|
+
examples/gladiatorial_sunburn.rb
|
17
|
+
examples/gridwalk.rb
|
18
|
+
examples/output/flattened_sombero.html
|
19
|
+
examples/output/flattened_sombero2_.html
|
20
|
+
examples/output/fopt1_dblopt.html
|
21
|
+
examples/output/hill10.html
|
22
|
+
examples/output/hill2.csv
|
23
|
+
examples/output/hill2.html
|
24
|
+
examples/output/royalroad1_report.html
|
25
|
+
examples/output/royalroad2_report.html
|
26
|
+
examples/output/royalroadquick_report.html
|
27
|
+
examples/output/tsp.html
|
28
|
+
examples/output/weasel1_report.html
|
29
|
+
examples/output/weasel2_report.html
|
30
|
+
examples/royalroad.rb
|
31
|
+
examples/royalroad2.rb
|
32
|
+
examples/simple_climb_hill2.rb
|
33
|
+
examples/tsp.rb
|
34
|
+
examples/weasel.rb
|
35
|
+
lib/charlie.rb
|
36
|
+
lib/charlie/crossover.rb
|
37
|
+
lib/charlie/etc/minireport.rb
|
38
|
+
lib/charlie/etc/monkey.rb
|
39
|
+
lib/charlie/genotype.rb
|
40
|
+
lib/charlie/list/list_crossover.rb
|
41
|
+
lib/charlie/list/list_genotype.rb
|
42
|
+
lib/charlie/list/list_mutate.rb
|
43
|
+
lib/charlie/mutate.rb
|
44
|
+
lib/charlie/permutation/permutation.rb
|
45
|
+
lib/charlie/population.rb
|
46
|
+
lib/charlie/selection.rb
|
47
|
+
test/t_common.rb
|
48
|
+
test/test_basic.rb
|
49
|
+
test/test_benchmark.rb
|
50
|
+
test/test_cross.rb
|
51
|
+
test/test_mutator.rb
|
52
|
+
test/test_permutation.rb
|
53
|
+
test/test_sel.rb
|
data/README.txt
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
Charlie
|
2
|
+
|
3
|
+
* http://rubyforge.org/projects/charlie/
|
4
|
+
* http://charlie.rubyforge.org
|
5
|
+
* mailto:sander.land+ruby@gmail.com
|
6
|
+
|
7
|
+
== DESCRIPTION:
|
8
|
+
Charlie is a library for genetic algorithms. It allows you to easily create
|
9
|
+
and run genetic algorithms. You can choose selection, crossover or mutation
|
10
|
+
strategies from either built-in options or simply write your own.
|
11
|
+
It also includes methods that can be used to compare several of these
|
12
|
+
strategies, generating reports with statistics that can be used to determine
|
13
|
+
which one to use in future problems.
|
14
|
+
|
15
|
+
== EXAMPLES:
|
16
|
+
This example finds the binary representation of the number 512.
|
17
|
+
require 'rubygems'
|
18
|
+
require 'charlie'
|
19
|
+
class Find512 < BitStringGenotype(10) # choose a genotype, in this case a list of 10 bits represents a solution
|
20
|
+
# Define a fitness function. This one returns minus the offset to the best solution, so a higher number is better.
|
21
|
+
# Usually, you won't know the best solution, and will define this as some value that needs to be maximized.
|
22
|
+
def fitness
|
23
|
+
# Use the 'genes' function to retrieve the array of bits representing this solution.
|
24
|
+
-(genes.map(&:to_s).join.to_i(2) - 512).abs
|
25
|
+
end
|
26
|
+
end
|
27
|
+
# Finally, create an instance of a population (with the default size of 20) and let it run for the default number of 100 generations.
|
28
|
+
Population.new(Find512).evolve_on_console
|
29
|
+
|
30
|
+
This example solves RubyQuiz #142.
|
31
|
+
|
32
|
+
require 'rubygems'
|
33
|
+
require 'charlie'
|
34
|
+
N=5
|
35
|
+
CITIES = (0...N).map{|i| (0...N).map{|j| [i,j] } }.inject{|a,b|a+b}
|
36
|
+
|
37
|
+
class TSP < PermutationGenotype(CITIES.size)
|
38
|
+
def fitness
|
39
|
+
d=0
|
40
|
+
(genes + [genes[0]]).each_cons(2){|a,b|
|
41
|
+
a,b=CITIES[a],CITIES[b]
|
42
|
+
d += Math.sqrt( (a[0]-b[0])**2 + (a[1]-b[1])**2 )
|
43
|
+
}
|
44
|
+
-d # lower distance -> higher fitness.
|
45
|
+
end
|
46
|
+
end
|
47
|
+
pop = Population.new(TSP,20).evolve_on_console(50)
|
48
|
+
|
49
|
+
== INSTALL:
|
50
|
+
|
51
|
+
* sudo gem install charlie
|
52
|
+
|
53
|
+
== Documentation
|
54
|
+
Because of the high amount of metaprogramming used in the package, the rdoc documentation is incomplete and also contains some non-existent functions.
|
55
|
+
|
56
|
+
The following pages contain overviews of the most important parts, including pointers to the appropriate pages of the documentation.
|
57
|
+
* Genotypes[link:files/data/GENOTYPE.html]
|
58
|
+
* Selection[link:files/data/SELECTION.html]
|
59
|
+
* Crossover[link:files/data/CROSSOVER.html]
|
60
|
+
* Mutation[link:files/data/MUTATION.html]
|
61
|
+
* Benchmarking[link:files/data/BENCHMARK.html]
|
62
|
+
|
63
|
+
Also see the 'examples' directory for several examples, where most of the functionality is used.
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
== LICENSE:
|
68
|
+
|
69
|
+
(The MIT License)
|
70
|
+
|
71
|
+
Copyright (c) 2007 Sander Land
|
72
|
+
|
73
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
74
|
+
a copy of this software and associated documentation files (the
|
75
|
+
"Software"), to deal in the Software without restriction, including
|
76
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
77
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
78
|
+
permit persons to whom the Software is furnished to do so, subject to
|
79
|
+
the following conditions:
|
80
|
+
|
81
|
+
The above copyright notice and this permission notice shall be
|
82
|
+
included in all copies or substantial portions of the Software.
|
83
|
+
|
84
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
85
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
86
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
87
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
88
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
89
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
90
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
require 'hoe'
|
4
|
+
|
5
|
+
$LOAD_PATH.unshift './lib'
|
6
|
+
|
7
|
+
require 'charlie'
|
8
|
+
|
9
|
+
Hoe.new('charlie', Charlie::VERSION) do |p|
|
10
|
+
p.rubyforge_name = 'charlie'
|
11
|
+
p.url = 'http://charlie.rubyforge.org'
|
12
|
+
|
13
|
+
p.author = 'Sander Land'
|
14
|
+
p.email = 'sander.land+ruby@gmail.com'
|
15
|
+
|
16
|
+
p.summary = 'A genetic algorithms library for Ruby.'
|
17
|
+
p.description = p.paragraphs_of('README.txt', 2..3).join("\n\n")
|
18
|
+
|
19
|
+
|
20
|
+
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
21
|
+
|
22
|
+
#p.test_globs ['test/test_all.rb'] # removed test_all, because rake now does that anyway
|
23
|
+
p.clean_globs = ['test/output/*','./**/*~'] # Remove this on "rake clean" : test output and kate backups
|
24
|
+
|
25
|
+
p.rdoc_pattern = /^lib|\.txt$|^data\/[A-Z]+$/
|
26
|
+
p.remote_rdoc_dir = '' # Release to root
|
27
|
+
end
|
28
|
+
|
29
|
+
task :build_manifest do |t|
|
30
|
+
require 'find'
|
31
|
+
paths = []
|
32
|
+
Find.find(".") do |path|
|
33
|
+
next if File.directory?(path)
|
34
|
+
next if path =~ /\.svn/ # no svn
|
35
|
+
next if path =~ /~$/ # no kate backups
|
36
|
+
paths << path.sub(%r{^\./}, '')
|
37
|
+
end
|
38
|
+
File.open("Manifest.txt", "w") do |f|
|
39
|
+
f.puts paths.sort.join("\n")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
data/TODO.txt
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
This is my todo list. Contributions and suggestions don't have to be restricted to these things in any way.
|
2
|
+
|
3
|
+
=== Small stuff
|
4
|
+
* fix the initialize call in Genotype#from_genes
|
5
|
+
* clean up PCross, PMutate
|
6
|
+
* n-point crossover for lists
|
7
|
+
|
8
|
+
=== Bigger stuff
|
9
|
+
* Better crossover and/or mutation operators for permutations. Especially something useful for TSP. (http://en.wikipedia.org/wiki/Edge_recombination_operator ?)
|
10
|
+
* More builtin genotypes:
|
11
|
+
1. Tree-based, extending into genetic programming.
|
12
|
+
2. Graphs / adjacency matrix.
|
13
|
+
3. Neural networks.
|
14
|
+
4. selection algorithms.
|
15
|
+
* Extend benchmarking options:
|
16
|
+
1. Compare several generation/population size settings. Especially both of them together while keeping the number of fitness evaluations roughly constant.
|
17
|
+
2. Detailed stats for use in comparing a small number of strategies? Including population stats for every generation and run, graphs?
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
|
data/data/BENCHMARK
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
== Benchmark documentation
|
2
|
+
Population#benchmark can compare several selection, crossover and mutation methods and give a report comparing their
|
3
|
+
performance, both for convergence and speed.
|
4
|
+
|
5
|
+
The call to the function is:
|
6
|
+
|
7
|
+
Population.benchmark(genotype_class,html_output_file,csv_output_file=nil) {
|
8
|
+
selection RandomSelection, TournamentSelection(3)
|
9
|
+
crossover SinglePointCrossover
|
10
|
+
mutator ListMutator(
|
11
|
+
}
|
12
|
+
|
13
|
+
* +genotype_class+ is simply your genotype class.
|
14
|
+
* +html_output_file+ is an output file where a large report with several tables of statistics will be written. Pass nil for no output file of this type.
|
15
|
+
* +csv_output_file+ is an output file where the raw data (the maximum fitness value for each run) will be written. Pass nil or omit parameter for no output file of this type.
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
In the block you can call several functions to specify the parameters of the benchmark.
|
20
|
+
This is sometimes refered to as a DSL. As inaccurate as that term may be, I'll still use it here.
|
21
|
+
|
22
|
+
|
23
|
+
=== Benchmark DSL documentation (also see StrategiesDSL)
|
24
|
+
In the block you must call the following functions:
|
25
|
+
|
26
|
+
==== selection(*s_args)
|
27
|
+
Will cause each of the selection modules in +s_args+ to be tested.
|
28
|
+
==== crossover(*c_args)
|
29
|
+
Will cause each of the crossover modules in +c_args+ to be tested.
|
30
|
+
==== mutator(*m_args)
|
31
|
+
Will cause each of the mutation modules in +m_args+ to be tested.
|
32
|
+
|
33
|
+
|
34
|
+
If you want to test the module that is already included without repeating it, just pass Module.new as one of the arguments (or Module.new{self.name='default'} for something more descriptive).
|
35
|
+
|
36
|
+
|
37
|
+
You can also call the following functions to change some other settings:
|
38
|
+
|
39
|
+
==== self.generations = g
|
40
|
+
Changes the number of generations in each test to +g+. Default is 50.
|
41
|
+
|
42
|
+
==== self.population_size = s
|
43
|
+
Changes the population size in each test to +g+. Default is 20.
|
44
|
+
|
45
|
+
==== self.repeat = r
|
46
|
+
Changes the number of times each test will be repeated to +r+. Default is 10, a higher number here will take longer to
|
47
|
+
complete, but will improve the accuracy of the results.
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
|
data/data/CROSSOVER
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
== Crossover documentation
|
2
|
+
A crossover operator combines two parents to generate one or (usually) two children.
|
3
|
+
|
4
|
+
The crossover operator should be defined as a +cross+ method in the metaclass of your genotype class.
|
5
|
+
class Example < Genotype
|
6
|
+
...
|
7
|
+
class << self
|
8
|
+
def cross(parent1,parent2)
|
9
|
+
# generate children.
|
10
|
+
end
|
11
|
+
end
|
12
|
+
use NullCrossover # or include some builtin operator
|
13
|
+
end
|
14
|
+
Also see the Genotype#from_genes function, which can be useful for generating children after extracting and recombining the parents' genes.
|
15
|
+
|
16
|
+
The builtin crossover operators are implemented as modules which should be included in the metaclass.
|
17
|
+
Using the Class#use keyword does this automatically.
|
18
|
+
|
19
|
+
== General Crossovers
|
20
|
+
=== NullCrossover
|
21
|
+
Just returns copies of the two parents, i.e. performs no crossover at all.
|
22
|
+
|
23
|
+
== List-based Crossovers
|
24
|
+
These crossovers can be used for all list- and string-based genotypes.
|
25
|
+
|
26
|
+
=== SinglePointCrossover
|
27
|
+
Standard single point crossover. Returns two children.
|
28
|
+
|
29
|
+
=== UniformCrossover
|
30
|
+
Standard uniform crossover.Returns two children.
|
31
|
+
|
32
|
+
|
33
|
+
== Specialized Crossovers
|
34
|
+
=== For PermutationGenotype
|
35
|
+
PermutationCrossover is a partial preservation crossover for permutations.
|
36
|
+
It is fairly destructive, which can lead to poor performance.
|
37
|
+
|
38
|
+
|
39
|
+
== Meta-crossovers
|
40
|
+
These functions take one or more crossover modules and generate a new crossover module.
|
41
|
+
|
42
|
+
=== SingleChild(crossover) (#SingleChild)
|
43
|
+
Applies an arbitrary crossover and returns a random child.
|
44
|
+
|
45
|
+
=== PCross(p,crossover,othercrossover=NullCrossover)
|
46
|
+
Applies an arbitrary crossover with probability p, and another crossover with probability 1-p.
|
47
|
+
|
48
|
+
|
49
|
+
|
data/data/GENOTYPE
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
== Genotype documentation
|
2
|
+
The genotype, aka genome, aka chromosomes is a simple representation of a solution to your problem.
|
3
|
+
This is usually an array of numbers or bits.
|
4
|
+
|
5
|
+
=== Creating your own.
|
6
|
+
If you are creating your own genotype, just inherit from the base Genotype class.
|
7
|
+
You should initialize an instance in the +initialize+ method, and make sure the +genes+ and +genes=+ functions work properly.
|
8
|
+
|
9
|
+
The base class includes NullCrossover, NullMutator and Elitism(ScaledRouletteSelection(),1) by default.
|
10
|
+
|
11
|
+
All of the other genotypes described here inherit the base class, and its associated selection/crossover/mutation operators, unless
|
12
|
+
otherwise indicated.
|
13
|
+
|
14
|
+
=== List-based genotypes (file)[link:files/lib/charlie/list/list_genotype_rb.html]
|
15
|
+
All of these genotypes are based on arrays and can use the list-based crossover and mutation operators.
|
16
|
+
They are all generated dynamically by functions, and should be used like:
|
17
|
+
|
18
|
+
class MyGenotype < FloatListGenotype(5)
|
19
|
+
def fitness
|
20
|
+
...
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
==== FloatListGenotype(n,range=0..1)
|
26
|
+
Genotype of +n+ floats in the range +range+.
|
27
|
+
|
28
|
+
Includes <tt>ListMutator()</tt> (with default parameters :expected_n[3], :uniform[ 0.25 ]) and <tt>SinglePointCrossover</tt> by default.
|
29
|
+
|
30
|
+
==== BitStringGenotype(n)
|
31
|
+
Genotype of +n+ bits. +genes+ returns an array of 0/1, +to_s+ returns a string.
|
32
|
+
|
33
|
+
Includes <tt>ListMutator(:expected_n[3],:flip), SinglePointCrossover</tt> by default.
|
34
|
+
|
35
|
+
==== StringGenotype(n,elements)
|
36
|
+
Genotype of +n+ elements (not necessarily chars).
|
37
|
+
|
38
|
+
Includes <tt>ListMutator(:expected_n[2],:replace[*elements]), SinglePointCrossover</tt> by default.
|
39
|
+
|
40
|
+
=== Specialized genotypes
|
41
|
+
These genotypes have their own crossover and mutation operators.
|
42
|
+
|
43
|
+
==== PermutationGenotype(n,elements=0...n) (file)[link:files/lib/charlie/permutation/permutation_rb.html]
|
44
|
+
Genotype for permutations. Includes PermutationMutator and PermutationCrossover by default.
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
|
data/data/MUTATION
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
== Mutation documentation
|
2
|
+
A mutation operator mutates a single instance in place.
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
The mutation operator should be defined as a +mutate!+ method in your genotype class.
|
7
|
+
class Example < Genotype
|
8
|
+
def mutate!
|
9
|
+
# apply mutation here.
|
10
|
+
end
|
11
|
+
use NullMutator # or include some builtin operator
|
12
|
+
end
|
13
|
+
|
14
|
+
The non-destructive counterpart +mutate+ is defined automatically by Genotype#mutate.
|
15
|
+
|
16
|
+
== General Mutators
|
17
|
+
=== NullMutator
|
18
|
+
Just returns self
|
19
|
+
|
20
|
+
== List-based Mutators
|
21
|
+
These crossovers can be used for all list- and string-based genotypes.
|
22
|
+
|
23
|
+
=== ListMutator(strategy=:expected_n ,point_mutator=:uniform)
|
24
|
+
Generates a wide variety of mutators for lists, strings and bitstrings.
|
25
|
+
|
26
|
+
* strategy can be a proc or one of the MutationStrategies : single point, multi-point and probabilistic.
|
27
|
+
* point_mutator can be a proc or one of the PointMutators : bit flipping, replacing elements, or adding some offset.
|
28
|
+
See the documentation of list_mutate.rb[link:files/lib/charlie/list/list_mutate_rb.html] for more info on these.
|
29
|
+
|
30
|
+
Both of these parameters use Symbol#[] in the examples. <tt>:replace['a','b']</tt> is simply equivalent to <tt>[:replace,'a','b']</tt>
|
31
|
+
|
32
|
+
== Specialized Mutators
|
33
|
+
=== For PermutationGenotype
|
34
|
+
PermutationMutator is a transposition mutator for permutations.
|
35
|
+
|
36
|
+
== Meta-mutators
|
37
|
+
These functions take one or more mutator modules and generate a new mutator module.
|
38
|
+
|
39
|
+
=== PMutate(p,mutator,othermutator=NullMutator)
|
40
|
+
Applies an arbitrary mutator with probability p, and another mutator with probability 1-p.
|
41
|
+
|
42
|
+
|
43
|
+
|
data/data/SELECTION
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
== Selection documentation
|
2
|
+
A selection operator generates the new generation from the old.
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
The selection strategy should be defined as a +next_generation+ method in the metaclass of your genotype class.
|
7
|
+
class Example < Genotype
|
8
|
+
...
|
9
|
+
class << self
|
10
|
+
def next_generation(population)
|
11
|
+
# select parents and yield(parent1,parent2) them to the crossover and mutation operator. Create an array from several of these calls to get the next generation.
|
12
|
+
end
|
13
|
+
end
|
14
|
+
use RouletteSelection # or include some builtin operator
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
== Fitness-based selection strategies
|
19
|
+
These strategies work with genotype classes which define a +fitness+ function. The +fitness+ function should return a number, higher fitness means better and more likely to be selected. All except RouletteSelection can handle negative fitness values.
|
20
|
+
|
21
|
+
* RandomSelection
|
22
|
+
* TruncationSelection(best=0.3)
|
23
|
+
* BestOnlySelection
|
24
|
+
* RouletteSelection
|
25
|
+
* ScaledRouletteSelection(&block)
|
26
|
+
* TournamentSelection(group_size=4,n_times=nil)
|
27
|
+
|
28
|
+
The documentation for selection_rb[link:files/lib/charlie/selection_rb.html] contains explanations for most of these.
|
29
|
+
|
30
|
+
=== Meta-selection
|
31
|
+
==== Elitism(selection,n=1)
|
32
|
+
Generates a module which applies elitism to some selection strategy. This:
|
33
|
+
* saves the best +n+ solutions
|
34
|
+
* applies the selection
|
35
|
+
* replaces the last +n+ individuals in the new population with the best +n+ of the old population (unless the newer individual has higher fitness).
|
36
|
+
This ensures the maximum fitness can never decrease.
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
== Co-evolutionary selection strategies
|
41
|
+
These strategies work with genotype classes which define a <tt>fight(other)</tt> function.
|
42
|
+
This function should return true if the instance defeats +other+ in a 'fight'.
|
43
|
+
|
44
|
+
* GladiatorialSelection
|
45
|
+
|
46
|
+
Because there is no way to determine who is the actual best individual, using Population#benchmark
|
47
|
+
for comparing strategies for convergence speed, etc.
|
48
|
+
is not possible. Defining a fitness function as some statistic you want to track and then using benchmark should be possible, but is untested.
|