evopop 0.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0a7d88db7ef7db0308c1a1f78622124c40f3f556
4
+ data.tar.gz: 2367d81655b2112e858828bfd4e1d64fd4f4e44e
5
+ SHA512:
6
+ metadata.gz: 0ff6289c46a13239cfc61267e42ee5c63980fc8d4aaef9073de188da6d6d7a92c4769bfff54db3315bcf8fa5ad0266f355385cca17cd594e662eb3863dbdf904
7
+ data.tar.gz: 9c461beb7fc05d35f824da3be0c487abe086c91357668ce08cbb47134491c558ec1e6a95ea6c194fb4f6eee9dd1f6dfe70822541e12da219ce13fcd46c114d6e
@@ -0,0 +1,10 @@
1
+ # Public: Represents a candidate in the population. Candidates are abstracted
2
+ # as a simple data structure which contains the DNA and fitness over the
3
+ # fitness function.
4
+ class Candidate
5
+ attr_accessor :dna, :fitness
6
+
7
+ def initialize
8
+ @dna = []
9
+ end
10
+ end
@@ -0,0 +1,95 @@
1
+
2
+ # Public: Represents the population that is being trained. Has various methods
3
+ # relevant to training.
4
+ #
5
+ #
6
+ # Examples
7
+ # population = Population.new
8
+ # ... initialize population with parameters ...
9
+ # population.train
10
+ # population.crossover
11
+ # population.mutate
12
+ class Population
13
+ attr_accessor :candidates, :population_size, :max_generations, :initial_range_min, :initial_range_max, :mutation_range_min, :mutation_range_max, :mutation_num, :fitness_function, :dna_len, :average_fitness
14
+
15
+ # Initializes the attributes with default values. This is not guaranteed
16
+ # to reach maxima.
17
+ def initialize
18
+ @average_fitness = []
19
+ @population_size = 100
20
+ @max_generations = 100
21
+ @initial_range_min = -100
22
+ @initial_range_max = 100
23
+ @mutation_range_min = -10
24
+ @mutation_range_max = 10
25
+ @mutation_num = (0.10*@population_size).to_i
26
+ @dna_len = 1
27
+
28
+ @fitness_function = Proc.new { |dna|
29
+ Math.sin(dna[0])
30
+ }
31
+
32
+ self.create
33
+ end
34
+
35
+ # Public: Creates a new population class. Should be called after all the
36
+ # parameters have been set to the attributes.
37
+ def create
38
+ @candidates = Array.new(@population_size) {|c|
39
+ candidate = Candidate.new
40
+ (0...@dna_len).each {
41
+ candidate.dna << Random.rand(@initial_range_min...@initial_range_max)
42
+ }
43
+ candidate
44
+ }
45
+ end
46
+
47
+ # Public: Determines the fitness of the population and thereafter sorts it
48
+ # based on fitness descdending (high fitness first, low fitness last).
49
+ def train
50
+ average_fitness = 0
51
+ @candidates.each { |c|
52
+ c.fitness = fitness_function.call(c.dna)
53
+ average_fitness = average_fitness + c.fitness
54
+ }
55
+ average_fitness = average_fitness/@population_size
56
+
57
+ @average_fitness << average_fitness
58
+
59
+ @candidates = @candidates.sort_by {|c| c.fitness}
60
+ @candidates = @candidates.reverse
61
+ end
62
+
63
+ # Public: Performs simple mechanism of crossover - in this case picks two
64
+ # random candidates in from a top percentile of the population and averages
65
+ # out their DNA per dimension, producing new offspring equal to the
66
+ # population size attribute.
67
+ def crossover
68
+ @candidates = @candidates.take((@population_size*0.75).to_i)
69
+
70
+ new_generation = Array.new
71
+ (0...@population_size).each {|i|
72
+ couple = @candidates.sample(2)
73
+ child = Candidate.new
74
+ (0...@dna_len).each {|j|
75
+ child.dna << (couple[0].dna[j] + couple[1].dna[j])/2.0 # Initialize the dna of the child with the average of the parents' dna.
76
+ }
77
+ new_generation << child
78
+ }
79
+
80
+ @candidates = new_generation
81
+ end
82
+
83
+ # Public: Performs simple mutation over the next generation. In this case,
84
+ # it either adds or substracts an amount to each dimension given the
85
+ # mutation range attributes.
86
+ def mutate
87
+ mutated = @candidates.sample(self.mutation_num)
88
+
89
+ mutated.each { |c|
90
+ (0...@dna_len).each {|i|
91
+ c.dna[i] = c.dna[i] + Random.rand(@mutation_range_min...@mutation_range_max)
92
+ }
93
+ }
94
+ end
95
+ end
data/lib/evopop.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'evopop/population'
2
+ require 'evopop/candidate'
3
+
4
+ class Evopop
5
+
6
+ def self.Population
7
+ Population
8
+ end
9
+
10
+ def self.Candidate
11
+ Candidate
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: evopop
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Elvin Lucero
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-08-19 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A simple library for implementing simple genetic algorithms.
14
+ email: elvinlucero@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/evopop.rb
20
+ - lib/evopop/population.rb
21
+ - lib/evopop/candidate.rb
22
+ homepage: https://github.com/elvinlucero/evopop
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 2.0.3
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: Genetic algorithms!
46
+ test_files: []