rbga 0.1.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.
- checksums.yaml +7 -0
- data/LICENSE +20 -0
- data/lib/chromosome_type.rb +6 -0
- data/lib/crossover_methods.rb +35 -0
- data/lib/mutation_methods.rb +20 -0
- data/lib/rbga.rb +148 -0
- data/lib/selection_methods.rb +12 -0
- data/lib/survive_methods.rb +11 -0
- metadata +51 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: d41bf1e0fb8bddb4244020a7a356e2ec90e43d8b
|
|
4
|
+
data.tar.gz: a151df0070b724322415b22e3207e551d8a5b49c
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 988d8801e58c49ac2b4cb94712d2e8c4777842ab0a873022a963cff6fec116b9daf9292c5b0dc8f609b784280559f69aacb6e14216351fa0b7e0c1027a80ddfa
|
|
7
|
+
data.tar.gz: cf709f516bf034ac621f96510902d6b6b06d8813da2ad753a050e7d301addd2f0a06909020f99271fd751f4e15ee88e9fa91add2bff4e42b8bd6bcd46025fe17
|
data/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2013 Szu-Kai Hsu (brucehsu)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module CrossoverMethods
|
|
2
|
+
def order_crossover(chs1, chs2)
|
|
3
|
+
idx = rand(chs1.size/2)
|
|
4
|
+
new_chs1 = Chromosome.new(@chromosome_type, chs1.size, @mutation_method, @mutation_probability)
|
|
5
|
+
new_chs1.clear
|
|
6
|
+
new_chs1 << chs1[idx..(idx+chs1.size/2)]
|
|
7
|
+
new_chs1.flatten!
|
|
8
|
+
new_chs2 = Chromosome.new(@chromosome_type, chs1.size, @mutation_method, @mutation_probability)
|
|
9
|
+
new_chs2.clear
|
|
10
|
+
new_chs2 << chs2[idx..(idx+chs2.size/2)]
|
|
11
|
+
new_chs2.flatten!
|
|
12
|
+
|
|
13
|
+
chs1.size.times do |i|
|
|
14
|
+
unless new_chs1.include? chs2[i]
|
|
15
|
+
if new_chs1.size<=(chs1.size*3/4)
|
|
16
|
+
new_chs1.insert(0,chs2[i])
|
|
17
|
+
else
|
|
18
|
+
new_chs1.push(chs2[i])
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
chs2.size.times do |i|
|
|
24
|
+
unless new_chs2.include? chs1[i]
|
|
25
|
+
if new_chs2.size<=(chs2.size*3/4)
|
|
26
|
+
new_chs2.insert(0,chs1[i])
|
|
27
|
+
else
|
|
28
|
+
new_chs2.push(chs1[i])
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
return [new_chs1, new_chs2]
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module MutationMethods
|
|
2
|
+
def swap
|
|
3
|
+
idx1 = rand(self.size)
|
|
4
|
+
idx2 = rand(self.size)
|
|
5
|
+
while idx1==idx2
|
|
6
|
+
idx2 = rand(self.size)
|
|
7
|
+
end
|
|
8
|
+
self[idx1], self[idx2] = self[idx2], self[idx1]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def inversion
|
|
12
|
+
head = self.size/4
|
|
13
|
+
tail = self.size*3/4
|
|
14
|
+
while head<=tail
|
|
15
|
+
self[head], self[tail] = self[tail], self[head]
|
|
16
|
+
head+=1
|
|
17
|
+
tail-=1
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/rbga.rb
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
require 'chromosome_type'
|
|
2
|
+
require 'mutation_methods'
|
|
3
|
+
require 'crossover_methods'
|
|
4
|
+
require 'selection_methods'
|
|
5
|
+
require 'survive_methods'
|
|
6
|
+
|
|
7
|
+
class GA
|
|
8
|
+
attr_reader :best_log, :avg_log
|
|
9
|
+
include CrossoverMethods
|
|
10
|
+
include SelectionMethods
|
|
11
|
+
include SurviveMethods
|
|
12
|
+
|
|
13
|
+
def initialize(&block)
|
|
14
|
+
instance_eval &block
|
|
15
|
+
@population = Population.new @population_size, @chromosome_type, @chromosome_length, @mutation_method, @mutation_probability
|
|
16
|
+
@best_log = []
|
|
17
|
+
@avg_log = []
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def chromosome_type(type)
|
|
21
|
+
@chromosome_type = type
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def chromosome_length(len)
|
|
25
|
+
@chromosome_length = len
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def population_size(size)
|
|
29
|
+
@population_size = size
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def crossover_method(crossover)
|
|
33
|
+
@crossover_method = crossover
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def mutation_method(mutation)
|
|
37
|
+
@mutation_method = mutation
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def mutation_probability(prob)
|
|
41
|
+
@mutation_probability = prob
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def selection_method(selection)
|
|
45
|
+
@selection_method = selection
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def survive_method(survive)
|
|
49
|
+
@survive_method = survive
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def evolve(generations)
|
|
53
|
+
generations.times do |i|
|
|
54
|
+
offspring = Population.new @population_size, @chromosome_type, @chromosome_length, @mutation_method, @mutation_probability
|
|
55
|
+
offspring.clear
|
|
56
|
+
offspring << @population
|
|
57
|
+
offspring.flatten!(1)
|
|
58
|
+
@population.size.times do |i|
|
|
59
|
+
chs1 = @population[select]
|
|
60
|
+
chs2 = @population[select]
|
|
61
|
+
while chs1==chs2
|
|
62
|
+
chs2 = @population[select]
|
|
63
|
+
end
|
|
64
|
+
new_chs = crossover(chs1,chs2)
|
|
65
|
+
while offspring.include?(new_chs[0]) or offspring.include?(new_chs[1])
|
|
66
|
+
chs1 = @population[select]
|
|
67
|
+
chs2 = @population[select]
|
|
68
|
+
while chs1==chs2
|
|
69
|
+
chs2 = @population[select]
|
|
70
|
+
end
|
|
71
|
+
new_chs = crossover(chs1,chs2)
|
|
72
|
+
end
|
|
73
|
+
offspring << new_chs[0] << new_chs[1]
|
|
74
|
+
end
|
|
75
|
+
survive offspring
|
|
76
|
+
@best_log << best.fitness
|
|
77
|
+
@avg_log << avg
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def select
|
|
83
|
+
send(@selection_method)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def crossover(chs1, chs2)
|
|
87
|
+
send(@crossover_method, chs1, chs2)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def set_fitness_eval(&block)
|
|
91
|
+
@fitness = block
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def survive(population)
|
|
95
|
+
population.each { |e| e.fitness = @fitness.call e }
|
|
96
|
+
send(@survive_method, population)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def best
|
|
100
|
+
best_idx = 0
|
|
101
|
+
best_fit = nil
|
|
102
|
+
@population.each_index do |idx|
|
|
103
|
+
ch = @population[idx]
|
|
104
|
+
ch.fitness = @fitness.call ch
|
|
105
|
+
best_fit = ch.fitness if best_fit==nil
|
|
106
|
+
best_idx = idx if best_fit < ch.fitness
|
|
107
|
+
best_fit = ch.fitness if best_fit < ch.fitness
|
|
108
|
+
end
|
|
109
|
+
return @population[best_idx]
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def avg
|
|
113
|
+
avg_fit = 0
|
|
114
|
+
@population.each do |ch|
|
|
115
|
+
avg_fit += ch.fitness
|
|
116
|
+
end
|
|
117
|
+
return avg_fit/@population.size
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
class Population < Array
|
|
123
|
+
def initialize(size, chs_type, chs_len, chs_mutation, chs_prob)
|
|
124
|
+
return if size==nil
|
|
125
|
+
size.times do |i|
|
|
126
|
+
self << Chromosome.new(chs_type, chs_len, chs_mutation, chs_prob)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
class Chromosome < Array
|
|
132
|
+
attr_accessor :fitness
|
|
133
|
+
include ChromosomeType
|
|
134
|
+
include MutationMethods
|
|
135
|
+
|
|
136
|
+
def initialize(type, size, mutation, probability)
|
|
137
|
+
@size = size
|
|
138
|
+
self.send(type)
|
|
139
|
+
@mutation_method = mutation
|
|
140
|
+
@mutation_probability = probability
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def mutate!
|
|
144
|
+
if rand(100)<=probability
|
|
145
|
+
self.send(:mutation_method)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module SelectionMethods
|
|
2
|
+
def two_tournament
|
|
3
|
+
idx1 = rand(@population.size)
|
|
4
|
+
idx2 = rand(@population.size)
|
|
5
|
+
while idx1==idx2
|
|
6
|
+
idx2 = rand(@population.size)
|
|
7
|
+
end
|
|
8
|
+
@population[idx1].fitness = @fitness.call @population[idx1]
|
|
9
|
+
@population[idx2].fitness = @fitness.call @population[idx2]
|
|
10
|
+
return ((@population[idx1].fitness) < (@population[idx2].fitness)) ? idx1 : idx2
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module SurviveMethods
|
|
2
|
+
def min_fitness(population)
|
|
3
|
+
population.sort! { |a, b| a.fitness <=> b.fitness }
|
|
4
|
+
@population = population[0..(@population.size-1)]
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def max_fitness(population)
|
|
8
|
+
population.sort! { |a, b| b.fitness <=> a.fitness }
|
|
9
|
+
@population = population[0..(@population.size-1)]
|
|
10
|
+
end
|
|
11
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rbga
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Szu-Kai Hsu(brucehsu)
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2013-08-14 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: Providing an expressive DSL to illustrate genetic algorithm problems
|
|
14
|
+
and sets of default methods.
|
|
15
|
+
email: brucehsu@gmail.com
|
|
16
|
+
executables: []
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- lib/chromosome_type.rb
|
|
21
|
+
- lib/crossover_methods.rb
|
|
22
|
+
- lib/mutation_methods.rb
|
|
23
|
+
- lib/rbga.rb
|
|
24
|
+
- lib/selection_methods.rb
|
|
25
|
+
- lib/survive_methods.rb
|
|
26
|
+
- LICENSE
|
|
27
|
+
homepage: https://github.com/brucehsu/rbga
|
|
28
|
+
licenses:
|
|
29
|
+
- MIT
|
|
30
|
+
metadata: {}
|
|
31
|
+
post_install_message:
|
|
32
|
+
rdoc_options: []
|
|
33
|
+
require_paths:
|
|
34
|
+
- lib
|
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - '>='
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0'
|
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
41
|
+
requirements:
|
|
42
|
+
- - '>='
|
|
43
|
+
- !ruby/object:Gem::Version
|
|
44
|
+
version: '0'
|
|
45
|
+
requirements: []
|
|
46
|
+
rubyforge_project:
|
|
47
|
+
rubygems_version: 2.0.3
|
|
48
|
+
signing_key:
|
|
49
|
+
specification_version: 4
|
|
50
|
+
summary: Genetic Algorithm DSL
|
|
51
|
+
test_files: []
|