darwinning 0.1.0 → 0.1.1
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.
- data/README.md +1 -3
- data/lib/darwinning/evolution_types/mutation.rb +8 -2
- data/lib/darwinning/evolution_types/reproduction.rb +3 -3
- data/lib/darwinning/population.rb +13 -3
- data/lib/darwinning/version.rb +1 -1
- data/spec/classes/new_single.rb +14 -0
- data/spec/classes/single.rb +11 -0
- data/spec/evolution_types/mutation_spec.rb +45 -0
- data/spec/population_spec.rb +23 -1
- data/spec/spec_helper.rb +4 -3
- metadata +8 -2
data/README.md
CHANGED
@@ -123,6 +123,4 @@ Check out the `/examples` folder for more examples. That seems like a good place
|
|
123
123
|
* [Dave Schwantes](https://github.com/dorkrawk "dorkrawk")
|
124
124
|
|
125
125
|
### With help from:
|
126
|
-
|
127
|
-
* [Maurizio Del Corno](https://github.com/druzn3k "druzn3k")
|
128
|
-
* [Evan Brynne](https://github.com/ebrynne "ebrynne")
|
126
|
+
[lots of great contributers](https://github.com/dorkrawk/darwinning/graphs/contributors)
|
@@ -31,8 +31,14 @@ module Darwinning
|
|
31
31
|
# Selects a random genotype from the organism and re-expresses its gene
|
32
32
|
def re_express_random_genotype(member)
|
33
33
|
random_index = (0..member.genotypes.length - 1).to_a.sample
|
34
|
-
|
35
|
-
|
34
|
+
gene = member.genes[random_index]
|
35
|
+
|
36
|
+
if member.class.superclass == Darwinning::Organism
|
37
|
+
member.genotypes[gene] = gene.express
|
38
|
+
else
|
39
|
+
member.send("#{gene.name}=", gene.express)
|
40
|
+
end
|
41
|
+
|
36
42
|
member
|
37
43
|
end
|
38
44
|
end
|
@@ -33,7 +33,7 @@ module Darwinning
|
|
33
33
|
|
34
34
|
def new_member_from_genotypes(organism_klass, genotypes)
|
35
35
|
new_member = organism_klass.new
|
36
|
-
if organism_klass.superclass
|
36
|
+
if organism_klass.superclass == Darwinning::Organism
|
37
37
|
new_member.genotypes = genotypes
|
38
38
|
else
|
39
39
|
new_member.genes.each do |gene|
|
@@ -60,7 +60,7 @@ module Darwinning
|
|
60
60
|
[genotypes1, genotypes2]
|
61
61
|
end
|
62
62
|
|
63
|
-
def random_swap(m1, m2)
|
63
|
+
def random_swap(m1, m2)
|
64
64
|
genotypes1 = {}
|
65
65
|
genotypes2 = {}
|
66
66
|
|
@@ -69,7 +69,7 @@ module Darwinning
|
|
69
69
|
g2_parent = [m1,m2].sample
|
70
70
|
|
71
71
|
genotypes1[gene] = g1_parent.genotypes[gene]
|
72
|
-
genotypes2[gene] = g2_parent.genotypes[gene]
|
72
|
+
genotypes2[gene] = g2_parent.genotypes[gene]
|
73
73
|
end
|
74
74
|
|
75
75
|
[genotypes1, genotypes2]
|
@@ -44,16 +44,20 @@ module Darwinning
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def make_next_generation!
|
47
|
-
|
47
|
+
verify_population_size_is_positive!
|
48
|
+
|
48
49
|
new_members = []
|
49
50
|
|
50
|
-
until new_members.length
|
51
|
+
until new_members.length >= members.length
|
51
52
|
m1 = weighted_select(members)
|
52
53
|
m2 = weighted_select(members)
|
53
54
|
|
54
55
|
new_members += apply_pairwise_evolutions(m1, m2)
|
55
56
|
end
|
56
57
|
|
58
|
+
# In the case of an odd population size, we likely added one too many members.
|
59
|
+
new_members.pop if new_members.length > members.length
|
60
|
+
|
57
61
|
@members = apply_non_pairwise_evolutions(new_members)
|
58
62
|
@history << @members
|
59
63
|
@generation += 1
|
@@ -87,9 +91,15 @@ module Darwinning
|
|
87
91
|
|
88
92
|
private
|
89
93
|
|
94
|
+
def verify_population_size_is_positive!
|
95
|
+
unless @population_size.positive?
|
96
|
+
raise "Population size must be a positive number!"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
90
100
|
def build_member
|
91
101
|
member = organism.new
|
92
|
-
unless member.class.superclass
|
102
|
+
unless member.class.superclass == Darwinning::Organism
|
93
103
|
member.class.genes.each do |gene|
|
94
104
|
gene_expression = gene.express
|
95
105
|
member.send("#{gene.name}=", gene_expression)
|
data/lib/darwinning/version.rb
CHANGED
@@ -0,0 +1,11 @@
|
|
1
|
+
class Single < Darwinning::Organism
|
2
|
+
@name = "Single"
|
3
|
+
@genes = [
|
4
|
+
Darwinning::Gene.new(name: "first digit", value_range: (0..9))
|
5
|
+
]
|
6
|
+
|
7
|
+
def fitness
|
8
|
+
# Try to get the digit to equal 15
|
9
|
+
(genotypes.values.inject{ |sum, x| sum + x } - 15).abs
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Darwinning::EvolutionTypes::Mutation do
|
4
|
+
|
5
|
+
describe '#evolve' do
|
6
|
+
context 'when the mutation is triggered' do
|
7
|
+
# Use a mutation_rate of 1 ... which means a 100% chance of mutation.
|
8
|
+
subject { described_class.new(mutation_rate: 1.0) }
|
9
|
+
let(:new_gene_variant) { double }
|
10
|
+
|
11
|
+
before do
|
12
|
+
allow(gene).to receive(:express).and_return(new_gene_variant)
|
13
|
+
end
|
14
|
+
|
15
|
+
shared_examples_for 'a mutation that updates the genotype of the member' do
|
16
|
+
before { subject.evolve([member]) }
|
17
|
+
|
18
|
+
it "modifies the member's genotype to be the new expression of the gene" do
|
19
|
+
expect(member.genotypes[gene]).to eq(new_gene_variant)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'with a subclass of Organism' do
|
24
|
+
let(:member) { Single.new }
|
25
|
+
let(:gene) { member.genes[0] }
|
26
|
+
|
27
|
+
it_behaves_like 'a mutation that updates the genotype of the member'
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'with a class that includes Darwinning' do
|
31
|
+
let(:member) { NewSingle.new }
|
32
|
+
let(:gene) { Darwinning::Gene.new(name: :first_digit, value_range: (0..9)) }
|
33
|
+
|
34
|
+
before do
|
35
|
+
allow(Darwinning::Gene).to receive(:new)
|
36
|
+
.with(name: :first_digit, value_range: (0..9))
|
37
|
+
.and_return(gene)
|
38
|
+
end
|
39
|
+
|
40
|
+
it_behaves_like 'a mutation that updates the genotype of the member'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
data/spec/population_spec.rb
CHANGED
@@ -6,7 +6,7 @@ describe Darwinning::Population do
|
|
6
6
|
organism: Triple, population_size: 10, fitness_goal: 0
|
7
7
|
)
|
8
8
|
}
|
9
|
-
|
9
|
+
|
10
10
|
it "fitness goal should be set to 0" do
|
11
11
|
expect(pop_triple.fitness_goal).to eq 0
|
12
12
|
end
|
@@ -27,6 +27,28 @@ describe Darwinning::Population do
|
|
27
27
|
expect(pop_triple.members).not_to eq old_members
|
28
28
|
end
|
29
29
|
|
30
|
+
describe "#make_next_generation!" do
|
31
|
+
context "with a specified odd-number for population size" do
|
32
|
+
it "does not change the member count" do
|
33
|
+
population = Darwinning::Population.new(
|
34
|
+
organism: Triple, fitness_goal: 0, population_size: 3
|
35
|
+
)
|
36
|
+
|
37
|
+
expect { population.make_next_generation! }.not_to change{ population.members.length }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "with a specified not-positive number for population size" do
|
42
|
+
it "raises an exception" do
|
43
|
+
population = Darwinning::Population.new(
|
44
|
+
organism: Triple, fitness_goal: 0, population_size: 0
|
45
|
+
)
|
46
|
+
|
47
|
+
expect { population.make_next_generation! }.to raise_error(RuntimeError)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
30
52
|
describe "#history" do
|
31
53
|
|
32
54
|
it "should be generations + 1 in size" do
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: darwinning
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2016-10-26 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Darwinning provides tools to build genetic algorithm solutions using
|
15
15
|
a Gene, Organism, and Population structure.
|
@@ -31,9 +31,12 @@ files:
|
|
31
31
|
- Rakefile
|
32
32
|
- README.md
|
33
33
|
- spec/classes/chimps.rb
|
34
|
+
- spec/classes/new_single.rb
|
34
35
|
- spec/classes/new_triple.rb
|
36
|
+
- spec/classes/single.rb
|
35
37
|
- spec/classes/triple.rb
|
36
38
|
- spec/darwinning_spec.rb
|
39
|
+
- spec/evolution_types/mutation_spec.rb
|
37
40
|
- spec/gene_spec.rb
|
38
41
|
- spec/organism_spec.rb
|
39
42
|
- spec/population_spec.rb
|
@@ -64,9 +67,12 @@ specification_version: 3
|
|
64
67
|
summary: A Ruby gem to aid in the use of genetic algorithms.
|
65
68
|
test_files:
|
66
69
|
- spec/classes/chimps.rb
|
70
|
+
- spec/classes/new_single.rb
|
67
71
|
- spec/classes/new_triple.rb
|
72
|
+
- spec/classes/single.rb
|
68
73
|
- spec/classes/triple.rb
|
69
74
|
- spec/darwinning_spec.rb
|
75
|
+
- spec/evolution_types/mutation_spec.rb
|
70
76
|
- spec/gene_spec.rb
|
71
77
|
- spec/organism_spec.rb
|
72
78
|
- spec/population_spec.rb
|