Class: Darwinning::Population

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

Constant Summary collapse

EPSILON =
0.01
DEFAULT_EVOLUTION_TYPES =
[
  Darwinning::EvolutionTypes::Reproduction.new(crossover_method: :alternating_swap),
  Darwinning::EvolutionTypes::Mutation.new(mutation_rate: 0.10)
]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Population

Returns a new instance of Population



15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/darwinning/population.rb', line 15

def initialize(options = {})
  @organism = options.fetch(:organism)
  @population_size = options.fetch(:population_size)
  @fitness_goal = options.fetch(:fitness_goal)
  @generations_limit = options.fetch(:generations_limit, 0)
  @evolution_types = options.fetch(:evolution_types, DEFAULT_EVOLUTION_TYPES)
  @members = []
  @generation = 0 # initial population is generation 0
  @history = []

  build_population(@population_size)
  @history << @members
end

Instance Attribute Details

#evolution_typesObject (readonly)

Returns the value of attribute evolution_types



6
7
8
# File 'lib/darwinning/population.rb', line 6

def evolution_types
  @evolution_types
end

#fitness_goalObject (readonly)

Returns the value of attribute fitness_goal



6
7
8
# File 'lib/darwinning/population.rb', line 6

def fitness_goal
  @fitness_goal
end

#generationObject (readonly)

Returns the value of attribute generation



6
7
8
# File 'lib/darwinning/population.rb', line 6

def generation
  @generation
end

#generations_limitObject (readonly)

Returns the value of attribute generations_limit



6
7
8
# File 'lib/darwinning/population.rb', line 6

def generations_limit
  @generations_limit
end

#historyObject (readonly)

Returns the value of attribute history



6
7
8
# File 'lib/darwinning/population.rb', line 6

def history
  @history
end

#membersObject (readonly)

Returns the value of attribute members



6
7
8
# File 'lib/darwinning/population.rb', line 6

def members
  @members
end

#organismObject (readonly)

Returns the value of attribute organism



6
7
8
# File 'lib/darwinning/population.rb', line 6

def organism
  @organism
end

#population_sizeObject (readonly)

Returns the value of attribute population_size



6
7
8
# File 'lib/darwinning/population.rb', line 6

def population_size
  @population_size
end

Instance Method Details

#best_memberObject



71
72
73
# File 'lib/darwinning/population.rb', line 71

def best_member
  @members.sort_by { |m| m.fitness }.first
end

#build_population(population_size) ⇒ Object



29
30
31
32
33
# File 'lib/darwinning/population.rb', line 29

def build_population(population_size)
  population_size.times do |i|
    @members << build_member
  end
end

#evolution_over?Boolean

Returns:

  • (Boolean)


62
63
64
65
66
67
68
69
# File 'lib/darwinning/population.rb', line 62

def evolution_over?
  # check if the fitness goal or generation limit has been met
  if generations_limit > 0
    generation == generations_limit || best_member.fitness == fitness_goal
  else
    best_member.fitness == fitness_goal
  end
end

#evolve!Object



35
36
37
38
39
# File 'lib/darwinning/population.rb', line 35

def evolve!
  until evolution_over?
    make_next_generation!
  end
end

#make_next_generation!Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/darwinning/population.rb', line 46

def make_next_generation!
  temp_members = members
  new_members = []

  until new_members.length == members.length
    m1 = weighted_select(members)
    m2 = weighted_select(members)

    new_members += apply_pairwise_evolutions(m1, m2)
  end

  @members = apply_non_pairwise_evolutions(new_members)
  @history << @members
  @generation += 1
end

#organism_klassObject



79
80
81
82
83
84
85
86
# File 'lib/darwinning/population.rb', line 79

def organism_klass
  real_organism = @organism
  fitness_function = @fitness_function
  klass = Class.new(Darwinning::Organism) do
    @name = real_organism.name
    @genes = real_organism.genes
  end
end

#set_members_fitness!(fitness_values) ⇒ Object



41
42
43
44
# File 'lib/darwinning/population.rb', line 41

def set_members_fitness!(fitness_values)
  throw "Invaid number of fitness values for population size" if fitness_values.size != members.size
  members.to_enum.each_with_index { |m, i| m.fitness = fitness_values[i] }
end

#sizeObject



75
76
77
# File 'lib/darwinning/population.rb', line 75

def size
  @members.length
end