0

I'm attempting to build a Discrete Event Simulation library by following this tutorial and fleshing it out.

How should I handle logging metrics in my Discrete Event Simulation engine?

If you don't want/need background, skip to The Design or The Question section below...

Simulation

The goal of a simulation of the type in question is to model a process to perform analysis of it that wouldn't be possible or at least feasible in reality.

Take the canonical example of a simulation of this kind is a Bank:

  • Customers enter the bank and get in line with a statistically distributed frequency
  • Tellers are available to handle customers from the front of the line one at a time with a certain distribution
  • As the line grows longer, the number of tellers available may have to be increased based on certain business rules

You can break this down into generic objects:

  • Entity: These would be the customers
  • Generator: This object generates Entities according to a distribution
  • Queue: This object represents the line at the bank. They find much real world use in acting as a buffer between customers and a limited service.
  • Activity: This is a representation of the work done by a teller. It generally processes Entities from a Queue

Discrete Event Simulation

Instead of a continuous tick by tick simulation such as one might do with physical systems, a "Discrete Event" Simulation is a recognition that in many systems only critical events require process and the rest of the time nothing important to the state of the system is happening.

In the case of the Bank, critical events might be a customer entering the line, a teller becoming available, the manager deciding whether or not to open a new teller window, etc.

In a Discrete Event Simulation, the flow of time is kept by maintaining a Priority Queue of Events instead of an explicit clock. Time is incremented by popping the next event in chronological order (the minimum event time) off the queue and processing as necessary.

The Design

I've got a Priority Queue implemented as a Min Heap for now.

In order for the objects of the simulation to be processed as events, they implement an ISimulationEvent interface that provides an EventTime property and an Execute method. Those together mean the Priority Queue can schedule the events, then Execute them one at a time in the correct order and increment the simulation clock appropriately.

The simulation engine is a basic event loop that pops the next event and Executes it until there are none left. An event can reschedule itself to occur again or allow itself to go idle. For example, when a Generator is Executed it creates an Entity and then reschedules itself for the generation of the next Entity at some point in the future.

The Question

How should I handle logging metrics in my Discrete Event Simulation engine?

In the midst of this simulation, it is necessary to take metrics. How long are Entities waiting in the Queue? How many Acitivity resources are being utilized at any one point? How many Entities were generated since the last metrics were logged?

It follows logically that the metric logging should be scheduled as an event to take place every few units of time in the simulation.

The difficulty is that this ends up being a cross-cutting concern: metrics may need to be taken of Generators or Queues or Activities or even Entities. Consider also that it might be necessary to take derivative calculated metrics: e.g. measure a, b, c, and ((a-c)/100) + Log(b).

I'm thinking there are a few main ways to go:

  1. Have a single, global Stats object that is aware of all of the simulation objects. Have the Generator/Queue/Activity/Entity objects store their properties in an associative array so that they can be referred to at runtime (my chosen language doesn't support reflection). This way the statistics can be attached as needed Stats.AddStats(Object, Properties). This wouldn't support calculated metrics easily unless they are built into each object class as properties somehow.

  2. Have a single, global Stats object that is aware of all of the simulation objects. Create some sort of ISimStats interface for the Generator/Queue/Activity/Entity classes to implement that returns an associative array of the important stats for that particular object. This would also allow runtime attachment, Stats.AddStats(ISimStats). The calculated metrics would have to be hardcoded in the straightforward implementation of this option.

  3. Have multiple Stats objects, one per Generator/Queue/Activity/Entity as a child object. This might make it easier to implement simulation object-specific calculated metrics, but clogs up the Priority Queue a little bit with extra things to schedule. It might also cause tighter coupling, which is bad :(.

  4. Some combination of the above or completely different solution I haven't thought of?

Let me know if I can provide more (or less) detail to clarify my question!

I may be in error using the Aspect-Oriented tag, but I suspect that people of that background would have good advice for this situation.

1

You have your answer already based on an observation you made: You have a Cross cutting concern and this definitely falls into the realm of an aspect. I just wrote about this yesterday as you are trying to do something identical to that post.

You're trying to roll a DES from scratch and that's ok. But, leveraging existing libraries to make use of aspects is crucial and acceptable.

In addition, in this example you can get a motivation for how to express the cutpoint. Spring AOP offers a syntax for doing so but you could also use AspectJ. I am SURE .NET offers facilities for aspects as well but I am not familiar with them. A clever programmer could probably use some macros or pragmas to do it in C as well.

Do I win the bounty? :)

  • I'm implementing in VBA, so I'm having to roll my own EVERYTHING :P (believe me, I'd use something else if I could). This leaves me in the unfortunate position of actually not having access to an AOP library. I could roll my own, buuuut that might be a bit overkill. Any suggestions based on your experience with Aspects that might apply to this case specifically? – Blackhawk May 20 '14 at 21:15
  • In looking at it, the logging I'm interested in doing would take place every "5 minutes" of simulation time. The numbers would be aggregated over that time period. The Aspect solution would allow me to hook into changes so I can log them as they happen, which is good for many kinds of logging, but for the scheduled logging doesn't help quite as much methinks. The VBA IDE is scriptable down to modifying the text of the code, so in theory I could 'precompile' it to include the Aspect code, but I'd have to think some more about how it could achieve the goal. – Blackhawk May 20 '14 at 21:28
  • msdn.microsoft.com/en-us/library/aa288717(v=vs.71).aspx This link seems to give clear guidance on implementing it in VB. Rolling your own aspect code is nightmarishly difficult. The answer I gave yesterday talk about this. Find a way to use some library code for the job. Ditch VB if you must – Christian Bongiorno May 20 '14 at 21:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.