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 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