Free cookie consent management tool by TermsFeed Policy Generator
wiki:Documentation/Howto/OptimizeAnyLogicModels

Version 9 (modified by abeham, 9 years ago) (diff)

--

Documentation not up-to-date

As of HeuristicLab 3.3.11 configuring the ExternalEvaluationProblem has been made considerably easier. This is not yet reflected in this documentation.

How to ... optimize parameters of AnyLogic 6 simulation models

Introduction

We assume the reader is familiar with xj technologies AnyLogic 6 and has basic understanding of the Java programming language.

This howto is written as a tutorial by taking one of the sample models that ships with AnyLogic and add connectors to optimize its parameters with HeuristicLab algorithms. If you go through this tutorial you will hopefully get an idea on how to solve your specific problem and implement the connector in your model. If you're interested in the technical details and the backgrounds you can also read the first section of the howto aimed more at developers: [UsersHowtosOptimizingExternalApplications optimize parameters of simulation models.]

AnyLogic 6 Supply Chain model

The model which we are going to optimize with HeuristicLab comes preinstalled with AnyLogic 6 and is called Supply Chain. You can open it either on the Welcome page after starting AnyLogic 6 or by choosing "Sample Models" from the Help menu. After you opened the model you can try to run the Simulation. There is also an Optimization Experiment in this model which uses the proprietary optimization package OptQuest.

Optimization Problem

Let's talk a little about the optimization problem: There are three players in a supply chain of which the first one produces goods from an unlimited source of resources and the last one sells goods to an unlimited number of customers. Each player maintains an inventory of goods out of which it fulfills the demands of the next player. There are ordering costs, holding costs and shipping costs. The optimization consists of defining parameters of an (s,S) inventory policy. The lower s in this policy defines the inventory level at which an order will be placed and the upper S defines the level which should be filled by the order. The optimization goal is to minimize the sum of all costs in the chain while satisfying a certain service level which is represented by the customer waiting time. If customers have to wait too long then the solution (aka. the parameters of the policy) is considered infeasible. In total we have 6 decision variables, one target variable and a constraint.

Preparing the Simulation Model in AnyLogic 6

First save the model in a new location. Click "Save As..." in the File menu. For the sake of simplicity just put "Supply Chain" in the box that asks for a model name and leave everything else. That way it will save it in a folder called "Models" in your user's directory.

Now download the HL3 External Evaluation Java library to a place that you remember (e.g. your Downloads directory; you should not download it into the model folder already). Then switch to AnyLogic 6 again and click the model icon in the project view (should be called "Supply Chain" if you followed the model name suggestion above). In the properties window of this model in the section "Jar files and class folders required to build the model:" click the add button. Choose the file you just downloaded, make sure "Import to model folder is ticked" and click "Finish" to add the library. Save the model.

Now we need to add a new experiment which we can run to serve as our evaluation function. The best type of experiment for this task is a "Parameters Variation" experiment, so choose this and choose a name for it, e.g. "HeuristicLabOptimizationExperiment". Leave everything else as it is and click "Finish". Now we have created a new experiment with which we can optimize the parameters.

In the "Properties" view of this experiment go to the "General" tab and choose "Freeform" instead of "Varied in range" and put a large number in the box asking for the "Number of runs", e.g.: 1,000,000,000. Then type in each field in the column "Expression" the same word as you see on the general property page of the Simulation experiment. So instead of the first number 20 you type sLoRetailer, then you replace the 80 with SHiRetailer, then the next 20 you replace with sLoWholesaler, then SHiWholesaler, then sLoFactory, and finally SHiFactory. Click save.

Now in the upper right hand corner of this property page is a button called "Create default UI", click that now and you have some user interface elements added to this experiment.

Next we need to go to the "Advanced" section of the properties and configure the experiment loop: perform the parameter retrieval, run the simulation, send the quality back, reset the model and continue with another attempt of retrieving parameters.

The following code samples need to be entered into the respective boxes.

Imports

import java.io.*;
import java.text.*;
import com.heuristiclab.problems.externalevaluation.*;
import com.heuristiclab.problems.externalevaluation.ExternalEvaluationMessages.*;

Additional class code

int replications;
double quality;
com.heuristiclab.problems.externalevaluation.PollService commDriver;
SolutionMessage currentSolution = null;

private void getMessage() {
  currentSolution = commDriver.getSolution();
  if (currentSolution.getIntegerArrayVarsCount() > 0) {
    SolutionMessage.IntegerArrayVariable vector = currentSolution.getIntegerArrayVars(0);
    int i = 0;
    for (Integer val : vector.getDataList()) {
      if (i == 0) {
        sLoRetailer = val.intValue();
      } else if (i == 1) {
        SHiRetailer = val.intValue();
      } else if (i == 2) {
        sLoWholesaler = val.intValue();
      } else if (i == 3) {
        SHiWholesaler = val.intValue();
      } else if (i == 4) {
        sLoFactory = val.intValue();
      } else if (i == 5) {
        SHiFactory = val.intValue();
      }
      i++;
    }
    int h;
    if (sLoRetailer > SHiRetailer) { h = sLoRetailer; sLoRetailer = SHiRetailer; SHiRetailer = h; }
    if (sLoWholesaler > SHiWholesaler) { h = sLoWholesaler; sLoWholesaler = SHiWholesaler; SHiWholesaler = h; }
    if (sLoFactory > SHiFactory) { h = sLoFactory; sLoFactory = SHiFactory; SHiFactory = h; }
  }
}

We have defined a method getMessage() that calls our library to get the next message from HeuristicLab and extract the parameters. You'll notice that here I have put the same text as before in the box "Expression" which is an intentional coincidence. Also notice that we need to check for invalid configurations, so if the value for the lower bound is greater than that for the upper bound I just swap them.

Initial experiment setup

commDriver = new com.heuristiclab.problems.externalevaluation.PollService(new ServerSocketListenerFactory(2112),1);
commDriver.start();

The number 2112 is important as this will be the TCP port that our simulation model will be listening on. This must be reachable by HeuristicLab through a network connection (yes this means you can run HeuristicLab on a different computer than your simulation model). You can of course choose another port (basically any number from 1 to 65535, but some numbers like 80 might be used by another application already).

Before each experiment run

quality = 0;
replications = 0;

getMessage();

The call to getMessage() will block, that means the simulation will wait here, until we have received a new set of parameters.

Before simulation run

leave this empty

After simulation run

double penalty = 10000 * (1 + root.histWaitingTime.max());
if (root.histWaitingTime.max() < 0.01) quality += root.meanDailyCost();
else quality += root.meanDailyCost() + penalty;
replications++;

This calls the cost function in the Main object called meanDailyCost() in this case. This is the target that we want to optimize (note that we add an increasing penalty term if the customer waiting time is above a certain level).

After iteration

try {
  commDriver.sendQuality(currentSolution, quality / replications);
} catch (IOException e) { }
quality = 0;
replications = 0;

getMessage();

This sends the mean quality of the (possible) replications back to HeuristicLab, resets the variables and receives a new message with which to perform the next simulation runs. We are done here. Save the model. You can now start the HeuristicLabOptimizationExperiement, although of course it won't do anything but block until it receives parameters.

Preparing the Optimization Problem in HeuristicLab 3.3

In HeuristicLab we need to define the problem and choose an algorithm with which we can optimize it. The problem is also attached to this page, if you're impatient go down to attachments and download the .hl file.

Defining the problem

We need to create a new External Evaluation Problem, so switch to the Clipboard (View > Clipboard if it is not visible) and click the yellow plus icon to add a new item. Type "external" without quotes in the search box and you'll find the right item called "External Evaluation Problem". Double click on it and you'll see it added to the clipboard. Double click it again in the clipboard so that we can edit it.

In the box you can type a Name, I'll use "AnyLogic Supply Chain Problem". You can also double click the information icon on the right end of the name box to edit the description.

In the Parameters box you'll see a number of different parameters. Let's configure the client first.

Client

Click on the parameter called "Clients" to see the list of clients. For each simulation model that participates in your experiment you have to add a client to this list. So this means you can optimize your parameters faster if you run the simulation on two separate computers (note however, that you need to use the "Parallel Engine" in your algorithm). Per default only one client is configured. Click on EvaluationServiceClient and you'll see another box with parameters. Among those is one called "Channel" which is currently null, meaning that it has no value defined. Click on Channel and then click on the pencil icon to give it a value. Choose the EvaluationTCPChannel by double clicking it in the emerging dialog. Now type the IP Address of the computer where the simulation will run ("127.0.0.1" in case it will be run on the same computer) and enter the port number (remember we chose "2112" above). Then we're done with the client.

Next we'll configure the parameter Evaluator. Click on this parameter to get its list of parameters.

Evaluator

In the "Collected values" section click on the yellow plus icon and add a LookupParameter<T> and for T choose an IntegerVector by double clicking on it (may take a couple of seconds). Name this parameter "IntegerVector", as always without quotes, and click Ok. Remember what you entered as Name!

So we're done with this parameter. The next one is Maximization which we'll not need to touch as it is already false (we're minimizing costs). So we get to the parameter "Operators" by clicking on it.

Operators

By clicking on the yellow plus button add following operators from the HeuristicLab.Encodings.IntegerVectorEncoding namespace:

  • SinglePointCrossover
  • UniformOnePositionManipulator

If you click on the just added UniformOnePositionManipulator you'll see one parameter called Bounds. We can either add a value to it here, or add a parameter at a higher level (e.g. at the problem level). In this case other operators might also be configured with the same bounds, so it's beneficial to add and configure them at the problem level. Let's add a ValueParameter<T>, choose IntMatrix for T and name it "Bounds" (the dialog to select a type for T may take some time to show up). Make the matrix 1 row and 3 columns and put "1", "101", "1" in those columns. The first column represents the minimum, the second column the exclusive maximum, and the third column holds a step size. So the values can only ever be multiples of that step within that range.

Now click on and configure the last parameter called SolutionCreator

SolutionCreator

Click the yellow plus icon and add a UniformRandomIntegerVectorCreator. Click on it to see its parameters. You'll note there is an additional one called "Length". Let's add a new ValueParameter<T> to our problem, just like Bounds but called Length and with "IntValue" as its type T. Give this parameter the value 6, because we have six parameters to optimize. You should save the clipboard now to save the problem within it (you can also save the problem to a separate file if you want).

Choosing an Algorithm

We're now done with the problem. We have added a crossover operator and a mutator so we're somewhat limited to a Genetic Algorithm or one of its variants. So create a new Genetic Algorithm by choosing "New" from the File menu.

Drag the problem from the clipboard onto the problem tab of the GA that we have just created. Go to the parameters tab and select the mutator that we have added (no mutator is chosen by default).

Optimizing the model

Now it's time, we're ready to start the optimization. First switch back to AnyLogic 6 and start the HeuristicLabOptimizationExperiment. Click on the button "Run Experiment" to set it into listening mode.

Go to HeuristicLab and click the green arrow at the bottom to start the algorithm.

Now in the back the algorithm attempts a TCP connection to the given IP Address and port and exchanges parameters with the simulation model. It will receive quality values and use these to determine the fitness of its solutions.

Attachments (2)

Download all attachments as: .zip