crossover.rb

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

Methods

PCross   PCrossN   SingleChild   cross  

Public Instance methods

Takes crossover c1 with probability p, and crossover c2 with probability 1-p

[Source]

    # 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.

[Source]

    # 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)

[Source]

    # 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

[Source]

    # File lib/charlie/crossover.rb, line 17
17:     def cross(parent1,parent2)
18:       super(parent1,parent2).at_rand
19:     end

[Validate]