123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- package gago
- import (
- "errors"
- "math"
- "testing"
- "time"
- )
- func TestValidationSuccess(t *testing.T) {
- var err = ga.Validate()
- if err != nil {
- t.Error("GA parameters are invalid")
- }
- }
- func TestValidationGenomeFactory(t *testing.T) {
- var genomeFactory = ga.GenomeFactory
- ga.GenomeFactory = nil
- if ga.Validate() == nil {
- t.Error("Nil GenomeFactory should return an error")
- }
- ga.GenomeFactory = genomeFactory
- }
- func TestValidationNPopulations(t *testing.T) {
- var nPops = ga.NPops
- ga.NPops = -1
- if ga.Validate() == nil {
- t.Error("Invalid number of Populations should return an error")
- }
- ga.NPops = nPops
- }
- func TestValidationNIndividuals(t *testing.T) {
- var popSize = ga.PopSize
- ga.PopSize = -1
- if ga.Validate() == nil {
- t.Error("Invalid number of Individuals should return an error")
- }
- ga.PopSize = popSize
- }
- func TestValidationModel(t *testing.T) {
- var model = ga.Model
- // Check nil model raises error
- ga.Model = nil
- if ga.Validate() == nil {
- t.Error("Nil Model should return an error")
- }
- // Check invalid model raises error
- ga.Model = ModGenerational{
- Selector: SelTournament{
- NContestants: 3,
- },
- MutRate: -1,
- }
- if ga.Validate() == nil {
- t.Error("Invalid Model should return an error")
- }
- ga.Model = model
- }
- func TestValidationMigFrequency(t *testing.T) {
- var (
- migrator = ga.Migrator
- migFrequency = ga.MigFrequency
- )
- ga.Migrator = MigRing{}
- ga.MigFrequency = 0
- if ga.Validate() == nil {
- t.Error("Invalid MigFrequency should return an error")
- }
- ga.Migrator = migrator
- ga.MigFrequency = migFrequency
- }
- func TestValidationSpeciator(t *testing.T) {
- var speciator = ga.Speciator
- ga.Speciator = SpecFitnessInterval{0}
- if ga.Validate() == nil {
- t.Error("Invalid Speciator should return an error")
- }
- ga.Speciator = speciator
- }
- func TestApplyWithSpeciator(t *testing.T) {
- var speciator = ga.Speciator
- ga.Speciator = SpecFitnessInterval{4}
- if ga.Enhance() != nil {
- t.Error("Calling Apply with a valid Speciator should not return an error")
- }
- ga.Speciator = speciator
- }
- func TestRandomNumberGenerators(t *testing.T) {
- for i, pop1 := range ga.Populations {
- for j, pop2 := range ga.Populations {
- if i != j && &pop1.rng == &pop2.rng {
- t.Error("Population should not share random number generators")
- }
- }
- }
- }
- func TestBest(t *testing.T) {
- for _, pop := range ga.Populations {
- for _, indi := range pop.Individuals {
- if ga.Best.Fitness > indi.Fitness {
- t.Error("The current best individual is not the overall best")
- }
- }
- }
- }
- func TestFindBest(t *testing.T) {
- // Check sure the findBest method works as expected
- var fitness = ga.Populations[0].Individuals[0].Fitness
- ga.Populations[0].Individuals[0].Fitness = math.Inf(-1)
- ga.findBest()
- if ga.Best.Fitness != math.Inf(-1) {
- t.Error("findBest didn't work")
- }
- ga.Populations[0].Individuals[0].Fitness = fitness
- // Check the best individual doesn't a share a pointer with anyone
- fitness = ga.Best.Fitness
- ga.Best.Fitness = 42
- if ga.Populations[0].Individuals[0].Fitness == 42 {
- t.Error("Best individual shares a pointer with an individual in the populations")
- }
- ga.Best.Fitness = fitness
- }
- // TestDuration verifies the sum of the duration of each population is higher
- // the actual duration. This is due to the fact that each population runs on a
- // separate core.
- func TestDuration(t *testing.T) {
- var totalDuration time.Duration
- for _, pop := range ga.Populations {
- totalDuration += pop.Age
- }
- if totalDuration < ga.Age {
- t.Error("Inefficient parallelism")
- }
- }
- func TestSpeciateEvolveMerge(t *testing.T) {
- var (
- rng = newRandomNumberGenerator()
- testCases = []struct {
- pop Population
- speciator Speciator
- model Model
- err error
- }{
- {
- pop: Population{
- ID: "42",
- rng: rng,
- Individuals: Individuals{
- Individual{Fitness: 0},
- Individual{Fitness: 1},
- Individual{Fitness: 2},
- Individual{Fitness: 3},
- Individual{Fitness: 4},
- },
- },
- speciator: SpecFitnessInterval{3},
- model: ModIdentity{},
- err: nil,
- },
- {
- pop: Population{
- ID: "42",
- rng: rng,
- Individuals: Individuals{
- Individual{Fitness: 0},
- Individual{Fitness: 1},
- Individual{Fitness: 2},
- },
- },
- speciator: SpecFitnessInterval{4},
- model: ModIdentity{},
- err: errors.New("Invalid speciator"),
- },
- {
- pop: Population{
- ID: "42",
- rng: rng,
- Individuals: Individuals{
- Individual{Fitness: 0},
- Individual{Fitness: 1},
- Individual{Fitness: 2},
- Individual{Fitness: 3},
- Individual{Fitness: 4},
- },
- },
- speciator: SpecFitnessInterval{3},
- model: ModGenerational{
- Selector: SelTournament{6},
- MutRate: 0.5,
- },
- err: errors.New("Invalid model"),
- },
- }
- )
- for i, tc := range testCases {
- var err = tc.pop.speciateEvolveMerge(tc.speciator, tc.model)
- if (err == nil) != (tc.err == nil) {
- t.Errorf("Wrong error in test case number %d", i)
- }
- // If there is no error check the individuals are ordered as they were
- // at they were initially
- if err == nil {
- for j, indi := range tc.pop.Individuals {
- if indi.Fitness != float64(j) {
- t.Errorf("Wrong result in test case number %d", i)
- }
- }
- }
- }
- }
- func TestCallback(t *testing.T) {
- var (
- counter int
- incrementCounter = func(ga *GA) {
- counter++
- }
- )
- ga.Callback = incrementCounter
- ga.Initialize()
- if counter != 1 {
- t.Error("Counter was not incremented by the callback at initialization")
- }
- ga.Enhance()
- if counter != 2 {
- t.Error("Counter was not incremented by the callback at enhancement")
- }
- }
|