| Path: | lib/charlie/crossover.rb |
| Last Update: | Sat Jan 26 00:46:47 +0100 2008 |
This file contains some generic crossovers and functions to generate crossovers
Takes crossover c1 with probability p, and crossover c2 with probability 1-p
# File lib/charlie/crossover.rb, line 25
25: def PCross(p,c1,c2=NullCrossover)
26: raise ArgumentError, "first argument to PCross should be numeric (probability)." unless p.is_a?(Numeric)
27: return c1 if c1==c2
28: c1_name, c2_name = [c1,c2].map{|c| '_cross_' + c.to_s.gsub(/[^A-Za-z0-9]/,'') }
29: Module.new{
30: include c1.dup # dup to avoid bugs on use PCross(..,c1) .. use c1
31: alias_method c1_name, :cross
32: include c2.dup
33: alias_method c2_name, :cross
34:
35: define_method(:cross) {|*args|
36: rand < p ? send(c1_name,*args) : send(c2_name,*args)
37: }
38: self.name= "PCross(#{p},#{c1},#{c2})"
39: }
40: end
Variant of PCross for more than 2 crossovers.
# File lib/charlie/crossover.rb, line 45
45: def PCrossN(hash)
46: tot_p = hash.inject(0){|s,(m,p)| s+p }
47: if (tot_p - 1.0).abs > 0.01 # close to 1?
48: raise ArgumentError, "PCrossN: sum of probabilities > 1.0" if tot_p > 1.0
49: hash[NullCrossover] = (hash[NullCrossover] || 0.0) + (1.0 - tot_p)
50: end
51: partial_sums = hash.sort_by{|m,p| -p } # max probability first
52: s = 0.0
53: partial_sums.map!{|m,p| ['_cross_' + m.to_s.gsub(/[^A-Za-z0-9]/,'') , s+=p, m] }
54:
55: Module.new{
56: partial_sums.each{|name,p,mod|
57: include mod.dup
58: alias_method name, :cross
59: }
60: define_method(:cross) {|*args|
61: r = rand
62: c_name = partial_sums.find{|name,p,mod| p >= r }.first
63: send(c_name,*args)
64: }
65: self.name= "PCrossN(#{hash.inspect})"
66: }
67: end
Turns a two-children crossover module into a single-child crossover module. Usage: use SingleChild(UniformCrossover)
# File lib/charlie/crossover.rb, line 14
14: def SingleChild(crossover_module)
15: Module.new{
16: include crossover_module.dup
17: def cross(parent1,parent2)
18: super(parent1,parent2).at_rand
19: end
20: self.name= "SingleChild(#{crossover_module})"
21: }
22: end