speciation_test.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package gago
  2. import (
  3. "errors"
  4. "math"
  5. "testing"
  6. )
  7. func TestSpecKMedoidsApply(t *testing.T) {
  8. var (
  9. rng = newRandomNumberGenerator()
  10. testCases = []struct {
  11. indis Individuals
  12. kmeds SpecKMedoids
  13. speciesSizes []int
  14. err error
  15. }{
  16. // Example dataset from https://www.wikiwand.com/en/K-medoids
  17. {
  18. indis: Individuals{
  19. NewIndividual(Vector{2, 6}, rng),
  20. NewIndividual(Vector{3, 4}, rng),
  21. NewIndividual(Vector{3, 8}, rng),
  22. NewIndividual(Vector{4, 7}, rng),
  23. NewIndividual(Vector{6, 2}, rng),
  24. NewIndividual(Vector{6, 4}, rng),
  25. NewIndividual(Vector{7, 3}, rng),
  26. NewIndividual(Vector{7, 4}, rng),
  27. NewIndividual(Vector{8, 5}, rng),
  28. NewIndividual(Vector{7, 6}, rng),
  29. },
  30. kmeds: SpecKMedoids{2, 1, l1Distance, 10},
  31. speciesSizes: []int{4, 6},
  32. err: nil,
  33. },
  34. {
  35. indis: Individuals{
  36. NewIndividual(Vector{1, 1}, rng),
  37. NewIndividual(Vector{1, 1}, rng),
  38. },
  39. kmeds: SpecKMedoids{2, 1, l1Distance, 10},
  40. speciesSizes: []int{1, 1},
  41. err: nil,
  42. },
  43. {
  44. indis: Individuals{
  45. NewIndividual(Vector{1, 1}, rng),
  46. NewIndividual(Vector{1, 2}, rng),
  47. },
  48. kmeds: SpecKMedoids{3, 1, l1Distance, 10},
  49. speciesSizes: []int{1, 1},
  50. err: errors.New("K > len(indis)"),
  51. },
  52. }
  53. )
  54. for i, tc := range testCases {
  55. var species, err = tc.kmeds.Apply(tc.indis, rng)
  56. // Check the number of species is correct
  57. if err == nil && len(species) != tc.kmeds.K {
  58. t.Errorf("Wrong number of species in test case number %d", i)
  59. }
  60. // Check size of each specie
  61. if err == nil {
  62. for j, specie := range species {
  63. if len(specie) != tc.speciesSizes[j] {
  64. t.Errorf("Wrong specie size test case number %d", i)
  65. }
  66. }
  67. }
  68. // Check error is nil or not
  69. if (err == nil) != (tc.err == nil) {
  70. t.Errorf("Wrong error in test case number %d", i)
  71. }
  72. }
  73. }
  74. func TestSpecKMedoidsValidate(t *testing.T) {
  75. var spec = SpecKMedoids{2, 1, l1Distance, 1}
  76. if err := spec.Validate(); err != nil {
  77. t.Error("Validation should not have raised error")
  78. }
  79. // Set K lower than 2
  80. spec.K = 1
  81. if err := spec.Validate(); err == nil {
  82. t.Error("Validation should have raised error")
  83. }
  84. spec.K = 2
  85. // Nullify Metric
  86. spec.Metric = nil
  87. if err := spec.Validate(); err == nil {
  88. t.Error("Validation should have raised error")
  89. }
  90. spec.Metric = l1Distance
  91. // Set MaxIterations lower than 1
  92. spec.MaxIterations = 0
  93. if err := spec.Validate(); err == nil {
  94. t.Error("Validation should have raised error")
  95. }
  96. }
  97. func TestSpecFitnessIntervalApply(t *testing.T) {
  98. var (
  99. nIndividuals = []int{1, 2, 3}
  100. nSpecies = []int{1, 2, 3}
  101. rng = newRandomNumberGenerator()
  102. )
  103. for _, nbi := range nIndividuals {
  104. for _, nbs := range nSpecies {
  105. var (
  106. m = min(int(math.Ceil(float64(nbi/nbs))), nbi)
  107. indis = newIndividuals(nbi, NewVector, rng)
  108. spec = SpecFitnessInterval{K: nbs}
  109. species, _ = spec.Apply(indis, rng)
  110. )
  111. // Check the cluster sizes are equal to min(n-i, m) where i is a
  112. // multiple of m
  113. for i, specie := range species {
  114. var (
  115. expected = min(nbi-i*m, m)
  116. obtained = len(specie)
  117. )
  118. if obtained != expected {
  119. t.Errorf("Wrong number of individuals, expected %d got %d", expected, obtained)
  120. }
  121. }
  122. }
  123. }
  124. }
  125. func TestSpecFitnessIntervalValidate(t *testing.T) {
  126. var spec = SpecFitnessInterval{2}
  127. if err := spec.Validate(); err != nil {
  128. t.Error("Validation should not have raised error")
  129. }
  130. // Set K lower than 2
  131. spec.K = 1
  132. if err := spec.Validate(); err == nil {
  133. t.Error("Validation should have raised error")
  134. }
  135. }