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 +3 -2
- data/lib/{metaheuristics/metaheuristic_init_factory.rb → metaheuristic_init_factory.rb} +0 -0
- data/lib/{metaheuristics/metaheuristic_interface.rb → metaheuristic_interface.rb} +0 -0
- data/lib/metaheuristics/genome_generic.rb +148 -0
- data/lib/metaheuristics/genome_interface.rb +7 -0
- data/lib/metaheuristics/genome_search/alps_ga.rb +5 -5
- data/lib/metaheuristics/genome_search/fgrn_ga.rb +1 -1
- data/lib/metaheuristics/genome_search/tournament_selection.rb +1 -1
- metadata +6 -4
data/README.md
CHANGED
File without changes
|
File without changes
|
@@ -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
|
+
|
@@ -1,6 +1,5 @@
|
|
1
|
-
require '
|
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
|
-
|
212
|
-
|
211
|
+
raise RuntimeError unless n < @max_layer_count
|
212
|
+
raise RuntimeError unless n == @layers.size
|
213
213
|
@layers[n] = []
|
214
214
|
end
|
215
215
|
|
metadata
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
name: metaheuristics
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 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-
|
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
|