A Simple Discrete-Event Simulation: Part 55

Today I got a lot of updates into the mechanism for forwarding entities from one component to another. The changes were chiefly made to the Queue and Process components with some supplementary changes to the Path component. The first change involved saving the destination chosen when an entity first tries to exit a component. This only applies when using model routing logic. The component then keeps trying to forward the entity to the chosen location until it is successful, at which point it resets the savedDestination property to its initialized value of -1, meaning that the method should generate a new destination.

The next changes involved handling pull requests from downstream components. When an exclusive component forwards an entity it sends a request back to a previous component to forward an entity if one is available. There are several things to consider during this process. One is that the request is only sent if the discharging component goes from being at capacity to being at less than capacity. If a component (usually a Queue in this case) is not at capacity then the upstream component(s) should have been able to forward entities to the present component as needed, so there is no reason to send the pull request. The second consideration is important when there are multiple upstream components that might be pulled from. The code was changed to select the entity that has been waiting the longest. I discussed this in yesterday’s post and I still have to address the method of setting the “age” of each entity.

Finally, I changed the pull mechanism to ensure that the item is forwarded to the component that requested it. It would make no sense to send a pull request and have the upstream component randomly generate a new destination and send the entity someplace else. In order to do this I had to add a new array to the Queue and Process components to store the index of the first non-Path component linked to in each of the nextComponentList references. The array is initialized using the new getNextComponentIDs method, which has to be called when the components are defined and linked but before the model runs. The componentID of the pulling component is relayed to the upstream component, which then cycles through its own downstream connection indices until it finds a match (which it should be guaranteed to do). Once the match is found the upstream component can forward the entity (if it’s available) to the proper downstream component. This method of selecting a forwarding destination overrides the one normally used.

Here’s the new code for the forwardEntity method:

Here’s the new code for the pullFromPrevious method:

Here’s the new code for the getNextComponentIDs method:

The Path component was modified so the pullFromPrevious method could relay the index of the requesting element.

The Path component was also modified to add a method to pass requests for component IDs through multiple paths.

Blissfully I think I’m pretty close to getting the major routing and plumbing issues worked out so I can move on with things that are more “fun” and interesting. That said, the hard part will be done when it’s done. I’ll begin next week by working off the comments and TODOs in the code.

At the end of another week here is the current To Do list:

  • Standardize linking and exclusivity process
  • Resolve and standardize new vs. advance issue
  • Rework drawing of Path components so correct elements are always on top
  • New property for forward exclusivity as opposed to receiving exclusivity.
  • Formalize and implement method of receiving from multiple upstream components in turn. Implementing and observing this may illuminate the behaviors that will need to be implemented for the general path solution described in one or more previous posts.
  • Rework the Queue mechanism to flexibly handle finite-traversal time and zero-traversal time configurations
  • Revisit distribution logic to make sure it’s cycling the way it should be.
  • Learn JavaScript’s prototype object pattern and re-implement everything in that in place of the closure pattern I’ve been using; I’ll want to bite that bullet before this thing goes much farther
  • Add Control, Bag, and Stack components
  • Expand function of Process components to handle multiple entities in parallel, in effect making a single component function as if it were multiple, associated ones
  • Discrete-event simulation frameworks often include the concept of sets (logical containers that that be iterated and compared for intersection and so on, so that idea should be implemented; this would expand on things were doing now with lists of components and entities; the need for this was inspired by thinking about the bag data structure in general
  • Ponder the idea of implementing a combined Queue-Process component
  • Expand Path component representation so it can incorporate multiple line segments
  • Add ability to sense reaching tail end of FIFO queue based on stopping to wait on a Path component; collect statistics accordingly (possibly add wait flag to entities so they can test against the next entity in line)
  • Look into creating a zero-duration, zero-queue decision component
  • Create standardized routing mechanism (to components of different types) based on process logic (vs. distribution logic to multiple components of the same type)
  • Implement mechanism to identify combinations of related components into groups (e.g., a group of tollbooths represent a single toll plaza)
  • Gather and report system-, component-, and group-level statistics
  • Add ability to stream large volumes of output information which can be post-processed and quantified via a parsing mechanism
  • Streamline the process of defining the endpoints of Path components (i.e., attach standard nodes to other components and connect to those automatically, which will greatly save on the number of x,y locations the designer must specify manually)
  • Add an edit mode that allows designers to change component properties interactively (ultimately including being able to drag them)
  • Use the new, completely external mechanism for displaying component data
  • Describe how abstract representation can be used to represent detailed layouts and interactions; include ability to flag or alarm situations which would cause conflicts in the real world that would not necessarily be captured in a model unless specifically tested for
  • Add the ability to graph outputs as part of reporting
  • Add scrolling, animated graphs to illustrate progress as simulations run
  • Include ability for users to call up component and entity status by written or graphical display interactively while runs are in progress
  • Create streamlined graphical representations of all component types; create data display for Path components
  • Add ability to display entities inside relevant non-path components
  • Abstract the current x,y locations of all elements and scale them to the screen so the user can zoom in and out
  • Add ability for users to interactively change things during runs
  • Add Monte Carlo mechanisms to various timing and routing events (beyond what’s already been demonstrated)
  • Allow designer to build Monte Carlo and other distributions from acquired data using standardized tools
  • Add ability to perform multiple runs and statistically quantify generated outputs
  • Make simulation display update at regular intervals of simulated time rather than intervals defined by individual events; also make this “speed” scalable
  • Include ability to add arbitrary graphic elements to models (labels, keys, tables, etc.)
  • Include ability to display an underlay “below” the model display (e.g., a floor plan of a modeled process)
  • Allow user to turn off display and run model in “fire-and-forget” mode where it generates results without wasting time redrawing graphics.
  • Allow user to selectively turn different display elements on and off
  • Create suite of test configurations to exercise every combination of connections and support regression testing.
  • Add ability to assign open/close schedules for components and groups
  • Add ability to introduce multiple types of entities in model with different processing rules for routing and timing
  • Add ability to combine multiple queues into a single, logical unit
  • Add ability to adapt stand base components to represent varied and specialized things (this applies mostly to Process components)
  • Add ability to save and restore model definitions (in files/XML and in databases, requires PHP/MySql, Node.js or other back end capability)
  • Add ability to represent more abstract processes:
    • Reintroduce wait..until mechanism that uses the current events queue
    • Include pools of resources that are needed by different processes
    • Implement non-FIFO queues or collections that receive and forward entities based on arbitrary (user-defined) criteria
    • Include ability to accept events that happen according to fixed schedules rather than random ones (e.g., to match observed data)
    • Include the ability to change representation of entities and components to represent state changes (by color, shape, labels, flags, etc.)
    • Support input and editing of modular packages of information used to define and drive models
    • Add ability to represent BPM processes using standard BPMN notation
  • Really complex stuff
    • Develop more complex, arbitrary node-and-link representation of model, which brings up worlds of complications on its own!
    • Polish related sections of code and break them into modules which can be included on a modular basis
    • Make modules and examples distributable for use by a wider community
      • Write documentation for modules as needed
      • Share on GitHub
      • Create dedicated project page on my website
      • Update and enhance my custom Graph component as well as the simulation framework
  • Re-implement this system in a more appropriate language like C++ or at least Java

Finally, just for kicks and giggles, I was inspired by a demo I saw at a recent Meetup of the three.js framework for creating 3D models simply. I’m therefore going to add an item to the list to render a simulated system in 3D. I’ll keep it simple, but it should still be pretty punchy. If I go really crazy I’ll run that through a simple VR framework I also saw demoed. I’m sure it won’t be as easy as the speaker made it look, but it’s so much fun it might be a good thing to do over the holidays.

This entry was posted in Simulation and tagged . Bookmark the permalink.

Leave a Reply