gago/individuals_test.go

189 lines
3.9 KiB
Go
Raw Permalink Normal View History

2021-09-11 12:47:32 +02:00
package gago
import (
"math"
"testing"
)
func TestNewIndividuals(t *testing.T) {
var rng = newRandomNumberGenerator()
for _, n := range []int{1, 2, 42} {
var indis = newIndividuals(n, NewVector, rng)
if len(indis) != n {
t.Error("newIndividuals didn't generate the right number of individuals")
}
}
}
func TestCloneIndividuals(t *testing.T) {
var (
rng = newRandomNumberGenerator()
indis = newIndividuals(20, NewVector, rng)
clones = indis.Clone(rng)
)
for _, indi := range indis {
for _, clone := range clones {
if &indi == &clone || indi.ID == clone.ID {
t.Error("Cloning did not work as expected")
}
}
}
}
func TestEvaluateIndividuals(t *testing.T) {
var indis = newIndividuals(10, NewVector, newRandomNumberGenerator())
for _, indi := range indis {
if indi.Evaluated {
t.Error("Individual shouldn't have Evaluated set to True")
}
}
indis.Evaluate()
for _, indi := range indis {
if !indi.Evaluated {
t.Error("Individual should have Evaluated set to True")
}
}
}
func TestMutateIndividuals(t *testing.T) {
var (
rng = newRandomNumberGenerator()
indis = newIndividuals(10, NewVector, rng)
)
indis.Evaluate()
indis.Mutate(1, rng)
for _, indi := range indis {
if indi.Evaluated {
t.Error("Individual shouldn't have Evaluated set to True")
}
}
}
func TestIndividualsSortByFitness(t *testing.T) {
var indis = newIndividuals(10, NewVector, newRandomNumberGenerator())
// Assign a fitness to each individual in decreasing order
for i := range indis {
indis[i].Fitness = float64(len(indis) - i)
}
indis.SortByFitness()
// Check fitnesses are in increasing order
for i := 1; i < len(indis); i++ {
if indis[i-1].Fitness > indis[i].Fitness {
t.Error("Individuals are not sorted")
}
}
}
func TestGetFitnesses(t *testing.T) {
var (
indis = Individuals{
Individual{Fitness: 0.0},
Individual{Fitness: 1.0},
Individual{Fitness: 2.0},
}
target = []float64{0.0, 1.0, 2.0}
fitnesses = indis.getFitnesses()
)
for i, fitness := range fitnesses {
if fitness != target[i] {
t.Error("getFitnesses didn't work as expected")
}
}
}
func TestFitMin(t *testing.T) {
var testCases = []struct {
indis Individuals
min float64
}{
{Individuals{
Individual{Fitness: 1.0},
}, 1.0},
{Individuals{
Individual{Fitness: 2.0},
Individual{Fitness: 1.0},
}, 1.0},
{Individuals{
Individual{Fitness: 1.0},
Individual{Fitness: -1.0},
}, -1.0},
}
for _, test := range testCases {
if test.indis.FitMin() != test.min {
t.Error("FitMin didn't work as expected")
}
}
}
func TestFitMax(t *testing.T) {
var testCases = []struct {
indis Individuals
max float64
}{
{Individuals{
Individual{Fitness: 1.0},
}, 1.0},
{Individuals{
Individual{Fitness: 2.0},
Individual{Fitness: 1.0},
}, 2.0},
{Individuals{
Individual{Fitness: 1.0},
Individual{Fitness: -1.0},
}, 1.0},
}
for _, test := range testCases {
if test.indis.FitMax() != test.max {
t.Error("FitMax didn't work as expected")
}
}
}
func TestFitAvg(t *testing.T) {
var testCases = []struct {
indis Individuals
mean float64
}{
{Individuals{
Individual{Fitness: 1.0},
}, 1.0},
{Individuals{
Individual{Fitness: 1.0},
Individual{Fitness: 2.0},
}, 1.5},
{Individuals{
Individual{Fitness: -1.0},
Individual{Fitness: 1.0},
}, 0.0},
}
for _, test := range testCases {
if test.indis.FitAvg() != test.mean {
t.Error("FitAvg didn't work as expected")
}
}
}
func TestFitStd(t *testing.T) {
var testCases = []struct {
indis Individuals
variance float64
}{
{Individuals{
Individual{Fitness: 1.0},
}, 0.0},
{Individuals{
Individual{Fitness: -1.0},
Individual{Fitness: 1.0},
}, 1.0},
{Individuals{
Individual{Fitness: -2.0},
Individual{Fitness: 2.0},
}, 4.0},
}
for _, test := range testCases {
if test.indis.FitStd() != math.Sqrt(test.variance) {
t.Error("FitStd didn't work as expected")
}
}
}