123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- package gago
- import (
- "errors"
- "math"
- "testing"
- )
- func TestSpecKMedoidsApply(t *testing.T) {
- var (
- rng = newRandomNumberGenerator()
- testCases = []struct {
- indis Individuals
- kmeds SpecKMedoids
- speciesSizes []int
- err error
- }{
- // Example dataset from https://www.wikiwand.com/en/K-medoids
- {
- indis: Individuals{
- NewIndividual(Vector{2, 6}, rng),
- NewIndividual(Vector{3, 4}, rng),
- NewIndividual(Vector{3, 8}, rng),
- NewIndividual(Vector{4, 7}, rng),
- NewIndividual(Vector{6, 2}, rng),
- NewIndividual(Vector{6, 4}, rng),
- NewIndividual(Vector{7, 3}, rng),
- NewIndividual(Vector{7, 4}, rng),
- NewIndividual(Vector{8, 5}, rng),
- NewIndividual(Vector{7, 6}, rng),
- },
- kmeds: SpecKMedoids{2, 1, l1Distance, 10},
- speciesSizes: []int{4, 6},
- err: nil,
- },
- {
- indis: Individuals{
- NewIndividual(Vector{1, 1}, rng),
- NewIndividual(Vector{1, 1}, rng),
- },
- kmeds: SpecKMedoids{2, 1, l1Distance, 10},
- speciesSizes: []int{1, 1},
- err: nil,
- },
- {
- indis: Individuals{
- NewIndividual(Vector{1, 1}, rng),
- NewIndividual(Vector{1, 2}, rng),
- },
- kmeds: SpecKMedoids{3, 1, l1Distance, 10},
- speciesSizes: []int{1, 1},
- err: errors.New("K > len(indis)"),
- },
- }
- )
- for i, tc := range testCases {
- var species, err = tc.kmeds.Apply(tc.indis, rng)
- // Check the number of species is correct
- if err == nil && len(species) != tc.kmeds.K {
- t.Errorf("Wrong number of species in test case number %d", i)
- }
- // Check size of each specie
- if err == nil {
- for j, specie := range species {
- if len(specie) != tc.speciesSizes[j] {
- t.Errorf("Wrong specie size test case number %d", i)
- }
- }
- }
- // Check error is nil or not
- if (err == nil) != (tc.err == nil) {
- t.Errorf("Wrong error in test case number %d", i)
- }
- }
- }
- func TestSpecKMedoidsValidate(t *testing.T) {
- var spec = SpecKMedoids{2, 1, l1Distance, 1}
- if err := spec.Validate(); err != nil {
- t.Error("Validation should not have raised error")
- }
- // Set K lower than 2
- spec.K = 1
- if err := spec.Validate(); err == nil {
- t.Error("Validation should have raised error")
- }
- spec.K = 2
- // Nullify Metric
- spec.Metric = nil
- if err := spec.Validate(); err == nil {
- t.Error("Validation should have raised error")
- }
- spec.Metric = l1Distance
- // Set MaxIterations lower than 1
- spec.MaxIterations = 0
- if err := spec.Validate(); err == nil {
- t.Error("Validation should have raised error")
- }
- }
- func TestSpecFitnessIntervalApply(t *testing.T) {
- var (
- nIndividuals = []int{1, 2, 3}
- nSpecies = []int{1, 2, 3}
- rng = newRandomNumberGenerator()
- )
- for _, nbi := range nIndividuals {
- for _, nbs := range nSpecies {
- var (
- m = min(int(math.Ceil(float64(nbi/nbs))), nbi)
- indis = newIndividuals(nbi, NewVector, rng)
- spec = SpecFitnessInterval{K: nbs}
- species, _ = spec.Apply(indis, rng)
- )
- // Check the cluster sizes are equal to min(n-i, m) where i is a
- // multiple of m
- for i, specie := range species {
- var (
- expected = min(nbi-i*m, m)
- obtained = len(specie)
- )
- if obtained != expected {
- t.Errorf("Wrong number of individuals, expected %d got %d", expected, obtained)
- }
- }
- }
- }
- }
- func TestSpecFitnessIntervalValidate(t *testing.T) {
- var spec = SpecFitnessInterval{2}
- if err := spec.Validate(); err != nil {
- t.Error("Validation should not have raised error")
- }
- // Set K lower than 2
- spec.K = 1
- if err := spec.Validate(); err == nil {
- t.Error("Validation should have raised error")
- }
- }
|