lib/individual.rb
# Multi point crossover
# gene is divided by points of the number of po_num.

Multi point crossover
gene is divided by points of the number of po_num.
Multi point crossover gene is divided by points of the number of po_num .
def multi_point_crossover(gene1, gene2, po_num=2)
    case po_num
    when 0
      raise "You must give 1 or more value for po_num."
    when 1
      return one_point_crossover(gene1, gene2)
    when (gene1.size - 1) 
      return stitch_crossover(gene1, gene2, 1)
    else 
      if po_num >= gene1.size
        raise "Too many points! po_num must be less than gene size."
      end
      points = []
      tmp1 = gene1.dup
      tmp2 = gene2.dup
      tmp_p = (1..tmp1.size).to_a
      while (points.size < po_num)
        points << tmp_p.delete_at(rand(tmp_p.size))
      end
      points.sort!
      child1 = []
      child2 = []
      flg = true
      points.unshift 0
      points.push tmp1.size
      (points.size - 1).times do |idx|
        p_from = points[idx]
        nof_p= points[idx+1] - points[idx] 
        if flg == true
          child1 += tmp1.slice(p_from, nof_p)
          child2 += tmp2.slice(p_from, nof_p)
        else
          child1 += tmp2.slice(p_from, nof_p)
          child2 += tmp1.slice(p_from, nof_p)
        end
        flg = !flg
      end
      return child1, child2
    end
  end
def multi_point_crossover ( gene1 , gene2 , po_num = 2 ) case po_num when 0 raise "You must give 1 or more value for po_num." when 1 return one_point_crossover ( gene1 , gene2 ) when ( gene1 . size - 1 ) return stitch_crossover ( gene1 , gene2 , 1 ) else if po_num >= gene1 . size raise "Too many points! po_num must be less than gene size." end points = [ ] tmp1 = gene1 . dup tmp2 = gene2 . dup tmp_p = ( 1 .. tmp1 . size ) . to_a while ( points . size < po_num ) points << tmp_p . delete_at ( rand ( tmp_p . size ) ) end points . sort! child1 = [ ] child2 = [ ] flg = true points . unshift 0 points . push tmp1 . size ( points . size - 1 ) . times do | idx | p_from = points [ idx ] nof_p = points [ idx + 1 ] - points [ idx ] if flg == true child1 += tmp1 . slice ( p_from , nof_p ) child2 += tmp2 . slice ( p_from , nof_p ) else child1 += tmp2 . slice ( p_from , nof_p ) child2 += tmp1 . slice ( p_from , nof_p ) end flg = ! flg end return child1 , child2 end end
Multi point crossover
gene is divided by points of the number of po_num.
Multi point crossover gene is divided by points of the number of po_num .
# same as stitch_crossover with cnum=1.
 # Decide which positions for crossover in random.
 # Duplicate gene1 and gene2 to avoid destructed by slice! method.
 # [memo] It doesn't need if there is no destructive methods for gene1, 2.
 # points in random.
 # Add 0 to head and points.size to tails for using them as index of slice.
 #p points # debug
 # num of points to slice
 #puts "from:#{p_from}, num of p:#{nof_p}"  # debug

gene1
<not_specific>
gene2
<not_specific>
po_num
<not_specific>