{"id":4580,"date":"2015-05-20T10:14:34","date_gmt":"2015-05-20T15:14:34","guid":{"rendered":"https:\/\/blogs.mathworks.com\/seth\/?p=4580"},"modified":"2016-12-30T14:16:30","modified_gmt":"2016-12-30T19:16:30","slug":"what-is-the-most-efficient-aircraft-seating-strategy","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/simulink\/2015\/05\/20\/what-is-the-most-efficient-aircraft-seating-strategy\/","title":{"rendered":"What is the most efficient aircraft seating strategy?"},"content":{"rendered":"<p>Today I am happy to welcome my colleague Ramamurthy Mani for another very interesting study using SimEvents.<\/p>\n<p><strong>Introduction<\/strong><\/p>\n<p>Recently, I read an <a href=\"http:\/\/www.wired.com\/2014\/11\/whats-boarding-airplanes-takes-forever\">article<\/a> in Wired (TM) magazine that posed a question that I am sure many of you have confronted &#8212; what is the most efficient way to get passengers onto an airplane. While this article highlights a theoretical (and deterministic) approach to doing this, I set about trying to model this situation and try some variations of this strategy and others that capture at least a few more elements of randomness in the boarding process.<\/p>\n<p><strong>Generating a queue of passengers<\/strong><\/p>\n<p>I used MATLAB to generate a queue of passengers utilizing many different boarding strategies. These strategies are shown in the figure below. The most common one used by airlines is the one labeled &#8216;backToFrontZone&#8217;. A colored circle in each plot is more bright than another when that passenger has a higher probability of being in the passenger queue earlier. I use the &#8216;datasample&#8217; function in MATLAB to generate a sample passenger queue with those weighted probabilities. Each decrease in shade of green represents a 10 fold decrease in probability of a darker shade dot (i.e. passenger) jumping ahead of the brighter shade dot in the queue.<\/p>\n<pre class=\"codeinput\">close <span class=\"string\">all<\/span>; clear <span class=\"string\">all<\/span>\r\n\r\n<span class=\"comment\">% Boarding types dictate how you want to order passengers for boarding<\/span>\r\nboardingTypes = {<span class=\"string\">'frontToBackZone'<\/span>, <span class=\"string\">'backToFrontZone'<\/span>, <span class=\"string\">'random'<\/span>, <span class=\"keyword\">...<\/span>\r\n                 <span class=\"string\">'alternateRowZone'<\/span>, <span class=\"string\">'windowToAisleZone'<\/span>, <span class=\"string\">'windowToAisleAlternateZone'<\/span>};\r\n<span class=\"comment\">%boardingTypes = {'windowToAisleAlternateZone'};<\/span>\r\n\r\nnumRows = 20; <span class=\"comment\">% Number of rows in the plane<\/span>\r\nnumSeatsPerRow = 6; <span class=\"comment\">% Number of seats per row<\/span>\r\ncrossZoneFactor = 10; <span class=\"comment\">% Factor that controls how likely people from different<\/span>\r\n                      <span class=\"comment\">% zones mix. Higher numbers means mixing less likely<\/span>\r\nexpRndMeanStowTime = 1\/4; <span class=\"comment\">% Mean time (mins) for stowing bags<\/span>\r\nexpRndMeanGetUpSitTime = 1\/6; <span class=\"comment\">% Mean time (mins) for getting up and sitting down<\/span>\r\n                              <span class=\"comment\">% when passenger needs to let someone into<\/span>\r\n                              <span class=\"comment\">% their row<\/span>\r\nseatOrders = [];\r\nidealOrders = [];\r\n<span class=\"keyword\">for<\/span> k = 1:length(boardingTypes)\r\n    fprintf(<span class=\"string\">'Generating %s\\n'<\/span>, boardingTypes{k});\r\n\r\n    <span class=\"comment\">% Use MATLAB to produce the passenger order<\/span>\r\n    [seatOrder, idealOrder] = airseatSetupSim(boardingTypes{k}, <span class=\"string\">'repeatable'<\/span>, <span class=\"keyword\">...<\/span>\r\n                                numRows, numSeatsPerRow, <span class=\"keyword\">...<\/span>\r\n                                crossZoneFactor, expRndMeanStowTime, <span class=\"keyword\">...<\/span>\r\n                                expRndMeanGetUpSitTime);\r\n    seatOrders = [seatOrders, seatOrder]; <span class=\"comment\">%#ok<\/span>\r\n    idealOrders = [idealOrders, idealOrder]; <span class=\"comment\">%#ok<\/span>\r\n<span class=\"keyword\">end<\/span>\r\nairseatDrawBoardingSchemes(boardingTypes, seatOrders);\r\n<\/pre>\n<p>The six strategies include:<\/p>\n<ol>\n<ol>\n<li><strong>frontToBackZone:<\/strong> Boarding from front of aircraft to back broken into 4 zones.<\/li>\n<li><strong>backToFrontZone:<\/strong> Boarding from back of aircraft to front broken into 4 zones.<\/li>\n<li><strong>random:<\/strong> Boarding happens across the aircraft randomly<\/li>\n<li><strong>alternateRowZone:<\/strong> Boarding (back to front) is done in four zones and each zone only includes alternate rows.<\/li>\n<li><strong>windowToAisleZone:<\/strong> Boarding broken into 3 zones as \u2018window\u2019, \u2018middle\u2019, and \u2018aisle\u2019<\/li>\n<li><strong>windowToAisleAlternateZone:<\/strong> Hybrid of 4 and 5 with 6 zones where alternate rows in window, middle, and aisle are treated as separate zones.<\/li>\n<\/ol>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2015Q2\/airseatRunBatch_01.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/><\/p>\n<p><strong>Run simulations<\/strong><\/p>\n<p>To model the aircraft cabin, I used a model built in SimEvents. SimEvents is discrete-event simulation library for the Simulink platform. To begin, we generate passenger entities and assign them attributes like row and seat number, along with a random amount of time it will take to stow their bag and sit down.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2015Q2\/EntityGeneration.png\" alt=\"Passenger Entity Generation\" \/><\/p>\n<p>Then using a library I can model one row of seats and then repeat that row as many times as I want to form the cabin. In each row, I use the Attribute Function block, where I can write MATLAB code accessing and modifying attributes of the passenger entities:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2015Q2\/row.png\" alt=\"Row\" \/><\/p>\n<p>I connected 20 of those in series and got interesting results I will describe below.<\/p>\n<p>To make the simulation more visually appealing, I created a custom visualization, using new features available in R2015a. In MATLAB, I created a simevents.CustomObserverInterface object, which I connected to my model using simevents.connectObserver. In the object, I can specify which blocks to observe using getBlocksToObserve, and then I can code any type of visualization in the entityAdvance to be updated when an entity advances.<\/p>\n<p>Here is what the custom observer object looks like. Note that I removed the actual plotting code to help keeping the focus on the SimEvent feature.<\/p>\n<pre class=\"codeinput\"><span class=\"keyword\">classdef<\/span> airseatViz &lt; simevents.CustomObserverInterface\r\n<span class=\"comment\">% AIRSEATVIZ Helper class that draws results of airplane seating model.<\/span>\r\n<span class=\"comment\">%<\/span>\r\n    <span class=\"keyword\">properties<\/span> (Access=private)\r\n        mFig;\r\n        mPatches = cell(1, 20);\r\n        mNumRows;\r\n        mNumSeats;\r\n    <span class=\"keyword\">end<\/span>\r\n\r\n    <span class=\"comment\">% ---------------------------------------------------------------------<\/span>\r\n    <span class=\"keyword\">methods<\/span> (Access=public)\r\n\r\n        <span class=\"keyword\">function<\/span> this = airseatViz(numRows, numSeats)\r\n            this.mNumRows = numRows;\r\n            this.mNumSeats = numSeats;\r\n        <span class=\"keyword\">end<\/span>\r\n\r\n        <span class=\"keyword\">function<\/span> fig = getFigure(this)\r\n            fig = this.mFig;\r\n        <span class=\"keyword\">end<\/span>\r\n\r\n        <span class=\"keyword\">function<\/span> blks = getBlocksToObserve(this) <span class=\"comment\">%#ok&lt;MANU&gt;<\/span>\r\n            blks1 = find_system(<span class=\"string\">'airseat'<\/span>, <span class=\"string\">'FollowLinks'<\/span>, <span class=\"string\">'on'<\/span>, <span class=\"keyword\">...<\/span>\r\n                                <span class=\"string\">'BlockType'<\/span>, <span class=\"string\">'SingleServer'<\/span>);\r\n            blks2 = find_system(<span class=\"string\">'airseat'<\/span>, <span class=\"string\">'FollowLinks'<\/span>, <span class=\"string\">'on'<\/span>, <span class=\"keyword\">...<\/span>\r\n                                <span class=\"string\">'BlockType'<\/span>, <span class=\"string\">'EntitySink'<\/span>);\r\n            blks = union(blks1,blks2);\r\n        <span class=\"keyword\">end<\/span>\r\n\r\n        <span class=\"keyword\">function<\/span> p = getPace(this) <span class=\"comment\">%#ok&lt;MANU&gt;<\/span>\r\n            p = 5;\r\n        <span class=\"keyword\">end<\/span>\r\n\r\n        <span class=\"keyword\">function<\/span> initialize(this, ~)\r\n            <span class=\"comment\">% Some code to initialiaze the visualization<\/span>\r\n        <span class=\"keyword\">end<\/span>\r\n\r\n\r\n        <span class=\"keyword\">function<\/span> entityAdvance(this, entity, ~, to)\r\n            enStruct = sedb.eninfo(entity);\r\n            currRow = enStruct.Attributes.CurrentSeatLoc;\r\n            destRow = enStruct.Attributes.Row;\r\n            <span class=\"comment\">% Some code to update the visualization when entity advance<\/span>\r\n        <span class=\"keyword\">end<\/span>\r\n\r\n        <span class=\"keyword\">function<\/span> entityDestroy(this, entity, ~)\r\n            <span class=\"comment\">% Code to update the isualization when the entity is destroyed<\/span>\r\n        <span class=\"keyword\">end<\/span>\r\n\r\n    <span class=\"keyword\">end<\/span>\r\n<span class=\"keyword\">end<\/span> <span class=\"comment\">% classdef<\/span>\r\n<\/pre>\n<p>Here is what the animation looks like for the case where boarding begins at the back of the plane:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2015Q2\/boarding.gif\" alt=\"Boarding animation\" \/><\/p>\n<p><strong>Results<\/strong><\/p>\n<p>I plotted the results for each scheme, along with the ideal case. I define ideal as a perfectly behaved group that boards exactly in the order prescribed by that scheme with no randomness.<\/p>\n<p>The results do validate that the current process used by airlines can only get worse if they decide to board front to back! I was surprised that some schemes work better than the truly random scheme &#8212; but perhaps I should have expected that given the article I started with. It looks like even with the randomness thrown into the deterministic model presented above &#8212; represented by the scheme labeled &#8216;windowToAisleAlternateZone&#8217;, it performed the best. Maybe when I am in the airport next time things would have changed for the better?<\/p>\n<p>Here are the results for the six schemes described above, normalized by the back to front scheme, which is the standard used by most companies.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2015Q2\/boardingResults.png\" alt=\"Boarding animation\" \/><\/p>\n<p><strong>Now it&#8217;s your turn<\/strong><\/p>\n<p>Download Mani&#8217;s project <a href=\"https:\/\/blogs.mathworks.com\/images\/seth\/2015Q2\/airseat.zip\">here<\/a> and try coming up with a better boarding scheme.<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/simulink\/files\/feature_image\/EntityGeneration1.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div>\n<p>Today I am happy to welcome my colleague Ramamurthy Mani for another very interesting study using SimEvents.<br \/>\nIntroduction<br \/>\nRecently, I read an article in Wired (TM) magazine that posed a question that&#8230; <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/simulink\/2015\/05\/20\/what-is-the-most-efficient-aircraft-seating-strategy\/\">read more >><\/a><\/p>\n","protected":false},"author":41,"featured_media":5017,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[121,65,16],"tags":[427,416],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/4580"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/comments?post=4580"}],"version-history":[{"count":11,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/4580\/revisions"}],"predecessor-version":[{"id":6137,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/4580\/revisions\/6137"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/media\/5017"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/media?parent=4580"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/categories?post=4580"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/tags?post=4580"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}