Algorithmically 0.1.4 → 0.1.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 553511b544e3ba3256109470cec9aa74afacf883
4
- data.tar.gz: 7c369687176d34c9105f30f068592b92ff8a8247
3
+ metadata.gz: 90dbca96e9a153e6acfbdd2eac99f9e06054aa73
4
+ data.tar.gz: a1a059aab483649dae1d890df74549a20cda0b42
5
5
  SHA512:
6
- metadata.gz: 69b85819ba8ba9e9f51c009263a2f66080977bf98bc71a7a4d92c98e54a654f1b0ead68adc6fc8e6955bc8312d4ed33f9fc8d37643fd5e8f947b69d8aafd1f79
7
- data.tar.gz: eace3c0a9fd63ee2d635cff1a3dc018a4b4a9dcf214d9d743445ea8a61cdcb285ce4417f633606d750e321157fa1c7b95a516ec4529e79a7d81ce0f907dc64da
6
+ metadata.gz: 9afc0731375aa0fae820aa4605b87ce7992f484430faaf0c1eabba5fa91eaf785c36457e4613c2c622e51078667a3ecec57f519243114cd3a0e7765e0c3f4029
7
+ data.tar.gz: 7d30e282bc64b82fe5683b33308e218cea14ed76100841f314fc3a02ab14c4399a8faa62ed9e4c5aee866ac4acee44fb37cb1124ca513d1846225cf32fb2a541
data/README.md CHANGED
@@ -20,6 +20,10 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
+ ### Evolutionary Algorithms
24
+
25
+ Algorithmically::Genetic.new(100, 64, 100, 0.98)
26
+
23
27
  ### Neural Algorithms
24
28
 
25
29
  Algorithmically::Perceptron.new([[0,0,0], [0,1,1], [1,0,1], [1,1,1]], 2, 20, 0.1)
@@ -1,4 +1,5 @@
1
1
  require 'Algorithmically/version'
2
+ require 'Algorithmically/Evolutionary/genetic'
2
3
  require 'Algorithmically/Neural/perceptron'
3
4
  require 'Algorithmically/Stochastic/random_search'
4
5
  require 'Algorithmically/Stochastic/hill_climbing'
@@ -6,6 +7,7 @@ require 'Algorithmically/Stochastic/guided_local_search'
6
7
 
7
8
 
8
9
  module Algorithmically
10
+ include Evolutionary
9
11
  include Neural
10
12
  include Stochastic
11
13
  end
@@ -0,0 +1,77 @@
1
+ module Evolutionary
2
+
3
+ class Genetic
4
+
5
+ def initialize(max_gens, num_bits, pop_size, p_crossover)
6
+ p_mutation = 1.0/num_bits
7
+ best = search(max_gens, num_bits, pop_size, p_crossover, p_mutation)
8
+ puts "done! Solution: f=#{best[:fitness]}, s=#{best[:bitstring]}"
9
+ end
10
+
11
+ def onemax(bitstring)
12
+ sum = 0
13
+ bitstring.size.times { |i| sum+=1 if bitstring[i].chr=='1' }
14
+ sum
15
+ end
16
+
17
+ def random_bitstring(num_bits)
18
+ (0...num_bits).inject("") { |s, i| s<<((rand<0.5) ? "1" : "0") }
19
+ end
20
+
21
+ def binary_tournament(pop)
22
+ i, j = rand(pop.size), rand(pop.size)
23
+ j = rand(pop.size) if j==i
24
+ (pop[i][:fitness] > pop[j][:fitness]) ? pop[i] : pop[j]
25
+ end
26
+
27
+ def point_mutation(bitstring, rate=1.0/bitstring.size)
28
+ child = ""
29
+ bitstring.size.times do |i|
30
+ bit = bitstring[i].chr
31
+ child << ((rand()<rate) ? ((bit=='1') ? "0" : "1") : bit)
32
+ end
33
+ child
34
+ end
35
+
36
+ def crossover(parent1, parent2, rate)
37
+ ""+parent1 if rand()>=rate
38
+ point = 1 + rand(parent1.size-2)
39
+ parent1[0...point]+parent2[point...(parent1.size)]
40
+ end
41
+
42
+ def reproduce(selected, pop_size, p_cross, p_mutation)
43
+ children = []
44
+ selected.each_with_index do |p1, i|
45
+ p2 = (i.modulo(2)==0) ? selected[i+1] : selected[i-1]
46
+ p2 = selected[0] if i == selected.size-1
47
+ child = {}
48
+ child[:bitstring] = crossover(p1[:bitstring], p2[:bitstring], p_cross)
49
+ child[:bitstring] = point_mutation(child[:bitstring], p_mutation)
50
+ children << child
51
+ children.size >= pop_size
52
+ end
53
+ children
54
+ end
55
+
56
+ def search(max_gens, num_bits, pop_size, p_crossover, p_mutation)
57
+ population = Array.new(pop_size) do |i|
58
+ {:bitstring => random_bitstring(num_bits)}
59
+ end
60
+ population.each { |c| c[:fitness] = onemax(c[:bitstring]) }
61
+ best = population.sort { |x, y| y[:fitness] <=> x[:fitness] }.first
62
+ max_gens.times do |gen|
63
+ selected = Array.new(pop_size) { |i| binary_tournament(population) }
64
+ children = reproduce(selected, pop_size, p_crossover, p_mutation)
65
+ children.each { |c| c[:fitness] = onemax(c[:bitstring]) }
66
+ children.sort! { |x, y| y[:fitness] <=> x[:fitness] }
67
+ best = children.first if children.first[:fitness] >= best[:fitness]
68
+ population = children
69
+ puts " > gen #{gen}, best: #{best[:fitness]}, #{best[:bitstring]}"
70
+ break best[:fitness] == num_bits
71
+ end
72
+ best
73
+ end
74
+
75
+ end
76
+
77
+ end
@@ -1,3 +1,3 @@
1
1
  module Algorithmically
2
- VERSION = '0.1.4'
2
+ VERSION = '0.1.5'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: Algorithmically
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - popac
@@ -76,6 +76,7 @@ files:
76
76
  - bin/console
77
77
  - bin/setup
78
78
  - lib/Algorithmically.rb
79
+ - lib/Algorithmically/Evolutionary/genetic.rb
79
80
  - lib/Algorithmically/Neural/perceptron.rb
80
81
  - lib/Algorithmically/Stochastic/adaptive_random_search.rb
81
82
  - lib/Algorithmically/Stochastic/guided_local_search.rb