Link them together and run the simulation

Example with a Netlogo random walk model


The model used is a simple random walk where, for each simulation step, agents (so-called walkers) choose a random direction and step forward. The Netlogo model specification is available here. The exchanged data will be here the walkers positions (x,y) the same for input and output. In this simplistic case, the model exchange theses data with itself (i.e. its input port correspond to its output port). Since not very useful for simulation results, this example allows to introduce the very first concepts and their implementation

In this tutorial, we present the operation we take on the positions in order for the walkers not go outside the boundaries of the model.

random walk example 1

An operation to filter the positions

In our example, we want that, when a walker reaches the boundaries of the model, its position is automatically set to (0,0). Although this operation is quite simple, it is the basis to more evolved ones (see link2models).

In order to implement an operation, you need to extend the Operation interface. The apply method is used to implement the core of the operation. In our example, for each positions, we check that it is inside the boundaries. If not, we set the position to (0,0).

/**
 * This class represents an operation which goal is to change the positions
 * (x,y) of the Netlogo turtles when they reach the borders (defined by
 * environment width and height)
 
 @author Julien Siebert
 */
public class PositionsLimitOp implements Operation {

  /**
   * Environment width (in order to replace the agents when they are out).
   */
  private int environmentWidth;

  /**
   * Environment height (in order to replace the agents when they are out).
   */
  private int environmentHeight;

  /**
   * Constructor
   @param width
   @param height
   */
  public PositionsLimitOp(int width, int height) {
    environmentHeight = height;
    environmentWidth = width;
  }

  public SimulData apply(SimulData someKindOfData) {

    // the list of new positions to return
    HashMap<Double, Point2D.Double> newPositionList = new HashMap<Double, Point2D.Double>();

    // check if the class of the simulData is correct (i.e. correspond to
    // the TurtlePosition Class)
    if (someKindOfData.getClass().equals(TurtlePositions.class)) {

      // get the initial list of positions
      TurtlePositions pos = (TurtlePositionssomeKindOfData;
      HashMap<Double, Point2D.Double> oldPositionList = pos
          .getTurtlePositions();

      // limit the turtle positions
      for (Double turtleID : oldPositionList.keySet()) {

        // get the initial positions
        Point2D.Double aPosition = oldPositionList.get(turtleID);

        // limit the initial position (if needed)
        aPosition = operation(aPosition);

        // fill the resulting hashMap (I.e. the new list of new
        // positions)
        newPositionList.put(turtleID, aPosition);
      }
    else {
      // exit.
      System.err
          .println("trying to take an operation on a non turtle position data");
      System.exit(666);
    }
    // the simulData to return
    SimulData res = new TurtlePositions(newPositionList);
    return res;
  }

  /**
   * This is an example of operation we can take on the set of input data. In
   * this example when an agent is outside the environment boundaries (width
   * and height), then its position is set to the origin (0,0).
   
   @param aPosition
   @return
   */
  private Point2D.Double operation(Point2D.Double aPosition) {

    Point2D.Double newPosToReturn = aPosition;

    if ((aPosition.getX() (-environmentWidth / 2))
        || (aPosition.getX() (environmentWidth / 2))
        || (aPosition.getY() (-environmentHeight / 2))
        || (aPosition.getY() (environmentHeight / 2))) {
      newPosToReturn.y = 0;
      newPosToReturn.x = 0;
    }
    return newPosToReturn;
  }

  public int getEnvironmentWidth() {
    return environmentWidth;
  }

  public int getEnvironmentHeight() {
    return environmentHeight;
  }
}