
---
title: "Random Search"
---

```{r ch_opt, child="include/chunk_options.rmd", cache=FALSE}
```

```{r, echo = FALSE}
library(nlexperiment)
nl_netlogo_path("c:/Program Files/NetLogo 6.0.1/app") 
```

This example is using NetLogo Flocking model (Wilensky, 1998) to
demonstrate random search for optimal parameter values.

<aside>
Wilensky, U. (1998). 
[NetLogo Flocking model](http://ccl.northwestern.edu/netlogo/models/Flocking). 
Center for Connected Learning and Computer-Based Modeling, 
Northwestern University, Evanston, IL.
</aside>

Like in the [LHS](flocking_sampling.html) example the
Latin hypercube sampling method is used but instead
of categorical criteria the
simulations are evaluated with single best-fit criterion
defined in [Best-fit](flocking_bestfit.html) example.

```{r flockSampModel, title = "Define the experiment"}
library(tgp)

experiment <- nl_experiment( 
  model_file = "models/Sample Models/Biology/Flocking.nlogo",
  setup_commands = c("setup", "repeat 100 [go]"),
  iterations = 5,

  param_values = nl_param_lhs(
    n = 100, 
    world_size = 50,
    population = 80,
    vision = 6,
    min_separation = c(0, 4),
    max_align_turn = c(0, 20)
  ),
  mapping = c(
    min_separation = "minimum-separation",
    max_align_turn = "max-align-turn"),

  step_measures = measures(
    converged = "1 - 
      (standard-deviation [dx] of turtles + 
       standard-deviation [dy] of turtles) / 2",
    mean_crowding = 
      "mean [count flockmates + 1] of turtles"
  ),
  eval_criteria = criteria(                # aggregate over time
    c_converged = mean(step$converged),
    c_mcrowding = mean(step$mean_crowding)
  ),

  repetitions = 10,                        # repeat simulations 10 times
  random_seed = 1:10,
  
  eval_aggregate_fun = mean                # aggregate over repetitions
)  
```

<aside>
Function `nl_param_lhs` is using `lhs` function from **tgp** package to create
  random parameter sets. Argument `n` defines the size of the LH sample.

Instead of using `nl_param_lhs` one can put any data frame in param_values.
  The columns of a data frame are interpreted as parameter names and rows should
  represent parameter sets.
</aside>


```{r flockRSRun, cache=TRUE}
result <- nl_run(experiment, parallel = TRUE)
```

We are using the same best-fit criterion function as in previous example:

$$ value = \sqrt{(crowding - 8)^2 + 100 \times (converged - 1)^2} $$

```{r flockRSData, title = "Define criterium"}
dat <- nl_get_criteria_result( 
  result,
  eval_value = sqrt((c_mcrowding - 8)^2 + 400*(c_converged - 1)^2)
)

```

```{r flockRSSolution, title = "Find parameter set with minimal value"}
res_value <- min(dat$eval_value)
min_eval_id <- which(dat$eval_value == res_value)
res_params <- dat[min_eval_id, c("min_separation", "max_align_turn")]
round(res_value, 1)
round(res_params,1)
```

```{r flockSampPlot1, title = "Plot the results", marginfigure = TRUE,fig.width=3.6,, fig.height=3.6, fig.cap="Minimal value found with random search"}
dat$eval_id = 1:nrow(result$criteria)
library(ggplot2)
ggplot(dat, aes(x = min_separation, y = max_align_turn, color = eval_value)) +
  geom_point(alpha = 0.3, size = 3) +
  geom_point(
    data = subset(dat, eval_id == min_eval_id), size = 10, shape = 1) +
  theme_minimal() +
  theme(legend.position = "none")
```


```{r flockSampPlot2, title = "Plot the results", fig.cap="Random searching for minimal value: best value as a function of time"}
dat$min_eval <- 
  sapply(1:nrow(dat), function(i) min(dat$eval_value[dat$eval_id <= i]) )
ggplot(dat, aes(x = eval_id, y = eval_value)) +
  geom_point(alpha = 0.5) +
  geom_step(aes(x = eval_id, y = min_eval), alpha = 0.3) +
  theme_minimal()

```

## See also

[L-BFGS-B Optimization](flocking_bfgs.html) shows how to use
  optimization functions from other R packages.

[Nelder-Mead Optimization](flocking_nm.html) shows how to use
  optimization functions from other R packages.

[Simulated Annealing](flocking_sa.html) demonstrates optimization
  with simulated annealing.

[Genetic Algorithm](flocking_ga.html) demonstrates optimization
  with genetic algorithm.
  
[Categorical Criteria](flocking_categorical.html) and 
[Hyper Latinc Cube Sampling](flocking_sampling.html) examples
demontrate how to explore parameter space with categorical 
criteria and sampling methods.

<asideclose>
Get [rmarkdown source](`r knitr::current_input()`) of this page.
</asideclose>


