evolvable 0.1.3 → 1.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.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +14 -0
- data/Gemfile.lock +9 -26
- data/README.md +167 -254
- data/bin/console +5 -41
- data/evolvable.gemspec +0 -1
- data/examples/evolvable_string.rb +32 -0
- data/examples/evolvable_string/char_gene.rb +9 -0
- data/lib/evolvable.rb +45 -58
- data/lib/evolvable/error/undefined_method.rb +7 -0
- data/lib/evolvable/evaluation.rb +51 -0
- data/lib/evolvable/evolution.rb +26 -0
- data/lib/evolvable/gene.rb +13 -0
- data/lib/evolvable/gene_crossover.rb +28 -0
- data/lib/evolvable/gene_space.rb +37 -0
- data/lib/evolvable/goal.rb +19 -0
- data/lib/evolvable/goal/equalize.rb +19 -0
- data/lib/evolvable/goal/maximize.rb +19 -0
- data/lib/evolvable/goal/minimize.rb +19 -0
- data/lib/evolvable/mutation.rb +22 -44
- data/lib/evolvable/point_crossover.rb +57 -0
- data/lib/evolvable/population.rb +70 -91
- data/lib/evolvable/selection.rb +18 -0
- data/lib/evolvable/uniform_crossover.rb +22 -0
- data/lib/evolvable/version.rb +1 -1
- metadata +18 -7
- data/lib/evolvable/crossover.rb +0 -35
- data/lib/evolvable/errors/not_implemented.rb +0 -5
- data/lib/evolvable/helper_methods.rb +0 -45
- data/lib/evolvable/hooks.rb +0 -9
data/lib/evolvable/crossover.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
class Crossover
|
2
|
-
def call(parent_genes, offspring_count)
|
3
|
-
parent_gene_couples = parent_genes.combination(2).cycle
|
4
|
-
Array.new(offspring_count) do
|
5
|
-
p1_genes, p2_genes = parent_gene_couples.next
|
6
|
-
p1_genes.merge(p2_genes) { |_k, p1_val, p2_val| [p1_val, p2_val].sample }
|
7
|
-
offspring_genes = merge_parent_genes(p1_genes, p2_genes)
|
8
|
-
trim_offspring_genes!(offspring_genes, p1_genes.count)
|
9
|
-
offspring_genes
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def inspect
|
14
|
-
"#<#{self.class.name} #{as_json.map { |a| a.join(': ') }.join(', ')} >"
|
15
|
-
end
|
16
|
-
|
17
|
-
def as_json
|
18
|
-
{ type: self.class.name }
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def merge_parent_genes(p1_genes, p2_genes)
|
24
|
-
p1_genes.merge(p2_genes) { |_k, p1_val, p2_val| [p1_val, p2_val].sample }
|
25
|
-
end
|
26
|
-
|
27
|
-
def trim_offspring_genes!(offspring_genes, parent_genes_count)
|
28
|
-
trim_genes_count = offspring_genes.count - parent_genes_count
|
29
|
-
return if trim_genes_count.zero?
|
30
|
-
|
31
|
-
offspring_genes.keys.sample(trim_genes_count).each do |name|
|
32
|
-
offspring_genes.delete(name)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
module Evolvable
|
2
|
-
module HelperMethods
|
3
|
-
def combine_dimensions(dimensions)
|
4
|
-
dimension_lengths = dimensions.map(&:length)
|
5
|
-
genes_count = dimension_lengths.inject(1) { |product, c| product * c }
|
6
|
-
|
7
|
-
genes = Array.new(genes_count) { [] }
|
8
|
-
element_repeat_counts = compute_element_repeat_counts(dimension_lengths)
|
9
|
-
sequence_counts = compute_sequence_counts(dimension_lengths)
|
10
|
-
|
11
|
-
dimensions.each_with_index do |dimension, dim_index|
|
12
|
-
element_count = element_repeat_counts[dim_index]
|
13
|
-
sequence = dimension.flat_map { |e| [e] * element_count }
|
14
|
-
dimension_sequence = sequence * sequence_counts[dim_index]
|
15
|
-
dimension_sequence.each_with_index do |element, gene_index|
|
16
|
-
genes[gene_index][dim_index] = element
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
genes
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def compute_element_repeat_counts(dimension_lengths)
|
26
|
-
repeat_counts = Array.new(dimension_lengths.count - 1) do |n|
|
27
|
-
right_side_counts = dimension_lengths[(n + 1)..-1]
|
28
|
-
right_side_counts.inject(1) { |product, a| product * a }
|
29
|
-
end
|
30
|
-
repeat_counts << 1
|
31
|
-
repeat_counts
|
32
|
-
end
|
33
|
-
|
34
|
-
def compute_sequence_counts(dimension_lengths)
|
35
|
-
Array.new(dimension_lengths.count) do |n|
|
36
|
-
if n.zero?
|
37
|
-
1
|
38
|
-
else
|
39
|
-
right_side_counts = dimension_lengths[0...n]
|
40
|
-
right_side_counts.inject(1) { |product, a| product * a }
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|