Class: Wallace::Operators::PartiallyMappedCrossoverOperator

Inherits:
Wallace::Operator show all
Defined in:
lib/operators/partially_mapped_crossover_operation.rb

Overview

The partially mapped crossover swaps a single genetic subsequence (at the same position) between two parents before fixing any resulting collisions by calculating and applying partial mappings on damaged genes.

Instance Method Summary collapse

Methods inherited from Wallace::Operator

#initialize, #produce

Constructor Details

This class inherits a constructor from Wallace::Operator

Instance Method Details

#operate(rng, inputs) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/operators/partially_mapped_crossover_operation.rb', line 8

def operate(rng, inputs)

  # Select two random crossover points.
  len = inputs[0].length
  i, j = Array.new(2) { rng.rand(len - 1) }.sort

  # Exchange the gene sequence of the two parents between these points
  # to form two proto-children (which may break the chromosome).
  inputs[0][i..j], inputs[1][i..j] = inputs[1][i..j], inputs[0][i..j]

  # To fix the proto-children we map any alleles which occur outside of
  # the exchanged sub-sequence with their counterpart in the partial map.
  mapping = Hash[(inputs[0][i..j] + inputs[1][i..j]).map { |a| [a, []] }]
  (i..j).each do |g|
    mapping[inputs[0][g]] << inputs[1][g]
    mapping[inputs[1][g]] << inputs[0][g]
  end

  # Fix all allele collisions via the map.
  inputs.each do |input|
    [(0...i), (j+1...len)].each do |sub|
      sub.each do |g|
        a = input[g]
        last = nil
        while input[i..j].include? a
          input[g] = (last.nil? or (mapping[a][0] != last)) ? mapping[a][0] : mapping[a][1]
          a, last = input[g], a
        end
      end
    end
  end

  return inputs

end