genetic.go 3.2 KB

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