Class: CrossoverArray

Inherits:
Object
  • Object
show all
Defined in:
lib/evopop/crossover_array.rb

Overview

Class for handling crossover against arrays. Supports

* Single point crossover
* n-point corssover

Class Method Summary collapse

Class Method Details

.build_dna_by_synchronous(cdna_a, cdna_b, pdna_a, pdna_b, ordinal_range, synchronous) ⇒ Object



57
58
59
60
61
62
63
64
# File 'lib/evopop/crossover_array.rb', line 57

def self.build_dna_by_synchronous(cdna_a, cdna_b, pdna_a, pdna_b, ordinal_range, synchronous)
  pdnas = [pdna_a, pdna_b]
  pdnas.reverse! unless synchronous
  cdna_a += pdnas[0][ordinal_range]
  cdna_b += pdnas[1][ordinal_range]

  [cdna_a, cdna_b]
end

.combine_on_ordinal(dna_a, dna_b, ordinals) ⇒ Object



53
54
55
# File 'lib/evopop/crossover_array.rb', line 53

def self.combine_on_ordinal(dna_a, dna_b, ordinals)
  dna_a[0..ordinals[0]] + dna_b[(ordinals[0] + 1)..ordinals[1]] + dna_a[(ordinals[1] + 1)..dna_a.length - 1]
end

.n_point_crossover(dna_a, dna_b, ordinals) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/evopop/crossover_array.rb', line 29

def self.n_point_crossover(dna_a, dna_b, ordinals)
  ret_a = []
  ret_b = []

  old_ordinal = 0
  toggle = true
  ordinals << dna_a.length + 1

  ordinals.each do |ordinal|
    if toggle
      ret_a += dna_a[old_ordinal..ordinal]
      ret_b += dna_b[old_ordinal..ordinal]
    else
      ret_a += dna_b[old_ordinal..ordinal]
      ret_b += dna_a[old_ordinal..ordinal]
    end

    old_ordinal = ordinal + 1
    toggle = !toggle
  end

  [ret_a, ret_b]
end

.one_point_crossover(a, b, ordinal) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/evopop/crossover_array.rb', line 8

def self.one_point_crossover(a, b, ordinal)
  # Compose the dna of the first child from the first chunk of the
  # first candidate and the second chunk of the second candidate
  dna_a_left = a[0..ordinal]
  dna_b_right = b[(ordinal + 1)..-1]

  # Compose the dna of the second child from the first chunk of the
  # first candidate and the second chunk of the second candidate
  dna_b_left = b[0..ordinal]
  dna_a_right = a[(ordinal + 1)..-1]

  [dna_a_left + dna_b_right, dna_b_left + dna_a_right]
end

.two_point_crossover(cdna_a, cdna_b, ordinals) ⇒ Object



22
23
24
25
26
27
# File 'lib/evopop/crossover_array.rb', line 22

def self.two_point_crossover(cdna_a, cdna_b, ordinals)
  dna_a = combine_on_ordinal(cdna_a, cdna_b, ordinals)
  dna_b = combine_on_ordinal(cdna_b, cdna_a, ordinals)

  [dna_a, dna_b]
end