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.

[View source]

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.

[View source]

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