package desmoj.extensions.verkettung;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import desmoj.core.dist.ContDistConstant;
import desmoj.core.simulator.Experiment;
import desmoj.core.simulator.Model;
import desmoj.core.simulator.TimeInstant;
import desmoj.extensions.verkettung.util.MergerConfig;
import desmoj.extensions.verkettung.util.SplitterOutput;
/**
* This is the model class. It is the main class of a simple event-oriented
* model of the loading zone of a container terminal. Trucks arrive at the
* terminal to load containers. They wait in line until a van carrier is
* available to fetch a certain container and load it onto the truck. After
* loading is completed, the truck leaves the terminal while the van carrier
* serves the next truck.
*
* @author Olaf Neidhardt, Ruth Meyer
*/
public class NewConnectionExample extends Model {
/**
* Runs the model.
*
* In DESMO-J used to - instantiate the experiment - instantiate the model -
* connect the model to the experiment - steer length of simulation and
* outputs - set the ending criterion (normally the time) - start the
* simulation - initiate reporting - clean up the experiment
*
* @param args
* is an array of command-line arguments (will be ignored here)
*/
public static void main(java.lang.String[] args) {
// create model and experiment
NewConnectionExample model = new NewConnectionExample(null, "VerkettungsExample", true, true);
// null as first parameter because it is the main model and has no
// mastermodel
Experiment exp = new Experiment("VerkettungsExampleExperiment", TimeUnit.SECONDS, TimeUnit.MINUTES, null);
// ATTENTION, since the name of the experiment is used in the names of
// the
// output files, you have to specify a string that's compatible with the
// filename constraints of your computer's operating system. The remaing
// three
// parameters specify the granularity of simulation time, default unit
// to
// display time and the time formatter to use (null yields a default
// formatter).
// connect both
model.connectToExperiment(exp);
// set experiment parameters
exp.setShowProgressBar(false); // display a progress bar (or not)
exp.stop(new TimeInstant(100, TimeUnit.MINUTES)); // set end of
// simulation at
// 1500 minutes
exp.tracePeriod(new TimeInstant(0), new TimeInstant(100, TimeUnit.MINUTES)); // set
// the
// period
// of
// the
// trace
exp.debugPeriod(new TimeInstant(0), new TimeInstant(50, TimeUnit.MINUTES)); // and
// debug
// output
// ATTENTION!
// Don't use too long periods. Otherwise a huge HTML page will
// be created which crashes Netscape :-)
// start the experiment at simulation time 0.0
exp.start();
// --> now the simulation is running until it reaches its end criterion
// ...
// ...
// <-- afterwards, the main thread returns here
// generate the report (and other output files)
exp.report();
// stop all threads still alive and close all output files
exp.finish();
}
private Source<Body> bodySource;
private Source<RedTire> redTireSource;
private Source<BlueTire> blueTireSource;
/**
* ObserverExample constructor.
*
* Creates a new ObserverExample model via calling the constructor of the
* superclass.
*
* @param owner
* the model this model is part of (set to <tt>null</tt> when
* there is no such model)
* @param modelName
* this model's name
* @param showInReport
* flag to indicate if this model shall produce output to the
* report file
* @param showInTrace
* flag to indicate if this model shall produce output to the
* trace file
*/
public NewConnectionExample(Model owner, String modelName, boolean showInReport, boolean showInTrace) {
super(owner, modelName, showInReport, showInTrace);
}
private ContDistConstant createConstantDistribution(double i) {
return new ContDistConstant(getModel(), "Distribution", i, false, false);
}
/**
* Returns a description of the model to be used in the report.
*
* @return model description as a string
*/
@Override
public String description() {
return "This model describes a queueing system located at a " + "container terminal. Trucks will arrive and "
+ "require the loading of a container. A van carrier (VC) is "
+ "on duty and will head off to find the required container "
+ "in the storage. It will then load the container onto the "
+ "truck. Afterwards, the truck leaves the terminal. " + "In case the VC is busy, the truck waits "
+ "for its turn on the parking-lot. " + "If the VC is idle, it waits on its own parking spot for the "
+ "truck to come.";
}
/**
* Activates dynamic model components (events).
*
* This method is used to place all events or processes on the internal
* event list of the simulator which are necessary to start the simulation.
*
* In this case, the truck generator event will have to be created and
* scheduled for the start time of the simulation.
*/
@Override
public void doInitialSchedules() {
// create the TruckGeneratorEvent
// TruckGeneratorEvent truckGenerator = new TruckGeneratorEvent(this,
// "TruckGenerator", true);
// schedule for start of simulation
// truckGenerator.schedule(new TimeSpan(0));
bodySource.startCreatingEntities();
redTireSource.startCreatingEntities();
blueTireSource.startCreatingEntities();
}
/**
* Initialises static model components like distributions and queues.
*/
@Override
public void init() {
ContDistConstant setupTime;
ContDistConstant serviceTime;
ContDistConstant recoveryTime;
ContDistConstant transportTime;
setupTime = createConstantDistribution(0);
serviceTime = createConstantDistribution(10);
recoveryTime = createConstantDistribution(0);
transportTime = createConstantDistribution(0);
bodySource = new Source<Body>(-1, 1, setupTime, serviceTime, recoveryTime, transportTime, getModel(),
"BodySource", true, true) {
@Override
protected Body createEntity() {
return new Body(getModel(), "Body", true);
}
};
setupTime = createConstantDistribution(0);
serviceTime = createConstantDistribution(10);
recoveryTime = createConstantDistribution(0);
transportTime = createConstantDistribution(0);
redTireSource = new Source<RedTire>(-1, 2, setupTime, serviceTime, recoveryTime, transportTime, getModel(),
"RedTireSource", true, true) {
@Override
protected RedTire createEntity() {
return new RedTire(getModel(), "RedTire", true);
}
};
setupTime = createConstantDistribution(0);
serviceTime = createConstantDistribution(5);
recoveryTime = createConstantDistribution(0);
transportTime = createConstantDistribution(0);
blueTireSource = new Source<BlueTire>(-1, 1, setupTime, serviceTime, recoveryTime, transportTime, getModel(),
"BlueTireSource", true, true) {
@Override
protected BlueTire createEntity() {
return new BlueTire(getModel(), "BlueTire", true);
}
};
MergerConfig<CarPart> mergerConfig = new MergerConfig<CarPart>();
mergerConfig.put(Body.class, 1);
mergerConfig.put(Tire.class, 4);
setupTime = createConstantDistribution(2);
serviceTime = createConstantDistribution(5);
recoveryTime = createConstantDistribution(1);
transportTime = createConstantDistribution(1);
Merger<CarPart, Truck> truckMerger = new Merger<CarPart, Truck>(mergerConfig, -1, -1, 1, setupTime,
serviceTime, recoveryTime, transportTime, getModel(), "TruckMerger", true, true) {
@SuppressWarnings("unchecked")
@Override
protected Truck mergeEntities(Map<Class<? extends CarPart>, List<CarPart>> parts) {
Body body;
@SuppressWarnings("rawtypes")
List tires;
body = null;
tires = new ArrayList<Tire>();
for (Class<? extends CarPart> partClass : parts.keySet()) {
List<CarPart> partList = parts.get(partClass);
if (partClass == Body.class) {
body = (Body) partList.get(0);
if (partList.size() > 1) {
throw new RuntimeException("Zu viele Karossen.");
}
} else
if (partClass == Tire.class) {
tires = partList;
} else {
throw new RuntimeException("Unbekannter Part");
}
}
return new Truck(body, tires, getModel(), "Truck", true);
}
};
setupTime = createConstantDistribution(0);
serviceTime = createConstantDistribution(5);
recoveryTime = createConstantDistribution(0);
transportTime = createConstantDistribution(0);
ServiceStation<Truck> truckServcieStation = new ServiceStation<Truck>(-1, -1, 2, setupTime, serviceTime,
recoveryTime, transportTime, getModel(), "ServiceStation", true, true);
setupTime = createConstantDistribution(0);
serviceTime = createConstantDistribution(10);
recoveryTime = createConstantDistribution(0);
transportTime = createConstantDistribution(10);
Transformer<Truck, OldTruck> truckTransformer = new Transformer<Truck, OldTruck>(-1, -1, 1, setupTime,
serviceTime, recoveryTime, transportTime, getModel(), "Transformer", true, true) {
@Override
protected OldTruck transformEntity(Truck originalEntity) {
return new OldTruck(originalEntity);
}
};
// Splitter START
transportTime = createConstantDistribution(0);
SplitterOutput<OldTruck, Body> bodyOutput = new SplitterOutput<OldTruck, Body>(1, transportTime) {
@Override
public Body createOutputEntity(OldTruck originalEntity) {
return originalEntity.getBody();
}
};
transportTime = createConstantDistribution(0);
SplitterOutput<OldTruck, Tire> tireOutput = new SplitterOutput<OldTruck, Tire>(4, transportTime) {
@Override
public Tire createOutputEntity(OldTruck originalEntity) {
return originalEntity.getTire();
}
};
List<SplitterOutput<OldTruck, ? extends CarPart>> outputConfig = new ArrayList<SplitterOutput<OldTruck, ? extends CarPart>>();
outputConfig.add(bodyOutput);
outputConfig.add(tireOutput);
setupTime = createConstantDistribution(0);
serviceTime = createConstantDistribution(10);
recoveryTime = createConstantDistribution(0);
Splitter<OldTruck, CarPart> truckSplitter = new Splitter<OldTruck, CarPart>(outputConfig, -1, -1, 1, setupTime,
serviceTime, recoveryTime, getModel(), "TruckSplitter", true, true);
// Splitter END
setupTime = createConstantDistribution(0);
serviceTime = createConstantDistribution(10);
recoveryTime = createConstantDistribution(0);
Sink<Body> bodySink = new Sink<Body>(-1, -1, 1, setupTime, serviceTime, recoveryTime, getModel(), "BodySink",
true, true);
setupTime = createConstantDistribution(0);
serviceTime = createConstantDistribution(2.5);
recoveryTime = createConstantDistribution(0);
Sink<Tire> tireSink = new Sink<Tire>(-1, -1, 1, setupTime, serviceTime, recoveryTime, getModel(), "TireSink",
true, true);
bodySource.setSuccessor(truckMerger);
redTireSource.setSuccessor(truckMerger);
blueTireSource.setSuccessor(truckMerger);
truckMerger.setSuccessor(truckServcieStation);
truckServcieStation.setSuccessor(truckTransformer);
truckTransformer.setSuccessor(truckSplitter);
bodyOutput.setSuccessor(bodySink);
tireOutput.setSuccessor(tireSink);
}
} /* end of model class */