Introduction to Simulation

In order to use the simulator, we must first write a simulation scenario. A scenario is a parallel and/or sequential composition of stochastic processes, which is a finite random sequence of events. We invoke a stochastic process with a specified distribution of inter-arrival times. In other words, stochastic processes define series of events that occur in simulation.

Stochastic Processes and Operations

The following snippet of code creates a single stochastic process that will generate 1000 events of type SimpleEvent with an interarrival time of 2000ms (or 2s) of simulation time.

Java
static Operation<SimpleEvent> simpleEventGen1 =
    new Operation<SimpleEvent>() {

      @Override
      public SimpleEvent generate() {
        return new SimpleEvent();
      }
    };
          StochasticProcess p1 =
              new StochasticProcess() {
                {
                  eventInterarrivalTime(constant(2000));
                  raise(1000, simpleEventGen1);
                }
              };
Scala
val simpleEventGen1 = Op { (_: Unit) =>
  SimpleEvent()
};
  /* ... */
  raise(1000, simpleEventGen1).arrival(constant(2.seconds))

However, in the example above, all events are exactly the same; there is no variation to the 1000 events generated. We can generate events that differ slightly, by having the event take an integer parameter and generating this parameter randomly.

Java
static Operation1<SimpleEvent, Long> simpleEventGen2 =
    new Operation1<SimpleEvent, Long>() {

      @Override
      public SimpleEvent generate(Long param) {
        return new SimpleEvent(param);
      }
    };
          StochasticProcess p2 =
              new StochasticProcess() {
                {
                  eventInterarrivalTime(constant(2000));
                  raise(1000, simpleEventGen2, uniform(1000L, 2000L));
                }
              };
Scala
val simpleEventGen2 = Op { (param: java.lang.Long) =>
  SimpleEvent(param)
};
  /* ... */
  raise(1000, simpleEventGen2, uniform(1000L, 2000L)).arrival(constant(2.seconds))

The new events generated have a parameter that takes uniform long random values between 1000 and 2000. Both the interarrival time and the event parameters are defined as instances of Distribution, and the constantconstant and uniformuniform are just helper methods to generate these distributions.

There are several types of operations (Operation, Operation1, …, Operation5) that can be interpreted by the simulator, and they differ in the number of parameters they take to customise the generated events. All parameters are given as distributions. There are a number of distributions provided by the simulator, or you can write your own distribution by extending Distribution.

In order to start the stochastic processes and to define the iterative/parallel behaviour, the StochasticProcess has a number of start/terminate methodsa builder DSL is provided.

If we want to start the two stochastic processes above, a possible example would be:

Java
p1.start();
p2.startAfterTerminationOf(1000, p1);
terminateAfterTerminationOf(1000, p2);
Scala
val scenario = raise(1000, simpleEventGen1)
  .arrival(constant(2.seconds))
  .andThen(1.second)
  .afterTermination(
    raise(1000, simpleEventGen2, uniform(1000L, 2000L))
      .arrival(constant(2.seconds))
  )
  .andThen(2.seconds)
  .afterTermination(Terminate);

The above example would start the first stochastic process at the beginning of the simulation. After all 1000 if its events are generated, the simulation waits another 1000ms of simulation time and then starts the second stochastic process. After generating all 1000 of its defined events and waiting another 2000ms of simulation time, the simulation is terminated.

Simluation Scenario

The stochastic processes created and their order will be defined within a SimulationScenario, such as the on the in the following classobject.

Basic Scenario

Java
package jexamples.simulation.basic;

import se.sics.kompics.simulator.adaptor.Operation;
import se.sics.kompics.simulator.adaptor.Operation1;
import se.sics.kompics.simulator.SimulationScenario;

public class BasicSimulation {

  static Operation<SimpleEvent> simpleEventGen1 =
      new Operation<SimpleEvent>() {

        @Override
        public SimpleEvent generate() {
          return new SimpleEvent();
        }
      };

  static Operation1<SimpleEvent, Long> simpleEventGen2 =
      new Operation1<SimpleEvent, Long>() {

        @Override
        public SimpleEvent generate(Long param) {
          return new SimpleEvent(param);
        }
      };

  public static SimulationScenario scenario() {
    SimulationScenario scen =
        new SimulationScenario() {
          {
            StochasticProcess p1 =
                new StochasticProcess() {
                  {
                    eventInterarrivalTime(constant(2000));
                    raise(1000, simpleEventGen1);
                  }
                };

            StochasticProcess p2 =
                new StochasticProcess() {
                  {
                    eventInterarrivalTime(constant(2000));
                    raise(1000, simpleEventGen2, uniform(1000L, 2000L));
                  }
                };

            p1.start();
            p2.startAfterTerminationOf(1000, p1);
            terminateAfterTerminationOf(1000, p2);
          }
        };
    return scen;
  }
}
Scala
package sexamples.simulation.basic

import se.sics.kompics.sl._
import se.sics.kompics.sl.simulator._
import se.sics.kompics.simulator.{SimulationScenario => JSimulationScenario}
import scala.concurrent.duration._

case class SimpleEvent(num: Long = 0L) extends KompicsEvent;

object BasicSimulation {
  import Distributions._
  // needed for the distributions, but needs to be initialised after setting the seed
  implicit val random = JSimulationScenario.getRandom();

  val simpleEventGen1 = Op { (_: Unit) =>
    SimpleEvent()
  };

  val simpleEventGen2 = Op { (param: java.lang.Long) =>
    SimpleEvent(param)
  };

  val _ignoreThisIsJustForDocs = {
    /* ... */
    raise(1000, simpleEventGen1).arrival(constant(2.seconds))
    /* ... */
    raise(1000, simpleEventGen2, uniform(1000L, 2000L)).arrival(constant(2.seconds))
    ()
  }

  val scenario = raise(1000, simpleEventGen1)
    .arrival(constant(2.seconds))
    .andThen(1.second)
    .afterTermination(
      raise(1000, simpleEventGen2, uniform(1000L, 2000L))
        .arrival(constant(2.seconds))
    )
    .andThen(2.seconds)
    .afterTermination(Terminate);
}

Running a Simulation Scenario

In order to run the simulation scenario, the following Main code is required:

Java
package jexamples.simulation.basic;

import se.sics.kompics.simulator.SimulationScenario;
import se.sics.kompics.simulator.run.LauncherComp;

public class Main {
  public static void main(String[] args) {
    long seed = 123;
    SimulationScenario.setSeed(seed);
    SimulationScenario simpleBootScenario = BasicSimulation.scenario();
    simpleBootScenario.simulate(LauncherComp.class);
  }
}
Scala
package sexamples.simulation.basic

import se.sics.kompics.simulator.SimulationScenario
import se.sics.kompics.simulator.run.LauncherComp

object Main {
  def main(args: Array[String]): Unit = {
    val seed = 123;
    SimulationScenario.setSeed(seed);
    val simpleBootScenario = BasicSimulation.scenario;
    simpleBootScenario.simulate(classOf[LauncherComp]);
  }
}

In the above code, we set the simulation scenario seed (more about this seed in later sections), we construct the simulation scenario and we use the LauncherComp to execute it.

We can attempt to run this using:

runMain jexamples.simulation.basic.Main
runMain sexamples.simulation.basic.Main

However, the execution will fail with an exception indicating that we are triggering an invalid event. In fact, the only events that can be generated by stochastic processes and interpreted by the simulator are:

  1. SetupEvent
  2. StartNodeEvent
  3. KillNodeEvent
  4. TerminateExperiment
  5. ChangeNetworkModelEvent

You can read more about operations, distributions and stochastic processes in the section on Scenarios.

The source code for this page can be found here.