darwinning 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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
- * [Cameron Dutro](https://github.com/camertron "camertron")
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
- new_gene = member.genes[random_index].express
35
- member.genotypes[random_index] = member.genes[random_index].express
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.to_s == "Darwinning::Organism"
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
- temp_members = members
47
+ verify_population_size_is_positive!
48
+
48
49
  new_members = []
49
50
 
50
- until new_members.length == 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.to_s == "Darwinning::Organism"
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)
@@ -1,3 +1,3 @@
1
1
  module Darwinning
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -0,0 +1,14 @@
1
+ class NewSingle
2
+ include Darwinning
3
+
4
+ GENE_RANGES = {
5
+ first_digit: (0..9)
6
+ }
7
+
8
+ attr_accessor :first_digit
9
+
10
+ def fitness
11
+ # Try to get the digit to equal 15
12
+ (first_digit - 15).abs
13
+ end
14
+ end
@@ -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
@@ -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
@@ -1,4 +1,5 @@
1
1
  require 'darwinning'
2
- require './spec/classes/triple'
3
- require './spec/classes/new_triple'
4
- require './spec/classes/chimps'
2
+
3
+ Dir[
4
+ File.join(File.dirname(__FILE__), './classes/*.rb'),
5
+ ].each { |file| require file }
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.0
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: 2015-09-27 00:00:00.000000000 Z
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