0

I am using AnyLogic 8.7.9 PLE for modeling a rule-based simulation. I want to compare the results of this simulation to the results of a Bonsai trained brain. For the rule-based simulation, I ran a single configuration 100 times through the Parameter Variation experiment. When I wanted to run the same with the trained brain, I received the following error:

root.bonsaiConnector: This block works only with simulation experiments.

I was thinking of a workaround to this problem and I thought of running everything from a single experiment run, I found some more information in the inquiry below:

Runnig N times the simulation in anylogic

Now, my question is, running these 100 simulations for the rule-based takes around 3-5 hours given that some of these simulations run in parallel, is there a workaround where I can run at least part of the 100 runs for the trained brain stimulation in parallel instead of running them consecutively such that it won't take more than the time it takes the rule-based simulation?

Duoaa
  • 25
  • 5

1 Answers1

1

Disclaimer: I have not rested this with a Bonsai Brain, there is a chance that it won't work with a Custom Experiment

Warning: Advanced Java ahead

You can run simulations by using the Custom Experiment functionality.

The example below is adapted from the Simulation Model Life Cycle articles you can find here, but with the added advancement of multi-threading. The code can be imposed on that simple example and it will work fine.

Create a custom experiment and add some custom code in the additional class code. Ideally, in this function, you provide some scenario class containing all the input data for your model, as well as a result class where you store all the result data from the model.

enter image description here

public void startRound( Scenario scenario, int seed, TextFile customerQueueTimeFile, Results results ) {
    
    // Create Engine, initialize random number generator:
    Engine engine = createEngine();
    engine.setTimeUnit( MINUTE );
    engine.getDefaultRandomGenerator().setSeed(seed);
    
    // start date
    SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
    try {
        engine.setStartDate(dateFormatter.parse("2021-02-01"));
    } catch (ParseException e) {
        throw new AssertionError("Invalid date: ");
    }
    
    // Create new root object and set the parameter
    Main root = new Main( engine, null, null );
    root.scenario = scenario;
    root.seed = seed;
    root.customerQueueTimeFile = customerQueueTimeFile;
    
    engine.start( root );
    engine.runFast();

    traceln("Experiment: " + scenario.scenarioName + ", replciation: " + seed + " Finished");
    if (results != null) {
        results.addResult("Min", root.averageWaitingTime.getStatistics().min());
        results.addResult("Average", root.averageWaitingTime.getStatistics().mean());
        results.addResult("Max", root.averageWaitingTime.getStatistics().max());
    }   
    engine.stop();
}

If you then want to run these custom experiments in parallel you need to implement multi-threading.

You can do this by creating a new runnable for every replication that you want to run and then in the runnable call the function to run the custom experiment.

When there is only 1 active thread in the thread pool you can save the outputs

enter image description here

for (String fileName:filesToLoad) {
    importFromExcel(fileName);
    Results result = new Results();
    resultsMap.put(selectFrom(model_setup).firstResult(false, model_setup.scenario_name), result);
    for (int i = 0; i < replications; i ++) {   
        final int x = i;
        Scenario s = getScenarioFromDB();
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                CustomExperiment customExperiment = new CustomExperiment(null);
                customExperiment.startRound(s, x, customerQueueTime, result);
                
                if (v_threadPool.getActiveCount() == 1){
                    outputResults();
                }
            }
        };
        v_threadPool.execute(runnable);
    }
}


v_threadPool is just a ThreadPool executor to ensure you don't run too many threads at the same time.

enter image description here

Jaco-Ben Vosloo
  • 3,770
  • 2
  • 16
  • 33
  • Thank you very much for your answer. Unfortunately, it also doesn't work with a custom experiment. – Duoaa Apr 08 '22 at 05:06