Class: Selection::Ranking

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

Overview

Linear ranking assignment. Ranking sorts the population by the certain criteria and asigns the :rank value and the non-negative :proportion value to each individual. The best individual obtains :rank==0 and the the biggest :proportion value, the worst individual obtains the biggest :rank value and the smallest :proportion value.

See reference.kfupm.edu.sa/content/c/o/a_comparative_analysis_of_selection_sche_73937.pdf

Defined Under Namespace

Classes: RankedFields

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (Ranking) initialize(order_by = nil, direction = nil, &block)

Initialize the ranker. See attributes and Ranking#rank method.



23
24
25
26
27
# File '../lib/ranking.rb', line 23

def initialize order_by=nil, direction=nil, &block 
  set_order( order_by, direction, block )
  @max = 1.1
  @min = 2.0 - @max
end

Instance Attribute Details

- (Object) direction

The sorting direction. Expected values are: :maximize, :minimize.



40
41
42
# File '../lib/ranking.rb', line 40

def direction
  @direction
end

- (Object) max

The :proportion value of the best individual. Default is 1.1



30
31
32
# File '../lib/ranking.rb', line 30

def max
  @max
end

- (Object) min

The :proportion value of the worst individual. Default is 0.9



33
34
35
# File '../lib/ranking.rb', line 33

def min
  @min
end

- (Object) order_by

The symbol used as the sorting key. The value for ordering is retireved by calling:


  individual.send(order_by)


37
38
39
# File '../lib/ranking.rb', line 37

def order_by
  @order_by
end

Instance Method Details

- (Object) rank(population)

If the block was given to the constructor, calls


  { |original, rank, proportion| ... }

for each population and returns the population container.

Otherwise it returns the array of the RankedFields structures, one for each population member.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File '../lib/ranking.rb', line 47

def rank population
  ranked = population.map { |orig| RankedFields.new orig }
  raise "Ranking: empty population" if ranked.empty?
  ranked.each_with_index { |individual, i| individual.index = i }
  ranked.sort! { |a,b| @order.call( a.original, b.original ) }

  rank = 0
  ranked.each_with_index do |individual, index|
    individual.rank = rank
    break if index == ranked.size-1
    rank += 1 unless 0 == @order.call( individual.original, ranked[index+1].original )
  end

  min = @min.to_f
  amplitude = @max.to_f-min
  rank = rank==0 ? 1.0 : rank.to_f
  ranked.each { |individual| individual.proportion = min+amplitude*(rank-individual.rank)/rank }
 
  if block_given?
    ranked.each { |r| yield( population[r.index], r.rank, r.proportion ) }
    return population
  else
    return ranked
  end
end