evolvable 1.0.0 → 1.2.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.
- checksums.yaml +4 -4
- data/.yardopts +4 -0
- data/CHANGELOG.md +56 -1
- data/Gemfile +3 -0
- data/Gemfile.lock +38 -21
- data/LICENSE +21 -0
- data/README.md +234 -161
- data/README_YARD.md +237 -0
- data/bin/console +18 -5
- data/evolvable.gemspec +2 -2
- data/examples/ascii_art.rb +62 -0
- data/examples/ascii_gene.rb +9 -0
- data/examples/hello_world.rb +91 -0
- data/examples/images/diagram.png +0 -0
- data/examples/stickman.rb +77 -0
- data/exe/hello +16 -0
- data/lib/evolvable/count_gene.rb +42 -0
- data/lib/evolvable/equalize_goal.rb +29 -0
- data/lib/evolvable/evaluation.rb +29 -6
- data/lib/evolvable/evolution.rb +40 -8
- data/lib/evolvable/gene.rb +54 -2
- data/lib/evolvable/gene_combination.rb +73 -0
- data/lib/evolvable/genome.rb +86 -0
- data/lib/evolvable/goal.rb +36 -3
- data/lib/evolvable/maximize_goal.rb +30 -0
- data/lib/evolvable/minimize_goal.rb +29 -0
- data/lib/evolvable/mutation.rb +66 -15
- data/lib/evolvable/point_crossover.rb +33 -19
- data/lib/evolvable/population.rb +171 -31
- data/lib/evolvable/rigid_count_gene.rb +17 -0
- data/lib/evolvable/search_space.rb +181 -0
- data/lib/evolvable/selection.rb +28 -1
- data/lib/evolvable/serializer.rb +21 -0
- data/lib/evolvable/uniform_crossover.rb +28 -8
- data/lib/evolvable/version.rb +1 -1
- data/lib/evolvable.rb +197 -29
- metadata +38 -27
- data/.rubocop.yml +0 -20
- data/examples/evolvable_string/char_gene.rb +0 -9
- data/examples/evolvable_string.rb +0 -32
- data/lib/evolvable/gene_crossover.rb +0 -28
- data/lib/evolvable/gene_space.rb +0 -37
- data/lib/evolvable/goal/equalize.rb +0 -19
- data/lib/evolvable/goal/maximize.rb +0 -19
- data/lib/evolvable/goal/minimize.rb +0 -19
data/lib/evolvable.rb
CHANGED
@@ -4,70 +4,238 @@ require 'forwardable'
|
|
4
4
|
require 'evolvable/version'
|
5
5
|
require 'evolvable/error/undefined_method'
|
6
6
|
require 'evolvable/gene'
|
7
|
-
require 'evolvable/
|
7
|
+
require 'evolvable/search_space'
|
8
|
+
require 'evolvable/genome'
|
8
9
|
require 'evolvable/goal'
|
9
|
-
require 'evolvable/
|
10
|
-
require 'evolvable/
|
11
|
-
require 'evolvable/
|
10
|
+
require 'evolvable/equalize_goal'
|
11
|
+
require 'evolvable/maximize_goal'
|
12
|
+
require 'evolvable/minimize_goal'
|
12
13
|
require 'evolvable/evaluation'
|
13
14
|
require 'evolvable/evolution'
|
14
15
|
require 'evolvable/selection'
|
15
|
-
require 'evolvable/
|
16
|
+
require 'evolvable/gene_combination'
|
16
17
|
require 'evolvable/point_crossover'
|
17
18
|
require 'evolvable/uniform_crossover'
|
18
19
|
require 'evolvable/mutation'
|
19
20
|
require 'evolvable/population'
|
21
|
+
require 'evolvable/count_gene'
|
22
|
+
require 'evolvable/rigid_count_gene'
|
23
|
+
require 'evolvable/serializer'
|
20
24
|
|
25
|
+
#
|
26
|
+
# @readme
|
27
|
+
# The `Evolvable` module makes it possible to implement evolutionary behaviors for
|
28
|
+
# any class by defining a `.search_space` class method and `#value` instance method.
|
29
|
+
# Then to evolve instances, initialize a population with `.new_population` and invoke
|
30
|
+
# the `#evolve` method on the resulting population object.
|
31
|
+
#
|
32
|
+
# ### Implementation Steps
|
33
|
+
#
|
34
|
+
# 1. [Include the `Evolvable` module in the class you want to evolve.](https://rubydoc.info/github/mattruzicka/evolvable/Evolvable)
|
35
|
+
# 2. [Define `.search_space` and any gene classes that you reference.](https://rubydoc.info/github/mattruzicka/evolvable/Evolvable/SearchSpace)
|
36
|
+
# 3. [Define `#value`.](https://rubydoc.info/github/mattruzicka/evolvable/Evolvable/Evaluation)
|
37
|
+
# 4. [Initialize a population with `.new_population` and use `#evolve`.](https://rubydoc.info/github/mattruzicka/evolvable/Evolvable/Population)
|
38
|
+
#
|
21
39
|
module Evolvable
|
40
|
+
extend Forwardable
|
41
|
+
|
22
42
|
def self.included(base)
|
23
|
-
|
24
|
-
|
43
|
+
base.extend(ClassMethods)
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.new_object(old_val, new_val, default_class)
|
47
|
+
new_val.is_a?(Hash) ? (old_val&.class || default_class).new(**new_val) : new_val
|
48
|
+
end
|
49
|
+
|
50
|
+
module ClassMethods
|
51
|
+
#
|
52
|
+
# @readme
|
53
|
+
# Initializes a population using configurable defaults that can be configured and optimized.
|
54
|
+
# Accepts the same named parameters as
|
55
|
+
# [Population#initialize](https://rubydoc.info/github/mattruzicka/evolvable/Evolvable/Population#initialize).
|
56
|
+
#
|
57
|
+
def new_population(keyword_args = {})
|
58
|
+
keyword_args[:evolvable_type] = self
|
25
59
|
Population.new(**keyword_args)
|
26
60
|
end
|
27
61
|
|
28
|
-
|
29
|
-
|
62
|
+
#
|
63
|
+
# Initializes a new instance. Accepts a population object, an array of gene objects,
|
64
|
+
# and the instance's population index. This method is useful for re-initializing
|
65
|
+
# instances and populations that have been saved.
|
66
|
+
#
|
67
|
+
# _It is not recommended that you override this method_ as it is used by
|
68
|
+
# Evolvable internals. If you need to customize how your instances are
|
69
|
+
# initialized you can override either of the following two "initialize_instance"
|
70
|
+
# methods.
|
71
|
+
#
|
72
|
+
def new_evolvable(population: nil,
|
73
|
+
genome: Genome.new,
|
74
|
+
generation_index: nil)
|
75
|
+
evolvable = initialize_evolvable
|
30
76
|
evolvable.population = population
|
31
|
-
evolvable.
|
32
|
-
evolvable.
|
33
|
-
evolvable.
|
77
|
+
evolvable.genome = genome
|
78
|
+
evolvable.generation_index = generation_index
|
79
|
+
evolvable.after_initialize
|
34
80
|
evolvable
|
35
81
|
end
|
36
82
|
|
37
|
-
def
|
83
|
+
def initialize_evolvable
|
38
84
|
new
|
39
85
|
end
|
40
86
|
|
41
|
-
def
|
42
|
-
|
87
|
+
def new_search_space
|
88
|
+
space_config = search_space.empty? ? gene_space : search_space
|
89
|
+
search_space = SearchSpace.build(space_config, self)
|
90
|
+
search_spaces.each { |space| search_space.merge_search_space!(space) }
|
91
|
+
search_space
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# @abstract
|
96
|
+
#
|
97
|
+
# This method is responsible for configuring the available gene types
|
98
|
+
# of evolvable instances. In effect, it provides the
|
99
|
+
# blueprint for constructing a hyperdimensional genetic space that's capable
|
100
|
+
# of being used and searched by evolvable objects.
|
101
|
+
#
|
102
|
+
# Override this method with a search space config for initializing
|
103
|
+
# SearchSpace objects. The config can be a hash, array of arrays,
|
104
|
+
# or single array when there's only one type of gene.
|
105
|
+
#
|
106
|
+
# The below example definitions could conceivably be used to generate evolvable music.
|
107
|
+
#
|
108
|
+
# @todo
|
109
|
+
# Define gene config attributes - name, type, count
|
110
|
+
#
|
111
|
+
# @example Hash config
|
112
|
+
# def search_space
|
113
|
+
# { instrument: { type: InstrumentGene, count: 1..4 },
|
114
|
+
# notes: { type: NoteGene, count: 16 } }
|
115
|
+
# end
|
116
|
+
# @example Array of arrays config
|
117
|
+
# # With explicit gene names
|
118
|
+
# def search_space
|
119
|
+
# [[:instrument, InstrumentGene, 1..4],
|
120
|
+
# [:notes, NoteGene, 16]]
|
121
|
+
# end
|
122
|
+
#
|
123
|
+
# # Without explicit gene names
|
124
|
+
# def search_space
|
125
|
+
# [[SynthGene, 0..4], [RhythmGene, 0..8]]
|
126
|
+
# end
|
127
|
+
# @example Array config
|
128
|
+
# # Available when when just one type of gene
|
129
|
+
# def search_space
|
130
|
+
# [NoteGene, 1..100]
|
131
|
+
# end
|
132
|
+
#
|
133
|
+
# # With explicit gene type name.
|
134
|
+
# def search_space
|
135
|
+
# ['notes', 'NoteGene', 1..100]
|
136
|
+
# end
|
137
|
+
#
|
138
|
+
# @return [Hash, Array]
|
139
|
+
#
|
140
|
+
# @see https://github.com/mattruzicka/evolvable#search_space
|
141
|
+
#
|
142
|
+
def search_space
|
143
|
+
{}
|
144
|
+
end
|
145
|
+
|
146
|
+
#
|
147
|
+
# @abstract Override this method to define multiple search spaces
|
148
|
+
#
|
149
|
+
# @return [Array]
|
150
|
+
#
|
151
|
+
# @see https://github.com/mattruzicka/evolvable#search_space
|
152
|
+
#
|
153
|
+
def search_spaces
|
154
|
+
[]
|
43
155
|
end
|
44
156
|
|
45
|
-
|
157
|
+
# @deprecated
|
158
|
+
# Will be removed in version 2.0.
|
159
|
+
# Use {#search_space} instead.
|
160
|
+
def gene_space
|
46
161
|
{}
|
47
162
|
end
|
48
163
|
|
49
|
-
def base.before_evaluation(population); end
|
50
164
|
|
51
|
-
|
165
|
+
#
|
166
|
+
# @readme
|
167
|
+
# Runs before evaluation.
|
168
|
+
#
|
169
|
+
def before_evaluation(population); end
|
170
|
+
|
171
|
+
#
|
172
|
+
# @readme
|
173
|
+
# Runs after evaluation and before evolution.
|
174
|
+
#
|
175
|
+
# @example
|
176
|
+
# class Melody
|
177
|
+
# include Evolvable
|
178
|
+
#
|
179
|
+
# # Play the best melody from each generation
|
180
|
+
# def self.before_evolution(population)
|
181
|
+
# population.best_evolvable.play
|
182
|
+
# end
|
183
|
+
#
|
184
|
+
# # ...
|
185
|
+
# end
|
186
|
+
#
|
187
|
+
def before_evolution(population); end
|
52
188
|
|
53
|
-
|
189
|
+
#
|
190
|
+
# @readme
|
191
|
+
# Runs after evolution.
|
192
|
+
#
|
193
|
+
def after_evolution(population); end
|
54
194
|
end
|
55
195
|
|
56
|
-
|
196
|
+
# Runs an evolvable is initialized. Ueful for implementing custom initialization logic.
|
197
|
+
def after_initialize; end
|
57
198
|
|
58
|
-
|
59
|
-
|
60
|
-
|
199
|
+
#
|
200
|
+
# @!method value
|
201
|
+
# Implementing this method is required for evaluation and selection.
|
202
|
+
#
|
203
|
+
attr_accessor :id,
|
204
|
+
:population,
|
205
|
+
:genome,
|
206
|
+
:generation_index,
|
207
|
+
:value
|
61
208
|
|
62
|
-
|
63
|
-
|
209
|
+
#
|
210
|
+
# @deprecated
|
211
|
+
# Will be removed in version 2.0.
|
212
|
+
# Use {#generation_index} instead.
|
213
|
+
#
|
214
|
+
def population_index
|
215
|
+
generation_index
|
64
216
|
end
|
65
217
|
|
66
|
-
|
67
|
-
|
218
|
+
#
|
219
|
+
# @!method find_gene
|
220
|
+
# @see Genome#find_gene
|
221
|
+
# @!method find_genes
|
222
|
+
# @see Genome#find_genes
|
223
|
+
# @!method find_genes_count
|
224
|
+
# @see Genome#find_genes_count
|
225
|
+
# @!method genes
|
226
|
+
# @see Genome#genes
|
227
|
+
#
|
228
|
+
def_delegators :genome,
|
229
|
+
:find_gene,
|
230
|
+
:find_genes,
|
231
|
+
:find_genes_count,
|
232
|
+
:genes
|
233
|
+
|
234
|
+
def dump_genome(serializer: Serializer)
|
235
|
+
@genome.dump(serializer: serializer)
|
68
236
|
end
|
69
237
|
|
70
|
-
def
|
71
|
-
@
|
238
|
+
def load_genome(data, serializer: Serializer)
|
239
|
+
@genome = Genome.load(data, serializer: serializer)
|
72
240
|
end
|
73
241
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: evolvable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Ruzicka
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -25,65 +25,76 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: readme_yard
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: yard
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0
|
47
|
+
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0
|
55
|
-
description:
|
56
|
-
email:
|
57
|
-
executables:
|
54
|
+
version: '0'
|
55
|
+
description:
|
56
|
+
email:
|
57
|
+
executables:
|
58
|
+
- hello
|
58
59
|
extensions: []
|
59
60
|
extra_rdoc_files: []
|
60
61
|
files:
|
61
62
|
- ".gitignore"
|
62
|
-
- ".
|
63
|
+
- ".yardopts"
|
63
64
|
- CHANGELOG.md
|
64
65
|
- Gemfile
|
65
66
|
- Gemfile.lock
|
67
|
+
- LICENSE
|
66
68
|
- README.md
|
69
|
+
- README_YARD.md
|
67
70
|
- bin/console
|
68
71
|
- bin/setup
|
69
72
|
- evolvable.gemspec
|
70
|
-
- examples/
|
71
|
-
- examples/
|
73
|
+
- examples/ascii_art.rb
|
74
|
+
- examples/ascii_gene.rb
|
75
|
+
- examples/hello_world.rb
|
76
|
+
- examples/images/diagram.png
|
77
|
+
- examples/stickman.rb
|
78
|
+
- exe/hello
|
72
79
|
- lib/evolvable.rb
|
80
|
+
- lib/evolvable/count_gene.rb
|
81
|
+
- lib/evolvable/equalize_goal.rb
|
73
82
|
- lib/evolvable/error/undefined_method.rb
|
74
83
|
- lib/evolvable/evaluation.rb
|
75
84
|
- lib/evolvable/evolution.rb
|
76
85
|
- lib/evolvable/gene.rb
|
77
|
-
- lib/evolvable/
|
78
|
-
- lib/evolvable/
|
86
|
+
- lib/evolvable/gene_combination.rb
|
87
|
+
- lib/evolvable/genome.rb
|
79
88
|
- lib/evolvable/goal.rb
|
80
|
-
- lib/evolvable/
|
81
|
-
- lib/evolvable/
|
82
|
-
- lib/evolvable/goal/minimize.rb
|
89
|
+
- lib/evolvable/maximize_goal.rb
|
90
|
+
- lib/evolvable/minimize_goal.rb
|
83
91
|
- lib/evolvable/mutation.rb
|
84
92
|
- lib/evolvable/point_crossover.rb
|
85
93
|
- lib/evolvable/population.rb
|
94
|
+
- lib/evolvable/rigid_count_gene.rb
|
95
|
+
- lib/evolvable/search_space.rb
|
86
96
|
- lib/evolvable/selection.rb
|
97
|
+
- lib/evolvable/serializer.rb
|
87
98
|
- lib/evolvable/uniform_crossover.rb
|
88
99
|
- lib/evolvable/version.rb
|
89
100
|
homepage: https://github.com/mattruzicka/evolvable
|
@@ -93,7 +104,7 @@ metadata:
|
|
93
104
|
homepage_uri: https://github.com/mattruzicka/evolvable
|
94
105
|
source_code_uri: https://github.com/mattruzicka/evolvable
|
95
106
|
changelog_uri: https://github.com/mattruzicka/evolvable/blob/master/CHANGELOG.md
|
96
|
-
post_install_message:
|
107
|
+
post_install_message:
|
97
108
|
rdoc_options: []
|
98
109
|
require_paths:
|
99
110
|
- lib
|
@@ -108,8 +119,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
119
|
- !ruby/object:Gem::Version
|
109
120
|
version: '0'
|
110
121
|
requirements: []
|
111
|
-
rubygems_version: 3.
|
112
|
-
signing_key:
|
122
|
+
rubygems_version: 3.3.3
|
123
|
+
signing_key:
|
113
124
|
specification_version: 4
|
114
125
|
summary: Add evolutionary behavior to any Ruby object
|
115
126
|
test_files: []
|
data/.rubocop.yml
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
AllCops:
|
2
|
-
TargetRubyVersion: 2.6.1
|
3
|
-
|
4
|
-
Style/Documentation:
|
5
|
-
Enabled: false
|
6
|
-
|
7
|
-
Style/SymbolArray:
|
8
|
-
Enabled: false
|
9
|
-
|
10
|
-
Style/FrozenStringLiteralComment:
|
11
|
-
Enabled: false
|
12
|
-
|
13
|
-
Style/ClassAndModuleChildren:
|
14
|
-
Enabled: false
|
15
|
-
|
16
|
-
Naming/VariableNumber:
|
17
|
-
EnforcedStyle: 'snake_case'
|
18
|
-
|
19
|
-
Metrics/LineLength:
|
20
|
-
Max: 90
|
@@ -1,32 +0,0 @@
|
|
1
|
-
require './examples/evolvable_string/char_gene'
|
2
|
-
|
3
|
-
class EvolvableString
|
4
|
-
include Evolvable
|
5
|
-
|
6
|
-
TARGET_STRING = 'supercalifragilisticexpialidocious'
|
7
|
-
|
8
|
-
def self.gene_space
|
9
|
-
{ char_genes: { type: 'CharGene', count: TARGET_STRING.length } }
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.before_evolution(population)
|
13
|
-
best_instance = population.best_instance
|
14
|
-
puts "#{best_instance} | #{best_instance.value} matches | Generation #{population.evolutions_count}"
|
15
|
-
end
|
16
|
-
|
17
|
-
def to_s
|
18
|
-
find_genes(:char_genes).join
|
19
|
-
end
|
20
|
-
|
21
|
-
def value
|
22
|
-
@value ||= compute_value
|
23
|
-
end
|
24
|
-
|
25
|
-
def compute_value
|
26
|
-
value = 0
|
27
|
-
find_genes(:char_genes).each_with_index do |gene, index|
|
28
|
-
value += 1 if gene.to_s == TARGET_STRING[index]
|
29
|
-
end
|
30
|
-
value
|
31
|
-
end
|
32
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Evolvable
|
4
|
-
class GeneCrossover
|
5
|
-
def call(population)
|
6
|
-
population.instances = initialize_offspring(population)
|
7
|
-
population
|
8
|
-
end
|
9
|
-
|
10
|
-
private
|
11
|
-
|
12
|
-
def initialize_offspring(population)
|
13
|
-
parent_genes = population.instances.map!(&:genes)
|
14
|
-
parent_gene_couples = parent_genes.combination(2).cycle
|
15
|
-
Array.new(population.size) do |index|
|
16
|
-
genes_1, genes_2 = parent_gene_couples.next
|
17
|
-
genes = crossover_genes(genes_1, genes_2)
|
18
|
-
population.new_instance(genes: genes, population_index: index)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def crossover_genes(genes_1, genes_2)
|
23
|
-
genes_1.zip(genes_2).map! do |gene_a, gene_b|
|
24
|
-
gene_a.class.crossover(gene_a, gene_b)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
data/lib/evolvable/gene_space.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Evolvable
|
4
|
-
class GeneSpace
|
5
|
-
def self.build(config)
|
6
|
-
return config if config.respond_to?(:new_genes)
|
7
|
-
|
8
|
-
new(config: config)
|
9
|
-
end
|
10
|
-
|
11
|
-
def initialize(config: {})
|
12
|
-
@config = normalize_config(config)
|
13
|
-
end
|
14
|
-
|
15
|
-
attr_reader :config
|
16
|
-
|
17
|
-
def new_genes
|
18
|
-
genes = []
|
19
|
-
config.each do |gene_key, gene_config|
|
20
|
-
(gene_config[:count] || 1).times do
|
21
|
-
gene = gene_config[:class].new
|
22
|
-
gene.key = gene_key
|
23
|
-
genes << gene
|
24
|
-
end
|
25
|
-
end
|
26
|
-
genes
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def normalize_config(config)
|
32
|
-
config.each do |_gene_key, gene_config|
|
33
|
-
gene_config[:class] = Kernel.const_get(gene_config[:type]) if gene_config[:type]
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Evolvable::Goal
|
4
|
-
class Equalize
|
5
|
-
include Evolvable::Goal
|
6
|
-
|
7
|
-
def value
|
8
|
-
@value ||= 0
|
9
|
-
end
|
10
|
-
|
11
|
-
def evaluate(instance)
|
12
|
-
-(instance.value - value).abs
|
13
|
-
end
|
14
|
-
|
15
|
-
def met?(instance)
|
16
|
-
instance.value == value
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Evolvable::Goal
|
4
|
-
class Maximize
|
5
|
-
include Evolvable::Goal
|
6
|
-
|
7
|
-
def value
|
8
|
-
@value ||= Float::INFINITY
|
9
|
-
end
|
10
|
-
|
11
|
-
def evaluate(instance)
|
12
|
-
instance.value
|
13
|
-
end
|
14
|
-
|
15
|
-
def met?(instance)
|
16
|
-
instance.value >= value
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Evolvable::Goal
|
4
|
-
class Minimize
|
5
|
-
include Evolvable::Goal
|
6
|
-
|
7
|
-
def value
|
8
|
-
@value ||= -Float::INFINITY
|
9
|
-
end
|
10
|
-
|
11
|
-
def evaluate(instance)
|
12
|
-
-instance.value
|
13
|
-
end
|
14
|
-
|
15
|
-
def met?(instance)
|
16
|
-
instance.value <= value
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|