charlie 0.6.0 → 0.7.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 (66) hide show
  1. data/History.txt +14 -0
  2. data/Manifest.txt +13 -22
  3. data/README.txt +3 -3
  4. data/Rakefile +1 -1
  5. data/TODO.txt +11 -21
  6. data/data/BENCHMARK +25 -23
  7. data/data/CROSSOVER +5 -1
  8. data/data/GENOTYPE +6 -6
  9. data/data/MUTATION +19 -7
  10. data/data/SELECTION +2 -1
  11. data/data/template.html +2 -1
  12. data/examples/EXAMPLES_README.txt +70 -0
  13. data/examples/bitstring.rb +72 -0
  14. data/examples/{gladiatorial_sunburn.rb → coevolution.rb} +80 -22
  15. data/examples/function_optimization.rb +113 -0
  16. data/examples/output/{royalroad1_report.html → bitstring_royalroad.html} +822 -655
  17. data/examples/output/function_optimization_sombrero.html +2289 -0
  18. data/examples/output/function_optimization_twopeak.csv +210 -0
  19. data/examples/output/function_optimization_twopeak.html +2477 -0
  20. data/examples/output/string_weasel.html +513 -0
  21. data/examples/output/tsp.html +633 -882
  22. data/examples/{money.rb → permutation.rb} +20 -8
  23. data/examples/string.rb +98 -0
  24. data/examples/tree.rb +37 -12
  25. data/examples/tsp.rb +34 -22
  26. data/lib/charlie.rb +5 -1
  27. data/lib/charlie/1.9fixes.rb +46 -0
  28. data/lib/charlie/crossover.rb +31 -14
  29. data/lib/charlie/etc/minireport.rb +5 -4
  30. data/lib/charlie/etc/monkey.rb +11 -8
  31. data/lib/charlie/gabenchmark.rb +230 -0
  32. data/lib/charlie/genotype.rb +4 -0
  33. data/lib/charlie/list/list_crossover.rb +25 -5
  34. data/lib/charlie/mutate.rb +34 -7
  35. data/lib/charlie/permutation/permutation.rb +34 -6
  36. data/lib/charlie/population.rb +12 -122
  37. data/lib/charlie/selection.rb +1 -0
  38. data/lib/charlie/tree/tree.rb +179 -17
  39. data/test/t_common.rb +1 -1
  40. data/test/test_benchmark.rb +19 -5
  41. data/test/test_cross.rb +23 -1
  42. data/test/test_evolve.rb +14 -1
  43. data/test/test_mutator.rb +28 -2
  44. data/test/test_permutation.rb +23 -1
  45. data/test/test_sel.rb +3 -1
  46. data/test/test_tree.rb +63 -1
  47. metadata +17 -25
  48. data/examples/bit.rb +0 -10
  49. data/examples/function_opt_2peak.rb +0 -24
  50. data/examples/function_opt_sombero.rb +0 -38
  51. data/examples/gladiatorial_simple.rb +0 -17
  52. data/examples/gridwalk.rb +0 -29
  53. data/examples/output/flattened_sombero.html +0 -6400
  54. data/examples/output/flattened_sombero2_.html +0 -3576
  55. data/examples/output/fopt1_dblopt.html +0 -2160
  56. data/examples/output/hill10.html +0 -5816
  57. data/examples/output/hill2.csv +0 -24
  58. data/examples/output/hill2.html +0 -384
  59. data/examples/output/royalroad2_report.html +0 -1076
  60. data/examples/output/royalroadquick_report.html +0 -504
  61. data/examples/output/weasel1_report.html +0 -1076
  62. data/examples/output/weasel2_report.html +0 -240
  63. data/examples/royalroad.rb +0 -26
  64. data/examples/royalroad2.rb +0 -18
  65. data/examples/simple_climb_hill2.rb +0 -47
  66. data/examples/weasel.rb +0 -36
@@ -11,7 +11,9 @@ class TestCrossover < Test::Unit::TestCase
11
11
  def test_singlechild
12
12
  $crs_mth.map{|c| SingleChild(c) }.each{|s|
13
13
  klass = TestClass(s)
14
- assert_nothing_raised{ Population.new(klass,10).evolve_silent(10) }
14
+ r = nil
15
+ assert_nothing_raised{ r=Population.new(klass,10).evolve_silent(10) }
16
+ r.each{|e| assert_equal klass.new.size, e.size } # crossovers should preserver size
15
17
  }
16
18
  end
17
19
 
@@ -25,4 +27,24 @@ class TestCrossover < Test::Unit::TestCase
25
27
  assert_nothing_raised{ Population.new(klass,10).evolve_silent(10) }
26
28
  }
27
29
  end
30
+
31
+
32
+ def test_pcrossn
33
+ 3.times{
34
+ $crs_mth.map{|c| PCrossN(c=>0.5,$crs_mth.at_rand=>0.3) }.each{|s|
35
+ klass = TestClass(s)
36
+ assert_nothing_raised{ Population.new(klass,10).evolve_silent(10) }
37
+ }
38
+ }
39
+ $crs_mth.map{|c| PCrossN(c=>0.9) }.each{|s|
40
+ klass = TestClass(s)
41
+ assert_nothing_raised{ Population.new(klass,10).evolve_silent(10) }
42
+ }
43
+ assert_raises(ArgumentError) {
44
+ PCrossN(UniformCrossover=>0.5,NullCrossover=>0.6) # => 1.1 > 1.0
45
+ }
46
+ s = PCrossN( Hash[*$crs_mth.map{|c| [c,1 / $crs_mth.size ] }.flatten] )
47
+ klass = TestClass(s)
48
+ assert_nothing_raised{ Population.new(klass,10).evolve_silent(10) }
49
+ end
28
50
  end
@@ -46,7 +46,7 @@ class EvolveTest < Test::Unit::TestCase
46
46
 
47
47
  def test_until_pop # test evolve_until_population
48
48
  start = Time.now
49
- r,g = Population.new(RRTest,10).evolve_until_population(1000_000_000){|p| p.count{|x| x.fitness == 0 } > 3}
49
+ r,g = Population.new(RRTest,10).evolve_until_population(100_000_000){|p| p.count{|x| x.fitness == 0 } > 3}
50
50
  assert_not_nil g
51
51
  assert g >= 0 && g < 1000, "test_until_pop failed to converge within 1000 generations"
52
52
  assert( (Time.now - start < 1), "test_until_pop failed to converge within 1 second.")
@@ -58,6 +58,12 @@ class EvolveTest < Test::Unit::TestCase
58
58
  assert_nil g # did not converge
59
59
  assert_respond_to r, :[]
60
60
  assert_respond_to r[-1], :fitness
61
+ # test check_every
62
+ r,g = Population.new(RRTest,10).evolve_until(100,200){|b| b.fitness == 0 }
63
+ assert(g.nil? || g.zero?) # did not converge (except in the gen 0 check), because check_every > max_gens
64
+ r,g = Population.new(RRTest,10).evolve_until(1000,10){|b| b.fitness == 0 }
65
+ assert_not_nil g
66
+ assert( (g % 10).zero?)
61
67
  end
62
68
 
63
69
  # doesn't really belong here, and should be moved...eventually
@@ -84,4 +90,11 @@ class EvolveTest < Test::Unit::TestCase
84
90
  }
85
91
  end
86
92
 
93
+
94
+ def test_acc # test accessors
95
+ p = Population.new(RRTest,10)
96
+ assert_equal p.max, p.population.max
97
+ assert_equal p.max, p.best
98
+ assert_equal p[6], p.population[6]
99
+ end
87
100
  end
@@ -1,11 +1,18 @@
1
1
  require 't_common'
2
2
 
3
- ms = [:single_point,:single_point[],[:single_point],:n_point,:n_point[],:n_point[3],:expected_n,:expected_n[1],:probability,:probability[0.3]]
4
- pm = [:gaussian,:gaussian[],:gaussian[0.25],:uniform,:uniform[0.1],:flip,:replace[0.2,0.1,0.0,-0.1,-0.2]]
3
+ module Enumerable
4
+ def uniq_by
5
+ h = {}; inject([]) {|a,x| h[yield(x)] ||= a << x}
6
+ end
7
+ end
8
+
9
+ ms = [:single_point,[:n_point],:n_point[3],:expected_n[],:expected_n[1],:probability,:probability[0.3]]
10
+ pm = [:gaussian,:gaussian[0.25],:uniform,:uniform[0.1],:flip,:replace[0.2,0.1,0.0,-0.1,-0.2]]
5
11
  $mut_mth = [NullMutator]
6
12
  ms.each{|m| pm.each{|p| $mut_mth << ListMutator(m,p) } }
7
13
 
8
14
 
15
+
9
16
  class TestMutator < Test::Unit::TestCase
10
17
  def test_mutate
11
18
  $mut_mth.each{|m|
@@ -41,4 +48,23 @@ class TestMutator < Test::Unit::TestCase
41
48
  assert_nothing_raised{ p=Population.new(klass,10).evolve_silent(10) }
42
49
  assert p.all?{|s| s.genes.all?{|x| ('a'..'d')===x }}
43
50
  end
51
+
52
+ def test_pmutaten
53
+ 3.times{
54
+ $mut_mth.map{|c| PMutateN(c=>0.5,$mut_mth.at_rand=>0.3) }.each{|s|
55
+ klass = TestClass(s)
56
+ assert_nothing_raised{ Population.new(klass,10).evolve_silent(10) }
57
+ }
58
+ }
59
+ $mut_mth.map{|c| PMutateN(c=>0.9) }.each{|s|
60
+ klass = TestClass(s)
61
+ assert_nothing_raised{ Population.new(klass,10).evolve_silent(10) }
62
+ }
63
+ assert_raises(ArgumentError) {
64
+ PMutateN(ListMutator(:single_point,:uniform)=>0.5,NullMutator=>0.6) # => 1.1 > 1.0
65
+ }
66
+ s = PMutateN( Hash[*$mut_mth.map{|c| [c,1 / $mut_mth.size ] }.flatten] )
67
+ klass = TestClass(s)
68
+ assert_nothing_raised{ Population.new(klass,10).evolve_silent(10) }
69
+ end
44
70
  end
@@ -10,13 +10,21 @@ end
10
10
 
11
11
  class PermutationTestERO < PermutationTest
12
12
  use EdgeRecombinationCrossover
13
- use PMutate(0.5,PermutationMutator)
13
+ use PMutate(0.5,TranspositionMutator)
14
14
  end
15
15
 
16
16
  class PermutationTestInvert < PermutationTest
17
17
  use InversionMutator, RandomSelection
18
18
  end
19
19
 
20
+ class PermutationTestRotate < PermutationTest
21
+ use RotationMutator, NullCrossover
22
+ end
23
+ class PermutationTestInsert < PermutationTest
24
+ use InsertionMutator, NullCrossover
25
+ end
26
+
27
+
20
28
 
21
29
  class PermTests < Test::Unit::TestCase
22
30
  def test_evolve
@@ -53,5 +61,19 @@ class PermTests < Test::Unit::TestCase
53
61
  p.each{|s| assert_equal s.genes.sort, (0...N).to_a }
54
62
  end
55
63
 
64
+ def test_rotation_mutator # test if rotation mutator works
65
+ p=nil
66
+ assert_nothing_raised{
67
+ p=Population.new(PermutationTestRotate,20).evolve_silent(20)
68
+ }
69
+ p.each{|s| assert_equal s.genes.sort, (0...N).to_a }
70
+ end
56
71
 
72
+ def test_insertion_mutator # test if insertion mutator works
73
+ p=nil
74
+ assert_nothing_raised{
75
+ p=Population.new(PermutationTestInsert,20).evolve_silent(20)
76
+ }
77
+ p.each{|s| assert_equal s.genes.sort, (0...N).to_a }
78
+ end
57
79
  end
@@ -22,10 +22,12 @@ class TestSelection < Test::Unit::TestCase
22
22
  end
23
23
 
24
24
  def test_elitism
25
- $sel_mth.map{|s| Elitism(s,rand(4)) }.each{|s|
25
+ [0,1,5].each{|k|
26
+ $sel_mth.map{|s| Elitism(s,k) }.each{|s|
26
27
  klass = TestClass(s)
27
28
  assert_nothing_raised{ Population.new(klass,10).evolve_silent(10) }
28
29
  }
30
+ }
29
31
  end
30
32
 
31
33
  def test_singlechild
@@ -1,6 +1,6 @@
1
1
  require 't_common'
2
2
 
3
- class TreeTest < TreeGenotype([1,:x,proc{rand}], [:+], [:+@])
3
+ class TreeTest < TreeGenotype([1,:x,proc{rand}], [:+@], [:+])
4
4
  def fitness
5
5
  - (eval_genes(:x=>1) - 5).abs
6
6
  end
@@ -12,6 +12,26 @@ class BloatTest < TreeTest
12
12
  end
13
13
  end
14
14
 
15
+ $tree_mutators = [
16
+ TreeReplaceMutator,
17
+ TreeReplaceMutator(),
18
+ TreeReplaceMutator(2,:full),
19
+ TreeReplaceMutator(0,:grow),
20
+ TreeReplaceMutator(0..3,:grow),
21
+ TreeReplaceMutator(3..3,:half),
22
+ TreeReplaceMutator(:same,:full),
23
+ TreeReplaceMutator(:same[-1,1],:full),
24
+ TreePruneMutator,
25
+ TreeChopMutator,
26
+ TreeRemoveNodeMutator,
27
+ TreeInsertNodeMutator,
28
+ TreeTerminalMutator,
29
+ TreeNumTerminalMutator,
30
+ TreeNumTerminalMutator(mutate=:gaussian[2.1]),
31
+ TreeNumTerminalMutator{|x|x},
32
+ TreeEvalMutator, NullMutator
33
+ ]
34
+
15
35
  # hard to test, also see examples/tree.rb
16
36
  class TreeTests < Test::Unit::TestCase
17
37
  def test_evolve
@@ -53,5 +73,47 @@ class TreeTests < Test::Unit::TestCase
53
73
  end
54
74
 
55
75
 
76
+ def test_init_full
77
+ p=Population.new(TreeGenotype([1],[],[:+],5,:full) )
78
+ p.population.each{|x|
79
+ assert_equal 5, x.depth, "#{x} has a depth < 5"
80
+ x.genes[1..-1].each{|st| assert_equal 4, GPTreeHelper.tree_depth(st), "#{st.inspect} has a depth < 4" }
81
+ }
82
+ end
83
+
84
+ def test_init_grow
85
+ p=Population.new(TreeGenotype([1],[],[:+],5,:grow), 100)
86
+ assert p.population.any?{|x| x.depth < 5 } # with very high probability
87
+ assert !p.population.any?{|x| x.depth > 5 }
88
+ assert p.population.all?{|x| x.depth > 0 }
89
+ end
90
+
91
+ def test_init_half
92
+ p=Population.new(TreeGenotype([1],[],[:+],5,:half), 100)
93
+ assert p.population.any?{|x| x.depth < 5 } # with very high probability
94
+ assert p.population.any?{|x| x.depth == 5 } # with very high probability
95
+ assert !p.population.all?{|x| x.depth == 5 } # with very high probability
96
+ assert !p.population.any?{|x| x.depth > 5 }
97
+ assert p.population.all?{|x| x.depth > 0 }
98
+ end
99
+
100
+
101
+
102
+ def test_mutators
103
+ $tree_mutators.each{|m|
104
+ klass = Class.new(BloatTest) { use m }
105
+ assert_nothing_raised("#{m} failed") { Population.new(klass,10).evolve_silent(10) }
106
+ }
107
+ $tree_mutators.each{|m|
108
+ klass = Class.new(TreeTest) { use PMutate(0.5,m) }
109
+ assert_nothing_raised("#{m} failed") { Population.new(klass,10).evolve_silent(10) }
110
+ }
111
+
112
+ all_mut = Hash[*$tree_mutators.map{|x| [x,1.0 / $tree_mutators.size]}.flatten]
113
+ assert_nothing_raised {
114
+ klass = Class.new(TreeTest) { use PMutateN(all_mut) }
115
+ assert_nothing_raised("PMutateN failed") { Population.new(klass,30).evolve_silent(30) }
116
+ }
117
+ end
56
118
 
57
119
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: charlie
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sander Land
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2007-12-26 00:00:00 +01:00
12
+ date: 2008-01-11 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -21,7 +21,7 @@ dependencies:
21
21
  - !ruby/object:Gem::Version
22
22
  version: 1.4.0
23
23
  version:
24
- description: "== DESCRIPTION: Charlie is a library for genetic algorithms (GA) and genetic programming (GP). == FEATURES: - Quickly develop GAs by combining several parts (genotype, selection, crossover, mutation) provided by the library. - Sensible defaults are provided with any genotype, so often you only need to define a fitness function. - Easily replace any of the parts by your own code. - Test different strategies in GA, and generate reports comparing them. Example report: http://charlie.rubyforge.org/example_report.html == EXAMPLES: This example solves a TSP problem (also quiz #142): N=5 CITIES = (0...N).map{|i| (0...N).map{|j| [i,j] } }.inject{|a,b|a+b} class TSP < PermutationGenotype(CITIES.size) def fitness d=0 (genes + [genes[0]]).each_cons(2){|a,b| a,b=CITIES[a],CITIES[b] d += Math.sqrt( (a[0]-b[0])**2 + (a[1]-b[1])**2 ) } -d # lower distance -> higher fitness. end use EdgeRecombinationCrossover, InversionMutator end Population.new(TSP,20).evolve_on_console(50) This example finds a polynomial which approximates cos(x) class Cos < TreeGenotype([proc{3*rand-1.5},:x], [:+,:*,:-], [:-@]) def fitness -[0,0.33,0.66,1].map{|x| (eval_genes(:x=>x) - Math.cos(x)).abs }.max end use TournamentSelection(4) end Population.new(Cos).evolve_on_console(500)"
24
+ description: "== DESCRIPTION: Charlie is a library for genetic algorithms (GA) and genetic programming (GP). == FEATURES: - Quickly develop GAs by combining several parts (genotype, selection, crossover, mutation) provided by the library. - Sensible defaults are provided with any genotype, so often you only need to define a fitness function. - Easily replace any of the parts by your own code. - Test different strategies in GA, and generate reports comparing them. Example report: http://charlie.rubyforge.org/example_report.html == INSTALL: * sudo gem install charlie == EXAMPLES: This example solves a TSP problem (also quiz #142): N=5 CITIES = (0...N).map{|i| (0...N).map{|j| [i,j] } }.inject{|a,b|a+b} class TSP < PermutationGenotype(CITIES.size) def fitness d=0 (genes + [genes[0]]).each_cons(2){|a,b| a,b=CITIES[a],CITIES[b] d += Math.sqrt( (a[0]-b[0])**2 + (a[1]-b[1])**2 ) } -d # lower distance -> higher fitness. end use EdgeRecombinationCrossover, InversionMutator end Population.new(TSP,20).evolve_on_console(50) This example finds a polynomial which approximates cos(x) class Cos < TreeGenotype([proc{3*rand-1.5},:x], [:-@], [:+,:*,:-]) def fitness -[0,0.33,0.66,1].map{|x| (eval_genes(:x=>x) - Math.cos(x)).abs }.max end use TournamentSelection(4) end Population.new(Cos).evolve_on_console(500)"
25
25
  email: sander.land+ruby@gmail.com
26
26
  executables: []
27
27
 
@@ -32,6 +32,7 @@ extra_rdoc_files:
32
32
  - Manifest.txt
33
33
  - README.txt
34
34
  - TODO.txt
35
+ - examples/EXAMPLES_README.txt
35
36
  - data/GENOTYPE
36
37
  - data/SELECTION
37
38
  - data/CROSSOVER
@@ -49,35 +50,26 @@ files:
49
50
  - data/MUTATION
50
51
  - data/SELECTION
51
52
  - data/template.html
52
- - examples/bit.rb
53
- - examples/function_opt_2peak.rb
54
- - examples/function_opt_sombero.rb
55
- - examples/gladiatorial_simple.rb
56
- - examples/gladiatorial_sunburn.rb
57
- - examples/gridwalk.rb
58
- - examples/money.rb
59
- - examples/output/flattened_sombero.html
60
- - examples/output/flattened_sombero2_.html
61
- - examples/output/fopt1_dblopt.html
62
- - examples/output/hill10.html
63
- - examples/output/hill2.csv
64
- - examples/output/hill2.html
65
- - examples/output/royalroad1_report.html
66
- - examples/output/royalroad2_report.html
67
- - examples/output/royalroadquick_report.html
53
+ - examples/EXAMPLES_README.txt
54
+ - examples/bitstring.rb
55
+ - examples/coevolution.rb
56
+ - examples/function_optimization.rb
57
+ - examples/output/bitstring_royalroad.html
58
+ - examples/output/function_optimization_sombrero.html
59
+ - examples/output/function_optimization_twopeak.csv
60
+ - examples/output/function_optimization_twopeak.html
61
+ - examples/output/string_weasel.html
68
62
  - examples/output/tsp.html
69
- - examples/output/weasel1_report.html
70
- - examples/output/weasel2_report.html
71
- - examples/royalroad.rb
72
- - examples/royalroad2.rb
73
- - examples/simple_climb_hill2.rb
63
+ - examples/permutation.rb
64
+ - examples/string.rb
74
65
  - examples/tree.rb
75
66
  - examples/tsp.rb
76
- - examples/weasel.rb
77
67
  - lib/charlie.rb
68
+ - lib/charlie/1.9fixes.rb
78
69
  - lib/charlie/crossover.rb
79
70
  - lib/charlie/etc/minireport.rb
80
71
  - lib/charlie/etc/monkey.rb
72
+ - lib/charlie/gabenchmark.rb
81
73
  - lib/charlie/genotype.rb
82
74
  - lib/charlie/list/list_crossover.rb
83
75
  - lib/charlie/list/list_genotype.rb
@@ -1,10 +0,0 @@
1
- require '../lib/charlie'
2
-
3
-
4
- class Test < BitStringGenotype(10)
5
- def fitness
6
- -(genes.map(&:to_s).join.to_i(2) - 512).abs # or just to_s.to_i(2)
7
- end
8
- end
9
- Population.new(Test).evolve_on_console
10
-
@@ -1,24 +0,0 @@
1
- require '../lib/charlie'
2
-
3
- class F < FloatListGenotype(1,(0..1))
4
- def fitness
5
- x=genes.first
6
- 3.1 / (1 + (40*x-4)**2) + 2.0 / (1+(3*x-2.4)**4) # two peaks, the left one being higher but very thin.
7
- end
8
-
9
- # use TournamentSelection(4)
10
- # use NullCrossover
11
- end
12
-
13
- Population.benchmark(F,'output/fopt1_dblopt.html') {
14
- selection BestOnlySelection, TournamentSelection(3), TournamentSelection(4), Elitism(RouletteSelection,1), Elitism(ScaledRouletteSelection(),1), RouletteSelection
15
- crossover NullCrossover #, SinglePointCrossover #, UniformCrossover
16
-
17
- mt = [:probability[0.5],:probability[0.75],:probability[1.0]].map{|s|
18
- [:uniform[0.1],:uniform[0.2],:uniform[0.4],:uniform[0.8],:uniform[1.6],:gaussian[0.1],:gaussian[0.2],:gaussian[0.4],:gaussian[0.8],:gaussian[1.6]].map{|p| ListMutator(s,p) } }.flatten
19
-
20
- mutator *mt
21
- self.generations = 10
22
- self.population_size = 10
23
- self.repeat = 200
24
- } #if nil
@@ -1,38 +0,0 @@
1
- require '../lib/charlie'
2
-
3
- class Sombero < FloatListGenotype(2,(-4*Math::PI..4*Math::PI))
4
- def fitness
5
- x,y=genes
6
- 1 + ( Math.cos(Math.sqrt(x*x+y*y)) / (1+0.1*(x*x+y*y)) )
7
- end
8
-
9
- # use TournamentSelection(4)
10
- # use NullCrossover
11
- end
12
-
13
- #Population.new(Sombero,10).evolve_on_console(20)
14
-
15
- Population.benchmark(Sombero,'output/flattened_sombero.html') {
16
- selection TruncationSelection(), BestOnlySelection, TournamentSelection(4), RouletteSelection, ScaledRouletteSelection(), Elitism(RouletteSelection,1)
17
- crossover NullCrossover,UniformCrossover
18
-
19
- mt = [:expected_n[1],:expected_n[2],:expected_n[3],:expected_n[5],:single_point,:n_point[2],:n_point[3]].map{|s|
20
- [:uniform[0.1],:uniform[0.2],:uniform[0.3],:gaussian[0.1],:gaussian[0.2],:gaussian[0.3],:gaussian[0.8]].map{|p| ListMutator(s,p) } }.flatten
21
-
22
- mutator *mt
23
- self.generations = 20
24
- self.population_size = 10
25
- }
26
-
27
- Population.benchmark(Sombero,'output/flattened_sombero2_.html') {
28
- selection BestOnlySelection, TournamentSelection(3), TournamentSelection(4), Elitism(RouletteSelection,1), Elitism(ScaledRouletteSelection(),1)
29
- crossover NullCrossover, SinglePointCrossover #, UniformCrossover
30
-
31
- mt = [:expected_n[2],:expected_n[3],:expected_n[4],:expected_n[5]].map{|s|
32
- [:uniform[0.2],:uniform[0.4],:uniform[0.8],:uniform[1.6],:gaussian[0.2],:gaussian[0.4],:gaussian[0.8],:gaussian[1.6]].map{|p| ListMutator(s,p) } }.flatten
33
-
34
- mutator *mt
35
- self.generations = 15
36
- self.population_size = 10
37
- self.repeat = 50
38
- }
@@ -1,17 +0,0 @@
1
- require '../lib/charlie'
2
-
3
- class TestFighter < FloatListGenotype(2)
4
- def fight(other)
5
- genes.sum >= other.genes.sum
6
- end
7
- def to_s
8
- genes.map{|f| '%02f' % f }.join(', ')
9
- end
10
- use GladiatorialSelection
11
- use UniformCrossover
12
- use ListMutator(:expected_n[1],:gaussian[0.25])
13
- end
14
-
15
- pop = Population.new(TestFighter,10).evolve_silent(200)
16
- puts pop
17
-
@@ -1,29 +0,0 @@
1
- require '../lib/charlie'
2
-
3
- DIRS = [[-1,0],[1,0],[0,-1],[0,1]]
4
- class Walk < StringGenotype(25,DIRS) # Walk with steps in 4 directions
5
-
6
- def fitness
7
- grid = Array.new(5){Array.new(5)}
8
- x,y=0,0
9
- genes.each{|dx,dy|
10
- grid[x][y] = :visited
11
- nx,ny = x+dx,y+dy
12
- x,y=nx,ny if (0..4)===nx && (0..4)===ny && grid[nx][ny].nil? # on grid and haven't been there before
13
- }
14
- grid[x][y] = :visited
15
- grid.flatten.compact.size
16
- end
17
- def to_s; ''; end
18
-
19
- use TournamentSelection(4)
20
- #use ListMutator(:expected_n[2],:replace[*DIRS])
21
- end
22
-
23
- pop = nil
24
- begin
25
- pop = Population.new(Walk,20).evolve_silent(100)
26
- print '.'; $stdout.flush
27
- end while pop[-1].fitness != 25
28
- puts 'Found walk of length 25:', pop[-1].genes.inspect
29
-