Version: v2.9.3 Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Apr 21, 2022 License: MIT Imports: 20 Imported by: 3



Package genetics holds data holders and helper utilities used to implement genetic evolution algorithm



This section is empty.


View Source
var (
	ErrUnsupportedGenomeEncoding = errors.New("unsupported genome encoding")


func NodeWithId

func NodeWithId(nodeId int, nodes []*network.NNode) *network.NNode

NodeWithId Utility to select NNode with given ID from provided NNodes array

func TraitWithId

func TraitWithId(traitId int, traits []*neat.Trait) *neat.Trait

TraitWithId Utility to select trait with given ID from provided Traits array


type ByOrganismFitness

type ByOrganismFitness []*Species

ByOrganismFitness is used for list sorting of species by maximal fitness

func (ByOrganismFitness) Len

func (f ByOrganismFitness) Len() int

func (ByOrganismFitness) Less

func (f ByOrganismFitness) Less(i, j int) bool

func (ByOrganismFitness) Swap

func (f ByOrganismFitness) Swap(i, j int)

type Gene

type Gene struct {
	// The link between nodes
	Link *network.Link
	// The current innovation number for this gene
	InnovationNum int64
	// Used to see how much mutation has changed the link
	MutationNum float64
	// If true the gene is enabled
	IsEnabled bool

The Gene type in this system specifies a "Connection Gene." Nodes are represented using the NNode class, which serves as both a genotypic and phenotypic representation of nodes. Genetic Representation of connections uses this special class because it calls for special operations better served by a specific genetic representation. A Gene object in this system specifies a link between two nodes along with an InnovationNum which tells when in the history of a population the gene first arose. This allows the system to track innovations and use those to determine which organisms are compatible (i.e. in the same species). A MutationNum gives a rough sense of how much mutation the gene has experienced since it originally appeared (Since it was first innovated). In the current implementation the mutation number is the same as the weight.

func NewConnectionGene

func NewConnectionGene(link *network.Link, innovationNum int64, mutationNum float64, enabled bool) *Gene

NewConnectionGene is to create new connection gene with provided link

func NewGene

func NewGene(weight float64, inNode, outNode *network.NNode, recurrent bool, innovationNum int64, mutationNum float64) *Gene

NewGene Creates new Gene

func NewGeneCopy

func NewGeneCopy(g *Gene, trait *neat.Trait, inNode, outNode *network.NNode) *Gene

NewGeneCopy Construct a gene off of another gene as a duplicate

func NewGeneWithTrait

func NewGeneWithTrait(trait *neat.Trait, weight float64, inNode, outNode *network.NNode,
	recurrent bool, innovationNum int64, mutationNum float64) *Gene

NewGeneWithTrait Creates new Gene with Trait

func (*Gene) String

func (g *Gene) String() string

type Genome

type Genome struct {
	// The genome ID
	Id int `yaml:"id"`
	// The parameters conglomerations
	Traits []*neat.Trait `yaml:"traits"`
	// List of NNodes for the Network
	Nodes []*network.NNode `yaml:"nodes"`
	// List of innovation-tracking genes
	Genes []*Gene `yaml:"genes"`
	// List of MIMO control genes
	ControlGenes []*MIMOControlGene `yaml:"modules"`

	// Allows Genome to be matched with its Network
	Phenotype *network.Network `yaml:""`

A Genome is the primary source of genotype information used to create a phenotype. It contains 3 major constituents:

  1. A Vector of Traits
  2. A List of NNodes pointing to a Trait from (1)
  3. A List of Genes with Links that point to Traits from (1)
  4. A List of MIMO Control Genes with Links to different genome modules

(1) Reserved parameter space for future use. (2) NNode specifications. (3) Is the primary source of innovation in the evolutionary Genome. (4) Control genes allows to receive inputs from multiple independent genome modules and output processed signal to the

multitude of output locations

Each Gene in (3) has a marker telling when it arose historically. Thus, these Genes can be used to speciate the population, and the list of Genes provide an evolutionary history of innovation and link-building.

func NewGenome

func NewGenome(id int, t []*neat.Trait, n []*network.NNode, g []*Gene) *Genome

NewGenome Constructor which takes full genome specs and puts them into the new one

func NewModularGenome

func NewModularGenome(id int, t []*neat.Trait, n []*network.NNode, g []*Gene, mimoG []*MIMOControlGene) *Genome

NewModularGenome Constructs new modular genome

func ReadGenome

func ReadGenome(ir io.Reader, id int) (*Genome, error)

ReadGenome reads Genome from reader

func (*Genome) Extrons

func (g *Genome) Extrons() int

Extrons Return # of non-disabled genes

func (*Genome) Genesis

func (g *Genome) Genesis(netId int) (*network.Network, error)

Genesis generates a Network phenotype from this Genome with specified id

func (*Genome) IsEqual

func (g *Genome) IsEqual(og *Genome) (bool, error)

IsEqual Tests if given genome is equal to this one genetically and phenotypically. This method will check that both genomes has the same traits, nodes and genes. If mismatch detected the error will be returned with mismatch details.

func (*Genome) String

func (g *Genome) String() string


func (*Genome) Write

func (g *Genome) Write(w io.Writer) error

Writes this genome into provided writer

type GenomeEncoding

type GenomeEncoding byte

GenomeEncoding Defines format of Genome data encoding

const (
	// PlainGenomeEncoding The plain text
	PlainGenomeEncoding GenomeEncoding = iota + 1
	// YAMLGenomeEncoding The rich text in YAML

type GenomeReader

type GenomeReader interface {
	// Read is tp read one Genome record
	Read() (*Genome, error)

GenomeReader The interface to define genome reader

func NewGenomeReader

func NewGenomeReader(r io.Reader, encoding GenomeEncoding) (GenomeReader, error)

NewGenomeReader Creates reader for Genome data with specified encoding format.

type GenomeWriter

type GenomeWriter interface {
	// WriteGenome writes Genome record into underlying writer
	WriteGenome(genome *Genome) error

GenomeWriter is the interface to define genome writer

func NewGenomeWriter

func NewGenomeWriter(w io.Writer, encoding GenomeEncoding) (GenomeWriter, error)

NewGenomeWriter creates genome writer with specified data encoding format

type Innovation

type Innovation struct {

	// Two nodes specify where the innovation took place
	InNodeId  int
	OutNodeId int
	// The number assigned to the innovation
	InnovationNum int64
	// If this is a new node innovation, then there are 2 innovations (links) added for the new node
	InnovationNum2 int64

	// If a link is added, this is its weight
	NewWeight float64
	// If a link is added, this is its connected trait index
	NewTraitNum int
	// If a new node was created, this is its node_id
	NewNodeId int

	// If a new node was created, this is the innovation number of the gene's link it is being stuck inside
	OldInnovNum int64

	// Flag to indicate whether its innovation for recurrent link
	IsRecurrent bool
	// contains filtered or unexported fields

Innovation serves as a way to record innovations specifically, so that an innovation in one genome can be compared with other innovations in the same epoch, and if they are the same innovation, they can both be assigned the same innovation number.

This class can encode innovations that represent a new link forming, or a new node being added. In each case, two nodes fully specify the innovation and where it must have occurred (between them).

func NewInnovationForLink(nodeInId, nodeOutId int, innovationNum int64, weight float64, traitId int) *Innovation

NewInnovationForLink is a constructor for new link case

func NewInnovationForNode

func NewInnovationForNode(nodeInId, nodeOutId int, innovationNum1, innovationNum2 int64, newNodeId int, oldInnovNum int64) *Innovation

NewInnovationForNode is a constructor for the new node case

func NewInnovationForRecurrentLink(nodeInId, nodeOutId int, innovationNum int64, weight float64, traitId int, recur bool) *Innovation

NewInnovationForRecurrentLink is a constructor for a recurrent link

type InnovationsObserver

type InnovationsObserver interface {
	// StoreInnovation is to store specific innovation
	StoreInnovation(innovation Innovation)
	// Innovations is to get list of known innovations
	Innovations() []Innovation
	// NextInnovationNumber is to get next unique global innovation number
	NextInnovationNumber() int64

InnovationsObserver the definition of component able to manage records of innovations

type MIMOControlGene

type MIMOControlGene struct {
	// The current innovation number for this gene
	InnovationNum int64
	// Used to see how much mutation has changed the link
	MutationNum float64
	// If true the gene is enabled
	IsEnabled bool

	// The control node with control/activation function
	ControlNode *network.NNode
	// contains filtered or unexported fields

MIMOControlGene The Multiple-Input Multiple-Output (MIMO) control Gene allows creating modular genomes, in which several groups of genes connected through single MIMO Gene and corresponding control function is applied to all inputs in order to produce outputs. This allows to build modular hierarchical genomes which can be considered as sum of constituent components and evolved as a whole and as a concrete parts simultaneously.

func NewMIMOGene

func NewMIMOGene(controlNode *network.NNode, innovNum int64, mutNum float64, enabled bool) *MIMOControlGene

NewMIMOGene Creates new MIMO gene

func NewMIMOGeneCopy

func NewMIMOGeneCopy(g *MIMOControlGene, controlNode *network.NNode) *MIMOControlGene

NewMIMOGeneCopy The copy constructor taking parameters from provided control gene for given control node

func (*MIMOControlGene) String

func (g *MIMOControlGene) String() string

The stringer

type Organism

type Organism struct {
	// A measure of fitness for the Organism
	Fitness float64
	// The error value indicating how far organism's performance is from ideal task goal, e.g. MSE
	Error float64
	// Win marker (if needed for a particular task)
	IsWinner bool

	// The Organism's phenotype
	Phenotype *network.Network
	// The Organism's genotype
	Genotype *Genome
	// The Species of the Organism
	Species *Species

	// Number of children this Organism may have
	ExpectedOffspring float64
	// Tells which generation this Organism is from
	Generation int

	// The utility data transfer object to be used by different GA implementations to hold additional data.
	// Implemented as ANY to allow implementation specific objects.
	Data *OrganismData

	// The flag to be used as utility value
	Flag int
	// contains filtered or unexported fields

Organism is Genotypes (Genomes) and Phenotypes (Networks) with fitness information, i.e. the genotype and phenotype together.

func NewOrganism

func NewOrganism(fit float64, g *Genome, generation int) (org *Organism, err error)

NewOrganism Creates new organism with specified genome, fitness and given generation number

func (*Organism) CheckChampionChildDamaged

func (o *Organism) CheckChampionChildDamaged() bool

CheckChampionChildDamaged Method to check if this organism is a child of the champion but has the fitness score less than of the parent. This can be used to check if champion's offsprings degraded.

func (*Organism) Dump

func (o *Organism) Dump() string

Dump is to dump all organism's fields into string

func (*Organism) MarshalBinary

func (o *Organism) MarshalBinary() ([]byte, error)

MarshalBinary Encodes this organism for wired transmission during parallel reproduction cycle

func (*Organism) String

func (o *Organism) String() string

func (*Organism) UnmarshalBinary

func (o *Organism) UnmarshalBinary(data []byte) error

UnmarshalBinary Decodes organism received over the wire during parallel reproduction cycle

func (*Organism) UpdatePhenotype

func (o *Organism) UpdatePhenotype() (err error)

UpdatePhenotype Regenerate the underlying network graph based on a change in the genotype

type OrganismData

type OrganismData struct {
	// The implementation specific data object to be associated with organism
	Value interface{}

OrganismData is the object to associate implementation specific data with particular organism for various algorithm implementations

type Organisms

type Organisms []*Organism

Organisms represents sortable list of organisms by fitness

func (Organisms) Len

func (f Organisms) Len() int

func (Organisms) Less

func (f Organisms) Less(i, j int) bool

func (Organisms) Swap

func (f Organisms) Swap(i, j int)

type ParallelPopulationEpochExecutor

type ParallelPopulationEpochExecutor struct {
	// contains filtered or unexported fields

ParallelPopulationEpochExecutor The population epoch executor with parallel reproduction cycle

func (*ParallelPopulationEpochExecutor) NextEpoch

func (p *ParallelPopulationEpochExecutor) NextEpoch(ctx context.Context, generation int, population *Population) error

type Population

type Population struct {
	// Species in the Population. Note that the species should comprise all the genomes
	Species []*Species
	// The organisms in the Population
	Organisms []*Organism
	// The highest species number
	LastSpecies int
	// An integer that when above zero tells when the first winner appeared
	WinnerGen int
	// The last generation played
	FinalGen int

	// Stagnation detector
	HighestFitness float64
	// The number of epochs when highest fitness was recorded for this population. If it was too long before
	// than delta coding will be applied to avoid population's fitness stagnation
	EpochsHighestLastChanged int

	/* Fitness Statistics */
	MeanFitness float64
	Variance    float64
	StandardDev float64
	// contains filtered or unexported fields

A Population is a group of Organisms including their species

func NewPopulation

func NewPopulation(g *Genome, opts *neat.Options) (*Population, error)

NewPopulation constructs off of a single spawning Genome

func NewPopulationRandom

func NewPopulationRandom(in, out, maxHidden int, recurrent bool, linkProb float64, opts *neat.Options) (*Population, error)

NewPopulationRandom is a special constructor to create a population of random topologies uses NewGenomeRand(new_id, in, out, n, maxHidden int, recurrent bool, link_prob float64) See the Genome constructor above for the argument specifications

func ReadPopulation

func ReadPopulation(ir io.Reader, options *neat.Options) (pop *Population, err error)

ReadPopulation reads population from provided reader

func (*Population) Innovations

func (p *Population) Innovations() []Innovation

func (*Population) NextInnovationNumber

func (p *Population) NextInnovationNumber() int64

func (*Population) NextNodeId

func (p *Population) NextNodeId() int

func (*Population) StoreInnovation

func (p *Population) StoreInnovation(innovation Innovation)

func (*Population) Verify

func (p *Population) Verify() (bool, error)

Verify is to run verification on all Genomes in this Population (Debugging)

func (*Population) Write

func (p *Population) Write(w io.Writer) error

Writes given population to a writer

func (*Population) WriteBySpecies

func (p *Population) WriteBySpecies(w io.Writer) error

WriteBySpecies Writes given population by species

type PopulationEpochExecutor

type PopulationEpochExecutor interface {
	// NextEpoch Turnover the population to a new generation
	NextEpoch(ctx context.Context, generation int, population *Population) error

PopulationEpochExecutor Executes epoch's turnover for a population of the organisms

type SequentialPopulationEpochExecutor

type SequentialPopulationEpochExecutor struct {
	// contains filtered or unexported fields

SequentialPopulationEpochExecutor The epoch executor that runs execution sequentially in single thread for all species and organisms

func (*SequentialPopulationEpochExecutor) NextEpoch

func (s *SequentialPopulationEpochExecutor) NextEpoch(ctx context.Context, generation int, population *Population) error

type Species

type Species struct {
	// The ID
	Id int
	// The age of the Species
	Age int
	// The maximal fitness it ever had
	MaxFitnessEver float64
	// How many child expected
	ExpectedOffspring int

	// Is it novel
	IsNovel bool

	// The organisms in the Species
	Organisms Organisms
	// If this is too long ago, the Species will goes extinct
	AgeOfLastImprovement int

	// Flag used for search optimization
	IsChecked bool

A Species is a group of similar Organisms. Reproduction takes place mostly within a single species, so that compatible organisms can mate.

func NewSpecies

func NewSpecies(id int) *Species

NewSpecies Construct new species with specified ID

func NewSpeciesNovel

func NewSpeciesNovel(id int, novel bool) *Species

NewSpeciesNovel Allows the creation of a Species that won't age (a novel one). This protects new Species from aging inside their first generation

func (*Species) ComputeMaxAndAvgFitness

func (s *Species) ComputeMaxAndAvgFitness() (max, avg float64)

ComputeMaxAndAvgFitness Computes maximal and average fitness of species

func (*Species) FindChampion

func (s *Species) FindChampion() *Organism

FindChampion Returns most fit organism for this species

func (*Species) Size

func (s *Species) Size() int

Size Returns size of this Species, i.e. number of Organisms belonging to it

func (*Species) String

func (s *Species) String() string

func (*Species) Write

func (s *Species) Write(w io.Writer) error

Writes species to the specified writer

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL