Documentation ¶
Index ¶
- func CrossCX(p1, p2 Slice)
- func CrossCXFloat64(s1 []float64, s2 []float64)
- func CrossCXInt(s1 []int, s2 []int)
- func CrossCXString(s1 []string, s2 []string)
- func CrossERX(p1, p2 Slice)
- func CrossERXFloat64(s1 []float64, s2 []float64)
- func CrossERXInt(s1 []int, s2 []int)
- func CrossERXString(s1 []string, s2 []string)
- func CrossGNX(p1 Slice, p2 Slice, n int, rng *rand.Rand)
- func CrossGNXFloat64(s1 []float64, s2 []float64, n int, rng *rand.Rand)
- func CrossGNXInt(s1 []int, s2 []int, n int, rng *rand.Rand)
- func CrossGNXString(s1 []string, s2 []string, n int, rng *rand.Rand)
- func CrossOX(p1 Slice, p2 Slice, rng *rand.Rand)
- func CrossOXFloat64(s1 []float64, s2 []float64, rng *rand.Rand)
- func CrossOXInt(s1 []int, s2 []int, rng *rand.Rand)
- func CrossOXString(s1 []string, s2 []string, rng *rand.Rand)
- func CrossPMX(p1 Slice, p2 Slice, rng *rand.Rand)
- func CrossPMXFloat64(s1 []float64, s2 []float64, rng *rand.Rand)
- func CrossPMXInt(s1 []int, s2 []int, rng *rand.Rand)
- func CrossPMXString(s1 []string, s2 []string, rng *rand.Rand)
- func CrossUniformFloat64(p1 []float64, p2 []float64, rng *rand.Rand)
- func InitJaggFloat64(n int, lower, upper []float64, rng *rand.Rand) (floats []float64)
- func InitNormFloat64(n int, mean, std float64, rng *rand.Rand) (floats []float64)
- func InitUnifFloat64(n int, lower, upper float64, rng *rand.Rand) (floats []float64)
- func InitUnifString(n int, corpus []string, rng *rand.Rand) (strings []string)
- func InitUniqueString(n int, corpus []string, rng *rand.Rand) (strings []string)
- func MutNormalFloat64(genome []float64, rate float64, rng *rand.Rand)
- func MutPermute(genome Slice, n int, rng *rand.Rand)
- func MutPermuteFloat64(s []float64, n int, rng *rand.Rand)
- func MutPermuteInt(s []int, n int, rng *rand.Rand)
- func MutPermuteString(s []string, n int, rng *rand.Rand)
- func MutSplice(genome Slice, rng *rand.Rand)
- func MutSpliceFloat64(s []float64, rng *rand.Rand)
- func MutSpliceInt(s []int, rng *rand.Rand)
- func MutSpliceString(s []string, rng *rand.Rand)
- func MutUniformString(genome []string, corpus []string, n int, rng *rand.Rand)
- type DistanceMemoizer
- type Float64Slice
- func (s Float64Slice) Append(t Slice) Slice
- func (s Float64Slice) At(i int) interface{}
- func (s Float64Slice) Copy() Slice
- func (s Float64Slice) Len() int
- func (s Float64Slice) Replace(t Slice)
- func (s Float64Slice) Set(i int, v interface{})
- func (s Float64Slice) Slice(a, b int) Slice
- func (s Float64Slice) Split(k int) (Slice, Slice)
- func (s Float64Slice) Swap(i, j int)
- type GA
- type Genome
- type Individual
- func (indi Individual) Clone(rng *rand.Rand) Individual
- func (indi *Individual) Crossover(mate Individual, rng *rand.Rand)
- func (indi *Individual) Evaluate()
- func (indi *Individual) GetFitness() float64
- func (indi Individual) IdxOfClosest(indis Individuals, dm DistanceMemoizer) (i int)
- func (indi *Individual) Mutate(rng *rand.Rand)
- func (indi Individual) String() string
- type Individuals
- func (indis Individuals) Apply(f func(indi *Individual) error, parallel bool) error
- func (indis Individuals) Clone(rng *rand.Rand) Individuals
- func (indis Individuals) Evaluate(parallel bool)
- func (indis Individuals) FitAvg() float64
- func (indis Individuals) FitMax() float64
- func (indis Individuals) FitMin() float64
- func (indis Individuals) FitStd() float64
- func (indis Individuals) IsSortedByFitness() bool
- func (indis Individuals) Mutate(mutRate float64, rng *rand.Rand)
- func (indis Individuals) SortByDistanceToMedoid(dm DistanceMemoizer)
- func (indis Individuals) SortByFitness()
- func (indis Individuals) String() string
- type IntSlice
- func (s IntSlice) Append(t Slice) Slice
- func (s IntSlice) At(i int) interface{}
- func (s IntSlice) Copy() Slice
- func (s IntSlice) Len() int
- func (s IntSlice) Replace(t Slice)
- func (s IntSlice) Set(i int, v interface{})
- func (s IntSlice) Slice(a, b int) Slice
- func (s IntSlice) Split(k int) (Slice, Slice)
- func (s IntSlice) Swap(i, j int)
- type Metric
- type MigRing
- type Migrator
- type ModDownToSize
- type ModGenerational
- type ModMutationOnly
- type ModRing
- type ModSimAnn
- type ModSteadyState
- type Model
- type NewGenome
- type Population
- type Populations
- type SelElitism
- type SelRoulette
- type SelTournament
- type Selector
- type Slice
- type SpecFitnessInterval
- type SpecKMedoids
- type Speciator
- type StringSlice
- func (s StringSlice) Append(t Slice) Slice
- func (s StringSlice) At(i int) interface{}
- func (s StringSlice) Copy() Slice
- func (s StringSlice) Len() int
- func (s StringSlice) Replace(t Slice)
- func (s StringSlice) Set(i int, v interface{})
- func (s StringSlice) Slice(a, b int) Slice
- func (s StringSlice) Split(k int) (Slice, Slice)
- func (s StringSlice) Swap(i, j int)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CrossCX ¶
func CrossCX(p1, p2 Slice)
CrossCX (Cycle Crossover). Cycles between the parents are indentified, they are then copied alternatively onto the offsprings. The CX method is deterministic and preserves gene uniqueness.
func CrossCXFloat64 ¶
CrossCXFloat64 calls CrossCX on a float64 slice.
func CrossCXString ¶
CrossCXString calls CrossCX on a string slice.
func CrossERXFloat64 ¶
CrossERXFloat64 callsCrossERX on a float64 slice.
func CrossERXString ¶
CrossERXString calls CrossERX on a string slice.
func CrossGNX ¶
CrossGNX (Generalized N-point Crossover). An identical point is chosen on each parent's genome and the mirroring segments are switched. n determines the number of crossovers (aka mirroring segments) to perform. n has to be equal or lower than the number of genes in each parent.
func CrossGNXFloat64 ¶
CrossGNXFloat64 calls CrossGNX on two float64 slices.
func CrossGNXInt ¶
CrossGNXInt calls CrossGNX on two int slices.
func CrossGNXString ¶
CrossGNXString calls CrossGNX on two string slices.
func CrossOX ¶
CrossOX (Ordered Crossover). Part of the first parent's genome is copied onto the first offspring's genome. Then the second parent's genome is iterated over, starting on the right of the part that was copied. Each gene of the second parent's genome is copied onto the next blank gene of the first offspring's genome if it wasn't already copied from the first parent. The OX method preserves gene uniqueness.
func CrossOXFloat64 ¶
CrossOXFloat64 calls CrossOX on a float64 slice.
func CrossOXInt ¶
CrossOXInt calls CrossOX on a int slice.
func CrossOXString ¶
CrossOXString calls CrossOX on a string slice.
func CrossPMX ¶
CrossPMX (Partially Mapped Crossover). The offsprings are generated by copying one of the parents and then copying the other parent's values up to a randomly chosen crossover point. Each gene that is replaced is permuted with the gene that is copied in the first parent's genome. Two offsprings are generated in such a way (because there are two parents). The PMX method preserves gene uniqueness.
func CrossPMXFloat64 ¶
CrossPMXFloat64 calls CrossPMX on a float64 slice.
func CrossPMXInt ¶
CrossPMXInt calls CrossPMX on an int slice.
func CrossPMXString ¶
CrossPMXString calls CrossPMX on a string slice.
func CrossUniformFloat64 ¶
CrossUniformFloat64 crossover combines two individuals (the parents) into one (the offspring). Each parent's contribution to the Genome is determined by the value of a probability p. Each offspring receives a proportion of both of it's parents genomes. The new values are located in the hyper-rectangle defined between both parent's position in Cartesian space.
func InitJaggFloat64 ¶
InitJaggFloat64 generates random float64s x such that lower < x < upper with jagged bounds
func InitNormFloat64 ¶
InitNormFloat64 generates random float64s sampled from a normal distribution.
func InitUnifFloat64 ¶
InitUnifFloat64 generates random float64s x such that lower < x < upper.
func InitUnifString ¶
InitUnifString generates random strings based on a given corpus. The strings are not necessarily distinct.
func InitUniqueString ¶
InitUniqueString generates random string slices based on a given corpus, each element from the corpus is only represented once in each slice. The method starts by shuffling, it then assigns the elements of the corpus in increasing index order to an individual.
func MutNormalFloat64 ¶
MutNormalFloat64 modifies a float64 gene if a coin toss is under a defined mutation rate. The new gene value is a random value sampled from a normal distribution centered on the gene's current value and with a standard deviation proportional to the current value. It does so for each gene.
func MutPermute ¶
MutPermute permutes two genes at random n times.
func MutPermuteFloat64 ¶
MutPermuteFloat64 calls MutPermute on a float64 slice.
func MutPermuteInt ¶
MutPermuteInt calls MutPermute on an int slice.
func MutPermuteString ¶
MutPermuteString callsMutPermute on a string slice.
func MutSplice ¶
MutSplice splits a genome in 2 and glues the pieces back together in reverse order.
func MutSpliceFloat64 ¶
MutSpliceFloat64 calls MutSplice on a float64 slice.
func MutSpliceInt ¶
MutSpliceInt calls MutSplice on an int slice.
func MutSpliceString ¶
MutSpliceString calls MutSplice on a string slice.
Types ¶
type DistanceMemoizer ¶
type DistanceMemoizer struct { Metric Metric Distances map[string]map[string]float64 // contains filtered or unexported fields }
A DistanceMemoizer computes and stores Metric calculations.
func (*DistanceMemoizer) GetDistance ¶
func (dm *DistanceMemoizer) GetDistance(a, b Individual) float64
GetDistance returns the distance between two Individuals based on the DistanceMemoizer's Metric field. If the two individuals share the same ID then GetDistance returns 0. DistanceMemoizer stores the calculated distances so that if GetDistance is called twice with the two same Individuals then the second call will return the stored distance instead of recomputing it.
type Float64Slice ¶
type Float64Slice []float64
Float64Slice attaches the methods of Slice to []float64
type GA ¶
type GA struct { // Required fields NewGenome NewGenome `json:"-"` NPops int `json:"-"` // Number of Populations PopSize int `json:"-"` // Number of Individuls per Population Model Model `json:"-"` // Optional fields NBest int `json:"-"` // Length of HallOfFame Migrator Migrator `json:"-"` MigFrequency int `json:"-"` // Frequency at which migrations occur Speciator Speciator `json:"-"` Logger *log.Logger `json:"-"` Callback func(ga *GA) `json:"-"` RNG *rand.Rand `json:"-"` ParallelEval bool `json:"-"` // Fields generated at runtime Populations Populations `json:"populations"` HallOfFame Individuals `json:"hall_of_fame"` // Sorted best Individuals ever encountered Age time.Duration `json:"duration"` // Duration during which the GA has been evolved Generations int `json:"generations"` // Number of generations the GA has been evolved }
A GA contains population which themselves contain individuals.
func Generational ¶
Generational returns a GA instance that uses the generational model.
func HillClimbing ¶
HillClimbing returns a GA instance that mimicks a basic hill-climbing procedure.
func SimulatedAnnealing ¶
SimulatedAnnealing returns a GA instance that mimicks a basic simulated annealing procedure.
func (*GA) Evolve ¶
Evolve each population in the GA. The population level operations are done in parallel with a wait group. After all the population operations have been run, the GA level operations are run.
func (*GA) Initialize ¶
func (ga *GA) Initialize()
Initialize each population in the GA and assign an initial fitness to each individual in each population. Running Initialize after running Evolve will reset the GA entirely.
func (GA) Initialized ¶
Initialized indicates if the GA has been initialized or not.
type Genome ¶
type Genome interface { Evaluate() float64 Mutate(rng *rand.Rand) Crossover(genome Genome, rng *rand.Rand) Clone() Genome }
A Genome is an object that can have any number and kinds of properties. As long as it can be evaluated, mutated and crossedover then it can evolved.
type Individual ¶
type Individual struct { Genome Genome `json:"genome"` Fitness float64 `json:"fitness"` Evaluated bool `json:"-"` ID string `json:"id"` }
An Individual wraps a Genome and contains the fitness assigned to the Genome.
func NewIndividual ¶
func NewIndividual(genome Genome, rng *rand.Rand) Individual
NewIndividual returns a fresh individual.
func (Individual) Clone ¶
func (indi Individual) Clone(rng *rand.Rand) Individual
Clone an individual to produce a new individual with a different pointer and a different ID.
func (*Individual) Crossover ¶
func (indi *Individual) Crossover(mate Individual, rng *rand.Rand)
Crossover an individual by calling the Crossover method of it's Genome.
func (*Individual) Evaluate ¶
func (indi *Individual) Evaluate()
Evaluate the fitness of an individual. Don't evaluate individuals that have already been evaluated.
func (*Individual) GetFitness ¶
func (indi *Individual) GetFitness() float64
GetFitness returns the fitness of an Individual after making sure it has been evaluated.
func (Individual) IdxOfClosest ¶
func (indi Individual) IdxOfClosest(indis Individuals, dm DistanceMemoizer) (i int)
IdxOfClosest returns the index of the closest individual from a slice of individuals based on the Metric field of a DistanceMemoizer.
func (*Individual) Mutate ¶
func (indi *Individual) Mutate(rng *rand.Rand)
Mutate an individual by calling the Mutate method of it's Genome.
func (Individual) String ¶
func (indi Individual) String() string
String representation of an Individual. A tick (✔) or cross (✘) marker is added at the end to indicate if the Individual has been evaluated or not.
type Individuals ¶
type Individuals []Individual
Individuals is a convenience type, methods that belong to an Individual can be called declaratively.
func (Individuals) Apply ¶
func (indis Individuals) Apply(f func(indi *Individual) error, parallel bool) error
Apply a function to a slice of Individuals.
func (Individuals) Clone ¶
func (indis Individuals) Clone(rng *rand.Rand) Individuals
Clone returns the same exact same slice of individuals but with different pointers and ID fields.
func (Individuals) Evaluate ¶
func (indis Individuals) Evaluate(parallel bool)
Evaluate each Individual. If parallel is true then each Individual will be evaluated in parallel thanks to the golang.org/x/sync/errgroup package. If not then a simple sequential loop will be used. Evaluating in parallel is only recommended for cases where evaluating an Individual takes a "long" time. Indeed there won't necessarily be a speed-up when evaluating in parallel. In fact performance can be degraded if evaluating an Individual is too cheap.
func (Individuals) FitAvg ¶
func (indis Individuals) FitAvg() float64
FitAvg returns the average fitness of a slice of individuals.
func (Individuals) FitMax ¶
func (indis Individuals) FitMax() float64
FitMax returns the best fitness of a slice of individuals.
func (Individuals) FitMin ¶
func (indis Individuals) FitMin() float64
FitMin returns the best fitness of a slice of individuals.
func (Individuals) FitStd ¶
func (indis Individuals) FitStd() float64
FitStd returns the standard deviation of the fitness of a slice of individuals.
func (Individuals) IsSortedByFitness ¶
func (indis Individuals) IsSortedByFitness() bool
IsSortedByFitness checks if individuals are ascendingly sorted by fitness.
func (Individuals) Mutate ¶
func (indis Individuals) Mutate(mutRate float64, rng *rand.Rand)
Mutate each individual.
func (Individuals) SortByDistanceToMedoid ¶
func (indis Individuals) SortByDistanceToMedoid(dm DistanceMemoizer)
SortByDistanceToMedoid sorts Individuals according to their distance to the medoid. The medoid is the Individual that has the lowest average distance to the rest of the Individuals.
func (Individuals) SortByFitness ¶
func (indis Individuals) SortByFitness()
SortByFitness ascendingly sorts individuals by fitness.
func (Individuals) String ¶
func (indis Individuals) String() string
String representation of a slice of Individuals.
type Metric ¶
type Metric func(a, b Individual) float64
A Metric returns the distance between two genomes.
type MigRing ¶
type MigRing struct {
NMigrants int // Number of migrants per exchange between Populations
}
MigRing migration exchanges individuals between consecutive Populations in a random fashion. One by one, each population exchanges NMigrants individuals at random with the next population. NMigrants should be higher than the number of individuals in each population, else all the individuals will migrate and it will be as if nothing happened.
type Migrator ¶
type Migrator interface { Apply(pops Populations, rng *rand.Rand) Validate() error }
Migrator applies crossover to the GA level, as such it doesn't require an independent random number generator and can use the global one.
type ModDownToSize ¶
ModDownToSize implements the select down to size model.
func (ModDownToSize) Apply ¶
func (mod ModDownToSize) Apply(pop *Population) error
Apply ModDownToSize.
func (ModDownToSize) Validate ¶
func (mod ModDownToSize) Validate() error
Validate ModDownToSize fields.
type ModGenerational ¶
ModGenerational implements the generational model.
func (ModGenerational) Apply ¶
func (mod ModGenerational) Apply(pop *Population) error
Apply ModGenerational.
func (ModGenerational) Validate ¶
func (mod ModGenerational) Validate() error
Validate ModGenerational fields.
type ModMutationOnly ¶
type ModMutationOnly struct { NChosen int // Number of individuals that are mutated each generation Selector Selector Strict bool }
ModMutationOnly implements the mutation only model. Each generation, NChosen are selected and are replaced with mutants. Mutants are obtained by mutating the selected Individuals. If Strict is set to true, then the mutants replace the chosen individuals only if they have a lower fitness.
func (ModMutationOnly) Apply ¶
func (mod ModMutationOnly) Apply(pop *Population) error
Apply ModMutationOnly.
func (ModMutationOnly) Validate ¶
func (mod ModMutationOnly) Validate() error
Validate ModMutationOnly fields.
type ModSimAnn ¶
type ModSimAnn struct { T float64 // Starting temperature Tmin float64 // Stopping temperature Alpha float64 // Decrease rate per iteration }
ModSimAnn implements simulated annealing. Enhancing a GA with the ModSimAnn model only has to be done once for the simulated annealing to do a complete run. Successive enhancements will simply reset the temperature and run the simulated annealing again (which can potentially stagnate).
type ModSteadyState ¶
ModSteadyState implements the steady state model.
func (ModSteadyState) Apply ¶
func (mod ModSteadyState) Apply(pop *Population) error
Apply ModSteadyState.
func (ModSteadyState) Validate ¶
func (mod ModSteadyState) Validate() error
Validate ModSteadyState fields.
type Model ¶
type Model interface { Apply(pop *Population) error Validate() error }
A Model specifies a protocol for applying genetic operators to a population at generation i in order for it obtain better individuals at generation i+1.
type Population ¶
type Population struct { Individuals Individuals `json:"indis"` Age time.Duration `json:"age"` Generations int `json:"generations"` ID string `json:"id"` RNG *rand.Rand }
A Population contains individuals. Individuals mate within a population. Individuals can migrate from one population to another. Each population has a random number generator to bypass the global rand mutex.
func (Population) Log ¶
func (pop Population) Log(logger *log.Logger)
Log a Population's current statistics with a provided log.Logger.
type Populations ¶
type Populations []Population
Populations type is necessary for migration and speciation purposes.
func (Populations) Apply ¶
func (pops Populations) Apply(f func(pop *Population) error, parallel bool) error
Apply a function to a slice of Populations.
type SelElitism ¶
type SelElitism struct{}
SelElitism selection returns the n best individuals of a group.
func (SelElitism) Apply ¶
func (sel SelElitism) Apply(n int, indis Individuals, rng *rand.Rand) (Individuals, []int, error)
Apply SelElitism.
type SelRoulette ¶
type SelRoulette struct{}
SelRoulette samples individuals through roulette wheel selection (also known as fitness proportionate selection).
func (SelRoulette) Apply ¶
func (sel SelRoulette) Apply(n int, indis Individuals, rng *rand.Rand) (Individuals, []int, error)
Apply SelRoulette.
type SelTournament ¶
type SelTournament struct {
NContestants int
}
SelTournament samples individuals through tournament selection. The tournament is composed of randomly chosen individuals. The winner of the tournament is the chosen individual with the lowest fitness. The obtained individuals are all distinct.
func (SelTournament) Apply ¶
func (sel SelTournament) Apply(n int, indis Individuals, rng *rand.Rand) (Individuals, []int, error)
Apply SelTournament.
func (SelTournament) Validate ¶
func (sel SelTournament) Validate() error
Validate SelTournament fields.
type Selector ¶
type Selector interface { Apply(n int, indis Individuals, rng *rand.Rand) (selected Individuals, indexes []int, err error) Validate() error }
Selector chooses a subset of size n from a group of individuals. The group of individuals a Selector is applied to is expected to be sorted.
type Slice ¶
type Slice interface { At(i int) interface{} Set(i int, v interface{}) Len() int Swap(i, j int) Slice(a, b int) Slice Split(k int) (Slice, Slice) Append(Slice) Slice Replace(Slice) Copy() Slice }
A Slice is a genome with a list-like structure.
type SpecFitnessInterval ¶
type SpecFitnessInterval struct {
K int // Number of intervals
}
SpecFitnessInterval speciates a population based on the fitness of each individual where each species contains m = n/k (rounded to the closest upper integer) individuals with similar fitnesses. For example, with 4 species, 30 individuals would be split into 3 groups of 8 individuals and 1 group of 6 individuals (3*8 + 1*6 = 30). More generally each group is of size min(n-i, m) where i is a multiple of m.
func (SpecFitnessInterval) Apply ¶
func (spec SpecFitnessInterval) Apply(indis Individuals, rng *rand.Rand) ([]Individuals, error)
Apply SpecFitnessInterval.
func (SpecFitnessInterval) Validate ¶
func (spec SpecFitnessInterval) Validate() error
Validate SpecFitnessInterval fields.
type SpecKMedoids ¶
type SpecKMedoids struct { K int // Number of medoids MinPerCluster int Metric Metric // Dissimimilarity measure MaxIterations int }
SpecKMedoids (k-medoid clustering).
func (SpecKMedoids) Apply ¶
func (spec SpecKMedoids) Apply(indis Individuals, rng *rand.Rand) ([]Individuals, error)
Apply SpecKMedoids.
func (SpecKMedoids) Validate ¶
func (spec SpecKMedoids) Validate() error
Validate SpecKMedoids fields.
type Speciator ¶
type Speciator interface { Apply(indis Individuals, rng *rand.Rand) ([]Individuals, error) Validate() error }
A Speciator partitions a population into n smaller subpopulations. Each subpopulation shares the same random number generator inherited from the initial population.