{"id":941,"date":"2016-08-30T23:46:10","date_gmt":"2016-08-31T04:46:10","guid":{"rendered":"http:\/\/rpchurchill.com\/?p=941"},"modified":"2016-08-30T23:51:05","modified_gmt":"2016-08-31T04:51:05","slug":"a-simple-discrete-event-simulation-part-2","status":"publish","type":"post","link":"https:\/\/rpchurchill.com\/wordpress\/posts\/2016\/08\/30\/a-simple-discrete-event-simulation-part-2\/","title":{"rendered":"A Simple Discrete-Event Simulation: Part 2"},"content":{"rendered":"<p>Today I&#8217;ve added the ability to retrieve the first item from the future events queue, which is the next item to process and that with the lowest activation time.  In this case I just update the item&#8217;s time when it&#8217;s retrieved, then insert it back into the future events queue wherever it belongs.  In the example it goes to the end of the queue with a time of 55.<\/p>\n<p>Note that I&#8217;ve updated that state values, though I haven&#8217;t defined how they&#8217;re going to work yet.<\/p>\n<p>I added an <code>update<\/code> function to the <code>futureEventItem<\/code> object.  I added the functions <code>getFirstItem<\/code> and <code>insertExistingItem<\/code> to the <code>futureEventsQueue<\/code> object.  Finally, I added some calls to exercise the new capabilities down at the bottom. <\/p>\n<pre class=\"toolbar-overlay:false wrap:false height-set:true lang:default decode:true \">\r\n    \/\/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 > 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.update = function(time,type,previousState,nextState) {\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 > 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: \"+this.entityID+\" Current Time: \"+globalSimClock+\" Speficied Time: \"+time);  \/\/alert on invalid time\r\n          }\r\n        }\r\n        this.previousState = previousState;\r\n        this.nextState = nextState;\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 > 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 < 0) {\r\n            insertIndex = this.feq.length;\r\n          }\r\n          this.feq.splice(insertIndex,0,feqItem);\r\n          this.feqSize++;\r\n          console.log(\"Array size: \"+this.feq.length);\r\n        }\r\n      };\r\n      this.getFirstItem = function() {\r\n        globalSimClock = this.feq[0].getActivationTime();\r\n        var feqItem = this.feq.splice(0,1);\r\n        if (feqItem) {\r\n          this.feqSize--;\r\n          return feqItem;\r\n        } else {\r\n          console.log(\"no items in FEQ to retrieve \"+this.feqSize)\r\n        }\r\n      };\r\n      this.insertExistingItem = function(feqItem) {\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 < 0) {\r\n            insertIndex = this.feq.length;\r\n          }\r\n          this.feq.splice(insertIndex,0,feqItem);\r\n          this.feqSize++;\r\n          console.log(\"Array size: \"+this.feq.length);\r\n        }\r\n      };\r\n      this.reportSize = function() {\r\n        console.log(\"Number of events in queue: \"+this.feqSize);\r\n      };\r\n\r\n    };  \/\/futureEventsQueue\r\n    \r\n    function reportItemInfo(element, index, arr) {\r\n      \/\/globalSimClock = 10.0;    \r\n      console.log(\"reportItemInfo: element: \"+element+\" index: \"+index+\" arr: \"+arr);\r\n      element.reportItem();\r\n    }\r\n    function findLaterTime1(item) {\r\n      globalSimClock = 10.0;\r\n      return item.getActivationTime() > 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    \r\n    \/\/get the first item to process\r\n    var item = feq.getFirstItem();\r\n    feq.feq.forEach(reportItemInfo); \r\n    feq.reportSize();  \/\/should be 2\r\n    \r\n    \/\/do something to it\r\n    item[0].update(25.0,\"advance\",\"prev1a\",\"next1a\");\r\n    \r\n    \/\/put it back in the queue\r\n    feq.insertExistingItem(item[0]);\r\n    feq.feq.forEach(reportItemInfo); \r\n    feq.reportSize();  \/\/should be 3\r\n    <\/pre>\n<p>The console output again indicates that things are working as expected.<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 \/>\nreportItemInfo: element: [object Object] index: 0 arr: [object Object],[object Object]<br \/>\nTime: 40 ID: 333 Prev: prev1 Next: next1<br \/>\nreportItemInfo: element: [object Object] index: 1 arr: [object Object],[object Object]<br \/>\nTime: 50 ID: 555 Prev: prev3 Next: next3<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: 40 ID: 333 Prev: prev1 Next: next1<br \/>\nreportItemInfo: element: [object Object] index: 1 arr: [object Object],[object Object],[object Object]<br \/>\nTime: 50 ID: 555 Prev: prev3 Next: next3<br \/>\nreportItemInfo: element: [object Object] index: 2 arr: [object Object],[object Object],[object Object]<br \/>\nTime: 55 ID: 444 Prev: prev1a Next: next1a<br \/>\nNumber of events in queue: 3<br \/>\n<\/code><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today I&#8217;ve added the ability to retrieve the first item from the future events queue, which is the next item to process and that with the lowest activation time. In this case I just update the item&#8217;s time when it&#8217;s &hellip; <a href=\"https:\/\/rpchurchill.com\/wordpress\/posts\/2016\/08\/30\/a-simple-discrete-event-simulation-part-2\/\">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":[60],"tags":[121,49],"_links":{"self":[{"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/posts\/941"}],"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=941"}],"version-history":[{"count":3,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/posts\/941\/revisions"}],"predecessor-version":[{"id":944,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/posts\/941\/revisions\/944"}],"wp:attachment":[{"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/media?parent=941"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/categories?post=941"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/tags?post=941"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}