Created
January 5, 2020 21:55
-
-
Save gauravsdeshmukh/009b77f4b34289f98409d87775c8b124 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Airplane Boarding Sim\n", | |
"\n", | |
"### Gaurav Deshmukh" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Import module" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import scipy as sci" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Initialization" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"#Initialize\n", | |
"#Define number of rows and columns\n", | |
"n_rows=23\n", | |
"n_cols=6\n", | |
"\n", | |
"#Calculate number of passengers\n", | |
"n_pass=n_rows*n_cols\n", | |
"\n", | |
"#Create seat matrix\n", | |
"seats=sci.zeros((n_rows,n_cols))\n", | |
"seats[:,:]=-1\n", | |
"\n", | |
"#Create aisle array\n", | |
"aisle_q=sci.zeros(n_rows)\n", | |
"aisle_q[:]=-1\n", | |
"\n", | |
"#Create initial passenger number queue\n", | |
"pass_q=[int(i) for i in range(n_pass)]\n", | |
"pass_q=sci.array(pass_q)\n", | |
"\n", | |
"#Create array for seat nos\n", | |
"row_q_init=sci.zeros(n_pass)\n", | |
"col_q_init=sci.zeros(n_pass)\n", | |
"\n", | |
"#Let's create moveto arrays\n", | |
"moveto_loc=sci.zeros(n_pass)\n", | |
"moveto_time=sci.zeros(n_pass)\n", | |
"\n", | |
"moveto_loc_dict={i:j for i in pass_q for j in moveto_loc}\n", | |
"moveto_time_dict={i:j for i in pass_q for j in moveto_time}" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Assign Seats" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"#Create function to assign seat number to each passenger\n", | |
"def AssignSeats(rq,cq,assign_type,n_pass=n_pass,n_rows=n_rows):\n", | |
" if(assign_type==\"SINP\"):\n", | |
" #Initialize initial and final positions\n", | |
" i=0\n", | |
" f=n_rows\n", | |
" \n", | |
" #Define column seating positions \n", | |
" c=[0,5,1,4,2,3]\n", | |
" \n", | |
" #Define iteratiion counter\n", | |
" count=0\n", | |
" \n", | |
" #Assign queue\n", | |
" while(f<=n_pass):\n", | |
" rq[i:f]=list(reversed(range(0,n_rows)))\n", | |
" cq[i:f]=[c[count]]*n_rows\n", | |
" i+=n_rows\n", | |
" f+=n_rows\n", | |
" count+=1\n", | |
" \n", | |
" if(assign_type==\"Random\"):\n", | |
" #Initialize possible row positions\n", | |
" av_rows=sci.arange(0,n_rows,1)\n", | |
" #Make as many copies of these positions as the number of columns\n", | |
" av_rows=sci.tile(av_rows,(n_cols,1))\n", | |
" av_rows=av_rows.T.flatten()\n", | |
" \n", | |
" #Initialize possible column positions\n", | |
" av_cols=sci.arange(0,n_cols,1)\n", | |
" #Make as many copies of these positions as the number of rows\n", | |
" av_cols=sci.tile(av_cols,(n_rows,1)).flatten()\n", | |
" \n", | |
" #Create list of all possbile seat positions\n", | |
" av_seats=sci.zeros((n_pass,2))\n", | |
" for i in range(n_pass):\n", | |
" av_seats[i]=[av_rows[i],av_cols[i]]\n", | |
" \n", | |
" #Randomize seat positions\n", | |
" sci.random.shuffle(av_seats)\n", | |
" rq=av_seats[:,0]\n", | |
" cq=av_seats[:,1]\n", | |
" \n", | |
" if(assign_type==\"BTF\"):\n", | |
" av_rows=sci.arange(0,n_rows,1)\n", | |
" av_rows=sci.tile(av_rows,(n_cols,1))\n", | |
" av_rows=av_rows.T.flatten()\n", | |
" av_cols=sci.arange(0,n_cols,1)\n", | |
" av_cols=sci.tile(av_cols,(n_rows,1)).flatten()\n", | |
" av_seats=sci.zeros((n_pass,2))\n", | |
" for i in range(n_pass):\n", | |
" av_seats[i]=[av_rows[i],av_cols[i]]\n", | |
" \n", | |
" #Same as randomize except randomization is limited to specific groups\n", | |
" group1=av_seats[:48]\n", | |
" sci.random.shuffle(group1)\n", | |
" group2=av_seats[48:96]\n", | |
" sci.random.shuffle(group2)\n", | |
" group3=av_seats[96:]\n", | |
" sci.random.shuffle(group3)\n", | |
" av_seats_final=sci.concatenate((group3,group2,group1))\n", | |
" rq=av_seats_final[:,0]\n", | |
" cq=av_seats_final[:,1]\n", | |
" \n", | |
" if(assign_type==\"FTB\"):\n", | |
" av_rows=sci.arange(0,n_rows,1)\n", | |
" av_rows=sci.tile(av_rows,(n_cols,1))\n", | |
" av_rows=av_rows.T.flatten()\n", | |
" av_cols=sci.arange(0,n_cols,1)\n", | |
" av_cols=sci.tile(av_cols,(n_rows,1)).flatten()\n", | |
" av_seats=sci.zeros((n_pass,2))\n", | |
" for i in range(n_pass):\n", | |
" av_seats[i]=[av_rows[i],av_cols[i]]\n", | |
" group1=av_seats[:48]\n", | |
" sci.random.shuffle(group1)\n", | |
" group2=av_seats[48:96]\n", | |
" sci.random.shuffle(group2)\n", | |
" group3=av_seats[96:]\n", | |
" sci.random.shuffle(group3)\n", | |
" \n", | |
" #Same as BTF except order of groups is swapped\n", | |
" av_seats_final=sci.concatenate((group1,group2,group3))\n", | |
" rq=av_seats_final[:,0]\n", | |
" cq=av_seats_final[:,1]\n", | |
" \n", | |
" if(assign_type==\"WMA\"):\n", | |
" window_1=sci.array([0]*n_rows)\n", | |
" rows_1=sci.arange(0,n_rows,1)\n", | |
" window_2=sci.array([5]*n_rows)\n", | |
" rows_2=sci.arange(0,n_rows,1)\n", | |
" window=sci.concatenate((window_1,window_2))\n", | |
" rows=sci.concatenate((rows_1,rows_2))\n", | |
" av_seats_w=sci.column_stack((rows,window))\n", | |
" sci.random.shuffle(av_seats_w)\n", | |
" \n", | |
" middle_1=sci.array([1]*n_rows)\n", | |
" middle_2=sci.array([4]*n_rows)\n", | |
" middle=sci.concatenate((middle_1,middle_2))\n", | |
" av_seats_m=sci.column_stack((rows,middle))\n", | |
" sci.random.shuffle(av_seats_m)\n", | |
" \n", | |
" aisle_1=sci.array([2]*n_rows)\n", | |
" aisle_2=sci.array([3]*n_rows)\n", | |
" aisle=sci.concatenate((aisle_1,aisle_2))\n", | |
" av_seats_a=sci.column_stack((rows,aisle))\n", | |
" sci.random.shuffle(av_seats_a)\n", | |
" \n", | |
" av_seats=sci.concatenate((av_seats_w,av_seats_m,av_seats_a))\n", | |
" rq=av_seats[:,0]\n", | |
" cq=av_seats[:,1]\n", | |
" \n", | |
" if(assign_type==\"Southwest\"):\n", | |
" #Make an array [0,5,0,5,...]\n", | |
" window=sci.array([0,5]*n_rows)\n", | |
" \n", | |
" #Make an array [0,0,1,1,2,2,...]\n", | |
" rows_1=sci.arange(0,n_rows,1)\n", | |
" rows_2=sci.arange(0,n_rows,1)\n", | |
" rows=sci.ravel(sci.column_stack((rows_1,rows_2)))\n", | |
" \n", | |
" w_seats=sci.column_stack((rows,window))\n", | |
" w_group1=w_seats[:32,:]\n", | |
" w_group2=w_seats[32:,:]\n", | |
" \n", | |
" aisle=sci.array([2,3]*n_rows)\n", | |
" a_seats=sci.column_stack((rows,aisle))\n", | |
" a_group1=a_seats[:32,:]\n", | |
" a_group2=a_seats[32:,:]\n", | |
" \n", | |
" mega_group1=sci.concatenate((w_group1,a_group1))\n", | |
" sci.random.shuffle(mega_group1)\n", | |
" mega_group2=sci.concatenate((w_group2,a_group2))\n", | |
" sci.random.shuffle(mega_group2)\n", | |
" \n", | |
" w_and_a=sci.concatenate((mega_group1,mega_group2))\n", | |
" \n", | |
" middle=sci.array([1,4]*n_rows)\n", | |
" m_seats=sci.column_stack((rows,middle))\n", | |
" m_group1=m_seats[:32,:]\n", | |
" sci.random.shuffle(m_group1)\n", | |
" m_group2=m_seats[32:,:]\n", | |
" sci.random.shuffle(m_group2)\n", | |
" \n", | |
" av_seats=sci.concatenate((w_and_a,m_group1,m_group2))\n", | |
" rq=av_seats[:,0]\n", | |
" cq=av_seats[:,1]\n", | |
" \n", | |
" return rq,cq" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Define movement from passenger queue to aisle" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"#Create function to move passengers into aircraft\n", | |
"def MoveToAisle(t,aisle_q,pass_q,sum_time):\n", | |
" if(t>sum_time[0]):\n", | |
" if(aisle_q[0]==-1):\n", | |
" aisle_q[0]=pass_q[0].copy()\n", | |
" pass_q=sci.delete(pass_q,0)\n", | |
" sum_time=sci.delete(sum_time,0)\n", | |
" return aisle_q,pass_q,sum_time" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Define times, movement rules and dictionaries" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"#Assign seating order\n", | |
"row_q,col_q=AssignSeats(row_q_init,col_q_init,\"Southwest\")\n", | |
"\n", | |
"#Create array for times\n", | |
"mean_time=1.\n", | |
"stddev_time=0.2\n", | |
"time_q=sci.random.normal(loc=mean_time,scale=stddev_time,size=n_pass)\n", | |
"\n", | |
"#Define multipliers (+2 for stowing luggage)\n", | |
"empty_mult=1+2\n", | |
"aisle_mult=4+2\n", | |
"middle_mult=5+2\n", | |
"aisle_middle_mult=7+2\n", | |
"\n", | |
"#Create seat and speed dictionary\n", | |
"pass_dict={}\n", | |
"time_dict={}\n", | |
"\n", | |
"seat_nos=sci.column_stack((row_q,col_q))\n", | |
"for i in range(n_pass):\n", | |
" pass_dict[i]=seat_nos[i]\n", | |
"\n", | |
"for i in range(n_pass):\n", | |
" time_dict[i]=time_q[i]\n", | |
"\n", | |
"#Create sum time array\n", | |
"sum_time=sci.zeros(n_pass)\n", | |
"for i in range(n_pass):\n", | |
" sum_time[i]=sum(time_q[:i+1])" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Let the passengers board into the airplane" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"#Let's define the boarding process in a while loop\n", | |
"#Define initial conditions\n", | |
"\n", | |
"time=0\n", | |
"time_step=0.1\n", | |
"exit_sum=sci.sum(pass_q)\n", | |
"pass_sum=sci.sum(seats)\n", | |
"\n", | |
"while(pass_sum!=exit_sum):\n", | |
" #Try to move passenger inside the plane if passengers are left\n", | |
" if(pass_q.size!=0):\n", | |
" aisle_q,pass_q,sum_time=MoveToAisle(time,aisle_q,pass_q,sum_time)\n", | |
" #Scan the aisle first for non-negative units (passengers)\n", | |
" for passg in aisle_q:\n", | |
" if(passg!=-1):\n", | |
" #Store the row of passenger in aisle\n", | |
" row=int(sci.where(aisle_q==passg)[0][0])\n", | |
" #See if move has been assigned to passenger\n", | |
" if(moveto_time_dict[passg]!=0):\n", | |
" #If move has been assigned check if it is time to move\n", | |
" if(time>moveto_time_dict[passg]):\n", | |
" #If it is time to move follow the procedure below\n", | |
" #Check if move is forward in aisle or to seat\n", | |
" if(moveto_loc_dict[passg]==\"a\"):\n", | |
" #If move is in the aisle, check if position ahead is empty\n", | |
" if(aisle_q[row+1]==-1):\n", | |
" #If position is empty move passenger ahead and free the position behind\n", | |
" aisle_q[row+1]=passg\n", | |
" aisle_q[row]=-1\n", | |
" #Set moves to 0 again\n", | |
" moveto_loc_dict[passg]=0\n", | |
" moveto_time_dict[passg]=0\n", | |
" elif(moveto_loc_dict[passg]==\"s\"):\n", | |
" #If move is to the seat,\n", | |
" #Find seat row and column of passenger\n", | |
" passg_row=int(pass_dict[passg][0])\n", | |
" passg_col=int(pass_dict[passg][1])\n", | |
" #Set seat matrix position to the passenger number\n", | |
" seats[passg_row,passg_col]=passg\n", | |
" #Free the aisle\n", | |
" aisle_q[row]=-1\n", | |
" elif(moveto_time_dict[passg]==0):\n", | |
" #If move hasn't been assgined to passenger\n", | |
" #Check passenger seat location\n", | |
" passg_row=int(pass_dict[passg][0])\n", | |
" passg_col=int(pass_dict[passg][1])\n", | |
" if(passg_row==row):\n", | |
" #If passenger at the row where his/her seat is,\n", | |
" #Designate move type as seat\n", | |
" moveto_loc_dict[passg]=\"s\"\n", | |
" #Check what type of seat: aisle, middle or window\n", | |
" #Depending upon seat type, designate when it is time to move\n", | |
" if(passg_col==0):\n", | |
" if(seats[passg_row,1]!=-1 and seats[passg_row,2]!=-1):\n", | |
" moveto_time_dict[passg]=time+aisle_middle_mult*time_dict[passg]\n", | |
" elif(seats[passg_row,1]!=-1):\n", | |
" moveto_time_dict[passg]=time+middle_mult*time_dict[passg] \n", | |
" elif(seats[passg_row,2]!=-1):\n", | |
" moveto_time_dict[passg]=time+aisle_mult*time_dict[passg]\n", | |
" else:\n", | |
" moveto_time_dict[passg]=time+empty_mult*time_dict[passg]\n", | |
" elif(passg_col==5):\n", | |
" if(seats[passg_row,4]!=-1 and seats[passg_row,3]!=-1):\n", | |
" moveto_time_dict[passg]=time+aisle_middle_mult*time_dict[passg]\n", | |
" elif(seats[passg_row,4]!=-1):\n", | |
" moveto_time_dict[passg]=time+middle_mult*time_dict[passg] \n", | |
" elif(seats[passg_row,3]!=-1):\n", | |
" moveto_time_dict[passg]=time+aisle_mult*time_dict[passg]\n", | |
" else:\n", | |
" moveto_time_dict[passg]=time+empty_mult*time_dict[passg]\n", | |
" elif(passg_col==1):\n", | |
" if(seats[passg_row,2]!=-1):\n", | |
" moveto_time_dict[passg]=time+aisle_mult*time_dict[passg] \n", | |
" else:\n", | |
" moveto_time_dict[passg]=time+empty_mult*time_dict[passg]\n", | |
" elif(passg_col==4):\n", | |
" if(seats[passg_row,3]!=-1):\n", | |
" moveto_time_dict[passg]=time+aisle_mult*time_dict[passg]\n", | |
" else:\n", | |
" moveto_time_dict[passg]=time+empty_mult*time_dict[passg]\n", | |
" elif(passg_col==2 or passg_col==3):\n", | |
" moveto_time_dict[passg]=time+empty_mult*time_dict[passg]\n", | |
" elif(passg_row!=row):\n", | |
" #If passenger is not at the row where his/her seat is,\n", | |
" #Designate movement type as aisle\n", | |
" moveto_loc_dict[passg]=\"a\"\n", | |
" #Designate time to move\n", | |
" moveto_time_dict[passg]=time+time_dict[passg]\n", | |
"\n", | |
" #Iteration timekeeping\n", | |
" time+=time_step\n", | |
" pass_sum=sci.sum(seats)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Print the final time" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"The time required to board is 349.20\n" | |
] | |
} | |
], | |
"source": [ | |
"print(\"The time required to board is {0:.2f}\".format(time))" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.7.4" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment