You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

131 lines
3.1 KiB

3 years ago
  1. library(reshape)
  2. library(tidyverse)
  3. library(ggforce)
  4. normalize_landscape <- function(landscape) {
  5. min_val <- min(landscape)
  6. max_val <- max(landscape)
  7. range_val <- max_val - min_val
  8. return((landscape - min_val) / range_val)
  9. }
  10. plot_landscape <- function(landscape) {
  11. p <- ggplot(data=melt(landscape), aes(x=X1, y=X2, z=value)) +
  12. geom_contour_filled()
  13. return(p)
  14. }
  15. init_population <- function(landscape, n) {
  16. population <- list()
  17. dims <- length(dim(landscape))
  18. for(i in 1:n) {
  19. coords <- round(runif(dims, 0, 1) * dim(landscape))
  20. sigmas <- rnorm(dims)
  21. population[[i]] <- matrix(c(coords, sigmas), ncol=2)
  22. }
  23. return(population)
  24. }
  25. next_generation <- function(landscape, population) {
  26. return(map(population, function(indiv) {
  27. return(select_indiv(landscape, list(indiv, create_child(indiv))))
  28. }))
  29. }
  30. select_indiv <- function(landscape, indivs) {
  31. return(reduce(indivs, function(a, b) {
  32. if(eval_indiv(landscape, a) >= eval_indiv(landscape, b)) {
  33. return(a)
  34. }
  35. return(b)
  36. }))
  37. }
  38. eval_indiv <- function(landscape, indiv) {
  39. dims <- dim(landscape)
  40. x <- indiv[1,1]
  41. y <- indiv[2, 1]
  42. if(x > dims[1] || y > dims[2] || x < 1 || y < 1) {
  43. return(-1)
  44. }
  45. return(landscape[indiv[1,1], indiv[2,1]])
  46. }
  47. create_child <- function(parent) {
  48. new_sigmas <- mutate_sigmas(parent[,2])
  49. new_coords <- mutate_coords(parent[,1], new_sigmas)
  50. return(matrix(c(new_coords, new_sigmas), ncol=2))
  51. }
  52. mutate_sigmas <- function(sigmas) {
  53. global_rate <- 1 / sqrt(2 * length(sigmas))
  54. local_rate <- 1 / (2 * sqrt(length(sigmas)))
  55. global_step <- global_rate * rnorm(1)
  56. return(map_dbl(sigmas, function(s) s * exp(global_step + local_rate * rnorm(1))))
  57. }
  58. mutate_coords <- function(coords, sigmas) {
  59. return(imap_dbl(coords, function(x, i) x + sigmas[i] * rnorm(1)))
  60. }
  61. experiment <- function(landscape, population, gens) {
  62. df <- population_to_df(landscape, population, 0)
  63. for(g in 1:gens) {
  64. population <- next_generation(landscape, population)
  65. df <- rbind(df, population_to_df(landscape, population, g))
  66. }
  67. return(df)
  68. }
  69. population_to_df <- function(landscape, population, gen) {
  70. df <- reduce(imap(population, function(indv, i) indiv_to_df(landscape, indv, i)), rbind)
  71. df["generation"] <- gen
  72. return(df)
  73. }
  74. indiv_to_df <- function(landscape, indiv, index) {
  75. return(data.frame(x=indiv[1,1], y=indiv[2,1],
  76. sx=indiv[1, 2], sy=indiv[2,2],
  77. individual=index, value=eval_indiv(landscape, indiv)))
  78. }
  79. plot_generation <- function(landscape, df) {
  80. p <-ggplot(data=df) +
  81. geom_contour_filled(data=melt(landscape), aes(x=X1, y=X2, z=value)) +
  82. geom_point(aes(x=x, y=y)) +
  83. geom_ellipse(aes(x0=x, y0=y, a=sx, b=sy, angle=0))
  84. return(p)
  85. }
  86. plot_experiment <- function(landscape, df, filename) {
  87. pdf(file=filename, onefile=TRUE)
  88. for(g in unique(df$generation)) {
  89. tmp_df <- df[df$generation == g,]
  90. p <- plot <- plot_generation(landscape, tmp_df)
  91. print(p)
  92. }
  93. dev.off()
  94. }