metaheuristics 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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