metaheuristics 0.1.0 → 0.2.0

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
@@ -1,9 +1,10 @@
1
1
 
2
- Metaheustics
3
- ============
2
+ Metaheuristics
3
+ ==============
4
4
 
5
5
  A ruby library of metaheuristics for search/optimisation.
6
6
 
7
+ `gem install metaheuristics`
7
8
 
8
9
  Usage
9
10
  -----
@@ -0,0 +1,148 @@
1
+ require 'metaheuristics/genome_interface'
2
+
3
+ # A generic genome class.
4
+ # random genomes for a given structure definition can be generated
5
+ # via calls to the class method +new_random+. The structure definition
6
+ # is an array of gene definitions; a gene definition is a hash like the followings:
7
+ #
8
+ # * { :type => :boolean }
9
+ # * { :type => :int , :range => 0..10 }
10
+ # * { :type => :real , :range => -3.42..176.8 }
11
+ #
12
+ class GenomeGeneric < GenomeInterface
13
+
14
+ attr_reader :definition, :values
15
+
16
+ # new random genome from definition
17
+ def self.new_random(definition)
18
+ values = definition.collect do |h|
19
+ type = h[:type]
20
+ case(type)
21
+ # boolean
22
+ when :boolean
23
+ rand(2) == 0
24
+
25
+ # int
26
+ when :int
27
+ range = h[:range] || (raise ArgumentError)
28
+ rand(range.last - range.first + 1) + range.first
29
+
30
+ # real
31
+ when :real
32
+ range = h[:range] || (raise ArgumentError)
33
+ rand * (range.last - range.first) + range.first
34
+
35
+ # sample
36
+ when :sample
37
+ range = h[:range] || (raise ArgumentError)
38
+ size = h[:size ] || (raise ArgumentError)
39
+ range.to_a.sample(size)
40
+
41
+ else raise ArgumentError, "Unknown gene type '#{type}'" end
42
+ end
43
+
44
+ self.new(
45
+ definition,
46
+ values)
47
+ end
48
+
49
+ # ctor
50
+ def initialize(definition, values)
51
+ definition.freeze
52
+ @definition = definition
53
+ @values = values
54
+ end
55
+
56
+ # clone
57
+ def clone
58
+ GenomeGeneric.new(
59
+ @definition,
60
+ @values.clone)
61
+ end
62
+
63
+
64
+ # mutate this
65
+ def mutate!(mutation_rate)
66
+ @definition.size.times do |i|
67
+ if rand < mutation_rate
68
+ h = @definition[i]
69
+ case(h[:type])
70
+ when :boolean # boolean
71
+ @values[i] = !@values[i]
72
+
73
+ when :int # int
74
+ range = h[:range]
75
+ @values[i] = rand(range.last - range.first + 1) + range.first
76
+
77
+ when :real # real
78
+ range = h[:range]
79
+ @values[i] = rand * (range.last - range.first) + range.first
80
+
81
+ when :sample # sample
82
+ range = h[:range]
83
+ size = h[:size ]
84
+ assert{ @values[i].size == size }
85
+ a = range.to_a
86
+ index = rand(size)
87
+ current = @values[i]
88
+ new_int = a.sample(1) while current.include?(new_int)
89
+ current[index] = new_int
90
+
91
+ else raise RuntimeError end
92
+ end
93
+ end
94
+
95
+ self
96
+ end
97
+
98
+
99
+ # crossover (uniformly applied)
100
+ def crossover(genome)
101
+ self_values = @values
102
+ other_values = genome.values
103
+ values =
104
+ Array.new(self_values.size) do |i|
105
+ h = @definition[i]
106
+ case(h[:type])
107
+ when :boolean, :int, :real
108
+ [self_values, other_values][rand(2)][i]
109
+
110
+ when :sample # sample
111
+ range = h[:range]
112
+ size = h[:size ]
113
+ (self_values[i] + other_values[i]).sort.uniq.sample(size)
114
+
115
+ else raise RuntimeError end
116
+ end
117
+
118
+ GenomeGeneric.new(
119
+ @definition,
120
+ @values)
121
+ end
122
+
123
+ # to string
124
+ def to_s
125
+ Array.new(@definition.size) do |i|
126
+ h = @definition[i]
127
+ v = @values[i]
128
+ case(h[:type])
129
+ when :boolean # boolean
130
+ v ? 'X' : '_'
131
+
132
+ when :int # int
133
+ range = h[:range]
134
+ count = (range.last - range.first) / 10
135
+ " #{v.to_s.rjust(count + 1)} "
136
+
137
+ when :real # real
138
+ range = h[:range]
139
+ " #{'%.2f' % v} "
140
+
141
+ when :sample # sample
142
+ "[#{v.collect{ |r| r.to_s.rjust(2) }.join(', ') }]"
143
+
144
+ else raise RuntimeError end
145
+ end.join
146
+ end
147
+ end # GenomeGeneric
148
+
@@ -0,0 +1,7 @@
1
+
2
+ class GenomeInterface
3
+ def clone ; raise NotImplementeError; end
4
+ def mutate!(mutation_rate); raise NotImplementeError; end
5
+ def crossover(genome) ; raise NotImplementeError; end
6
+ end # GenomeInterface
7
+
@@ -1,6 +1,5 @@
1
- require 'metaheuristics/metaheuristic_interface'
1
+ require 'metaheuristic_interface'
2
2
  require 'metaheuristics/search_results'
3
- require 'utils/assert'
4
3
 
5
4
  class AlpsGa < MetaheuristicInterface
6
5
 
@@ -115,7 +114,8 @@ class AlpsGa < MetaheuristicInterface
115
114
  l.sort!.reverse!
116
115
  $stderr << "= layer #{idx} : max age #{max_layer_age(idx)} ---------------------------------------------------------------\n"
117
116
  l.each do |i|
118
- $stderr << " - #{i.solution.__id__.to_s.rjust(7)}, fitness #{i.fitness.to_i.to_s.rjust(6)}, age #{i.age.to_s.rjust(4)}\n"
117
+ # $stderr << " - #{i.solution.__id__.to_s.rjust(7)}, fitness #{i.fitness.to_i.to_s.rjust(6)}, age #{i.age.to_s.rjust(4)}\n"
118
+ $stderr << " - #{i.solution.__id__.to_s.rjust(7)}, fitness #{('%.4f' % i.fitness).rjust(7)}, age #{i.age.to_s.rjust(4)}\n"
119
119
  end
120
120
  end
121
121
  $stderr << "\n"
@@ -208,8 +208,8 @@ private
208
208
  def move_to_layer(individuals, n)
209
209
  # add layer
210
210
  if n > (@layers.size - 1)
211
- assert{ n < @max_layer_count }
212
- assert{ n == @layers.size }
211
+ raise RuntimeError unless n < @max_layer_count
212
+ raise RuntimeError unless n == @layers.size
213
213
  @layers[n] = []
214
214
  end
215
215
 
@@ -1,4 +1,4 @@
1
- require 'metaheuristics/metaheuristic_interface'
1
+ require 'metaheuristic_interface'
2
2
  require 'metaheuristics/individual_solution'
3
3
 
4
4
  class FgrnGa < MetaheuristicInterface
@@ -1,4 +1,4 @@
1
- require 'metaheuristics/metaheuristic_interface'
1
+ require 'metaheuristic_interface'
2
2
  require 'metaheuristics/individual_solution'
3
3
  require 'metaheuristics/search_results'
4
4
 
metadata CHANGED
@@ -2,14 +2,14 @@
2
2
  name: metaheuristics
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.0
5
+ version: 0.2.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Jean Krohn
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-29 00:00:00.000000000 Z
12
+ date: 2012-09-25 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Metaheuristics include Genetic Algorithms (GAs), such as ALPS and tournament selection.
15
15
  email: jbk@susano.org
@@ -18,10 +18,12 @@ extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
20
  - README.md
21
+ - lib/metaheuristic_interface.rb
22
+ - lib/metaheuristic_init_factory.rb
23
+ - lib/metaheuristics/genome_generic.rb
24
+ - lib/metaheuristics/genome_interface.rb
21
25
  - lib/metaheuristics/individual_solution.rb
22
26
  - lib/metaheuristics/search_results.rb
23
- - lib/metaheuristics/metaheuristic_interface.rb
24
- - lib/metaheuristics/metaheuristic_init_factory.rb
25
27
  - lib/metaheuristics/genome_search/alps_ga.rb
26
28
  - lib/metaheuristics/genome_search/fgrn_ga.rb
27
29
  - lib/metaheuristics/genome_search/tournament_selection.rb