class Gargor
Constants
- VERSION
Public Class Methods
base()
click to toggle source
# File lib/gargor.rb, line 50 def base @@base end
crossover(a,b)
click to toggle source
# File lib/gargor.rb, line 107 def crossover a,b return a.clone if a.params == b.params log "crossover: #{a} #{b}" total = a.fitness + b.fitness c = Individual.new c.params = a.params.clone c.overwrite_by(b,b.fitness,total) end
debug(message)
click to toggle source
# File lib/gargor.rb, line 18 def debug message log message,Logger::DEBUG end
first_generation?()
click to toggle source
# File lib/gargor.rb, line 71 def first_generation? @@generation == 1 end
float_rand(f,p = @@dsl.fitness_precision)
click to toggle source
浮動小数点対応のrand
# File lib/gargor.rb, line 99 def float_rand(f,p = @@dsl.fitness_precision) raise ArgumentError,"max must be > 0" unless f > 0 f *= p i = f.to_i f = rand(i) f / p.to_f end
generation()
click to toggle source
# File lib/gargor.rb, line 26 def generation @@generation end
individuals()
click to toggle source
# File lib/gargor.rb, line 34 def individuals @@individuals end
last_trials()
click to toggle source
# File lib/gargor.rb, line 209 def last_trials last_trials_at_this_generation + (opt("max_generations")-@@generation)*(opt("population")-opt("elite")) end
last_trials_at_this_generation()
click to toggle source
# File lib/gargor.rb, line 205 def last_trials_at_this_generation @@individuals.select{ |i| i.fitness == nil }.count end
load_dsl(params_file)
click to toggle source
# File lib/gargor.rb, line 81 def load_dsl(params_file) @@dsl_file = params_file contents = File.read(params_file) @@dsl.instance_eval(contents) validate end
log(message,level=Logger::INFO)
click to toggle source
# File lib/gargor.rb, line 13 def log message,level=Logger::INFO return if $TESTING message.to_s.split("\n").each { |line| @@logger.add(level) {line} } end
logfile(file)
click to toggle source
# File lib/gargor.rb, line 197 def logfile file File.expand_path(File.join(File.dirname(@@dsl_file),file)) end
logger()
click to toggle source
# File lib/gargor.rb, line 38 def logger @@logger end
logger=(logger)
click to toggle source
# File lib/gargor.rb, line 42 def logger= logger @@logger = logger end
mutate()
click to toggle source
# File lib/gargor.rb, line 92 def mutate individual = @@dsl.create_individual log "mutate #{individual}" individual end
mutation?(mutation= opt("mutation"))
click to toggle source
# File lib/gargor.rb, line 144 def mutation? mutation= opt("mutation") rand <= mutation end
next_generation()
click to toggle source
# File lib/gargor.rb, line 187 def next_generation log "<== end generation #{@@generation}" @@generation += 1 return false if @@generation > opt("max_generations") log "==> next generation #{@@generation}" @@prev_generation = @@individuals true end
opt(name)
click to toggle source
# File lib/gargor.rb, line 46 def opt name @@dsl.send(name) end
options=(options)
click to toggle source
# File lib/gargor.rb, line 88 def options= options @@dsl.options = options end
params()
click to toggle source
# File lib/gargor.rb, line 22 def params @@dsl.params end
populate()
click to toggle source
# File lib/gargor.rb, line 171 def populate @@individuals = if first_generation? # 第一世代 populate_first_generation else # 次世代 raise ExterminationError unless prev_count >= 2 populate_next_generation end @@dsl.save_state(@@individuals) if @@dsl.has_state? log "populate:" @@individuals.each { |i| log i } end
populate_first_generation()
click to toggle source
# File lib/gargor.rb, line 126 def populate_first_generation @@base = @@dsl.create_individual.load_now individuals = @@dsl.load_state if @@dsl.has_state? unless individuals individuals = Gargor::Individuals.new individuals << base until individuals.length >= opt("population") individuals << mutate end end Gargor::Individuals.new(individuals.shuffle) end
populate_next_generation()
click to toggle source
# File lib/gargor.rb, line 160 def populate_next_generation log "population: #{@@prev_generation.length}" individuals = Gargor::Individuals.new(select_elites @@prev_generation,opt("elite")) until individuals.length >= opt("population") do i = populate_one individuals << i unless individuals.has?(i) end Gargor::Individuals.new(individuals.shuffle) end
populate_one()
click to toggle source
# File lib/gargor.rb, line 152 def populate_one if mutation? mutate else crossover(*select_parents(@@prev_generation)) end end
prev_count(g = @@prev_generation)
click to toggle source
前世代の数
# File lib/gargor.rb, line 76 def prev_count g = @@prev_generation # fitness > 0 適応している個体 g.select { |i| i.fitness && i.fitness > 0 }.count end
prev_generation()
click to toggle source
# File lib/gargor.rb, line 30 def prev_generation @@prev_generation end
select_elites(g,count)
click to toggle source
# File lib/gargor.rb, line 139 def select_elites g,count return [] unless count > 0 Gargor::Individuals.new(g.sort{ |a,b| a.fitness<=>b.fitness }.last(count)) end
select_parents(g)
click to toggle source
# File lib/gargor.rb, line 148 def select_parents g [selection(g),selection(g)] end
selection(g)
click to toggle source
# File lib/gargor.rb, line 116 def selection g total = g.inject(0) { |sum,i| sum += i.fitness } cur = float_rand(total) g.each { |i| return i if i.fitness > cur cur -= i.fitness } raise GargorError,"error selection" end
start()
click to toggle source
# File lib/gargor.rb, line 54 def start @@logger = Logger.new(STDOUT) @@base = nil @@individuals = [] @@prev_generation = nil @@generation = 1 @@dsl = Dsl.new @@dsl_file = nil true end
total_trials()
click to toggle source
# File lib/gargor.rb, line 201 def total_trials opt("population")+(opt("population")-opt("elite"))*(opt("max_generations")-1) end
validate()
click to toggle source
# File lib/gargor.rb, line 66 def validate raise ValidationError,"POPULATION isn't > 0" unless opt("population") > 0 true end