evolvable 1.2.0 → 2.0.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 (79) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -0
  3. data/CHANGELOG.md +24 -0
  4. data/Gemfile +2 -2
  5. data/Gemfile.lock +44 -25
  6. data/README.md +498 -190
  7. data/README_YARD.md +85 -166
  8. data/bin/console +10 -19
  9. data/docs/Evolvable/ClassMethods.html +1233 -0
  10. data/docs/Evolvable/Community/ClassMethods.html +708 -0
  11. data/docs/Evolvable/Community.html +1342 -0
  12. data/docs/Evolvable/CountGene.html +886 -0
  13. data/docs/Evolvable/EqualizeGoal.html +347 -0
  14. data/docs/Evolvable/Error.html +134 -0
  15. data/docs/Evolvable/Evaluation.html +773 -0
  16. data/docs/Evolvable/Evolution.html +616 -0
  17. data/docs/Evolvable/Gene/ClassMethods.html +413 -0
  18. data/docs/Evolvable/Gene.html +522 -0
  19. data/docs/Evolvable/GeneCluster/ClassMethods.html +431 -0
  20. data/docs/Evolvable/GeneCluster.html +280 -0
  21. data/docs/Evolvable/GeneCombination.html +515 -0
  22. data/docs/Evolvable/GeneSpace.html +619 -0
  23. data/docs/Evolvable/Genome.html +1070 -0
  24. data/docs/Evolvable/Goal.html +500 -0
  25. data/docs/Evolvable/MaximizeGoal.html +348 -0
  26. data/docs/Evolvable/MinimizeGoal.html +348 -0
  27. data/docs/Evolvable/Mutation.html +729 -0
  28. data/docs/Evolvable/PointCrossover.html +444 -0
  29. data/docs/Evolvable/Population.html +2826 -0
  30. data/docs/Evolvable/RigidCountGene.html +501 -0
  31. data/docs/Evolvable/Selection.html +594 -0
  32. data/docs/Evolvable/Serializer.html +293 -0
  33. data/docs/Evolvable/UniformCrossover.html +286 -0
  34. data/docs/Evolvable.html +1619 -0
  35. data/docs/_index.html +341 -0
  36. data/docs/class_list.html +54 -0
  37. data/docs/css/common.css +1 -0
  38. data/docs/css/full_list.css +58 -0
  39. data/docs/css/style.css +503 -0
  40. data/docs/file.README.html +750 -0
  41. data/docs/file_list.html +59 -0
  42. data/docs/frames.html +22 -0
  43. data/docs/index.html +750 -0
  44. data/docs/js/app.js +344 -0
  45. data/docs/js/full_list.js +242 -0
  46. data/docs/js/jquery.js +4 -0
  47. data/docs/method_list.html +1302 -0
  48. data/docs/top-level-namespace.html +110 -0
  49. data/evolvable.gemspec +6 -6
  50. data/examples/ascii_art.rb +5 -9
  51. data/examples/stickman.rb +25 -33
  52. data/{examples/hello_world.rb → exe/hello_evolvable_world} +46 -30
  53. data/lib/evolvable/community.rb +190 -0
  54. data/lib/evolvable/count_gene.rb +65 -0
  55. data/lib/evolvable/equalize_goal.rb +2 -9
  56. data/lib/evolvable/evaluation.rb +113 -14
  57. data/lib/evolvable/evolution.rb +38 -15
  58. data/lib/evolvable/gene.rb +124 -25
  59. data/lib/evolvable/gene_cluster.rb +106 -0
  60. data/lib/evolvable/gene_combination.rb +57 -16
  61. data/lib/evolvable/gene_space.rb +111 -0
  62. data/lib/evolvable/genome.rb +32 -4
  63. data/lib/evolvable/goal.rb +19 -24
  64. data/lib/evolvable/maximize_goal.rb +2 -9
  65. data/lib/evolvable/minimize_goal.rb +3 -9
  66. data/lib/evolvable/mutation.rb +87 -41
  67. data/lib/evolvable/point_crossover.rb +24 -4
  68. data/lib/evolvable/population.rb +258 -84
  69. data/lib/evolvable/rigid_count_gene.rb +36 -0
  70. data/lib/evolvable/selection.rb +68 -14
  71. data/lib/evolvable/serializer.rb +46 -0
  72. data/lib/evolvable/uniform_crossover.rb +30 -6
  73. data/lib/evolvable/version.rb +2 -1
  74. data/lib/evolvable.rb +268 -107
  75. metadata +57 -36
  76. data/examples/images/diagram.png +0 -0
  77. data/exe/hello +0 -16
  78. data/lib/evolvable/error/undefined_method.rb +0 -7
  79. data/lib/evolvable/search_space.rb +0 -181
metadata CHANGED
@@ -1,61 +1,44 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: evolvable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Ruzicka
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2022-01-22 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
- name: bundler
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '2.0'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '2.0'
27
- - !ruby/object:Gem::Dependency
28
- name: readme_yard
13
+ name: irb
29
14
  requirement: !ruby/object:Gem::Requirement
30
15
  requirements:
31
16
  - - ">="
32
17
  - !ruby/object:Gem::Version
33
- version: '0'
18
+ version: '1.0'
34
19
  type: :development
35
20
  prerelease: false
36
21
  version_requirements: !ruby/object:Gem::Requirement
37
22
  requirements:
38
23
  - - ">="
39
24
  - !ruby/object:Gem::Version
40
- version: '0'
25
+ version: '1.0'
41
26
  - !ruby/object:Gem::Dependency
42
- name: yard
27
+ name: readme_yard
43
28
  requirement: !ruby/object:Gem::Requirement
44
29
  requirements:
45
30
  - - ">="
46
31
  - !ruby/object:Gem::Version
47
- version: '0'
32
+ version: '0.5'
48
33
  type: :development
49
34
  prerelease: false
50
35
  version_requirements: !ruby/object:Gem::Requirement
51
36
  requirements:
52
37
  - - ">="
53
38
  - !ruby/object:Gem::Version
54
- version: '0'
55
- description:
56
- email:
39
+ version: '0.5'
57
40
  executables:
58
- - hello
41
+ - hello_evolvable_world
59
42
  extensions: []
60
43
  extra_rdoc_files: []
61
44
  files:
@@ -69,21 +52,61 @@ files:
69
52
  - README_YARD.md
70
53
  - bin/console
71
54
  - bin/setup
55
+ - docs/Evolvable.html
56
+ - docs/Evolvable/ClassMethods.html
57
+ - docs/Evolvable/Community.html
58
+ - docs/Evolvable/Community/ClassMethods.html
59
+ - docs/Evolvable/CountGene.html
60
+ - docs/Evolvable/EqualizeGoal.html
61
+ - docs/Evolvable/Error.html
62
+ - docs/Evolvable/Evaluation.html
63
+ - docs/Evolvable/Evolution.html
64
+ - docs/Evolvable/Gene.html
65
+ - docs/Evolvable/Gene/ClassMethods.html
66
+ - docs/Evolvable/GeneCluster.html
67
+ - docs/Evolvable/GeneCluster/ClassMethods.html
68
+ - docs/Evolvable/GeneCombination.html
69
+ - docs/Evolvable/GeneSpace.html
70
+ - docs/Evolvable/Genome.html
71
+ - docs/Evolvable/Goal.html
72
+ - docs/Evolvable/MaximizeGoal.html
73
+ - docs/Evolvable/MinimizeGoal.html
74
+ - docs/Evolvable/Mutation.html
75
+ - docs/Evolvable/PointCrossover.html
76
+ - docs/Evolvable/Population.html
77
+ - docs/Evolvable/RigidCountGene.html
78
+ - docs/Evolvable/Selection.html
79
+ - docs/Evolvable/Serializer.html
80
+ - docs/Evolvable/UniformCrossover.html
81
+ - docs/_index.html
82
+ - docs/class_list.html
83
+ - docs/css/common.css
84
+ - docs/css/full_list.css
85
+ - docs/css/style.css
86
+ - docs/file.README.html
87
+ - docs/file_list.html
88
+ - docs/frames.html
89
+ - docs/index.html
90
+ - docs/js/app.js
91
+ - docs/js/full_list.js
92
+ - docs/js/jquery.js
93
+ - docs/method_list.html
94
+ - docs/top-level-namespace.html
72
95
  - evolvable.gemspec
73
96
  - examples/ascii_art.rb
74
97
  - examples/ascii_gene.rb
75
- - examples/hello_world.rb
76
- - examples/images/diagram.png
77
98
  - examples/stickman.rb
78
- - exe/hello
99
+ - exe/hello_evolvable_world
79
100
  - lib/evolvable.rb
101
+ - lib/evolvable/community.rb
80
102
  - lib/evolvable/count_gene.rb
81
103
  - lib/evolvable/equalize_goal.rb
82
- - lib/evolvable/error/undefined_method.rb
83
104
  - lib/evolvable/evaluation.rb
84
105
  - lib/evolvable/evolution.rb
85
106
  - lib/evolvable/gene.rb
107
+ - lib/evolvable/gene_cluster.rb
86
108
  - lib/evolvable/gene_combination.rb
109
+ - lib/evolvable/gene_space.rb
87
110
  - lib/evolvable/genome.rb
88
111
  - lib/evolvable/goal.rb
89
112
  - lib/evolvable/maximize_goal.rb
@@ -92,7 +115,6 @@ files:
92
115
  - lib/evolvable/point_crossover.rb
93
116
  - lib/evolvable/population.rb
94
117
  - lib/evolvable/rigid_count_gene.rb
95
- - lib/evolvable/search_space.rb
96
118
  - lib/evolvable/selection.rb
97
119
  - lib/evolvable/serializer.rb
98
120
  - lib/evolvable/uniform_crossover.rb
@@ -103,8 +125,8 @@ licenses:
103
125
  metadata:
104
126
  homepage_uri: https://github.com/mattruzicka/evolvable
105
127
  source_code_uri: https://github.com/mattruzicka/evolvable
106
- changelog_uri: https://github.com/mattruzicka/evolvable/blob/master/CHANGELOG.md
107
- post_install_message:
128
+ changelog_uri: https://github.com/mattruzicka/evolvable/blob/main/CHANGELOG.md
129
+ documentation_uri: https://mattruzicka.github.io/evolvable
108
130
  rdoc_options: []
109
131
  require_paths:
110
132
  - lib
@@ -112,15 +134,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
112
134
  requirements:
113
135
  - - ">="
114
136
  - !ruby/object:Gem::Version
115
- version: '0'
137
+ version: '2.6'
116
138
  required_rubygems_version: !ruby/object:Gem::Requirement
117
139
  requirements:
118
140
  - - ">="
119
141
  - !ruby/object:Gem::Version
120
142
  version: '0'
121
143
  requirements: []
122
- rubygems_version: 3.3.3
123
- signing_key:
144
+ rubygems_version: 3.6.8
124
145
  specification_version: 4
125
146
  summary: Add evolutionary behavior to any Ruby object
126
147
  test_files: []
Binary file
data/exe/hello DELETED
@@ -1,16 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'bundler/setup'
4
- require 'evolvable'
5
- require 'byebug'
6
-
7
- Dir['./examples/*.rb'].each { |f| require f }
8
-
9
- population = HelloWorld.new_population(size: 100,
10
- evaluation: { equalize: 0 },
11
- mutation: { probability: 0.6 })
12
- population.evolve
13
- HelloWorld.start_loop(population)
14
-
15
- require 'irb'
16
- IRB.start(__FILE__)
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Evolvable
4
- module Errors
5
- class UndefinedMethod < StandardError; end
6
- end
7
- end
@@ -1,181 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Evolvable
4
- #
5
- # @readme
6
- # The search space encapsulates the range of possible genes
7
- # for a particular evolvable. You can think of it as the boundaries of
8
- # genetic variation. It is configured via the
9
- # [.search_space](#evolvableclasssearch_space) method that you define
10
- # on your evolvable class. It's used by populations to initialize
11
- # new evolvables.
12
- #
13
- # Evolvable provides flexibility in how you define your search space.
14
- # The below example implementations for `.search_space` produce the
15
- # exact same search space for the
16
- # [Hello World](https://github.com/mattruzicka/evolvable#hello-world)
17
- # demo program. The different styles arguably vary in suitability for
18
- # different contexts, perhaps depending on how programs are loaded and
19
- # the number of different gene types.
20
- #
21
- # @example
22
- # # All 9 of these example definitions are equivalent
23
- #
24
- # # Hash syntax
25
- # { chars: { type: 'CharGene', max_count: 100 } }
26
- # { chars: { type: 'CharGene', min_count: 1, max_count: 100 } }
27
- # { chars: { type: 'CharGene', count: 1..100 } }
28
- #
29
- # # Array of arrays syntax
30
- # [[:chars, 'CharGene', 1..100]]
31
- # [['chars', 'CharGene', 1..100]]
32
- # [['CharGene', 1..100]]
33
- #
34
- # # A single array works when there's only one type of gene
35
- # ['CharGene', 1..100]
36
- # [:chars, 'CharGene', 1..100]
37
- # ['chars', 'CharGene', 1..100]
38
- #
39
- #
40
-
41
- class SearchSpace
42
- class << self
43
- def build(config, evolvable_class = nil)
44
- if config.is_a?(SearchSpace)
45
- config.evolvable_class = evolvable_class if evolvable_class
46
- config
47
- else
48
- new(config: config, evolvable_class: evolvable_class)
49
- end
50
- end
51
- end
52
-
53
- def initialize(config: {}, evolvable_class: nil)
54
- @evolvable_class = evolvable_class
55
- @config = normalize_config(config)
56
- end
57
-
58
- attr_accessor :evolvable_class, :config
59
-
60
- def new_genome
61
- Genome.new(config: new_genome_config)
62
- end
63
-
64
- def merge_search_space(val)
65
- val = val.config if val.is_a?(self.class)
66
- @config.merge normalize_config(val)
67
- end
68
-
69
- def merge_search_space!(val)
70
- val = val.config if val.is_a?(self.class)
71
- @config.merge! normalize_config(val)
72
- end
73
-
74
- private
75
-
76
- def normalize_config(config)
77
- case config
78
- when Hash
79
- normalize_hash_config(config)
80
- when Array
81
- if config.first.is_a?(Array)
82
- build_config_from_2d_array(config)
83
- else
84
- merge_config_with_array({}, config)
85
- end
86
- end
87
- end
88
-
89
- def normalize_hash_config(config)
90
- config.each do |gene_key, gene_config|
91
- next unless gene_config[:type]
92
-
93
- gene_class = lookup_gene_class(gene_config[:type])
94
- gene_class.key = gene_key
95
- gene_config[:class] = gene_class
96
- end
97
- end
98
-
99
- def build_config_from_2d_array(array_config)
100
- config = {}
101
- array_config.each { |array| merge_config_with_array(config, array) }
102
- config
103
- end
104
-
105
- def merge_config_with_array(config, gene_array)
106
- gene_key, gene_class, count = extract_array_configs(gene_array)
107
- gene_class.key = gene_key
108
- config[gene_key] = { class: gene_class, count: count }
109
- config
110
- end
111
-
112
- def extract_array_configs(gene_array)
113
- first_item = gene_array.first
114
- return extract_array_with_key_configs(gene_array) if first_item.is_a?(Symbol)
115
-
116
- gene_class = lookup_gene_class(first_item)
117
- _type, count = gene_array
118
- [gene_class, gene_class, count]
119
- rescue NameError
120
- extract_array_with_key_configs(gene_array)
121
- end
122
-
123
- def extract_array_with_key_configs(gene_array)
124
- gene_key, type, count = gene_array
125
- gene_class = lookup_gene_class(type)
126
- [gene_key, gene_class, count]
127
- end
128
-
129
- def lookup_gene_class(class_name)
130
- return class_name if class_name.is_a?(Class)
131
-
132
- (@evolvable_class || Object).const_get(class_name)
133
- end
134
-
135
- def new_genome_config
136
- genome_config = {}
137
- config.each do |gene_key, gene_config|
138
- genome_config[gene_key] = new_gene_config(gene_config)
139
- end
140
- genome_config
141
- end
142
-
143
- def new_gene_config(gene_config)
144
- count_gene = init_count_gene(gene_config)
145
- gene_class = gene_config[:class]
146
- genes = Array.new(count_gene.count) { gene_class.new }
147
- { count_gene: count_gene, genes: genes }
148
- end
149
-
150
- def init_count_gene(gene_config)
151
- min = gene_config[:min_count]
152
- max = gene_config[:max_count]
153
- return init_min_max_count_gene(min, max) if min || max
154
-
155
- count = gene_config[:count] || 1
156
- case count
157
- when Numeric
158
- RigidCountGene.new(count)
159
- when Range
160
- CountGene.new(range: count)
161
- when String
162
- Kernel.const_get(gene_config[:count]).new
163
- when Class
164
- gene_config[:count].new
165
- end
166
- end
167
-
168
- def init_min_max_count_gene(min, max)
169
- min ||= 1
170
- max ||= min * 10
171
- CountGene.new(range: min..max)
172
- end
173
- end
174
-
175
- #
176
- # @deprecated
177
- # Will be removed in 2.0
178
- # use {SearchSpace} instead
179
- #
180
- class GeneSpace < SearchSpace; end
181
- end