evolvable 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f1a067e6b2b71bbbfb1ddd936a14401262a6ec59dce36305500fcabebcde47e
4
- data.tar.gz: 943d7a9efe2f50a387efac9f3f48115beacc0a9550d6ec14f0765f4a17d4e2a4
3
+ metadata.gz: e9b226220f12cc98cfd94f14caf0f3898f0b1dab435bc4e8ce58696c053c8ea8
4
+ data.tar.gz: d8f03fb093698fd25c24ee0038e813832caba6c80a802933c0d3cc97125e96b6
5
5
  SHA512:
6
- metadata.gz: 64db467632fdfedbc7671229a80e8bad20ac8c5495ec731ec1111991bdbf50616e12091886c142fc44eaac5de1a5c4073e1c5f1ff8e5a304bc6272632e85411f
7
- data.tar.gz: 3d8fd1aee8c638e521e6d5535cb3f00a5ca85064dec909790827dffad21ec9d9a13658b99d1ec0078e61d113356c2b950caefa84ffd86737f42f4ed8d71ee2a9
6
+ metadata.gz: d25f4af589b828b4791c52b469e91f5814e5e06f372a331f4214cbfab6daf8d74dd2f7db777e6117c9b97fb04e55c9f007a612d31b6fba7b253784117df4edca
7
+ data.tar.gz: ad7d7a46306d20512d199dc32eb688c0c2e8f03ff86358a9ef17e8f9e868117f40ebf5fe4cbafedf8ad843b8a055e722b1781bf145feaa9e51369889ee3131a5
@@ -1,4 +1,8 @@
1
- # Release 1.0.0
1
+ ## 1.0.1
2
+
3
+ Fix goal normalization in `Evolvable::Evaluation` when given an object
4
+
5
+ ## 1.0.0
2
6
 
3
7
  Hello 🌎 🌍 🌏
4
8
 
data/README.md CHANGED
@@ -7,9 +7,7 @@ A framework for building evolutionary behaviors in Ruby.
7
7
  With a straightforward and extensible API, Evolvable aims to make building simple as well as complex evolutionary algorithms fun and relatively easy.
8
8
 
9
9
  ### The Evolvable Abstraction
10
- Population objects are composed of instances that include the `Evolvable` module. Instances are composed of gene objects that include the `Evolvable::Gene` module. Evaluation and evolution objects are used by population objects to evolve your instances. An evaluation object has one goal object and the evolution object is composed of selection, crossover, and mutation objects by default.
11
-
12
- All classes exposed by Evolvable are prefixed with `Evolvable::` and can be configured, inherited, removed, and extended. You can also choose between various Evolvable implementations documented below or substitute your own. Don't worry if none of this made sense, this will become clearer as you continue reading.
10
+ Population objects are composed of instances that include the `Evolvable` module. Instances are composed of gene objects that include the `Evolvable::Gene` module. Evaluation and evolution objects are used by population objects to evolve your instances. An evaluation object has one goal object and the evolution object is composed of selection, crossover, and mutation objects by default. All classes exposed by Evolvable are prefixed with `Evolvable::` and can be configured, inherited, removed, and extended.
13
11
 
14
12
  ## Installation
15
13
 
@@ -21,22 +19,22 @@ After installing and requiring the "evolvable" Ruby gem:
21
19
 
22
20
  1. Include the `Evolvable` module in the class for the instances you want to evolve. (See [Configuration](#Configuration)).
23
21
  2. Implement `.gene_space`, define any gene classes referenced by it, and include the `Evolvable::Gene` module for each. (See [Genes](#Genes)).
24
- 3. Implement `#value`. (See [Evaluation](#Evaluation)).
22
+ 3. Implement `#value`. (See [Evaluation](#evaluation-1)).
25
23
  4. Initialize a population and start evolving. (See [Populations](#Populations)).
26
24
 
27
- Visit the [Evolvable Strings Tutorial](https://github.com/mattruzicka/evolvable/wiki/Evolvable-Strings-Tutorial) to see these steps in action. It walks through a simplified implementation of the [evolve string](https://github.com/mattruzicka/evolve_string) command-line program. Here's the [example source code](https://github.com/mattruzicka/evolvable/blob/master/examples/evolvable_string.rb) for the tutorial.
25
+ Visit the [Evolving Strings](https://github.com/mattruzicka/evolvable/wiki/Evolving-Strings) tutorial to see these steps in action. It walks through a simplified implementation of the [evolve string](https://github.com/mattruzicka/evolve_string) command-line program. Here's the [example source code](https://github.com/mattruzicka/evolvable/blob/master/examples/evolvable_string.rb) for the tutorial.
28
26
 
29
27
  If you’d like to quickly play around with an evolvable string Population object, you can do so by cloning this repo and running the command `bin/console` in this project's directory.
30
28
 
31
29
  ## Usage
32
30
  - [Configuration](#Configuration)
33
31
  - [Genes](#Genes)
34
- - [Evaluation](#Evaluation)
35
32
  - [Populations](#Populations)
36
- - [Evolution](#Evolution)
37
- - [Selection](#Selection)
33
+ - [Evaluation](#evaluation-1)
34
+ - [Evolution](#evolution-1)
35
+ - [Selection](#selection-1)
38
36
  - [Crossover](#Crossover)
39
- - [Mutation](#Mutation)
37
+ - [Mutation](#mutation-1)
40
38
 
41
39
  ## Configuration
42
40
 
@@ -47,83 +45,73 @@ class Melody
47
45
  include Evolvable
48
46
 
49
47
  def self.gene_space
50
- # Expected
48
+ { instrument: { type: 'InstrumentGene', count: 1 },
49
+ notes: { type: 'NoteGene', count: 16 } }
51
50
  end
52
51
 
53
52
  def value
54
- # Required
53
+ average_rating # ...
55
54
  end
56
55
  end
57
56
  ```
58
57
 
59
- The `Evolvable` module exposes the following class and instance methods for you.
60
-
61
- #### .gene_space
58
+ The `Evolvable` module expects the [".gene_space" class method](#evolvableclassgene_space) and requires the ["#value" instance method](#evolvableclassvalue) to be defined as documented below. Other methods exposed by `Evolvable` have also been documented below.
62
59
 
63
- You're expected to override this and return a gene space configuration hash or GeneSpace object.
60
+ ### EvolvableClass.gene_space
64
61
 
65
- Here's a sample definition for the melody class defined above. It configures each instance to have 16 note genes and 1 instrument gene.
66
-
67
- ```ruby
68
- def self.gene_space
69
- { instrument: { type: 'InstrumentGene', count: 1 },
70
- notes: { type: 'NoteGene', count: 16 } }
71
- end
72
- ```
62
+ You're expected to override this and return a gene space configuration hash or GeneSpace object. It defines the mapping for a hyperdimensional "gene space" so to speak. The above sample definition for the melody class configures each instance to have 16 note genes and 1 instrument gene.
73
63
 
74
64
  See the section on [Genes](#genes) for more details.
75
65
 
76
- #### .new_population(keyword_args = {})
66
+ ### EvolvableClass.new_population(keyword_args = {})
77
67
 
78
68
  Initializes a new population. Example: `population = Melody.new_population(size: 100)`
79
69
 
80
- Accepts the same arguments as `Population.new`
81
-
82
- #### .new_instance(population: nil, genes: [], population_index: nil)
70
+ Accepts the same arguments as [Population.new](#evolvablepopulationnew)
83
71
 
84
- Initializes a new instance. Accepts a population object, an array of gene objects, and the instance's population index.
72
+ ### EvolvableClass.new_instance(population: nil, genes: [], population_index: nil)
85
73
 
86
- This method is useful for re-initializing instances and populations that have been saved.
74
+ Initializes a new instance. Accepts a population object, an array of gene objects, and the instance's population index. This method is useful for re-initializing instances and populations that have been saved.
87
75
 
88
76
  _It is not recommended that you override this method_ as it is used by Evolvable internals. If you need to customize how your instances are initialized you can override either of the following two "initialize_instance" methods.
89
77
 
90
- #### .initialize_instance
78
+ ### EvolvableClass.initialize_instance
91
79
 
92
80
  The default implementation simply delegates to `.new` and is useful for instances with custom initialize methods.
93
81
 
94
- #### #initialize_instance
82
+ ### EvolvableClass#initialize_instance
95
83
 
96
84
  Runs after Evolvable finishes building your instance. It's useful for stuff like implementing custom gene initialization logic. For example, the Evolvable Strings web demo (coming soon) uses it to read from a "length gene" and add or remove "char genes" accordingly.
97
85
 
98
- #### #population, #population=
86
+ ### EvolvableClass#population, #population=
99
87
 
100
88
  The population object being used to evolve this instance.
101
89
 
102
- #### #genes, #genes=
90
+ ### EvolvableClass#genes, #genes=
103
91
 
104
92
  An array of all an instance's genes. You can find specific types of genes with the following two methods.
105
93
 
106
- #### #find_genes(key)
94
+ ### EvolvableClass#find_genes(key)
107
95
 
108
- Returns an array of genes that have the given key. Gene keys are defined in the [.gene_space](####.gene_space) method. In the Melody example above, the key for the note genes would be `:notes`. The following would return an array of them: `note_genes = melody.find_genes(:notes)`
96
+ Returns an array of genes that have the given key. Gene keys are defined in the [EvolvableClass.gene_space](#evolvableclassgene_space) method. In the Melody example above, the key for the note genes would be `:notes`. The following would return an array of them: `note_genes = melody.find_genes(:notes)`
109
97
 
110
- #### #find_gene(key)
98
+ ### EvolvableClass#find_gene(key)
111
99
 
112
100
  Returns the first gene with the given key. In the Melody example above, the instrument gene has the key `:instrument` so we might write something like: `instrument_gene = melody.find_gene(instrument)`
113
101
 
114
- #### #population_index, #population_index=
102
+ ### EvolvableClass#population_index, #population_index=
115
103
 
116
104
  Returns an instance's population index - an integer representing the order in which it was initialized in a population. It's the most basic way to distinguish instances in a population.
117
105
 
118
- #### #value
106
+ ### EvolvableClass#value
119
107
 
120
- It is required that you implement this method. It is used when evaluating instances before undergoing evolution.
108
+ You must implement this method. It is used when evaluating instances before undergoing evolution. The above melody example imagines that the melodies have ratings and uses them as the basis for evaluation and selection.
121
109
 
122
- Technically, this method can return any object that implements Ruby's [Comparable](https://ruby-doc.org/core-2.7.1/Comparable.html). See the section on [Evaluation](#Evaluation) for details.
110
+ Technically, this method can return any object that implements Ruby's [Comparable](https://ruby-doc.org/core-2.7.1/Comparable.html). See the section on [Evaluation](#evaluation-1) for details.
123
111
 
124
- #### Evolvable Hooks
112
+ ### Evolvable Hooks
125
113
 
126
- The following class methods can be overridden in order to hook into a population's evolutions. The hooks run for each evolution in the following order:
114
+ The following class method hooks can be overridden. The hooks run for each evolution in the following order:
127
115
 
128
116
  **.before_evaluation(population)**
129
117
 
@@ -152,7 +140,7 @@ end
152
140
 
153
141
  Instances rely on gene objects to compose behaviors. In other words, a gene can be thought of as an object that in some way affects the behavior of an instance. They are used to encapsulate a "sample space" and return a sample outcome when accessed.
154
142
 
155
- #### The Evolvable::Gene module
143
+ ### The Evolvable::Gene module
156
144
 
157
145
  Gene objects must include the `Evolvable::Gene` module which enables them to undergo evolutionary operations such as crossover and mutation.
158
146
 
@@ -169,11 +157,9 @@ class NoteGene
169
157
  end
170
158
  end
171
159
  ```
172
- Here, the "sample space" for the NoteGene class has twelve notes, but each individual object will have only one note. The note is randomly chosen when the "value" method is invoked for the first time.
160
+ Here, the "sample space" for the NoteGene class has twelve notes, but each object will have only one note which is randomly chosen when the "value" method is invoked for the first time. _It is important that the data for a particular gene never change._ Ruby's or-equals operator `||=` is super useful for memoizing gene attributes. It is used above to randomly pick a note only once and return the same note for the lifetime of the object.
173
161
 
174
- _It is important that the data for a particular gene never change._ Ruby's or-equals operator `||=` is super useful for memoizing gene attributes like this. It is used above to randomly pick a note only once and return the same note for the lifetime of the object.
175
-
176
- A melody instance with multiple note genes might use the `NoteGene#value` method to compose the notes of its melody like so: `melody.find_genes(:note).map(&:value)`. Let's keep going with this example and implement the `InstrumentGene` too:
162
+ A melody instance with multiple note genes might use the `NoteGene#value` method to compose the notes of its melody like so: `melody.find_genes(:note).map(&:value)`. Let's keep humming with the melody example and implement the `InstrumentGene` too:
177
163
 
178
164
  ```ruby
179
165
  class InstrumentGene
@@ -211,76 +197,225 @@ class Melody
211
197
  end
212
198
  ```
213
199
 
214
- In this way, instances can express behaviors via genes and even orchestrate interactions between them. Genes can also interact with each other during an instance's initialization process via the [#initialize_instance](#initialize_instance-1) method
200
+ In this way, instances can express behaviors via genes and even orchestrate interactions between them. Genes can also interact with each other during an instance's initialization process via the [EvolvableClass#initialize_instance](#evolvableclassinitialize_instance-1) method
201
+
202
+ ### The Evolvable::GeneSpace object
203
+
204
+ The `Evolvable::GeneSpace` object is responsible for initializing the full set of genes for a particular instance according to the configuration returned by the [EvolvableClass.gene_space](#evolvableclassgene_space) method. It is used by the `Evolvable::Population` to initialize new instances.
205
+
206
+ Technically, any object that responds to a `new_genes` method which returns an array of genes for a particular instance can function as a GeneSpace object. Custom implementations will be used if returned by the `.gene_space` method.
207
+
208
+
209
+ ## Populations
210
+
211
+ The `Evolvable::Population` object is responsible for generating and evolving instances. It orchestrates all the other Evolvable objects to do so.
212
+
213
+ ### Evolvable::Population.new
214
+
215
+ Initializes an Evolvable::Population.
215
216
 
216
- #### The Evolvable::GeneSpace object
217
+ Keyword arguments:
217
218
 
218
- TODO
219
+ #### evolvable_class
220
+ Required. Implicitly specified when using EvolvableClass.new_population.
221
+ #### id, name
222
+ Both default to `nil`. Not used by Evolvable, but convenient when working with multiple populations.
223
+ #### size
224
+ Defaults to `40`. Specifies the number of instances in the population.
225
+ #### evolutions_count
226
+ Defaults to `0`. Useful when re-initializing a saved population with instances.
227
+ #### gene_space
228
+ Defaults to `evolvable_class.new_gene_space` which uses the [EvolvableClass.gene_space](#evolvableclassgene_space) method
229
+ #### evolution
230
+ Defaults to `Evolvable::Evolution.new`. See [evolution](#evolution-1)
231
+ #### evaluation
232
+ Defaults to `Evolvable::Evaluation.new`, with a goal of maximizing towards Float::INFINITY. See [evaluation](#evaluation-1)
233
+ #### instances
234
+ Defaults to initializing a `size` number of `evolvable_class` instances using the `gene_space` object. Any given instances are assigned, but if given less than `size`, more will be initialized.
235
+
236
+ ### Evolvable::Population#evolve
237
+
238
+ Keyword arguments:
239
+
240
+ #### count
241
+ The number of evolutions to run. Expects a positive integer and Defaults to Float::INFINITY and will therefore run indefinitely unless a `goal_value` is specified.
242
+ #### goal_value
243
+ Assigns the goal object's value. Will continue running until any instance's value reaches it. See [evaluation](#evaluation-1)
244
+
245
+ ### Evolvable::Population#best_instance
246
+ Returns an instance with the value that is nearest to the goal value.
247
+
248
+ ### Evolvable::Population#met_goal?
249
+ Returns true if any instance's value matches the goal value, otherwise false.
250
+
251
+ ### Evolvable::Population#new_instance
252
+ Initializes an instance for the population. Note that this method does not add the new instance to its array of instances.
253
+
254
+ Keyword arguments:
255
+
256
+ #### genes
257
+ An array of initialized gene objects. Defaults to `[]`
258
+ #### population_index
259
+ Defaults to `nil` and expects an integer. See (EvolvableClass#population_index)[#evolvableclasspopulation_index-population_index]
260
+
261
+
262
+ ### Population#selection, #selection=
263
+ The [selection](#selection-1) object.
264
+
265
+ ### Population#crossover, #crossover=
266
+ The [crossover](#crossover) object.
267
+
268
+ ### Population#mutation, #mutation=
269
+ The [mutation](#mutation-1) object.
270
+
271
+ ### Population#goal, #goal=
272
+ The [evaluation](#evaluation-1)'s goal object.
219
273
 
220
274
  ## Evaluation
221
275
 
222
- TODO
276
+ For selection to be effective in the context of progressive evolution, there needs to be some way of comparing various instances with each other. In traditional genetic algorithms, this is referred to as the "fitness function". The `Evolvable::Evaluation` object expects instances to define a [EvolvableClass#value](#evolvableclassvalue) method that it uses to evaluate them relative to each other and against a definable goal.
223
277
 
224
- #### The Evolvable::Evaluation object
278
+ A goal object has a value that can be most easily assigned via an argument to `Evolvable::Population#evolve` like this: `population.evolve(goal_value: 1000)`. Evolvable provides the following goal object implementations and goal value defaults.
225
279
 
226
- TODO
280
+ ### The Evolvable::Goal::Maximize object
227
281
 
228
- #### The Evolvable::Goal::Maximize object
282
+ Prioritizes instances with greater values. This is the default.
229
283
 
230
- TODO
284
+ The default goal value is `Float::INFINITY`, but it can be reassigned as anything that implements the Ruby [Comparable](https://ruby-doc.org/core-2.7.1/Comparable.html) module.
231
285
 
232
- #### The Evolvable::Goal::Minimize object
286
+ ### The Evolvable::Goal::Minimize object
233
287
 
234
- TODO
288
+ Prioritizes instances with lesser values.
235
289
 
236
- #### The Evolvable::Goal::Equalize object
290
+ The default goal value is `-Float::INFINITY`, but it can be reassigned as anything that implements the Ruby [Comparable](https://ruby-doc.org/core-2.7.1/Comparable.html) module.
237
291
 
238
- TODO
292
+ ### The Evolvable::Goal::Equalize object
239
293
 
240
- ## Populations
294
+ Prioritizes instances that equal the goal value.
295
+
296
+ The default goal value is `0`, but it can be reassigned as anything that implements the Ruby [Comparable](https://ruby-doc.org/core-2.7.1/Comparable.html) module.
297
+
298
+ ### Custom Goal Objects
299
+
300
+ You can implement custom goal object like so:
241
301
 
242
- TODO
302
+ ```ruby
303
+ class CustomGoal
304
+ include Evolvable::Goal
243
305
 
244
- #### The Evolvable::Population object
306
+ def evaluate(instance)
307
+ # Required by Evolvable::Evaluation in order to sort instances in preparation for selection.
308
+ end
245
309
 
246
- TODO
310
+ def met?(instance)
311
+ # Used by Evolvable::Population#evolve to stop evolving when the goal value has been reached.
312
+ end
313
+ end
314
+ ```
315
+
316
+ The goal for a population can be specified via assignment - `population.goal = Evolvable::Goal::Equalize.new` - or by passing an evaluation object when [initializing a population](#evolvablepopulationnew).
317
+
318
+ You can intialize the `Evolvable::Evaluation` object with any goal object like this:
319
+
320
+ ```ruby
321
+ goal_object = SomeGoal.new(value: 100)
322
+ Evolvable::Evaluation.new(goal_object)
323
+ ```
324
+
325
+ or more succinctly like this:
326
+
327
+ ```ruby
328
+ Evolvable::Evaluation.new(:maximize) # Uses default goal value of Float::INFINITY
329
+ Evolvable::Evaluation.new(maximize: 50) # Sets goal value to 50
330
+ Evolvable::Evaluation.new(:minimize) # Uses default goal value of -Float::INFINITY
331
+ Evolvable::Evaluation.new(minimize: 100) # Sets goal value to 100
332
+ Evolvable::Evaluation.new(:equalize) # Uses default goal value of 0
333
+ Evolvable::Evaluation.new(equalize: 1000) # Sets goal value to 1000
334
+
335
+ ```
247
336
 
248
337
  ## Evolution
249
338
 
250
- TODO
339
+ After a population's instances are evaluated, they undergo evolution. The default `Evolvable::Evolution` object is composed of selection, crossover, and mutation objects and applies them as operations to the population in that order.
340
+
341
+ Populations can be assigned with custom evolution objects. The only necessary dependency for evolution objects is that they implement the `#call` method which accepts a population as the first argument. Population objects also expect evolution objects to define a getter and setter for selection, crossover, and mutation, but these methods are simply for ease-of-use and not necessary.
342
+
343
+ ### Evolvable::Evolution.new
251
344
 
252
- #### The Evolvable::Evolution object
345
+ Initializes a new evolution object.
253
346
 
254
- TODO
347
+ Keyword arguments:
348
+
349
+ #### selection
350
+ The default is `Selection.new`
351
+ #### crossover
352
+ The default is `GeneCrossover.new`
353
+ #### mutation
354
+ The default is `Mutation.new`
255
355
 
256
356
  ## Selection
257
357
 
258
- TODO
358
+ The selection process assumes that the population's instances have already been sorted by the `Evaluation` object. It leaves only a select number of instances in a given population's instances array.
359
+
360
+ Custom selection objects must implement the `#call` method which accepts the population as the first object.
361
+
362
+ ### Evolvable::Selection.new
259
363
 
260
- #### The Evolvable::Selection object
364
+ Initializes a new selection object.
261
365
 
262
- TODO
366
+ Keyword arguments:
367
+
368
+ #### size
369
+ The number of instances to select from each generation from which to perform crossover and generate or "breed" the next generation. The number of parents The default is 2.
263
370
 
264
371
  ## Crossover
265
372
 
266
- TODO
373
+ Generates new instances by combining the genes of selected instances. You can think of it as a mixing of parent genes from one generation to produce a next generation.
374
+
375
+ Custom crossover objects must implement the `#call` method which accepts the population as the first object.
267
376
 
268
- #### The Evolvable::GeneCrossover object
377
+ ### The Evolvable::GeneCrossover object
269
378
 
270
- TODO
379
+ Enables gene types to define crossover behaviors. Each gene class can implement a unique behavior for crossover by overriding the following default implementation which mirrors the behavior of `Evolvable::UniformCrossover`
380
+
381
+ ```ruby
382
+ def self.crossover(gene_a, gene_b)
383
+ [gene_a, gene_b].sample
384
+ end
385
+ ```
271
386
 
272
- #### The Evolvable::UniformCrossover object
387
+ ### The Evolvable::UniformCrossover object
273
388
 
274
- TODO
389
+ Randomly chooses a gene from one of the parents for each gene position.
275
390
 
276
- #### The Evolvable::PointCrossover object
391
+ ### The Evolvable::PointCrossover object
277
392
 
278
- TODO
393
+ Supports single and multi-point crossover. The default is single-point crossover via a `points_count` of 1 which can be changed on an existing population (`population.crossover.points_count = 5`) or during initialization (`Evolvable::PointCrossover.new(5)`)
279
394
 
280
395
  ## Mutation
281
396
 
282
- TODO
397
+ Mutation serves the role of increasing genetic variation, especially when a population's instances are small in number and mostly homogeneous. When an instance undergoes a mutation, it means that one of its existing genes is replaced with a newly initialized gene. Using the language from the [section on genes](genes), a gene mutation invokes a new outcome from the gene's sample space.
283
398
 
284
- #### The Evolvable::Mutation object
399
+ ### Evolvable::Mutation.new
400
+
401
+ Initializes a new mutation object.
402
+
403
+ Keyword arguments:
404
+
405
+ #### probability
406
+ The probability that a particular instance undergoes a mutation. By default, the probability is 0.03 which translates to 3%. If initialized with a `rate`, the probability will be 1 which means all genes _can_ undergo mutation, but actual gene mutations will be subject to the given mutation rate.
407
+ #### rate
408
+ the rate at which individual genes mutate. The default rate is 0 which, when combined with a non-zero `probability` (the default), means that one gene for each instance that undergoes mutation will change. If a rate is given, but no `probability` is given, then the `probability` will bet set to 1 which always defers to the mutation rate.
409
+
410
+ To summarize, the `probability` represents the chance of mutation on the instance level and the `rate` represents the chance on the gene level. The `probability` and `rate` can be any number from 0 to 1. When the `probability` is 0, no mutation will ever happen. When the `probability` is not 0 but the rate is 0, then any instance that undergoes mutation will only receive one mutant gene. If the rate is not 0, then if an instance has been chosen to undergo mutation, each of its genes will mutate with a probability as defined by the `rate`.
411
+
412
+ Example Initializations:
413
+
414
+ ```ruby
415
+ Evolvable::Mutation.new # Approximately 3% of instances will receive one mutant gene
416
+ Evolvable::Mutation.new(probability: 0.5) # Approximately 50% of instances will receive one mutant gene
417
+ Evolvable::Mutation.new(rate: 0.03) # Approximately 3% of all genes in the population will mutate.
418
+ Evolvable::Mutation.new(probability: 0.3, rate: 0.03) # Approximately 30% of instances will have approximately 3% of their genes mutated.
419
+ ```
285
420
 
286
- TODO
421
+ Custom mutation objects must implement the `#call` method which accepts the population as the first object.
@@ -33,7 +33,7 @@ module Evolvable
33
33
  when Hash
34
34
  goal_from_hash(goal_arg)
35
35
  else
36
- goal
36
+ goal_arg
37
37
  end
38
38
  end
39
39
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Evolvable
4
- VERSION = '1.0.0'
4
+ VERSION = '1.0.1'
5
5
  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.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Ruzicka
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-09-11 00:00:00.000000000 Z
11
+ date: 2020-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler