genetic.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package genetic
  2. import (
  3. "fmt"
  4. "log"
  5. "sort"
  6. neuralnetwork "../neuralnetwork"
  7. )
  8. type PopulationConfig struct {
  9. PopulationSize int
  10. SelectionSize float64 // 0..1 persentage of success individuals to be used as parents for population
  11. CrossbreedPart float64 // 0..1 persentage of weights and biases to be exchanged beetween individuals while Crossbreed
  12. }
  13. type Population struct {
  14. populationConfig *PopulationConfig
  15. Networks []*neuralnetwork.NeuralNetwork
  16. verifier PopulationVerifier
  17. mutagen Mutagen
  18. }
  19. func NewPopulation(verifier PopulationVerifier, mutagen Mutagen, populationConfig PopulationConfig, sizes []int) (p *Population) {
  20. if populationConfig.PopulationSize%2 != 0 {
  21. return nil
  22. }
  23. p = &Population{
  24. populationConfig: &populationConfig,
  25. Networks: make([]*neuralnetwork.NeuralNetwork, populationConfig.PopulationSize),
  26. verifier: verifier,
  27. mutagen: mutagen,
  28. }
  29. for i := 0; i < populationConfig.PopulationSize; i++ {
  30. var err error
  31. p.Networks[i], err = neuralnetwork.NewNeuralNetwork(sizes, nil)
  32. if err != nil {
  33. log.Fatal("Could not initialize NeuralNetwork")
  34. }
  35. }
  36. return
  37. }
  38. func (p *Population) NaturalSelection(generationCount int) {
  39. for g := 0; g < generationCount; g++ {
  40. p.crossbreedPopulation(p.verifier.Verify(p))
  41. }
  42. }
  43. func (p *Population) crossbreedPopulation(results []*IndividalResult) {
  44. sort.SliceStable(results, func(i, j int) bool {
  45. return results[i].Result > results[j].Result //Descent order best will be on top, worst in the bottom
  46. })
  47. etalons := int(float64(p.populationConfig.PopulationSize) * p.populationConfig.SelectionSize)
  48. if etalons%2 != 0 {
  49. etalons -= 1
  50. }
  51. etalonNetworks := make([]*neuralnetwork.NeuralNetwork, etalons)
  52. for i := 1; i < etalons; i += 2 {
  53. firstParentBase := results[i-1].Index
  54. secondParentBase := results[i].Index
  55. etalonNetworks[i-1] = p.Networks[firstParentBase].Copy()
  56. etalonNetworks[i] = p.Networks[secondParentBase].Copy()
  57. }
  58. for i := 1; i < p.populationConfig.PopulationSize; i += 2 {
  59. firstParentBase := etalonNetworks[(i-1)%etalons]
  60. secondParentBase := etalonNetworks[i%etalons]
  61. firstParent := results[i-1].Index
  62. secondParent := results[i].Index
  63. fmt.Printf("Result value %v i %v firstParent %v secondParent %v\n", results[i].Result, i, firstParent, secondParent)
  64. p.Networks[firstParent] = firstParentBase.Copy()
  65. p.Networks[secondParent] = secondParentBase.Copy()
  66. crossbreed(p.Networks[firstParent], p.Networks[secondParent], p.populationConfig.CrossbreedPart)
  67. p.mutagen.Mutate(p.Networks[firstParent])
  68. p.mutagen.Mutate(p.Networks[secondParent])
  69. }
  70. }
  71. func crossbreed(firstParent, secondParent *neuralnetwork.NeuralNetwork, crossbreedPart float64) {
  72. for l := 1; l < firstParent.LayerCount; l++ {
  73. firstParentWeights := firstParent.Weights[l]
  74. secondParentWeights := secondParent.Weights[l]
  75. firstParentBiases := firstParent.Biases[l]
  76. secondParentBiases := secondParent.Biases[l]
  77. r, c := firstParentWeights.Dims()
  78. // rp := int(float64(r) * crossbreedPart)
  79. // cp := int(float64(c) * crossbreedPart)
  80. // r = int(rand.Uint32()) % r //(r-rp) + rp
  81. // c = int(rand.Uint32()) % c //(c-cp) + cp
  82. for i := 0; i < int(float64(r)*crossbreedPart); i++ {
  83. // for i := 0; i < r; i++ {
  84. for j := 0; j < c; j++ {
  85. // Swap first half of weights
  86. w := firstParentWeights.At(i, j)
  87. firstParentWeights.Set(i, j, secondParentWeights.At(i, j))
  88. secondParentWeights.Set(i, j, w)
  89. }
  90. // Swap first half of biases
  91. b := firstParentBiases.At(i, 0)
  92. firstParentBiases.Set(i, 0, secondParentBiases.At(i, 0))
  93. secondParentBiases.Set(i, 0, b)
  94. }
  95. }
  96. }