Class: Evolvable::CountGene

Inherits:
Object
  • Object
show all
Includes:
Gene
Defined in:
lib/evolvable/count_gene.rb

Overview

The CountGene class handles the dynamic count of genes in evolvable instances. When a gene is defined with a range for count: (e.g., count: 2..8), a CountGene is created to manage this count, allowing the number of genes to change over successive generations.

Examples:

Define a melody with a variable number of notes (4 to 16)

class Melody
  include Evolvable

  gene :notes, type: NoteGene, count: 4..16

  # The actual number of notes can change during evolution
  def play
    puts "Playing melody with #{notes.count} notes"
  end
end

Constant Summary collapse

LAMBDAS =

Available strategies for combining count genes. These lambdas determine how two count genes are merged during evolution.

  1. Random selection with slight mutation (-1, 0, or +1)
  2. Average of the two counts
[->(a, b) { [a, b].sample.count + rand(-1..1) },
->(a, b) { a.count + b.count / 2 }].freeze

Instance Attribute Summary collapse

Attributes included from Gene

#evolvable

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Gene

included, #key

Constructor Details

#initialize(range:, count: nil) ⇒ CountGene

Initializes a new CountGene instance.

Parameters:

  • range (Range)

    The valid range for the count value

  • count (Integer, nil) (defaults to: nil)

    Optional initial count value, randomly selected from range if nil



67
68
69
70
# File 'lib/evolvable/count_gene.rb', line 67

def initialize(range:, count: nil)
  @range = range
  @count = count
end

Instance Attribute Details

#rangeRange (readonly)

The valid range for the count value.

Returns:

  • (Range)

    The range of possible count values



77
78
79
# File 'lib/evolvable/count_gene.rb', line 77

def range
  @range
end

Class Method Details

.combinationProc

Selects a random combination strategy from LAMBDAS.

Returns:

  • (Proc)

    A lambda function for combining two count genes



56
57
58
# File 'lib/evolvable/count_gene.rb', line 56

def combination
  LAMBDAS.sample
end

.combine(gene_a, gene_b) ⇒ CountGene

Combines two count genes to produce a new count gene. The combination strategy is randomly selected from LAMBDAS.

Parameters:

  • gene_a (CountGene)

    The first count gene

  • gene_b (CountGene)

    The second count gene

Returns:

  • (CountGene)

    A new count gene with a combined count value



34
35
36
37
38
39
# File 'lib/evolvable/count_gene.rb', line 34

def combine(gene_a, gene_b)
  min = gene_a.min_count
  max = gene_a.max_count
  count = combination.call(gene_a, gene_b).clamp(min, max)
  new(range: gene_a.range, count: count)
end

Instance Method Details

#countInteger

Returns the current count value. If not already set, randomly selects a value from the range.

Returns:

  • (Integer)

    The number of genes to create



85
86
87
# File 'lib/evolvable/count_gene.rb', line 85

def count
  @count ||= rand(@range)
end

#max_countInteger

The maximum allowed count value.

Returns:

  • (Integer)

    The maximum value from the range



103
104
105
# File 'lib/evolvable/count_gene.rb', line 103

def max_count
  @range.max
end

#min_countInteger

The minimum allowed count value.

Returns:

  • (Integer)

    The minimum value from the range



94
95
96
# File 'lib/evolvable/count_gene.rb', line 94

def min_count
  @range.min
end