migration.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. package gago
  2. import (
  3. "errors"
  4. "math/rand"
  5. )
  6. // Migrator applies crossover to the GA level, as such it doesn't
  7. // require an independent random number generator and can use the global one.
  8. type Migrator interface {
  9. Apply(pops Populations, rng *rand.Rand)
  10. Validate() error
  11. }
  12. // MigRing migration exchanges individuals between consecutive Populations in a
  13. // random fashion. One by one, each population exchanges NMigrants individuals
  14. // at random with the next population. NMigrants should be higher than the
  15. // number of individuals in each population, else all the individuals will
  16. // migrate and it will be as if nothing happened.
  17. type MigRing struct {
  18. NMigrants int // Number of migrants per exchange between Populations
  19. }
  20. // Apply MigRing.
  21. func (mig MigRing) Apply(pops Populations, rng *rand.Rand) {
  22. for i := 0; i < len(pops)-1; i++ {
  23. for _, k := range randomInts(mig.NMigrants, 0, len(pops[i].Individuals), rng) {
  24. pops[i].Individuals[k], pops[i+1].Individuals[k] = pops[i+1].Individuals[k], pops[i].Individuals[k]
  25. }
  26. }
  27. }
  28. // Validate MigRing fields.
  29. func (mig MigRing) Validate() error {
  30. if mig.NMigrants < 1 {
  31. return errors.New("NMigrants should be higher than 0")
  32. }
  33. return nil
  34. }