Class: Operator::CrossoverRipple
- Inherits:
-
Object
- Object
- Operator::CrossoverRipple
- Defined in:
- ../lib/crossover_ripple.rb
Overview
Single point GE crossover. It assumes two parents has the form of Arrays. First, the cutting points in both parents are randomly selected, then the parts after these points are swapped, forming two new offsprings.
The positions of possible cutting points can be flexibly configured (which may be important for complex Mappers using more than one genome value per codon). Production of empty offsprings can be allowed or prohibited as well by the crossover’s configuration. The cutting point positions in both parents can be either fixed or independent.
Instance Attribute Summary (collapse)
-
- (Object) fixed
Whether the CrossoverRipple uses the same position (Array index) for both parents’ cutting points, defaulting to false.
-
- (Object) margin
The minimal number of genome vector values kept from the beginning and ending of the parent vector, defaulting to 0.
-
- (Object) random
The source of randomness, used for calling “random.rand( limit )”, defaulting to ‘Kernel’ class.
-
- (Object) step
The number of genome vector values between tho possible cutting points, defaulting to 1.
-
- (Object) tolerance
Whether the empty array is allowed as the valid offspring (if set to false, the exception is raised), defaulting to true.
Instance Method Summary (collapse)
-
- (Object) crossover(parent1, parent2, dummy1 = nil, dummy2 = nil)
Take parent1, parent2 arguments and produce [offspring1, offspring2].
-
- (CrossoverRipple) initialize
constructor
Create a new crossover facility with the default attribute values.
Constructor Details
- (CrossoverRipple) initialize
Create a new crossover facility with the default attribute values.
16 17 18 19 20 21 22 |
# File '../lib/crossover_ripple.rb', line 16 def initialize @random = Kernel @margin = 0 @step = 1 @fixed = false @tolerance = true end |
Instance Attribute Details
- (Object) fixed
Whether the CrossoverRipple uses the same position (Array index) for both parents’ cutting points, defaulting to false.
34 35 36 |
# File '../lib/crossover_ripple.rb', line 34 def fixed @fixed end |
- (Object) margin
The minimal number of genome vector values kept from the beginning and ending of the parent vector, defaulting to 0.
28 29 30 |
# File '../lib/crossover_ripple.rb', line 28 def margin @margin end |
- (Object) random
The source of randomness, used for calling “random.rand( limit )”, defaulting to ‘Kernel’ class.
25 26 27 |
# File '../lib/crossover_ripple.rb', line 25 def random @random end |
- (Object) step
The number of genome vector values between tho possible cutting points, defaulting to 1.
31 32 33 |
# File '../lib/crossover_ripple.rb', line 31 def step @step end |
- (Object) tolerance
Whether the empty array is allowed as the valid offspring (if set to false, the exception is raised), defaulting to true.
37 38 39 |
# File '../lib/crossover_ripple.rb', line 37 def tolerance @tolerance end |
Instance Method Details
- (Object) crossover(parent1, parent2, dummy1 = nil, dummy2 = nil)
Take parent1, parent2 arguments and produce [offspring1, offspring2]. For instance:
parent1 = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
parent2 = [ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 ]
xover = CrossoverRipple.new
possible cutting points with default setting (denoted by ’|’ symbol):
parent1 = [ | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | ]
parent2 = [ | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ]
after xover.margin = 3, the allowed cutting points are:
parent1 = [ 1, 2, 3 | 4 | 5 | 6 | 7 | 8, 9, 10 ]
parent2 = [ 11, 12, 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21, 22, 23 ]
after xover.step = 2, the allowed cutting points are:
parent1 = [ 1, 2, 3 | 4, 5 | 6, 7 | 8, 9, 10 ]
parent2 = [ 11, 12, 13 | 14, 15 | 16, 17 | 18, 19 | 20, 21, 22, 23 ]
now producing the offsprings:
offspring1, offspring2 = xover.crossover( parent1, parent2 )
offspring1 is [ 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 ] offspring2 is [ 11, 12, 13, 14, 15, 8, 9, 10 ]
This is stochastic process, thus repeating:
offspring1, offspring2 = xover.crossover( parent1, parent2 )
produces: offspring1 : [ 1, 2, 3, 18, 19, 20, 21, 22, 23 ] offspring2 : [ 11, 12, 13, 14, 15, 16, 17, 4, 5, 6, 7, 8, 9, 10 ]
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File '../lib/crossover_ripple.rb', line 70 def crossover( parent1, parent2, dummy1=nil, dummy2=nil ) pts1 = [] @margin.step( parent1.size - @margin, @step ) { |i| pts1.push i } pts2 = [] @margin.step( parent2.size - @margin, @step ) { |i| pts2.push i } if pts1.empty? or pts2.empty? return parent1.clone, parent2.clone if @tolerance #fallback raise "CrossoverRipple: operand(s) too short" end if @fixed if parent1.size < parent2.size pt1 = pt2 = pts1.at( @random.rand(pts1.size) ) else pt1 = pt2 = pts2.at( @random.rand(pts2.size) ) end else pt1 = pts1.at @random.rand(pts1.size) pt2 = pts2.at @random.rand(pts2.size) end offs1 = parent1[0...pt1].clone offs1 = offs1.concat parent2[pt2...parent2.size] offs2 = parent2[0...pt2].clone offs2 = offs2.concat parent1[pt1...parent1.size] return offs1, offs2 end |