{"id":927,"date":"2016-08-29T23:14:09","date_gmt":"2016-08-30T04:14:09","guid":{"rendered":"http:\/\/rpchurchill.com\/?p=927"},"modified":"2017-02-17T10:10:06","modified_gmt":"2017-02-17T15:10:06","slug":"a-simple-discrete-event-simulation-part-1","status":"publish","type":"post","link":"https:\/\/rpchurchill.com\/wordpress\/posts\/2016\/08\/29\/a-simple-discrete-event-simulation-part-1\/","title":{"rendered":"A Simple Discrete-Event Simulation: Part 1"},"content":{"rendered":"<p><a href=\"https:\/\/rpchurchill.com\/wordpress\/posts\/2016\/01\/14\/discrete-event-simulation-looking-under-the-hood\/\">Some months ago<\/a> I discussed some internal features of a discrete-event simulation. My next series of exercises and ruminations will proceed toward building one in JavaScript, using the simple pseudo-construct I outlined in the linked post.<\/p>\n<p>I&#8217;ll start with the creation of a future events queue. Since the point is to get something running in a reasonably brief series of posts I&#8217;ll keep it simple. There are many ways to make a future events queue more efficient, but for our purposes we&#8217;ll create one with a straightforward insert\/pull structure. That is, it&#8217;ll be a single list of items, sorted by time (we&#8217;ll assume items occurring at the exact same time are processed in the order in which they were added to the queue, in one dimension.<\/p>\n<p>Here&#8217;s a rough bit of code I worked out a while ago.<\/p>\n<pre class=\"toolbar-overlay:false wrap:false height-set:true lang:default decode:true \">    \/\/global simulation clock\r\n    var globalSimClock = 0.0;  \/\/starts at zero, units to be specified\r\n    var globalSimUnits = \"minutes\";\r\n    var globalInsertTime = 0.0;\r\n    \/\/events queue item\r\n    function futureEventItem(time,type,entityID,previousState,nextState) {\r\n      this.activationTime = 0.0;\r\n      if (type == \"advance\") {\r\n        this.activationTime = globalSimClock + time;  \/\/activate 'time' from now\r\n      } else if (type == \"absolute\") {\r\n        if (time &gt; globalSimClock) {\r\n          this.activationTime = time;                 \/\/activate at specified absolute time, if in future\r\n        } else {\r\n          alert(\"Invalid time past time supplied.  Entity ID: \"+entityID+\" Current Time: \"+globalSimClock+\" Speficied Time: \"+time);  \/\/alert on invalid time\r\n        }\r\n      }\r\n      this.entityID = entityID;\r\n      this.previousState = previousState;\r\n      this.nextState = nextState;\r\n      this.getActivationTime = function() {\r\n        return this.activationTime;\r\n      };\r\n      this.reportItem = function() {\r\n        console.log(\"Time: \"+this.activationTime+\" ID: \"+this.entityID+\" Prev: \"+this.previousState+\" Next: \"+this.nextState);\r\n      };\r\n    };  \/\/futureEventItem\r\n    function futureEventsQueue() {\r\n      this.feq = new Array();\r\n      this.feqSize = 0;\r\n      this.insertTime = 0.0;\r\n      this.findLaterTime = function(item) {\r\n        globalSimClock = 10.0;\r\n        var a = item.getActivationTime();\r\n        var b = globalInsertTime; \/\/this.insertTime;  why is the scope of \"this\" messed up here?  window and not queue\r\n        var result = a &gt; b;\r\n        return result;\r\n      };\r\n      this.insertItem = function(time,type,entityID,previousState,nextState) {\r\n        \/\/create futureEventItem\r\n        var feqItem = new futureEventItem(time,type,entityID,previousState,nextState);\r\n        this.insertTime = feqItem.getActivationTime();\r\n        globalInsertTime = this.insertTime;\r\n        if (this.feqSize == 0) {  \r\n          this.feq[0] = feqItem;\r\n          this.feqSize++;\r\n          console.log(\"Array size: \"+this.feq.length);\r\n        } else {\r\n          \/\/find index of feq item to insert before\r\n          var insertIndex = this.feq.findIndex(this.findLaterTime);\r\n          \/\/var insertIndex = this.feq.findIndex(this.findLaterTime1);\r\n          \/\/insert the element\r\n          if (insertIndex &lt; 0) { insertIndex = this.feq.length; } this.feq.splice(insertIndex,0,feqItem); this.feqSize++; console.log(\"Array size: \"+this.feq.length); } }; this.reportSize = function() { console.log(\"Number of events in queue: \"+this.feqSize); }; }; \/\/futureEventsQueue function reportItemInfo(element, index, arr) { globalSimClock = 10.0; console.log(\"reportItemInfo: element: \"+element+\" index: \"+index+\" arr: \"+arr); element.reportItem(); } function findLaterTime1(item) { globalSimClock = 10.0; return item.getActivationTime() &gt; globalInsertTime;\r\n    };\r\n    \r\n    \/\/initialize future events queue\r\n    feq = new futureEventsQueue();\r\n    feq.reportSize();  \/\/should be zero;\r\n    \r\n    feq.insertItem(40.0,\"absolute\",333,\"prev1\",\"next1\");\r\n    feq.feq.forEach(reportItemInfo); \r\n    feq.reportSize();  \/\/should be 1\r\n    \r\n    globalSimClock = 10.0;\r\n    feq.insertItem(20.0,\"advance\",444,\"prev2\",\"next2\");\r\n    feq.feq.forEach(reportItemInfo); \r\n    feq.reportSize();  \/\/should be 2\r\n\r\n    feq.insertItem(50.0,\"absolute\",555,\"prev3\",\"next3\");\r\n    feq.feq.forEach(reportItemInfo); \r\n    feq.reportSize();  \/\/should be 3\r\n<\/pre>\n<p>This code generates the following output to the console, which indicates that the basic insertion mechanism is working.<br \/>\n<code><br \/>\nNumber of events in queue: 0<br \/>\nArray size: 1<br \/>\nreportItemInfo: element: [object Object] index: 0 arr: [object Object]<br \/>\nTime: 40 ID: 333 Prev: prev1 Next: next1<br \/>\nNumber of events in queue: 1<br \/>\nArray size: 2<br \/>\nreportItemInfo: element: [object Object] index: 0 arr: [object Object],[object Object]<br \/>\nTime: 30 ID: 444 Prev: prev2 Next: next2<br \/>\nreportItemInfo: element: [object Object] index: 1 arr: [object Object],[object Object]<br \/>\nTime: 40 ID: 333 Prev: prev1 Next: next1<br \/>\nNumber of events in queue: 2<br \/>\nArray size: 3<br \/>\nreportItemInfo: element: [object Object] index: 0 arr: [object Object],[object Object],[object Object]<br \/>\nTime: 30 ID: 444 Prev: prev2 Next: next2<br \/>\nreportItemInfo: element: [object Object] index: 1 arr: [object Object],[object Object],[object Object]<br \/>\nTime: 40 ID: 333 Prev: prev1 Next: next1<br \/>\nreportItemInfo: element: [object Object] index: 2 arr: [object Object],[object Object],[object Object]<br \/>\nTime: 50 ID: 555 Prev: prev3 Next: next3<br \/>\nNumber of events in queue: 3<br \/>\n<\/code><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Some months ago I discussed some internal features of a discrete-event simulation. My next series of exercises and ruminations will proceed toward building one in JavaScript, using the simple pseudo-construct I outlined in the linked post. I&#8217;ll start with the &hellip; <a href=\"https:\/\/rpchurchill.com\/wordpress\/posts\/2016\/08\/29\/a-simple-discrete-event-simulation-part-1\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[121,49],"_links":{"self":[{"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/posts\/927"}],"collection":[{"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/comments?post=927"}],"version-history":[{"count":6,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/posts\/927\/revisions"}],"predecessor-version":[{"id":1637,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/posts\/927\/revisions\/1637"}],"wp:attachment":[{"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/media?parent=927"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/categories?post=927"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/tags?post=927"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}