Module: Evolvable::Community

Defined in:
lib/evolvable/community.rb

Overview

The Community module provides a framework for coordinating multiple evolvable populations under a unified interface. Each population represents a distinct type of evolvable, and each key returns a single evolvable instance drawn from its corresponding population.

Communities are ideal for simulations or systems where different components evolve in parallel but interact as part of a larger whole - such as ecosystems, design systems, or modular agents. Evolvables from different populations can co-evolve, influencing each other's fitness.

Use the evolvable_community macro to declare the set of named populations in the community. Each population will have a corresponding method (e.g., fish_1, plant, shrimp) that returns a single evolvable instance. You can evolve all populations together using the evolve method, or per population.

Key Features

  • Define a community composed of named populations
  • Automatically generate accessors for each evolvable instance
  • Coordinate evolution across populations through a shared interface
  • Evolve all populations in a single call with evolve(...)

This FishTank example sets up a community with four named populations:

class FishTank
  include Evolvable::Community

  evolvable_community fish_1: Fish,
                      fish_2: Fish,
                      plant: AquariumPlant,
                      shrimp: CleanerShrimp

  def describe_tank
    puts "🐟 Fish 1: #{fish_1.name} (#{fish_1.color})"
    puts "🐟 Fish 2: #{fish_2.name} (#{fish_2.color})"
    puts "🌿 Plant: #{plant.name} (#{plant.color})"
    puts "🦐 Shrimp: #{shrimp.name} (#{shrimp.color})"
  end
end

Initialize the community, describe the tank, and evolve each population:

tank = FishTank.new_community
tank.describe_tank
tank.evolve

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



54
55
56
# File 'lib/evolvable/community.rb', line 54

def self.included(base)
  base.extend(ClassMethods)
end

Instance Method Details

#add_evolvable(name, evolvable) ⇒ Object

Adds an evolvable instance to the community

Parameters:

  • name (String, Symbol)

    The name of the evolvable

  • evolvable (Object)

    The evolvable instance

Returns:

  • (Object)

    The added evolvable



174
175
176
# File 'lib/evolvable/community.rb', line 174

def add_evolvable(name, evolvable)
  evolvables_by_name[name.to_sym] = evolvable
end

#add_population(name, population) ⇒ Object

Adds a population to the community

Parameters:

  • name (String, Symbol)

    The name of the population

  • population (Object)

    The population instance

Returns:

  • (Object)

    The added population



138
139
140
# File 'lib/evolvable/community.rb', line 138

def add_population(name, population)
  populations_by_name[name.to_sym] = population
end

#evolvables_by_nameHash

Returns a hash of evolvable instances by name

Returns:

  • (Hash)

    A hash mapping names to evolvable instances



180
181
182
# File 'lib/evolvable/community.rb', line 180

def evolvables_by_name
  @evolvables_by_name ||= {}
end

#evolvevoid

This method returns an undefined value.

Evolves all populations in the community



124
125
126
# File 'lib/evolvable/community.rb', line 124

def evolve(...)
  populations.each { |population| population.evolve(...) }
end

#find_evolvable(name) ⇒ Object?

Finds an evolvable instance by name

Parameters:

  • name (String, Symbol)

    The name of the evolvable

Returns:

  • (Object, nil)

    The evolvable instance or nil if not found



152
153
154
# File 'lib/evolvable/community.rb', line 152

def find_evolvable(name)
  evolvables_by_name[name.to_sym]
end

#find_or_new_evolvable(name) ⇒ Object

Finds an existing evolvable instance by name or creates a new one

Parameters:

  • name (String, Symbol)

    The name of the evolvable

Returns:

  • (Object)

    The existing or new evolvable instance



159
160
161
# File 'lib/evolvable/community.rb', line 159

def find_or_new_evolvable(name)
  find_evolvable(name) || new_evolvable(name)
end

#find_population(name) ⇒ Object?

Finds a population by name

Parameters:

  • name (String, Symbol)

    The name of the population

Returns:

  • (Object, nil)

    The population instance or nil if not found



145
146
147
# File 'lib/evolvable/community.rb', line 145

def find_population(name)
  populations_by_name[name.to_sym]
end

#new_evolvable(name) ⇒ Object

Creates a new evolvable instance from the corresponding population

Parameters:

  • name (String, Symbol)

    The name of the evolvable

Returns:

  • (Object)

    The new evolvable instance



166
167
168
# File 'lib/evolvable/community.rb', line 166

def new_evolvable(name)
  evolvables_by_name[name.to_sym] = find_population(name).new_evolvable
end

#populationsArray

Returns an array of population instances

Returns:

  • (Array)

    An array of population instances



118
119
120
# File 'lib/evolvable/community.rb', line 118

def populations
  populations_by_name.values
end

#populations_by_nameHash

Returns a hash of population instances by name

Returns:

  • (Hash)

    A hash mapping names to population instances



112
113
114
# File 'lib/evolvable/community.rb', line 112

def populations_by_name
  @populations_by_name ||= self.class.populations_by_name.dup
end

#reset_evolvablesHash

Resets the evolvables hash to an empty hash

Returns:

  • (Hash)

    An empty hash



186
187
188
# File 'lib/evolvable/community.rb', line 186

def reset_evolvables
  @evolvables_by_name = {}
end

#reset_populationsHash

Resets the populations hash to an empty hash

Returns:

  • (Hash)

    An empty hash



130
131
132
# File 'lib/evolvable/community.rb', line 130

def reset_populations
  @populations_by_name = {}
end