models.go 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. package gago
  2. import (
  3. "errors"
  4. "math"
  5. "math/rand"
  6. )
  7. var (
  8. errNilSelector = errors.New("Selector cannot be nil")
  9. errInvalidMutRate = errors.New("MutRate should be between 0 and 1")
  10. )
  11. // Two parents are selected from a pool of individuals, crossover is then
  12. // applied to generate two offsprings. The selection and crossover process is
  13. // repeated until n offsprings have been generated. If n is uneven then the
  14. // second offspring of the last crossover is discarded.
  15. func generateOffsprings(n int, indis Individuals, sel Selector, rng *rand.Rand) (Individuals, error) {
  16. var (
  17. offsprings = make(Individuals, n)
  18. i = 0
  19. )
  20. for i < len(offsprings) {
  21. // Select 2 parents
  22. var parents, _, err = sel.Apply(2, indis, rng)
  23. if err != nil {
  24. return nil, err
  25. }
  26. // Generate 2 offsprings from the parents
  27. var offspring1, offspring2 = parents[0].Crossover(parents[1], rng)
  28. if i < len(offsprings) {
  29. offsprings[i] = offspring1
  30. i++
  31. }
  32. if i < len(offsprings) {
  33. offsprings[i] = offspring2
  34. i++
  35. }
  36. }
  37. return offsprings, nil
  38. }
  39. // A Model specifies a protocol for applying genetic operators to a
  40. // population at generation i in order for it obtain better individuals at
  41. // generation i+1.
  42. type Model interface {
  43. Apply(pop *Population) error
  44. Validate() error
  45. }
  46. // ModGenerational implements the generational model.
  47. type ModGenerational struct {
  48. Selector Selector
  49. MutRate float64
  50. }
  51. // Apply ModGenerational.
  52. func (mod ModGenerational) Apply(pop *Population) error {
  53. // Generate as many offsprings as there are of individuals in the current population
  54. var offsprings, err = generateOffsprings(
  55. len(pop.Individuals),
  56. pop.Individuals,
  57. mod.Selector,
  58. pop.rng,
  59. )
  60. if err != nil {
  61. return err
  62. }
  63. // Apply mutation to the offsprings
  64. if mod.MutRate > 0 {
  65. offsprings.Mutate(mod.MutRate, pop.rng)
  66. }
  67. // Replace the old population with the new one
  68. copy(pop.Individuals, offsprings)
  69. return nil
  70. }
  71. // Validate ModGenerational fields.
  72. func (mod ModGenerational) Validate() error {
  73. // Check the selection method presence
  74. if mod.Selector == nil {
  75. return errNilSelector
  76. }
  77. // Check the selection method parameters
  78. var errSelector = mod.Selector.Validate()
  79. if errSelector != nil {
  80. return errSelector
  81. }
  82. // Check the mutation rate
  83. if mod.MutRate < 0 || mod.MutRate > 1 {
  84. return errInvalidMutRate
  85. }
  86. return nil
  87. }
  88. // ModSteadyState implements the steady state model.
  89. type ModSteadyState struct {
  90. Selector Selector
  91. KeepBest bool
  92. MutRate float64
  93. }
  94. // Apply ModSteadyState.
  95. func (mod ModSteadyState) Apply(pop *Population) error {
  96. var parents, indexes, err = mod.Selector.Apply(2, pop.Individuals, pop.rng)
  97. if err != nil {
  98. return err
  99. }
  100. var offspring1, offspring2 = parents[0].Crossover(parents[1], pop.rng)
  101. // Apply mutation to the offsprings
  102. if mod.MutRate > 0 {
  103. if pop.rng.Float64() < mod.MutRate {
  104. offspring1.Mutate(pop.rng)
  105. }
  106. if pop.rng.Float64() < mod.MutRate {
  107. offspring2.Mutate(pop.rng)
  108. }
  109. }
  110. if mod.KeepBest {
  111. // Replace the chosen parents with the best individuals out of the
  112. // parents and the individuals
  113. offspring1.Evaluate()
  114. offspring2.Evaluate()
  115. var indis = Individuals{parents[0], parents[1], offspring1, offspring2}
  116. indis.SortByFitness()
  117. pop.Individuals[indexes[0]] = indis[0]
  118. pop.Individuals[indexes[1]] = indis[1]
  119. } else {
  120. // Replace the chosen parents with the offsprings
  121. pop.Individuals[indexes[0]] = offspring1
  122. pop.Individuals[indexes[1]] = offspring2
  123. }
  124. return nil
  125. }
  126. // Validate ModSteadyState fields.
  127. func (mod ModSteadyState) Validate() error {
  128. // Check the selection method presence
  129. if mod.Selector == nil {
  130. return errNilSelector
  131. }
  132. // Check the selection method parameters
  133. var errSelector = mod.Selector.Validate()
  134. if errSelector != nil {
  135. return errSelector
  136. }
  137. // Check the mutation rate in the presence of a mutator
  138. if mod.MutRate < 0 || mod.MutRate > 1 {
  139. return errInvalidMutRate
  140. }
  141. return nil
  142. }
  143. // ModDownToSize implements the select down to size model.
  144. type ModDownToSize struct {
  145. NOffsprings int
  146. SelectorA Selector
  147. SelectorB Selector
  148. MutRate float64
  149. }
  150. // Apply ModDownToSize.
  151. func (mod ModDownToSize) Apply(pop *Population) error {
  152. var offsprings, err = generateOffsprings(
  153. mod.NOffsprings,
  154. pop.Individuals,
  155. mod.SelectorA,
  156. pop.rng,
  157. )
  158. if err != nil {
  159. return err
  160. }
  161. // Apply mutation to the offsprings
  162. if mod.MutRate > 0 {
  163. offsprings.Mutate(mod.MutRate, pop.rng)
  164. }
  165. offsprings.Evaluate()
  166. // Merge the current population with the offsprings
  167. offsprings = append(offsprings, pop.Individuals...)
  168. // Select down to size
  169. var selected, _, _ = mod.SelectorB.Apply(len(pop.Individuals), offsprings, pop.rng)
  170. // Replace the current population of individuals
  171. copy(pop.Individuals, selected)
  172. return nil
  173. }
  174. // Validate ModDownToSize fields.
  175. func (mod ModDownToSize) Validate() error {
  176. // Check the number of offsprings value
  177. if mod.NOffsprings <= 0 {
  178. return errors.New("NOffsprings has to higher than 0")
  179. }
  180. // Check the first selection method presence
  181. if mod.SelectorA == nil {
  182. return errNilSelector
  183. }
  184. // Check the first selection method parameters
  185. var errSelectorA = mod.SelectorA.Validate()
  186. if errSelectorA != nil {
  187. return errSelectorA
  188. }
  189. // Check the second selection method presence
  190. if mod.SelectorB == nil {
  191. return errNilSelector
  192. }
  193. // Check the second selection method parameters
  194. var errSelectorB = mod.SelectorB.Validate()
  195. if errSelectorB != nil {
  196. return errSelectorB
  197. }
  198. // Check the mutation rate in the presence of a mutator
  199. if mod.MutRate < 0 || mod.MutRate > 1 {
  200. return errInvalidMutRate
  201. }
  202. return nil
  203. }
  204. // ModRing implements the island ring model.
  205. type ModRing struct {
  206. Selector Selector
  207. MutRate float64
  208. }
  209. // Apply ModRing.
  210. func (mod ModRing) Apply(pop *Population) error {
  211. for i, indi := range pop.Individuals {
  212. var (
  213. neighbour = pop.Individuals[i%len(pop.Individuals)]
  214. offspring1, offspring2 = indi.Crossover(neighbour, pop.rng)
  215. )
  216. // Apply mutation to the offsprings
  217. if mod.MutRate > 0 {
  218. if pop.rng.Float64() < mod.MutRate {
  219. offspring1.Mutate(pop.rng)
  220. }
  221. if pop.rng.Float64() < mod.MutRate {
  222. offspring2.Mutate(pop.rng)
  223. }
  224. }
  225. offspring1.Evaluate()
  226. offspring2.Evaluate()
  227. // Select an individual out of the original individual and the
  228. // offsprings
  229. var (
  230. indis = Individuals{indi, offspring1, offspring2}
  231. selected, _, err = mod.Selector.Apply(1, indis, pop.rng)
  232. )
  233. if err != nil {
  234. return err
  235. }
  236. pop.Individuals[i] = selected[0]
  237. }
  238. return nil
  239. }
  240. // Validate ModRing fields.
  241. func (mod ModRing) Validate() error {
  242. // Check the selection method presence
  243. if mod.Selector == nil {
  244. return errNilSelector
  245. }
  246. // Check the selection method parameters
  247. var errSelector = mod.Selector.Validate()
  248. if errSelector != nil {
  249. return errSelector
  250. }
  251. // Check the mutation rate in the presence of a mutator
  252. if mod.MutRate < 0 || mod.MutRate > 1 {
  253. return errInvalidMutRate
  254. }
  255. return nil
  256. }
  257. // ModSimAnn implements simulated annealing. Enhancing a GA with the ModSimAnn
  258. // model only has to be done once for the simulated annealing to do a complete
  259. // run. Successive enhancements will simply reset the temperature and run the
  260. // simulated annealing again (which can potentially stagnate).
  261. type ModSimAnn struct {
  262. T float64 // Starting temperature
  263. Tmin float64 // Stopping temperature
  264. Alpha float64 // Decrease rate per iteration
  265. }
  266. // Apply ModSimAnn.
  267. func (mod ModSimAnn) Apply(pop *Population) error {
  268. // Continue until having reached the minimum temperature
  269. for mod.T > mod.Tmin {
  270. for i, indi := range pop.Individuals {
  271. // Generate a random neighbour through mutation
  272. var neighbour = indi.Clone(pop.rng)
  273. neighbour.Mutate(pop.rng)
  274. neighbour.Evaluate()
  275. if neighbour.Fitness < indi.Fitness {
  276. pop.Individuals[i] = neighbour
  277. } else {
  278. var p = math.Exp((indi.Fitness - neighbour.Fitness) / mod.T)
  279. if p > pop.rng.Float64() {
  280. pop.Individuals[i] = neighbour
  281. }
  282. }
  283. }
  284. mod.T *= mod.Alpha // Reduce the temperature
  285. }
  286. return nil
  287. }
  288. // Validate ModSimAnn fields.
  289. func (mod ModSimAnn) Validate() error {
  290. // Check the stopping temperature value
  291. if mod.Tmin < 0 {
  292. return errors.New("Tmin should be higher than 0")
  293. }
  294. // Check the starting temperature value
  295. if mod.T < mod.Tmin {
  296. return errors.New("T should be a number higher than Tmin")
  297. }
  298. // Check the decrease rate value
  299. if mod.Alpha <= 0 || mod.Alpha >= 1 {
  300. return errInvalidMutRate
  301. }
  302. return nil
  303. }
  304. // ModMutationOnly implements the mutation only model. Each generation,
  305. // NChosen are selected and are replaced with mutants. Mutants are obtained by
  306. // mutating the selected Individuals. If Strict is set to true, then the mutants
  307. // replace the chosen individuals only if they have a lower fitness.
  308. type ModMutationOnly struct {
  309. NChosen int // Number of individuals that are mutated each generation
  310. Selector Selector
  311. Strict bool
  312. }
  313. // Apply ModMutationOnly.
  314. func (mod ModMutationOnly) Apply(pop *Population) error {
  315. var selected, positions, err = mod.Selector.Apply(mod.NChosen, pop.Individuals, pop.rng)
  316. if err != nil {
  317. return err
  318. }
  319. for i, indi := range selected {
  320. var mutant = indi.Clone(pop.rng)
  321. mutant.Mutate(pop.rng)
  322. mutant.Evaluate()
  323. if !mod.Strict || (mod.Strict && mutant.Fitness > indi.Fitness) {
  324. pop.Individuals[positions[i]] = mutant
  325. }
  326. }
  327. return nil
  328. }
  329. // Validate ModMutationOnly fields.
  330. func (mod ModMutationOnly) Validate() error {
  331. // Check the number of chosen individuals value
  332. if mod.NChosen < 1 {
  333. return errors.New("NChosen should be higher than 0")
  334. }
  335. // Check the selector presence
  336. if mod.Selector == nil {
  337. return errNilSelector
  338. }
  339. // Check the selection method parameters
  340. var errSelector = mod.Selector.Validate()
  341. if errSelector != nil {
  342. return errSelector
  343. }
  344. return nil
  345. }