This example presents how to explore a NetLogo model step by step with an Evolutionary/Genetic Algorithm (EA/GA) in OpenMOLE.
 In this tutorial we use a headless version of the
    model. This modified version is available here.
     In this tutorial we use a headless version of the
    model. This modified version is available here.
 It can be interesting to search the best combination of the two parameters
     It can be interesting to search the best combination of the two parameters
    evaporation-rate and diffusion-rate
    which minimises the eating time of each food source.
     To build our fitness function, we modify the NetLogo Ants source code to store for each food source the first ticks
    indicating that this food source is empty.
     to compute-fitness
  if ((sum [food] of patches with [food-source-number = 1] = 0) and (final-ticks-food1 = 0)) [
    set final-ticks-food1 ticks ]
  if ((sum [food] of patches with [food-source-number = 2] = 0) and (final-ticks-food2 = 0)) [
    set final-ticks-food2 ticks ]
  if ((sum [food] of patches with [food-source-number = 3] = 0) and (final-ticks-food3 = 0)) [
    set final-ticks-food3 ticks ]
end// Define the input variables
val gPopulation = Val[Double]
val gDiffusionRate = Val[Double]
val gEvaporationRate = Val[Double]
val seed = Val[Int]
// Define the output variables
val food1 = Val[Double]
val food2 = Val[Double]
val food3 = Val[Double]
// Define the NetlogoTask
val cmds = Seq("run-to-grid")
val ants =
  NetLogo5Task(workDirectory / "Ants.nlogo", cmds, seed = seed) set (
    // Map the OpenMOLE variables to NetLogo variables
    netLogoInputs += (gPopulation, "gpopulation"),
    netLogoInputs += (gDiffusionRate, "gdiffusion-rate"),
    netLogoInputs += (gEvaporationRate, "gevaporation-rate"),
    netLogoOutputs += ("final-ticks-food1", food1),
    netLogoOutputs += ("final-ticks-food2", food2),
    netLogoOutputs += ("final-ticks-food3", food3),
    // Define default values for inputs of the model
    seed := 42,
    gPopulation := 125.0,
    gDiffusionRate := 50.0,
    gEvaporationRate := 50
  )
// Define the hooks to collect the results
val displayHook = ToStringHook(food1, food2, food3)
// Start a workflow with 1 task
val model_execution = (ants hook displayHook) start
{food1=746.0, food2=1000.0, food3=2109.0}
/tmp/ants.
    Notice how the evaluation parameter of the SteadyStateEvolution
    method, is the netlogo task i.e. running the model, which indeed provides an evaluation of the genome
    (parameter settings) efficiency regarding the objectives.
    // Define the population size: 100.
// Define the inputs and their respective variation bounds.
// Define the objectives to minimize.
// Tell OpenMOLE that this model is stochastic and that it should generate a seed for each execution
// Define the fitness evaluation
// Define the parallelism level
// Terminate after 10000 evaluations
val evolution =
  SteadyStateEvolution(
    // Define the population (10) and the number of generations (100).
    // Define the inputs and their respective variation bounds.
    // Define the objectives to minimize.
    algorithm =
      NSGA2(
        mu = 100,
        genome = Seq(gDiffusionRate in (0.0, 99.0), gEvaporationRate in (0.0, 99.0)),
        objectives = Seq(food1, food2, food3),
        stochastic = Stochastic(seed = seed)
      ),
    evaluation = ants,
    parallelism = 10,
    termination = 1000
  )
// Define a hook to save the Pareto frontier
val savePopulationHook = SavePopulationHook(evolution, workDirectory / "results")
// Plug everything together to create the workflow
(evolution hook savePopulationHook)
val evolution =
SteadyStateEvolution(
  algorithm =
    NSGA2(
      mu = 100,
      genome = Seq(gDiffusionRate in (0.0, 99.0), gEvaporationRate in (0.0, 99.0)),
      objectives = Seq(food1, food2, food3),
      stochastic = Stochastic(seed = seed)
    ),
    evaluation = ants,
    termination = 1 hour
)
// Define the island model with 1,000 concurrent islands. Each island gets 50 individuals sampled from the global
// population. The algorithm stops after 100,000 islands evaluations.
val island =
IslandEvolution(
  evolution,
  parallelism = 1000,
  termination = 100000
)
val savePopulationHook = SavePopulationHook(island, workDirectory / "results")
// Define the execution environment
val env = EGIEnvironment("biomed", openMOLEMemory = 1200 megabytes, cpuTime = 4 hours)
// Define the workflow
(island on env hook savePopulationHook)