SlideShare a Scribd company logo
1 of 44
Download to read offline
Taxicab Modeling
Carl Bucella, Kelsey Harrington, Corey Marsh
Novemeber 17th, 2013
Abstract
To address the need for improved taxi services in the Town of Mythical, we have
developed a model that uses a minimum-weight pairing algorithm and discrete event
simulation. The minimum-weight pairing algorithm matches available cabs with in-
coming customer orders so as to minimize customer wait times. The discrete event
simulation generates Poisson distributed orders and probabilistically deļ¬ned starting
and ending locations dependent on the time of day. After running multiple simulation,
we were able to determine an estimated upper and lower bound for the number of cabs
needed to ensure that the average customer wait time was under 15 minutes and that
less than 10% of customers had to wait more than 25 minutes. Our upper bound esti-
mate is based on the assumption that the distance between two points was calculated
using right-angle distance, i.e. d = |x2 āˆ’ x1| + |y2 āˆ’ y1|. Our lower bound estimate
uses the Euclidean distance between two points, i.e. it assumes there is a straight line
path between point a and point b. A visual validation of the results is performed by
graphing the average customer wait time and the percentage of customers who wait
longer than 25 minutes as a function of the number of cabs in operation. We develop
our model further by implementing both ļ¬xed and variable pricing functions. In order
to maintain the current levels of revenues for local taxi companies as determined by
the ļ¬xed pricing structure, a variable cost of $X per mile is suggested. Finally, we
consider the eļ¬€ect of an increase or decrease in the market share of unlicensed cab
companies. Our results determine that stricter regulations against unlicensed compa-
nies would decrease the average wait time for taxi customers in Mythical, so we are in
favor of greatly strengthening the regulations against unlicensed cab companies.
1
Contents
1 Problem Statement 3
2 Problem Analysis and Possible Models 3
2.1 Deļ¬nition of Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 Modeling Orders Arrivals . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2.1 Uniform Distribution . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2.2 Poisson Distribution . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3 Modeling Call Pick-Up and Drop-Oļ¬€ Locations . . . . . . . . . . . . 6
2.4 Modeling Travel Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.5 Modeling Cab Responses to Calls . . . . . . . . . . . . . . . . . . . . . 8
2.5.1 Minimal Weight Matching . . . . . . . . . . . . . . . . . . . . . . 8
2.5.2 Minimal Weight Spanning Tree with Priority . . . . . . . . . 8
2.6 Modeling Pricing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.6.1 Prelimary Zone Pricing Analysis . . . . . . . . . . . . . . . . . . 10
2.6.2 Zone Pricing Simulation . . . . . . . . . . . . . . . . . . . . . . . 10
2.7 Modeling Market Share Diļ¬€erences . . . . . . . . . . . . . . . . . . . . 10
3 Results 11
3.1 Required Number of Taxicabs . . . . . . . . . . . . . . . . . . . . . . . 11
3.2 Pricing Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.2.1 Simulated Pricing Analysis . . . . . . . . . . . . . . . . . . . . . . . . 13
3.3 Market Share Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4 Strengths and Weaknesses of the Proposed Model 16
5 Robustness - Sensitivity of Ī»āˆ—
16
6 Further Extensions and Considerations 18
7 Appendix 19
7.1 MATLAB code for Parts 1 and 2 . . . . . . . . . . . . . . . . . . . . . . 19
7.2 MATLAB code for Part 4 . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2
1 Problem Statement
Mythical city and county oļ¬ƒcials are interested in improving the quality and price of services
oļ¬€ered by local taxi companies. In order to do so, they have asked us to determine:
1. The total number of cabs needed to serve the ā€Greater Mythicalā€ area such that the
average customer is waiting for no more than 15 minutes and less than 10% of customers
are waiting for more than 25 minutes.
2. The value X that would cause taxicab revenues to be roughly the same as they are
now if the city switches to meter-based pricing where you pay a $2.50 ļ¬‚at rate and X
cents per mile. Currently the city has determined taxi ride prices based on originating
and terminating zones.
3. The impact on the average wait times and prices of non-regulated rides if the con-
glomerate, Mythical Dispatch, Inc. were to be splitup into 3 companies that operated
independently from each other. Mythical Dispatch, Inc. currently owns 2/3 of all cabs
oļ¬ƒcially licensed in the city.
4. The consequences of strengthening regulations against unlicensed companies, who cur-
rently contol about 1/7 of all cabs in the city.
Disclaimer: Upon reading the problem statement, we immediately noticed a similarity be-
tween the Town of Mythical and the Town of Ithaca. We base our assumptions and calcu-
lations heavily on the Town of Ithaca. However, we must stress that these similarities are
only a coincidence, and that our model was speciļ¬cally designed for the ļ¬ctional Town of
Mythical. Therefore, whenever we refer to information about the Town of Ithaca, we are
only doing so because it provides accurate background information for our model.
2 Problem Analysis and Possible Models
Our models focus on providing answers to the ļ¬rst, second, and fourth parts of the problem.
2.1 Deļ¬nition of Parameters
In order to solve this problem, we made some simplifying assumptions:
1. The Town of Mythical has speciļ¬c regions and points of interest. Based
on the problem statement, we know that the town of Mythical has a large college
(Mornell University), a small liberal arts college (Mythical College), an airport, a
mall, a downtown area, etc. In order to make our problem simpler, we based these
regions and points of interest oļ¬€ of the corresponding regions for the Town of Ithaca.
3
2. The taxis travel at a constant velocity of 25 miles per hour. We estimated the
average miles per hour for roads in the Town of Ithaca to be around 40. Within the
City, the speed limit is 35 miles per hour, but in the surrounding areas the speed limit
can become as high as 65 miles per hour. The roads with higher speed limits are less
common, so we estimated the average speed limit to be closer to 40 miles per hour. In
order to account for traļ¬ƒc, traļ¬ƒc lights, stop signs, etc. we decided to set the average
speed to 25 miles per hour.
3. The Greater Mythical Area is approximately a 6.6832 by 5.1602 mile rect-
angle. We assumed that the Town of Ithaca is similar in size to the Town of Mythical.
Using a map image for the Town of Ithaca, [1], as well as the scale image for the map,
we processed the two images in MATLAB to determine the size of Ithaca and in turn,
Mythical.
4. The expected number of orders is a function of time. The idea that customer
orders are time dependent is based on empirical evidence gathered as a result of research
into the taxicab system in Boston, [2]. Although we were unable to ļ¬nd speciļ¬c data
on the expected number of orders at each point in time, we were able to estimate these
values using our own personal experience. For example, it is likely that a taxi company
receives far less customer orders between 2 AM and 6 AM than it does between 8 PM
and 11 PM. Later, we discuss using a Poisson distribution to determine the number of
orders per minute. We designed our values of Ī»(t) to reļ¬‚ect our prior knowledge and
experience.
5. There are speciļ¬c probabilities for the starting and ending region of a trip
based on the time of day. We know that based on the time of day, people are
more likely to travel from certain places to others. We also know that the probability
of ending in one region is likely conditional on the region the trip started in. The
numbers we came up for these probabilities are based on various factors:
ā€¢ There are no ļ¬‚ights in and out of the airport between 2AM and 5 AM, so the
probability of getting a order from or to the airport during these hours is 0, [3].
ā€¢ The mall is closed from 10 PM to 8 AM, so the probability of getting an order to
or from the mall during these hours is 0, [4].
ā€¢ People travel to and from downtown more frequently between the hours of 11 PM
to 2 AM, so the probability of receiving calls from and to these areas is greater
during that time period.
ā€¢ If you are starting your order from a random location in the Town of Mythical,
then you are likely traveling to one of the main regions (Airport, Mall, Mornell,
etc.), so the probability of going to these areas is higher.
4
ā€¢ If you are starting your order from one of these main regions (Airport, Mall,
Mornell, etc.), it is likely that you do not have a car and are therefore a student,
so you have a higher probability of traveling to Mornell or Mythical College.
A lot of thought went into determining these probabilities. We combined the in-
formation about taxi cab transportation in Boston, [2], with our own knowlege and
experience, to determine the values of these probabilites.
2.2 Modeling Orders Arrivals
2.2.1 Uniform Distribution
In our original model, we modeled order arrival times as uniform distribution over a 24-hour
day. For each iteration of our algorithm, which corresponds to a one-minute interval in real
time, we generated a random number uniformly distributed between 0 and 1. We checked if
that random number was less than a certain value c, where c āˆˆ [0, 1], to determine whether a
customer placed an order in that time interval. The value of c corresponded to the expected
number of orders, which we set to 0.3 and 1.0 in trial runs but later determined would likely
be somewhere between these values, approximately 0.8.
Although the choice of uniformly distributed order arrivals helped to simplify the imple-
mentation of our model, the assumption fails to account for changes in customer demand
dependent on the time of day. Furthermore, the uniform assumption restricted the number
of possible orders that could be placed in a minute to zero and one. In a town with a strong
college presence such as Mythical, it is very likely that multiple orders will be placed in a
given minute during peak hours, especially when there is an event, such as a concert. It is
assumed that many college students do not have cars and it is estimated that they make up
a large portion of taxicab customers in Mythical.
2.2.2 Poisson Distribution
Based on our research, we settled on a Poisson distribution for modeling the order arrivals.
Arrival times are often modeled using the Poisson distribution in other applications, and
because our algorithm is a discrete-event simulation with a variable Ī» parameter, this distri-
bution works well. The distribution function for a Poisson random variable is given below:
f(k; Ī») = P(X = k) =
Ī»(t)k
eāˆ’Ī»(t)
k!
(1)
This choice also allows us to vary Ī», corresponding to the expected number of orders, as
a function of time. As we discussed above, the expected number of orders per minute is
dependent upon the time of day. Our model implements a piece-wise function for Ī», given
below. The function shows that the taxicab companys peak hours are between 8 PM and
5
midnight, and that the lowest frequency of orders can be expected to occur between 2 AM
and 6 AM. Our choices for these values are our best estimates based on observations of
taxicab use in a town very similar to Mythical. Our Ī» values are based on the value of Ī»āˆ—
,
which is the expected number of calls per minute between 6 AM - 4 PM (midday). We used
Ī»āˆ—
to calculate the other values of Ī», as can be seen below, and varied Ī»āˆ—
to see how this
would change our output.
E(X) = Ī»(t) =
ļ£±
ļ£“ļ£“ļ£“ļ£“ļ£²
ļ£“ļ£“ļ£“ļ£“ļ£³
1.2Ī»āˆ—
if t is between 12AM-2AM
0.2Ī»āˆ—
if t is between 2AM-6AM
1.0Ī»āˆ—
if t is between 6AM-4PM
1.2Ī»āˆ—
if t is between 4PM-8PM
1.6Ī»āˆ—
if t is between 8PM-12AM
2.3 Modeling Call Pick-Up and Drop-Oļ¬€ Locations
We originially selected random x and y values that were in the ā€Greater Mythical Regionā€.
Later we decided to select the trip starting and ending locations based on time of day and
points of interest, as is alluded to in our deļ¬nition of parameters. Most of the orders will
originate or end in the ā€City of Mythicalā€ and/or a point of interest (Airport, Mall, Mornell,
etc.). Outside of the city is assumed to be predominantly agricultural with fewer roads and
the people living there are assumed to own cars therefore, fewer orders would originate from
or go to these regions. We assigned diļ¬€erent probabilities, that varied with time of day, that
an order is placed from a region and that an order will end in another region (conditional
on the region the order was placed in). The main regions that we consider are:
1. The Mythical-Dompkins Airport - considered as Zone 7
2. Mythical Mall - considered as Zone 8
3. Mornell University - Zones 5 and 6
4. Mythical College - considered as Zone 9
5. Downtown Mythical - Zones 3 and 4
6. The parts of the City of Mythical that have not previously been considered - Zones 1
and 2
7. The parts of the Town of Mythical that have not previously been considered - consid-
ered as Zone 10
Zones 1 through 6 correspond to the pricing zones, [5], and are used in the pricing section.
Once the starting and ending regions were determined, the starting and ending points were
randomly selected from within the rectangular approximations to each zone displayed on the
following page.
6
Figure 1: Map of ā€Greater Mythical Areaā€ with Zones
2.4 Modeling Travel Time
In our model, we have two diļ¬€erent options for calculating the travel time between two points.
Our initial simpliļ¬cation was to simply use the Euclidean distance formula to calculate the
distance between two points. In order to ļ¬nd the time it takes to travel this distance, we
divide this distance by our assumed velocity.
d = (x1 āˆ’ x2)2 + (y1 āˆ’ y2)2 (2)
While this distance greatly simpliļ¬es our model, we realize that it is very unrealistic to
assume that you can get between any two points in a straight line considering that roads
rarely allow this. Using this formula for distance therefore, gives us a lower bound for our
simulation results.
In order to combat this issue, we use the following distance formula to ļ¬nd the upper
7
bound. Which is the sum of the total x distance and y distance traveled between two points.
d = |x2 āˆ’ x1| + |y2 āˆ’ y1| (3)
This formula represents the distance the trip would be if you could only travel at right angles
between the two points. We later refer to this as the right angle distance between the two
points.
While we did not have time to make a more detailed distance function based oļ¬€ of roads
and speed limits, the use of these two functions to ļ¬nd an upper and lower bound for the
travel time makes our model more robust than simply choosing one.
2.5 Modeling Cab Responses to Calls
2.5.1 Minimal Weight Matching
In order to ļ¬ll these orders, we need to ļ¬nd a matching between the list of available cabs
and the list of orders at each time step. If there are no available cabs or no new orders at
time t, we do not perform a matching and increment t. We repeat this process until we
have at least one available cab and new order. At this point, we call ļ¬llOrders to ļ¬nd the
matching between the orders and cabs. ļ¬llOrders uses an adaptation of Kruskals algorithm
to ļ¬nd the minimal distance pairing between the two sets. In order to do so, ļ¬llOrders stores
the wait time from every cab A to every order B. This list is then sorted by the distances
so that the smallest distance is at the top of the list. Then, ļ¬llOrders considers the edges
in increasing order; if the cab for the edge is available, and the order is still unļ¬lled, we
accept this edge. We repeat this process, and ignore any edges where the cab and order have
already been used/ļ¬lled. Once we have ļ¬lled all the orders, or used all possible cabs, the
process is ļ¬nished.
Using the list of ļ¬lled orders, we update the list of cabs with their ļ¬nal locations, as well
as the time for which they will be unavailable. In order to calculate the unavailable time,
we add the wait time to the time of the trip. We have already modeled the start and end
positions of each order, so this information is easily calculated from our list of orders. We
create a vector that contains the wait times for each ļ¬lled order during the current time step.
At the end of ļ¬llOrders, we return this vector and concatenate it with the vector containing
data for the previous wait times. At the end of the simulation, we are left with a vector of
wait times for each order placed, which we analyze to determine the result of the simulation.
2.5.2 Minimal Weight Spanning Tree with Priority
One issue with the method above is that the orders are ļ¬lled only based on the distance
between them and the nearest available cabs. This could cause orders far away from all
available cabs to remain unļ¬lled for long periods of time, and we did not feel that this
8
coincides with how a cab company would typically operate. In order to ļ¬x this problem, we
treat the list of orders as a queue. A queue operates by the ļ¬rst-in-ļ¬rst-out (FIFO) property,
so the oldest orders placed are considered ļ¬rst before any new orders. If there are two orders
that were placed at the same time, we always consider them together, to prevent favoring
the order that was stored in the list ļ¬rst. The orders are then processed in the same way as
before, but only the oldest orders are considered by the matching algorithm.
2.6 Modeling Pricing
We based our model pricing oļ¬€ of the following map of each zone and the corresponding
zone-to-zone prices listed in the matrix below, [5].
Figure 2: Map of Zones
Figure 3: Zone Pricing
9
1 2 3 4 5 6
1 - 1.83 1.89 1.73 3.1 2.6
2 1.83 - 1.88 1.19 2.75 2.24
3 1.89 1.88 - 0.87 1.62 1.67
4 1.73 1.19 0.87 - 1.71 1.21
5 3.1 2.75 1.62 1.71 - 1.2
6 2.6 2.24 1.67 1.21 1.2 -
Table 1: Distance between Zone Centers (mi)
2.6.1 Prelimary Zone Pricing Analysis
To start our zone pricing analysis we calculated the distance from the center of each zone
to the center of each other zone, using MapQuest, [6]. Our results are listed in the table
above. We then subtracted $2.50, the base price for a cab ride, from the zone prices depicted
in Figure 3 and divided the remaining price by the distance between the zone centers. We
then averaged these prices to get the average price per mile that would need to be charged
for the metered pricing to be roughly equilivalent to the ļ¬xed zone pricing.
2.6.2 Zone Pricing Simulation
The problem asked us to leave the revenues of cab companies, rather than prices per trip,
relatively the same as they are now. Therefore, in order to more accurately compare the
diļ¬€erence in revenue between a ļ¬xed price plan and a variable price plan (for orders placed
within the city), we calculate and store the two prices for each trip. From the order infor-
mation, we know the two zones that the order is traveling between, as well as the x and y
coordinates of the start and end points. Using the zones along with the zone pricing map,
[5], we calculate the ļ¬xed price of the order. Similarly, we use the x and y coordinates to
calculate the variable price for the trip. Both of these values are returned by ļ¬llOrders for
the orders ļ¬lled in the current time step. Like wait time, we concatenate this new vector
with the vector holding the previous prices of orders. At the end of the simulation, we are
left with a 2 by p matrix, where P(1,i) is the ļ¬xed price for order i, and P(2,i) is the variable
price for the same order.
2.7 Modeling Market Share Diļ¬€erences
In order to solve part 4 of the problem statement, we needed to set up a simulation in
which there are two distinct cab companies operating within the City of Mythical. The ļ¬rst
company is considered to be Mythical Dispatch, the conglomerate of 3 companies, while
10
Company 2 is assumed to be the group of non-regulated taxicab companies. Because of the
way our code was written, it was simple to complete this by performing the following steps:
ā€¢ First, we deļ¬ned the total number of cabs in mythical (n) and the market share of
company 2 (m).
ā€¢ Second, we created separate data structures for Company 2 to hold the data for their
cabs, orders, available cabs, wait times, and prices.
Then, we modiļ¬ed orders so that if a person is traveling within the City of Mythical, they
have probability m of calling Company 2. This assumption follows directly from the deļ¬nition
of market share. Using a uniform distribution, we determine which company should get a
speciļ¬c order, and then return two lists of orders, one for each company. We then call
ļ¬llOrders for each company, using the appropriate data structures for each. At the end of
the simulation, we are left with a list of wait times and prices for each company, which we
then analyze to determine our results.
3 Results
3.1 Required Number of Taxicabs
After using our model to simulate a 24-hour day over 25 trials, we were able to determine
the total number of cabs needed to serve the ā€Greater Mythicalā€ area. The graphs on the
following page show the average wait time and percent of people who wait longer than 25
minutes as a function of the number of cabs operating.
The ļ¬gures show that the average wait time decreases as the number of taxis increases,
which is to be expected. The rate of decrease appears to be consistent with logistic decay
since the average wait time decreases less as the number of taxis increases. Therefore,
deploying more cabs than is necessary to meet the cityā€™s goals does not result in an equivalent
increase in productivity. We ran our simulation using both the Euclidean distance, which
serves as a lower bound for the number of cabs necessary, and using the right angle distance,
which serves as an upper bound for the number of cabs. Our lower and upper bound estimates
for the number of cabs necessary to meet the citys goals are 11 and 14 cabs respectively.
11
Figure 4: Average Wait Time and % of Wait Times Over 25 min for Euclidean Distance
Figure 5: Average Wait Time and % of Wait Times Over 25 min for Right Angle Distance
12
1 2 3 4 5 6
1 - 1.42 1.38 1.50 1.00 1.19
2 1.42 - 1.38 2.18 1.13 1.38
3 1.38 1.38 - 2.99 1.60 1.56
4 1.50 2.18 0.87 - 1.52 2.15
5 1.00 1.13 1.62 1.52 - 2.17
6 1.19 1.38 1.67 2.15 2.17 -
Table 2: Distance between Zone Centers (mi)
3.2 Pricing Analysis
The results of our preliminary pricing analysis are shown above. We found that the average
price per mile from one zone center to another should be approximately $1.64 (average of
the values depicted). This is the price per mile needed to keep the trip from one zone center
to another roughly equal to what it is currently.
3.2.1 Simulated Pricing Analysis
The results of our simulated pricing analysis using 15 cabs and Ī»āˆ—
= 0.8 are depicted on the
following page. We varied price per mile from $0.50 to $3.00 by $0.10. We ran the simulation
for only 5 days for each price per mile and calculated the daily revenue diļ¬€erence for each
of these days. This was believed to be suļ¬ƒcient since there are several orders per day and
that averaging the daily revenue diļ¬€erence over more days would produce a similar result.
Then we averaged these revenue diļ¬€erences to get the average daily price diļ¬€erence for each
price per mile. We found that the price of $2.00 per mile minimized the diļ¬€erence between
the average daily revenue when it is assumed you can only travel in right angles. We found
that the price of $2.50 per mile minimized the diļ¬€erence between the average daily revenue
when it is assumed you can travel straight to your ļ¬nal destination, calculated using the
Euclidean distance formula. This makes sense because using the right angle distance causes
trips to be longer than when you travel straight there causing the price per mile of the right
angle distance to be less if we are trying to keep the overall revenue the same. These values
are slightly larger than the ones found by our prelimary analysis but still relatively close
and we believe that these are more accurate since they take more parameters into account.
Therefore, we conclude that the average price per mile should be $2.25 if we want to switch
to metered pricing but leave the revenues of taxicab companies roughly the same as they are
currently. The advantage to switching to meters is that a cab company could make more
money if they are traveling further into a zone than before however, a disadvantage is that
13
they could make less money if they are just barely entering a new zone. The cab driverā€™s
hapiness likely depends on whether they are making more or less money and the city and
county oļ¬ƒcials likely want to keep the cab drivers happy.
Figure 6: Right Angle Distance
Figure 7: Euclidean Distance
14
3.3 Market Share Results
In order to see the eļ¬€ect of market share on wait time, we set the value of n to 20 and Ī»āˆ—
to
1.2. We increased the number of cabs and the average number of orders per minute so, it is
easier to represent a smaller percentage of the market share by Company 2. Then, we ran
MythicalCabs2 for multiple trials for each value of m (market share). This resulted in the
following graphs:
Figure 8: Average Wait Time for Variable Market Shares
Figure 9: % of Wait Times over 25 min for Variable Market Shares
15
As you can see, adding a second cab company with a market share of 1/7 drastically
increases the average wait time of all customers. From these results, we can easily make a
conclusion about the eļ¬€ect of reducing the market share of Company 2. If you reduce the
market share of Company 2, the average wait times for everyone will decrease. Therefore,
we are in favor of stricter regulations on the unlicensed cab companies operating within the
city.
4 Strengths and Weaknesses of the Proposed Model
The main strength of our model is its adaptability. This is partly due to the nature of our
model, and partly due to the way we broke down our code into functions. For example,
writing separate functions for generating orders and ļ¬lling orders made it very easy to add
a second cab company and monitor the eļ¬€ect of its market share. Not only was our code
compartmentalized well, but the parameters that determine the model are easily adjustable,
so it was very easy for us to run the simulation over many trials while varying certain
parameters. This allowed us to easily perform sensitivity tests on our data, which will be
discussed in the Sensitivity of Ī»āˆ—
section.
Our model has one main weakness, which is in how the travel time is calculated. While
we use the two diļ¬€erent distance formulas to provide an upper and lower bound for our
results, it is obvious that our model would be more accurate if we forced cabs to stay on a
predetermined set of roads, with designated speed limits for each road. In the city, where
the roads are more densely packed, this simpliļ¬cation does not aļ¬€ect our model too much.
However, in the town of Ithaca, where roads are more spread out, this simpliļ¬cation will
cause more inaccuracy. The distance traveled on these roads could vary from our distance
calculations, and our average velocity is probably lower than the actual average velocity
when traveling in the town. There is a way to remove this weakness, which will be discussed
in the Further Extensions and Considerations section.
5 Robustness - Sensitivity of Ī»āˆ—
While we used background data to determine our value for Ī»āˆ—
, we wanted to see how changing
the value of Ī»āˆ—
by a small amount aļ¬€ected the average wait time based on a ļ¬xed number
of cabs. In order to do so, we ran multiple trials where we varied Ī»āˆ—
from 0 to 2 while
keeping the number of cabs constant. Running this experiment helped us to validate our
results in the following way: we noticed that as Ī»āˆ—
increases, the average wait time grows
logistically, which we expect because after a certain point, the wait times are already so large
that increasing Ī»āˆ—
does not have much of an eļ¬€ect.
16
Figure 10: Average Wait Time for Variable Values of Ī»āˆ—
Figure 11: % of Wait Times over 25 min for Variable Values of Ī»āˆ—
We noticed from earlier experiments that for every Ī»āˆ—
, there is a value for n (number of
cabs) which is essentially a ā€tipping pointā€. This tipping point represents the number of
cabs for which the company is able to keep up with the orders it receives. For n less than
this tipping point, the cab company will not be able to keep up with the orders. As the
number of unļ¬lled orders increase, the wait times grow exponentially. By keeping n ļ¬xed and
running the simulation while varying Ī»āˆ—
, this could tell a company with n cabs the average
orders per minute that they would be capable of serving. While we did not intend to solve
17
this problem, it is an interesting result nonetheless.
6 Further Extensions and Considerations
As we discussed in our Strengths and Weaknesses section, our model has one main weakness:
the estimation of travel time and distance. There is a simple way to solve this, but it requires
a lot of time to gather the appropriate data and write the algorithm. This is how we would
approach this problem if we had time:
First, we would need to collect data for the intersections and roads of Mythical. We
would create a graph, with nodes representing the various intersections throughout Mythical
and edges representing the roads between the intersections. The weight of each edge would
be the time required to travel the edge, which is the distance of the edge divided by the
speed limit of the edge. After determining the starting and ending points of a route, we
would use Dijkstras algorithm to ļ¬nd the shortest weighted path from point A to point B,
and return the total time and distance of the path.
To take this method even further, we could also return the number of nodes on the path
and use it to estimate the time waited at lights. For example, we could assume that there
is some probability (p) that a node N has a traļ¬ƒc light. So, for each node passed, we could
check if there was a traļ¬ƒc light at that node using a uniform distribution. If there is a traļ¬ƒc
light, we could model the wait time at the light on a normal distribution, where wait times
less than or equal to zero mean the light is green when you pass it. If we added the wait
time from each node to the wait time of the trip, the accuracy of our travel time between
two points would increase dramatically.
18
7 Appendix
7.1 MATLAB code for Parts 1 and 2
%The following script runs the simulation for N trials on each value of n,
%and graphs the results
close all
N = 25;
upper_bound = true;
n_s = 5; %Starting number of cabs
n = 15; % iterate over n cabs per trials
x = []; % x-axis vector
avgwait = []; % average wait time
perover25 = []; % percentage wait times greater than 25min
sum_perover25 = zeros(1,n);
sum_avgwait = zeros(1,n);
X = 2; %Price per mile
for k = 1:N
perover25 = [];
x = [];
avgwait = [];
for i=n_s:n+n_s-1
x=[x i];
[wait,price] = MythicalCabs(i,X,upper_bound);
avgwait=[avgwait, mean(wait)];
over25=0;
for j=1:length(wait)
if wait(j)>25
over25=over25+1;
end
end
over25=100*over25/length(wait);
perover25=[perover25 over25];
end
sum_avgwait = sum_avgwait + avgwait;
avg_avgwait = sum_avgwait/N;
19
sum_perover25 = sum_perover25 + perover25;
avg_perover25 = sum_perover25/N;
end
figure
bar(x,avg_avgwait);
xlabel(ā€™Number of Taxisā€™);
ylabel(ā€™Average Wait Timeā€™);
figure
bar(x,avg_perover25);
hold on
line(ā€™XDataā€™, [0 n+5], ā€™YDataā€™, [10 10], ā€™LineStyleā€™, ā€™-ā€™, ...
ā€™LineWidthā€™, 2, ā€™Colorā€™,ā€™rā€™)
xlabel(ā€™Number of Taxisā€™);
ylabel(ā€™% of Wait Times Greater Than 25minā€™);
function [M,I] = PricingGraph()
% Displays a graph of the average daily revenue difference based on price
% per mile
close all
r_diff=[];
xax=[];
for X=0.5:0.1:4 % set price values = 0.5,0.6,...,4.0
xax=[xax,X];
r_diffd=[];
for d=1:5
[W,P]=MythicalCabs(15,X,true);
% daily revenue difference
r_diffd=[r_diffd, sum(P(1,:))-sum(P(2,:))];
end
% calculate average revenue difference over 5 days
r_diff=[r_diff, mean(r_diffd)];
end
[M,I]=min(r_diff);
20
bar(xax,r_diff);
title(ā€™Average Price Differenceā€™);
xlabel(ā€™Price ($/mi)ā€™);
ylabel(ā€™Average Price Differenceā€™);
end
function [W,P] = MythicalCabs(n,X,bound_flag)
%The following script simulates the movement of cabs around the city of
%Mythical in order to determine the wait times of customers.
%If bound_flag is false, use the straight line distance between points
%to find the lower bound for the number of cabs.
%If bound_flag is true, use the right angle distance between two points
%to find the upper bound for the number of cabs.
t_stop = 24*60; %The length of the simulation in minutes
%The following array holds the information about the position of the cabs,
%as well as the remaining time that they are unavailable
C = zeros(n,3);
W = []; %This vector contains the wait times for all filled orders
O = []; %The initially empty vector of orders
P = [;];
%Fill in the array C with random starting positions, and a current time
%unavailable of 1
for i = 1:n
C(i,1) = rand(1)*5.6832;
C(i,2) = rand(1)*5.1602;
C(i,3) = 1;
end
%Main simulation loop
for t = 1:t_stop
C(:,3) = C(:,3)-1; %Each cab has one less minute until available
%Generate the list of new orders (O) for this time step, return as a
%vector of with width 5 (x1,y1,x2,y2,t)
%Concatenate this vector with the vector of remaining orders
21
new_O = orders(t);
O = [O ; new_O];
%The following vector is the list of indeces for available cabs for
%the current time step. If i is in A, then C(i) is available
A = [];
j = 1;
for i = 1:n
if C(i,3) <= 0 %If the cab is available
A(j) = i; %Store the index in a temp array T
j = j + 1; %Increment j
end
end
%Get the updated C and O vectors after filling orders during this time
%step. Also get the wait times for filling the orders.
if ~isempty(A) && ~isempty(O)
[C,O,temp_W,temp_P] = fillOrders(t,A,C,O,X,bound_flag);
P = [P temp_P];
W = [W temp_W]; %Add the new wait times to the current list
end
end
end
function O = orders(t)
current_hr = t/60; % converts t into hours
factor = [1.2, .2, 1.6]; % determines percent increase or decrease of opm
lambda = .8;
% this block of code varies the orders per minute based on
% the time of day i.e. hour 0 is midnight, 1 is 1 AM, 2 is 2 AM
% etc... so hour 24 corresponds to midnight of next day
if current_hr <= 2
% set prob of starting location being cornell or IC to be
% a higher probability.
% set prob of ending location being somewhere on either of those
22
% campuses to be high prob...ie most trips should be a short
% distance (downtown,cornell; downtown, ic; cornell, cornell; etc)
randOrder = poissrnd(factor(1)*lambda);
if randOrder <= 0 % if 0 orders this minute, set O to empty
O = [];
return; % if randOrder = 0, that means 0 orders in this minute so
% return to MythicalCabs and go to next time step
end
O = zeros(randOrder,7);
for i = 1:randOrder
position = location(t);
O(i,1) = position(1); % starting x-coord of order
O(i,2) = position(2); % starting y-coord
O(i,3) = position(3); % ending x-coord
O(i,4) = position(4); % ending y-coord;
O(i,5) = t; % time order placed (in mins)
O(i,6) = position(5); % beginning region of order
O(i,7) = position(6); % ending region of order
end
elseif current_hr <= 6
% Decrease orders per minute, i.e. there will be significantly
% less orders between 2 AM and 6 AM
randOrder = poissrnd(factor(2)*lambda);
if randOrder <= 0 % if 0 orders this minute, set O to empty
O = [];
return; % if randOrder = 0, that means 0 orders in this minute so
% return to MythicalCabs and go to next time step
end
O = zeros(randOrder,7);
for i = 1:randOrder
position = location(t);
23
O(i,1) = position(1);
O(i,2) = position(2);
O(i,3) = position(3);
O(i,4) = position(4);
O(i,5) = t;
O(i,6) = position(5);
O(i,7) = position(6);
end
elseif current_hr <= 16
% Orders per minute should be higher than 2 AM - 6 AM but lower
% than 4 PM to midnight
% prob of starting and ending location being the mall or airport
% should be much higher for this time interval
randOrder = poissrnd(lambda);
if randOrder <= 0 % if 0 orders this minute, set O to empty
O = [];
return; % if randOrder = 0, that means 0 orders in this minute so
% return to MythicalCabs and go to next time step
end
O = zeros(randOrder,7);
for i = 1:randOrder
position = location(t);
O(i,1) = position(1);
O(i,2) = position(2);
O(i,3) = position(3);
O(i,4) = position(4);
O(i,5) = t;
O(i,6) = position(5);
O(i,7) = position(6);
end
elseif current_hr <= 20
% Orders per minute should be higher than 6 AM - 4 PM but slightly
% lower than 8 PM - Midnight
% prob of starting and ending location being mall or airport
24
% should be lower than for the 6 AM - 4 PM time interval
randOrder = poissrnd(factor(1)*lambda);
if randOrder <= 0 % if 0 orders this minute, set O to empty
O = [];
return; % if randOrder = 0, that means 0 orders in this minute so
% return to MythicalCabs and go to next time step
end
O = zeros(randOrder,7);
for i = 1:randOrder
position = location(t);
O(i,1) = position(1);
O(i,2) = position(2);
O(i,3) = position(3);
O(i,4) = position(4);
O(i,5) = t;
O(i,6) = position(5);
O(i,7) = position(6);
end
elseif current_hr <=24
% Orders per minute should be highest for this time interval
% starting and ending locations probabilities should be higher
% for collegetown, IC, downtown, i.e. trips should be shorter
% (not as many cabs going to/coming from the mall)
randOrder = poissrnd(factor(3)*lambda);
if randOrder <= 0 % if 0 orders this minute, set O to empty
O = [];
return; % if randOrder = 0, that means 0 orders in this minute so
% return to MythicalCabs and go to next time step
end
O = zeros(randOrder,7);
for i = 1:randOrder
25
position = location(t);
O(i,1) = position(1);
O(i,2) = position(2);
O(i,3) = position(3);
O(i,4) = position(4);
O(i,5) = t;
O(i,6) = position(5);
O(i,7) = position(6);
end
end
end
function [rC,rO,W,P] = fillOrders(t,A,C,O,X,b_f)
%This function takes three lists: A - the vector of available cabs,
%C - the list of all cabs, and O - the list of orders. Using these
%lists, it finds the matching that minimizes the total distance
%travelled when fufiling as many orders in O as possible. It returns
%three lists: rC - the cab list, updated with new positions and times
%of unavailability, rO - the list of remaining orders, and W - the list
%of the wait times for each order.
rC = C;
rO = [];
T_O = O;
O = [];
T = [];
W = [];
P = [;];
k = 1;
%If there are less cabs than orders
if length(A) < length(T_O(:,1));
r = find(T_O(:,5) == k,1,ā€™lastā€™);
while isempty(r) || r < length(A)
k = k + 1;
r = find(T_O(:,5) == k,1,ā€™lastā€™);
end
latest_considered_order_time = k;
26
else
latest_considered_order_time = max(T_O(:,5));
end
k = 1;
for i = 1:length(T_O(:,1))
if T_O(i,5) <= latest_considered_order_time
O(k,:) = T_O(i,:);
k = k + 1;
else
break
end
end
k = 1;
for i = 1:length(A)
A_i = A(i);
for j = 1:length(O(:,1))
T(k,1) = A_i; %Index of the cab
T(k,2) = j; %Index of the order
T(k,3) = t - O(j,5); %Time waited since call
T(k,4) = travelTime(C(A_i,1),C(A_i,2),O(j,1),O(j,2),b_f);
k = k + 1;
end
end
%Sorts the travel time collumn of T and stores the ordering
[values,order] = sort(T(:,4));
%Re orders T based on the order of travel time
T = T(order,:);
%The number of orders that will be filled. If there are less cabs than
%available orders, this will equal the number of available cabs. If
%there are less orders than available cabs, it will equal the number of
%orders.
orders_to_fill = min(length(A),length(O(:,1)));
filled_orders = 0; %The number of filled orders
used_C = []; %The list of cabs that have been used so far
filled_O = []; %The list of orders that have been filled
27
%The matrix used to store the filled orders for processing later
F = zeros(orders_to_fill,4);
j = 1;
k = 1;
while filled_orders < orders_to_fill
%If the cab and order for the current edge are not already
%used/filled
a = find(used_C == T(j,1),1);
b = find(filled_O == T(j,2),1);
ins_flag = isempty(a) && isempty(b);
if ins_flag
F(k,:) = T(j,:); %Store the current edge data in F
k = k + 1; %Increment k
filled_orders = filled_orders + 1; %Increment filled_orders
used_C = [used_C T(j,1)]; %Add the current cab to the used list
filled_O = [filled_O T(j,2)]; %Add the current order to the filled l
end
j = j + 1;
end
for i = 1:length(F(:,1))
F_cab = F(i,1); %The cab used for order i
F_order = F(i,2); %The index of the order filled
W_time = F(i,3) + F(i,4);
[U_time,U_dist] = travelTime(O(F_order,1),O(F_order,2),O(F_order,3),...
O(F_order,4),b_f);
U_time = U_time + W_time;
if O(F_order,6) <= 6 && O(F_order,7) <= 6
[prices(1,1) , prices(2,1)] = pricing(U_dist,X,O(F_order,6),O(F_order,7));
P = [P prices];
end
rC(F_cab,1) = O(F_order,3); %Update the x coordinate
rC(F_cab,2) = O(F_order,4); %Update the y coordinate
rC(F_cab,3) = ceil(U_time); %Update the unavailable time
28
W = [W W_time];
end
k = 1;
for i = 1:length(T_O(:,1))
if isempty(find(filled_O == i,1))
rO(k,:) = T_O(i,:);
k = k + 1;
end
end
end
function [out] = location( t )
% Used to generate which location an order will be made at and will be
% headed to based on a given time and will return the starting and ending x
% and y values and zones
% region 1: airport
% region 2: mall
% region 3: Mornell University
% region 4: Mythical College
% region 5: downtown Mythical
% region 6: City of Mythical
% region 7: Town of Mythical
p=zeros(1,7); %probabilities of being in each region
pg=zeros(7,7); %probabilities given in each region
if t<2 % btwn 12am and 2am, mainly college students out
p(3)=.5;
p(4)=.2;
p(5)=.2;
p(6)=.05;
p(7)=.05;
pg(3,:)=p;
pg(4,:)=p;
pg(5,:)=p;
pg(6,:)=p;
pg(7,:)=p;
29
elseif t < 6 % btwn 2am and 6pm only random ppl out
p(3)=.2;
p(4)=.2;
p(5)=.2;
p(6)=.2;
p(7)=.2;
pg(3,:)=p;
pg(4,:)=p;
pg(5,:)=p;
pg(6,:)=p;
pg(7,:)=p;
elseif t < 10 % btwn 6-10am, airport opens
p(1)=.3;
p(5)=.25;
p(6)=.25;
p(7)=.2;
pg(1,:)=[0,0,0,0,.35,.35,.3];
pg(5,:)=[.4,0,0,0,.25,.25,.1];
pg(6,:)=[.4,0,0,0,.25,.25,.1];
pg(7,:)=[.4,0,0,0,.25,.25,.1];
elseif t < 5 % btwn 10am-5pm, students in class
p(1)=.2;
p(2)=.2;
p(5)=.2;
p(6)=.2;
p(7)=.2;
pg(1,:)=[0,0,0,0,.4,.3,.3];
pg(2,:)=[0,0,0,0,.4,.3,.3];
pg(5,:)=[.3,.3,0,0,.2,.1,.1];
pg(6,:)=[.3,.3,0,0,.2,.1,.1];
pg(7,:)=[.3,.3,0,0,.2,.1,.1];
elseif t < 9 % btwn 5-9pm, students out of class
p(1)=.2;
p(2)=.2;
p(3)=.2;
p(4)=.1;
p(5)=.2;
p(6)=.05;
p(7)=.05;
pg(1,:)=[0,0,.3,.2,.3,.1,.1];
30
pg(2,:)=[0,0,.3,.2,.3,.1,.1];
pg(3,:)=[.3,.3,.1,0,.2,.05,.05];
pg(4,:)=[.3,.3,0,1,.2,.05,.05];
pg(5,:)=[.3,.3,.15,.05,.1,.05,.05];
pg(6,:)=[.3,.3,.15,.05,.1,.05,.05];
pg(7,:)=[.3,.3,.15,.05,.1,.05,.05];
elseif t<11 % btwn 9-11pm
p(1)=.2;
p(3)=.3;
p(4)=.1;
p(5)=.3;
p(6)=.05;
p(7)=.05;
pg(1,:)=[0,0,.4,.2,.2,.1,.1];
pg(3,:)=[.1,0,.4,.2,.2,.05,.05];
pg(4,:)=[.1,0,.4,.2,.2,.05,.05];
pg(5,:)=[.1,0,.4,.2,.2,.05,.05];
pg(6,:)=[.1,0,.4,.2,.2,.05,.05];
pg(7,:)=[.1,0,.4,.2,.2,.05,.05];
else % after 11pm, mainly college students out
p(3)=.5;
p(4)=.2;
p(5)=.2;
p(6)=.05;
p(7)=.05;
pg(3,:)=[0,0,.4,.2,.2,.1,.1];
pg(4,:)=[0,0,.4,.2,.2,.1,.1];
pg(5,:)=[0,0,.4,.2,.2,.1,.1];
pg(6,:)=[0,0,.4,.2,.2,.1,.1];
pg(7,:)=[0,0,.4,.2,.2,.1,.1];
end
r1=path(p);
r2=path(pg(r1,:));
[x1,y1,z1]=getXYZone(r1);
[x2,y2,z2]=getXYZone(r2);
out=[x1,y1,x2,y2,z1,z2];
end
31
%Helper function that determines the region based on a list of probabilities pp
function [loc]=path(pp)
rr=rand();
for i=1:length(pp)
if rr<=pp(i)
loc=i;
break
else
pp(i+1)=pp(i)+pp(i+1); % cummulates probabilities
end
end
end
function [x,y,z] = getXYZone(r)
% Calculates a random x and y value within a given region and returns that
% x and y values and the pricing zone, z, that this point lies in
scale=70.7342; % pixels per mi
if r==1 % airport - zone 7
x=364;
y=0;
z=7;
elseif r==2 % mall - zone 8
x=279;
y=0;
z=8;
elseif r==3 % Mornell
rndd=rand();
if rndd<.5 % zone 6
x=51*rand()+266;
if x<281
y=33*rand()+159;
else
y=49*rand()+159;
end
z=6;
else % zone 5
x=53*rand()+264;
32
y=72*rand()+87;
z=5;
end
elseif r==4 % Mythical College - zone 10
x=15*rand()+201;
y=34*rand()+252;
z=10;
elseif r==5 % downtown Mythical
rndd=rand();
if rndd<.5 % zone 4
y=49*rand()+159;
if y>192
x=75*rand()+206;
else
x=60*rand()+206;
end
z=4;
else % zone 3
y=72*rand()+87;
x=58*rand()+206;
z=3;
end
elseif r==6 % City of Mythical
rndd=rand();
if rndd<.5 % zone 1
y=119*rand()+40;
if y<87
x=68*rand()+168;
else
x=61*rand()+145;
end
z=1;
else % zone 2
x=61*rand()+145;
if x<161
y=50*rand()+159;
else
y=77*rand()+159;
end
33
z=2;
end
elseif r==7 % Town of Mythical - zone 9
rndd=rand();
if rndd<.4
x=145*rand();
y=365*rand();
elseif rndd<.7
k=0;
while k==0
x=157*rand()+145;
y=157*rand()+208;
if x<161 || x>206 || y>236
k=1;
end
end
elseif rndd<.9
x=85*rand()+317;
y=365*rand();
else
x=81*rand()+236;
y=87*rand();
end
z=9;
end
x=x/scale;
y=y/scale;
end
function [t,d] = travelTime(x1,y1,x2,y2,b_f)
%This function calculates the time it takes to travel between two
%points. Eventually, we can update this to be more accurate.
v = 25/60; %Velocity
X = [x1 y1 ; x2 y2];
if b_f
34
d = abs(x2-x1) + abs(y2-y1);
else
d = pdist(X,ā€™euclideanā€™);
end
t = d/v;
end
function [p_fixed,p_variable] = pricing(d,mile_price,z1,z2)
%This function returns two prices for a cab trip. The first method uses
%the coordinates of the start and end point to find the distance
PF = [4.6 5.1 5.1 5.1 5.6 5.6 10 10 15 15.5;
5.1 4.6 5.1 5.1 5.6 5.6 12 12 15 15.5;
5.1 5.1 4.6 5.1 5.1 5.1 16 11.5 13 9.5;
5.1 5.1 5.1 4.6 5.1 5.1 16 11.5 13 9.5;
5.6 5.6 5.1 5.1 4.6 5.1 16 11.5 13 10.5;
5.6 5.6 5.1 5.1 5.1 4.6 16 11.5 13 10.5;
10 12 16 16 16 16 0 16 18 18;
10 12 11.5 11.5 11.5 11.5 0 16 18 15;
15 15 13 13 13 13 18 18 13 15;
15.5 15.5 9.5 9.5 10.5 10.5 18 15 15 5];
p_variable = 2.5 + d*mile_price;
p_fixed = PF(z1,z2);
end
35
7.2 MATLAB code for Part 4
%Graphs the average wait time based on the market share of the two
%companies.
n = 20; %# of cabs
N = 50; %# of trials
lambda = 1.2;
upper_bound = false; %false denotes euclidean distance
x = []; % x-axis vector
avgwait = []; % average wait time
perover25 = []; % percentage wait times greater than 25min
sum_perover25 = zeros(1,21);
sum_avgwait = zeros(1,21);
X = 2; %Price per mile
for k = 1:N
perover25 = [];
x = [];
avgwait = [];
for i=1:21
x=[x i*.025-.025];
[W1,W2,P1,P2] = MythicalCabs2(i,X,upper_bound,i*.025,lambda);
wait = W1;
avgwait=[avgwait, mean(wait)];
over25=0;
for j=1:length(wait)
if wait(j)>25
over25=over25+1;
end
end
over25=100*over25/length(wait);
perover25=[perover25 over25];
end
sum_avgwait = sum_avgwait + avgwait;
avg_avgwait = sum_avgwait/N;
36
sum_perover25 = sum_perover25 + perover25;
avg_perover25 = sum_perover25/N;
end
figure
bar(x,avg_avgwait);
title(ā€™Average Wait vs. Market Share of Company 2ā€™);
xlabel(ā€™Market Shareā€™);
ylabel(ā€™Average Wait Timeā€™);
line(ā€™XDataā€™, [0 .5], ā€™YDataā€™, [15 15], ā€™LineStyleā€™, ā€™-ā€™, ...
ā€™LineWidthā€™, 2, ā€™Colorā€™,ā€™rā€™)
axis tight
figure
bar(x,avg_perover25);
hold on
line(ā€™XDataā€™, [0 .5], ā€™YDataā€™, [10 10], ā€™LineStyleā€™, ā€™-ā€™, ...
ā€™LineWidthā€™, 2, ā€™Colorā€™,ā€™rā€™)
xlabel(ā€™Market Shareā€™);
ylabel(ā€™% of Wait Times Greater Than 25minā€™);
title(ā€™% of Wait Times Greater Than 25min vs. Market Share of Company 2ā€™);
axis tight
function [W1,W2,P1,P2] = MythicalCabs2(n,X,bound_flag,market_share,lambda)
%The following script simulates the movement of cabs around the city of
%Mythical in order to determine the wait times of customers.
%If bound_flag is false, use the straight line distance between points
%to find the lower bound for the number of cabs.
%If bound_flag is true, use the right angle distance between two points
%to find the upper bound for the number of cabs.
t_stop = 24*60; %The length of the simulation in minutes
%The following array holds the information about the position of the cabs,
%as well as the remaining time that they are unavailable (for companies
%one and two)
C1 = zeros(n-ceil(n*market_share),3);
C2 = zeros(ceil(n*market_share),3);
37
W1 = []; %This vector contains the wait times for all filled orders
W2 = [];
O1 = []; %The initially empty vector of orders
O2 = [];
P1 = [;]; %The initially empty revenue vector
P2 = [;];
%Fill in the array C1 with random starting positions, and a current time
%unavailable of 1
for i = 1:length(C1(:,1))
C1(i,1) = rand(1)*5.6832;
C1(i,2) = rand(1)*5.1602;
C1(i,3) = 1;
end
for i = 1:length(C2(:,1))
C2(i,1) = rand(1)*5.6832;
C2(i,2) = rand(1)*5.1602;
C2(i,3) = 1;
end
%Main simulation loop
for t = 1:t_stop
C1(:,3) = C1(:,3)-1; %Each cab has one less minute until available
C2(:,3) = C2(:,3)-1;
%Generate the list of new orders (O) for this time step, return as a
%vector of with width 5 (x1,y1,x2,y2,t)
%Concatenate this vector with the vector of remaining orders
[new_O1,new_O2] = orders2(t,market_share,lambda);
O1 = [O1 ; new_O1];
O2 = [O2 ; new_O2];
%The following vector is the list of indeces for available cabs for
%the current time step. If i is in A, then C(i) is available
A1 = [];
A2 = [];
38
j = 1;
for i = 1:length(C1(:,1))
if C1(i,3) <= 0 %If the cab is available
A1(j) = i; %Store the index in a temp array T
j = j + 1; %Increment j
end
end
j = 1;
for i = 1:length(C2(:,1))
if C2(i,3) <= 0 %If the cab is available
A2(j) = i; %Store the index in a temp array T
j = j + 1; %Increment j
end
end
%Get the updated C and O vectors after filling orders during this time
%step. Also get the wait times for filling the orders.
if ~isempty(A1) && ~isempty(O1)
[C1,O1,temp_W,temp_P] = fillOrders(t,A1,C1,O1,X,bound_flag);
P1 = [P1 temp_P];
W1 = [W1 temp_W]; %Add the new wait times to the current list
end
if ~isempty(A2) && ~isempty(O2)
[C2,O2,temp_W,temp_P] = fillOrders(t,A2,C2,O2,X,bound_flag);
P2 = [P2 temp_P];
W2 = [W2 temp_W]; %Add the new wait times to the current list
end
end
end
function [O1,O2] = orders2(t,market_share,lambda)
current_hr = t/60; % converts t into hours
factor = [1.5, .5, 2]; % determines percent increase or decrease of opm
39
O1 = [];
O2 = [];
% this block of code varies the orders per minute based on
% the time of day i.e. hour 0 is midnight, 1 is 1 AM, 2 is 2 AM
% etc... so hour 24 corresponds to midnight of next day
if current_hr <= 2
% set prob of starting location being cornell or IC to be
% a higher probability.
% set prob of ending location being somewhere on either of those
% campuses to be high prob...ie most trips should be a short
% distance (downtown,cornell; downtown, ic; cornell, cornell; etc)
randOrder = poissrnd(factor(1)*lambda);
if randOrder <= 0 % if 0 orders this minute, set O to empty
O = [];
return; % if randOrder = 0, that means 0 orders in this minute so
% return to MythicalCabs and go to next time step
end
O = zeros(randOrder,7);
for i = 1:randOrder
position = location(t);
O(i,1) = position(1); % starting x-coord of order
O(i,2) = position(2); % starting y-coord
O(i,3) = position(3); % ending x-coord
O(i,4) = position(4); % ending y-coord;
O(i,5) = t; % time order placed (in mins)
O(i,6) = position(5); % beginning region of order
O(i,7) = position(6); % ending region of order
end
elseif current_hr <= 6
% Decrease orders per minute, i.e. there will be significantly
% less orders between 2 AM and 6 AM
randOrder = poissrnd(factor(2)*lambda);
40
if randOrder <= 0 % if 0 orders this minute, set O to empty
O = [];
return; % if randOrder = 0, that means 0 orders in this minute so
% return to MythicalCabs and go to next time step
end
O = zeros(randOrder,7);
for i = 1:randOrder
position = location(t);
O(i,1) = position(1);
O(i,2) = position(2);
O(i,3) = position(3);
O(i,4) = position(4);
O(i,5) = t;
O(i,6) = position(5);
O(i,7) = position(6);
end
elseif current_hr <= 16
% Orders per minute should be higher than 2 AM - 6 AM but lower
% than 4 PM to midnight
% prob of starting and ending location being the mall or airport
% should be much higher for this time interval
randOrder = poissrnd(lambda);
if randOrder <= 0 % if 0 orders this minute, set O to empty
O = [];
return; % if randOrder = 0, that means 0 orders in this minute so
% return to MythicalCabs and go to next time step
end
O = zeros(randOrder,7);
for i = 1:randOrder
position = location(t);
O(i,1) = position(1);
O(i,2) = position(2);
41
O(i,3) = position(3);
O(i,4) = position(4);
O(i,5) = t;
O(i,6) = position(5);
O(i,7) = position(6);
end
elseif current_hr <= 20
% Orders per minute should be higher than 6 AM - 4 PM but slightly
% lower than 8 PM - Midnight
% prob of starting and ending location being mall or airport
% should be lower than for the 6 AM - 4 PM time interval
randOrder = poissrnd(factor(1)*lambda);
if randOrder <= 0 % if 0 orders this minute, set O to empty
O = [];
return; % if randOrder = 0, that means 0 orders in this minute so
% return to MythicalCabs and go to next time step
end
O = zeros(randOrder,7);
for i = 1:randOrder
position = location(t);
O(i,1) = position(1);
O(i,2) = position(2);
O(i,3) = position(3);
O(i,4) = position(4);
O(i,5) = t;
O(i,6) = position(5);
O(i,7) = position(6);
end
elseif current_hr <=24
% Orders per minute should be highest for this time interval
% starting and ending locations probabilities should be higher
% for collegetown, IC, downtown, i.e. trips should be shorter
% (not as many cabs going to/coming from the mall)
42
randOrder = poissrnd(factor(3)*lambda);
if randOrder <= 0 % if 0 orders this minute, set O to empty
O = [];
return; % if randOrder = 0, that means 0 orders in this minute so
% return to MythicalCabs and go to next time step
end
O = zeros(randOrder,7);
for i = 1:randOrder
position = location(t);
O(i,1) = position(1);
O(i,2) = position(2);
O(i,3) = position(3);
O(i,4) = position(4);
O(i,5) = t;
O(i,6) = position(5);
O(i,7) = position(6);
end
end
for i = 1:randOrder
if rand(1) <= market_share && O(i,6) <= 6 && O(i,7) <= 6
O2 = [O2 ; O(i,:)];
else
O1 = [O1 ; O(i,:)];
end
end
end
43
References
[1] ā€Maps - Town of Ithaca.ā€ Maps - Town of Ithaca. N.p., n.d. Web. 17 Nov. 2013.
[2] Austin, Drew, and P. Christopher Zegras. ā€The Taxicab as Public Transportation in Boston.ā€
Transport Chicago. N.p., n.d. Web. 17 Nov. 2013.
[3] ā€Ithaca Tompkins Regional Airport Flight Schedule.ā€ OMNITRANS. N.p., n.d. Web. 17 Nov.
2013.
[4] ā€Center Hours.ā€ The Shops at Ithaca Mall. N.p., n.d. Web. 17 Nov. 2013.
[5] ā€City of Ithaca Zones and Pricing.ā€ Ithaca Dispatch, Inc. (City of Ithaca Fares). N.p., n.d.
Web. 17 Nov. 2013.
[6] ā€MapQuest Maps - Driving Directions - Map.ā€ MapQuest Maps - Driving Directions - Map.
N.p., n.d. Web. 17 Nov. 2013.
44

More Related Content

Viewers also liked (7)

anita_morrison_03-08-2016
anita_morrison_03-08-2016anita_morrison_03-08-2016
anita_morrison_03-08-2016
Ā 
Boot Camp Continuum
Boot Camp ContinuumBoot Camp Continuum
Boot Camp Continuum
Ā 
Radio IT By Group 3 :)
Radio IT By Group 3 :)Radio IT By Group 3 :)
Radio IT By Group 3 :)
Ā 
EWMA 2013 - Ep452 - Stage Closure Simple Approach for Challenging Wounds
EWMA 2013 - Ep452 -  Stage Closure Simple Approach for Challenging Wounds EWMA 2013 - Ep452 -  Stage Closure Simple Approach for Challenging Wounds
EWMA 2013 - Ep452 - Stage Closure Simple Approach for Challenging Wounds
Ā 
Positioning terminology of lower limbs
Positioning terminology of lower limbsPositioning terminology of lower limbs
Positioning terminology of lower limbs
Ā 
Social_Suicide_A_Psychoanalysis_of_Adole-2
Social_Suicide_A_Psychoanalysis_of_Adole-2Social_Suicide_A_Psychoanalysis_of_Adole-2
Social_Suicide_A_Psychoanalysis_of_Adole-2
Ā 
VOGUE The Shoe Press Release-3
VOGUE The Shoe Press Release-3VOGUE The Shoe Press Release-3
VOGUE The Shoe Press Release-3
Ā 

Similar to CabModelWriteup

MasterThesis_MarcMartinezGomez
MasterThesis_MarcMartinezGomezMasterThesis_MarcMartinezGomez
MasterThesis_MarcMartinezGomez
Marc Martinez Gomez
Ā 
907438-Mobile-Data-Arbitrage-Portal-System-for-Mid-Range-Automotive-Servicers
907438-Mobile-Data-Arbitrage-Portal-System-for-Mid-Range-Automotive-Servicers907438-Mobile-Data-Arbitrage-Portal-System-for-Mid-Range-Automotive-Servicers
907438-Mobile-Data-Arbitrage-Portal-System-for-Mid-Range-Automotive-Servicers
bizquirk
Ā 
A feasible solution algorithm for a primitive vehicle routing problem
A feasible solution algorithm for a primitive vehicle routing problemA feasible solution algorithm for a primitive vehicle routing problem
A feasible solution algorithm for a primitive vehicle routing problem
Cem Recai Ƈırak
Ā 
Amazon_Collider_Project
Amazon_Collider_ProjectAmazon_Collider_Project
Amazon_Collider_Project
Abbey Chaver
Ā 
Simulation analysis Halmstad University 2013_project
Simulation analysis Halmstad University 2013_projectSimulation analysis Halmstad University 2013_project
Simulation analysis Halmstad University 2013_project
Alexandru Gutu
Ā 
Vehicle tracking system
Vehicle tracking systemVehicle tracking system
Vehicle tracking system
Sujit9561
Ā 
ModelINPUTS# LoadsInterimPer-Mile Rates for CarriersDestinationSta.docx
ModelINPUTS# LoadsInterimPer-Mile Rates for CarriersDestinationSta.docxModelINPUTS# LoadsInterimPer-Mile Rates for CarriersDestinationSta.docx
ModelINPUTS# LoadsInterimPer-Mile Rates for CarriersDestinationSta.docx
annandleola
Ā 

Similar to CabModelWriteup (20)

MasterThesis_MarcMartinezGomez
MasterThesis_MarcMartinezGomezMasterThesis_MarcMartinezGomez
MasterThesis_MarcMartinezGomez
Ā 
Vanet report 2020 2nd semester
Vanet report 2020 2nd semesterVanet report 2020 2nd semester
Vanet report 2020 2nd semester
Ā 
Marketing Analytics Final Project
Marketing Analytics Final ProjectMarketing Analytics Final Project
Marketing Analytics Final Project
Ā 
TAXI DEMAND PREDICTION IN REAL TIME
TAXI DEMAND PREDICTION IN REAL TIMETAXI DEMAND PREDICTION IN REAL TIME
TAXI DEMAND PREDICTION IN REAL TIME
Ā 
907438-Mobile-Data-Arbitrage-Portal-System-for-Mid-Range-Automotive-Servicers
907438-Mobile-Data-Arbitrage-Portal-System-for-Mid-Range-Automotive-Servicers907438-Mobile-Data-Arbitrage-Portal-System-for-Mid-Range-Automotive-Servicers
907438-Mobile-Data-Arbitrage-Portal-System-for-Mid-Range-Automotive-Servicers
Ā 
thesis
thesisthesis
thesis
Ā 
Mixed Integer Linear Programming Formulation for the Taxi Sharing Problem
Mixed Integer Linear Programming Formulation for the Taxi Sharing ProblemMixed Integer Linear Programming Formulation for the Taxi Sharing Problem
Mixed Integer Linear Programming Formulation for the Taxi Sharing Problem
Ā 
A feasible solution algorithm for a primitive vehicle routing problem
A feasible solution algorithm for a primitive vehicle routing problemA feasible solution algorithm for a primitive vehicle routing problem
A feasible solution algorithm for a primitive vehicle routing problem
Ā 
Dynamic Pricing in Ride-Hailing Platforms
Dynamic Pricing in Ride-Hailing PlatformsDynamic Pricing in Ride-Hailing Platforms
Dynamic Pricing in Ride-Hailing Platforms
Ā 
The Third Eye
The Third EyeThe Third Eye
The Third Eye
Ā 
Koober Preduction IO Presentation
Koober Preduction IO PresentationKoober Preduction IO Presentation
Koober Preduction IO Presentation
Ā 
Koober Machine Learning
Koober Machine LearningKoober Machine Learning
Koober Machine Learning
Ā 
TRANSFORMING PUBLIC TRANSPORTATION
TRANSFORMING PUBLIC TRANSPORTATIONTRANSFORMING PUBLIC TRANSPORTATION
TRANSFORMING PUBLIC TRANSPORTATION
Ā 
Amazon_Collider_Project
Amazon_Collider_ProjectAmazon_Collider_Project
Amazon_Collider_Project
Ā 
Simulation of BART Station at Embarcadero, SFO using Arena
Simulation of BART Station at Embarcadero, SFO using ArenaSimulation of BART Station at Embarcadero, SFO using Arena
Simulation of BART Station at Embarcadero, SFO using Arena
Ā 
Simulation analysis Halmstad University 2013_project
Simulation analysis Halmstad University 2013_projectSimulation analysis Halmstad University 2013_project
Simulation analysis Halmstad University 2013_project
Ā 
Hybrid Ant Colony Optimization for Real-World Delivery Problems Based on Real...
Hybrid Ant Colony Optimization for Real-World Delivery Problems Based on Real...Hybrid Ant Colony Optimization for Real-World Delivery Problems Based on Real...
Hybrid Ant Colony Optimization for Real-World Delivery Problems Based on Real...
Ā 
Vehicle tracking system,be computer android report,android project report,gps...
Vehicle tracking system,be computer android report,android project report,gps...Vehicle tracking system,be computer android report,android project report,gps...
Vehicle tracking system,be computer android report,android project report,gps...
Ā 
Vehicle tracking system
Vehicle tracking systemVehicle tracking system
Vehicle tracking system
Ā 
ModelINPUTS# LoadsInterimPer-Mile Rates for CarriersDestinationSta.docx
ModelINPUTS# LoadsInterimPer-Mile Rates for CarriersDestinationSta.docxModelINPUTS# LoadsInterimPer-Mile Rates for CarriersDestinationSta.docx
ModelINPUTS# LoadsInterimPer-Mile Rates for CarriersDestinationSta.docx
Ā 

CabModelWriteup

  • 1. Taxicab Modeling Carl Bucella, Kelsey Harrington, Corey Marsh Novemeber 17th, 2013 Abstract To address the need for improved taxi services in the Town of Mythical, we have developed a model that uses a minimum-weight pairing algorithm and discrete event simulation. The minimum-weight pairing algorithm matches available cabs with in- coming customer orders so as to minimize customer wait times. The discrete event simulation generates Poisson distributed orders and probabilistically deļ¬ned starting and ending locations dependent on the time of day. After running multiple simulation, we were able to determine an estimated upper and lower bound for the number of cabs needed to ensure that the average customer wait time was under 15 minutes and that less than 10% of customers had to wait more than 25 minutes. Our upper bound esti- mate is based on the assumption that the distance between two points was calculated using right-angle distance, i.e. d = |x2 āˆ’ x1| + |y2 āˆ’ y1|. Our lower bound estimate uses the Euclidean distance between two points, i.e. it assumes there is a straight line path between point a and point b. A visual validation of the results is performed by graphing the average customer wait time and the percentage of customers who wait longer than 25 minutes as a function of the number of cabs in operation. We develop our model further by implementing both ļ¬xed and variable pricing functions. In order to maintain the current levels of revenues for local taxi companies as determined by the ļ¬xed pricing structure, a variable cost of $X per mile is suggested. Finally, we consider the eļ¬€ect of an increase or decrease in the market share of unlicensed cab companies. Our results determine that stricter regulations against unlicensed compa- nies would decrease the average wait time for taxi customers in Mythical, so we are in favor of greatly strengthening the regulations against unlicensed cab companies. 1
  • 2. Contents 1 Problem Statement 3 2 Problem Analysis and Possible Models 3 2.1 Deļ¬nition of Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.2 Modeling Orders Arrivals . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.2.1 Uniform Distribution . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.2.2 Poisson Distribution . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.3 Modeling Call Pick-Up and Drop-Oļ¬€ Locations . . . . . . . . . . . . 6 2.4 Modeling Travel Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.5 Modeling Cab Responses to Calls . . . . . . . . . . . . . . . . . . . . . 8 2.5.1 Minimal Weight Matching . . . . . . . . . . . . . . . . . . . . . . 8 2.5.2 Minimal Weight Spanning Tree with Priority . . . . . . . . . 8 2.6 Modeling Pricing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.6.1 Prelimary Zone Pricing Analysis . . . . . . . . . . . . . . . . . . 10 2.6.2 Zone Pricing Simulation . . . . . . . . . . . . . . . . . . . . . . . 10 2.7 Modeling Market Share Diļ¬€erences . . . . . . . . . . . . . . . . . . . . 10 3 Results 11 3.1 Required Number of Taxicabs . . . . . . . . . . . . . . . . . . . . . . . 11 3.2 Pricing Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 3.2.1 Simulated Pricing Analysis . . . . . . . . . . . . . . . . . . . . . . . . 13 3.3 Market Share Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 4 Strengths and Weaknesses of the Proposed Model 16 5 Robustness - Sensitivity of Ī»āˆ— 16 6 Further Extensions and Considerations 18 7 Appendix 19 7.1 MATLAB code for Parts 1 and 2 . . . . . . . . . . . . . . . . . . . . . . 19 7.2 MATLAB code for Part 4 . . . . . . . . . . . . . . . . . . . . . . . . . . 36 2
  • 3. 1 Problem Statement Mythical city and county oļ¬ƒcials are interested in improving the quality and price of services oļ¬€ered by local taxi companies. In order to do so, they have asked us to determine: 1. The total number of cabs needed to serve the ā€Greater Mythicalā€ area such that the average customer is waiting for no more than 15 minutes and less than 10% of customers are waiting for more than 25 minutes. 2. The value X that would cause taxicab revenues to be roughly the same as they are now if the city switches to meter-based pricing where you pay a $2.50 ļ¬‚at rate and X cents per mile. Currently the city has determined taxi ride prices based on originating and terminating zones. 3. The impact on the average wait times and prices of non-regulated rides if the con- glomerate, Mythical Dispatch, Inc. were to be splitup into 3 companies that operated independently from each other. Mythical Dispatch, Inc. currently owns 2/3 of all cabs oļ¬ƒcially licensed in the city. 4. The consequences of strengthening regulations against unlicensed companies, who cur- rently contol about 1/7 of all cabs in the city. Disclaimer: Upon reading the problem statement, we immediately noticed a similarity be- tween the Town of Mythical and the Town of Ithaca. We base our assumptions and calcu- lations heavily on the Town of Ithaca. However, we must stress that these similarities are only a coincidence, and that our model was speciļ¬cally designed for the ļ¬ctional Town of Mythical. Therefore, whenever we refer to information about the Town of Ithaca, we are only doing so because it provides accurate background information for our model. 2 Problem Analysis and Possible Models Our models focus on providing answers to the ļ¬rst, second, and fourth parts of the problem. 2.1 Deļ¬nition of Parameters In order to solve this problem, we made some simplifying assumptions: 1. The Town of Mythical has speciļ¬c regions and points of interest. Based on the problem statement, we know that the town of Mythical has a large college (Mornell University), a small liberal arts college (Mythical College), an airport, a mall, a downtown area, etc. In order to make our problem simpler, we based these regions and points of interest oļ¬€ of the corresponding regions for the Town of Ithaca. 3
  • 4. 2. The taxis travel at a constant velocity of 25 miles per hour. We estimated the average miles per hour for roads in the Town of Ithaca to be around 40. Within the City, the speed limit is 35 miles per hour, but in the surrounding areas the speed limit can become as high as 65 miles per hour. The roads with higher speed limits are less common, so we estimated the average speed limit to be closer to 40 miles per hour. In order to account for traļ¬ƒc, traļ¬ƒc lights, stop signs, etc. we decided to set the average speed to 25 miles per hour. 3. The Greater Mythical Area is approximately a 6.6832 by 5.1602 mile rect- angle. We assumed that the Town of Ithaca is similar in size to the Town of Mythical. Using a map image for the Town of Ithaca, [1], as well as the scale image for the map, we processed the two images in MATLAB to determine the size of Ithaca and in turn, Mythical. 4. The expected number of orders is a function of time. The idea that customer orders are time dependent is based on empirical evidence gathered as a result of research into the taxicab system in Boston, [2]. Although we were unable to ļ¬nd speciļ¬c data on the expected number of orders at each point in time, we were able to estimate these values using our own personal experience. For example, it is likely that a taxi company receives far less customer orders between 2 AM and 6 AM than it does between 8 PM and 11 PM. Later, we discuss using a Poisson distribution to determine the number of orders per minute. We designed our values of Ī»(t) to reļ¬‚ect our prior knowledge and experience. 5. There are speciļ¬c probabilities for the starting and ending region of a trip based on the time of day. We know that based on the time of day, people are more likely to travel from certain places to others. We also know that the probability of ending in one region is likely conditional on the region the trip started in. The numbers we came up for these probabilities are based on various factors: ā€¢ There are no ļ¬‚ights in and out of the airport between 2AM and 5 AM, so the probability of getting a order from or to the airport during these hours is 0, [3]. ā€¢ The mall is closed from 10 PM to 8 AM, so the probability of getting an order to or from the mall during these hours is 0, [4]. ā€¢ People travel to and from downtown more frequently between the hours of 11 PM to 2 AM, so the probability of receiving calls from and to these areas is greater during that time period. ā€¢ If you are starting your order from a random location in the Town of Mythical, then you are likely traveling to one of the main regions (Airport, Mall, Mornell, etc.), so the probability of going to these areas is higher. 4
  • 5. ā€¢ If you are starting your order from one of these main regions (Airport, Mall, Mornell, etc.), it is likely that you do not have a car and are therefore a student, so you have a higher probability of traveling to Mornell or Mythical College. A lot of thought went into determining these probabilities. We combined the in- formation about taxi cab transportation in Boston, [2], with our own knowlege and experience, to determine the values of these probabilites. 2.2 Modeling Orders Arrivals 2.2.1 Uniform Distribution In our original model, we modeled order arrival times as uniform distribution over a 24-hour day. For each iteration of our algorithm, which corresponds to a one-minute interval in real time, we generated a random number uniformly distributed between 0 and 1. We checked if that random number was less than a certain value c, where c āˆˆ [0, 1], to determine whether a customer placed an order in that time interval. The value of c corresponded to the expected number of orders, which we set to 0.3 and 1.0 in trial runs but later determined would likely be somewhere between these values, approximately 0.8. Although the choice of uniformly distributed order arrivals helped to simplify the imple- mentation of our model, the assumption fails to account for changes in customer demand dependent on the time of day. Furthermore, the uniform assumption restricted the number of possible orders that could be placed in a minute to zero and one. In a town with a strong college presence such as Mythical, it is very likely that multiple orders will be placed in a given minute during peak hours, especially when there is an event, such as a concert. It is assumed that many college students do not have cars and it is estimated that they make up a large portion of taxicab customers in Mythical. 2.2.2 Poisson Distribution Based on our research, we settled on a Poisson distribution for modeling the order arrivals. Arrival times are often modeled using the Poisson distribution in other applications, and because our algorithm is a discrete-event simulation with a variable Ī» parameter, this distri- bution works well. The distribution function for a Poisson random variable is given below: f(k; Ī») = P(X = k) = Ī»(t)k eāˆ’Ī»(t) k! (1) This choice also allows us to vary Ī», corresponding to the expected number of orders, as a function of time. As we discussed above, the expected number of orders per minute is dependent upon the time of day. Our model implements a piece-wise function for Ī», given below. The function shows that the taxicab companys peak hours are between 8 PM and 5
  • 6. midnight, and that the lowest frequency of orders can be expected to occur between 2 AM and 6 AM. Our choices for these values are our best estimates based on observations of taxicab use in a town very similar to Mythical. Our Ī» values are based on the value of Ī»āˆ— , which is the expected number of calls per minute between 6 AM - 4 PM (midday). We used Ī»āˆ— to calculate the other values of Ī», as can be seen below, and varied Ī»āˆ— to see how this would change our output. E(X) = Ī»(t) = ļ£± ļ£“ļ£“ļ£“ļ£“ļ£² ļ£“ļ£“ļ£“ļ£“ļ£³ 1.2Ī»āˆ— if t is between 12AM-2AM 0.2Ī»āˆ— if t is between 2AM-6AM 1.0Ī»āˆ— if t is between 6AM-4PM 1.2Ī»āˆ— if t is between 4PM-8PM 1.6Ī»āˆ— if t is between 8PM-12AM 2.3 Modeling Call Pick-Up and Drop-Oļ¬€ Locations We originially selected random x and y values that were in the ā€Greater Mythical Regionā€. Later we decided to select the trip starting and ending locations based on time of day and points of interest, as is alluded to in our deļ¬nition of parameters. Most of the orders will originate or end in the ā€City of Mythicalā€ and/or a point of interest (Airport, Mall, Mornell, etc.). Outside of the city is assumed to be predominantly agricultural with fewer roads and the people living there are assumed to own cars therefore, fewer orders would originate from or go to these regions. We assigned diļ¬€erent probabilities, that varied with time of day, that an order is placed from a region and that an order will end in another region (conditional on the region the order was placed in). The main regions that we consider are: 1. The Mythical-Dompkins Airport - considered as Zone 7 2. Mythical Mall - considered as Zone 8 3. Mornell University - Zones 5 and 6 4. Mythical College - considered as Zone 9 5. Downtown Mythical - Zones 3 and 4 6. The parts of the City of Mythical that have not previously been considered - Zones 1 and 2 7. The parts of the Town of Mythical that have not previously been considered - consid- ered as Zone 10 Zones 1 through 6 correspond to the pricing zones, [5], and are used in the pricing section. Once the starting and ending regions were determined, the starting and ending points were randomly selected from within the rectangular approximations to each zone displayed on the following page. 6
  • 7. Figure 1: Map of ā€Greater Mythical Areaā€ with Zones 2.4 Modeling Travel Time In our model, we have two diļ¬€erent options for calculating the travel time between two points. Our initial simpliļ¬cation was to simply use the Euclidean distance formula to calculate the distance between two points. In order to ļ¬nd the time it takes to travel this distance, we divide this distance by our assumed velocity. d = (x1 āˆ’ x2)2 + (y1 āˆ’ y2)2 (2) While this distance greatly simpliļ¬es our model, we realize that it is very unrealistic to assume that you can get between any two points in a straight line considering that roads rarely allow this. Using this formula for distance therefore, gives us a lower bound for our simulation results. In order to combat this issue, we use the following distance formula to ļ¬nd the upper 7
  • 8. bound. Which is the sum of the total x distance and y distance traveled between two points. d = |x2 āˆ’ x1| + |y2 āˆ’ y1| (3) This formula represents the distance the trip would be if you could only travel at right angles between the two points. We later refer to this as the right angle distance between the two points. While we did not have time to make a more detailed distance function based oļ¬€ of roads and speed limits, the use of these two functions to ļ¬nd an upper and lower bound for the travel time makes our model more robust than simply choosing one. 2.5 Modeling Cab Responses to Calls 2.5.1 Minimal Weight Matching In order to ļ¬ll these orders, we need to ļ¬nd a matching between the list of available cabs and the list of orders at each time step. If there are no available cabs or no new orders at time t, we do not perform a matching and increment t. We repeat this process until we have at least one available cab and new order. At this point, we call ļ¬llOrders to ļ¬nd the matching between the orders and cabs. ļ¬llOrders uses an adaptation of Kruskals algorithm to ļ¬nd the minimal distance pairing between the two sets. In order to do so, ļ¬llOrders stores the wait time from every cab A to every order B. This list is then sorted by the distances so that the smallest distance is at the top of the list. Then, ļ¬llOrders considers the edges in increasing order; if the cab for the edge is available, and the order is still unļ¬lled, we accept this edge. We repeat this process, and ignore any edges where the cab and order have already been used/ļ¬lled. Once we have ļ¬lled all the orders, or used all possible cabs, the process is ļ¬nished. Using the list of ļ¬lled orders, we update the list of cabs with their ļ¬nal locations, as well as the time for which they will be unavailable. In order to calculate the unavailable time, we add the wait time to the time of the trip. We have already modeled the start and end positions of each order, so this information is easily calculated from our list of orders. We create a vector that contains the wait times for each ļ¬lled order during the current time step. At the end of ļ¬llOrders, we return this vector and concatenate it with the vector containing data for the previous wait times. At the end of the simulation, we are left with a vector of wait times for each order placed, which we analyze to determine the result of the simulation. 2.5.2 Minimal Weight Spanning Tree with Priority One issue with the method above is that the orders are ļ¬lled only based on the distance between them and the nearest available cabs. This could cause orders far away from all available cabs to remain unļ¬lled for long periods of time, and we did not feel that this 8
  • 9. coincides with how a cab company would typically operate. In order to ļ¬x this problem, we treat the list of orders as a queue. A queue operates by the ļ¬rst-in-ļ¬rst-out (FIFO) property, so the oldest orders placed are considered ļ¬rst before any new orders. If there are two orders that were placed at the same time, we always consider them together, to prevent favoring the order that was stored in the list ļ¬rst. The orders are then processed in the same way as before, but only the oldest orders are considered by the matching algorithm. 2.6 Modeling Pricing We based our model pricing oļ¬€ of the following map of each zone and the corresponding zone-to-zone prices listed in the matrix below, [5]. Figure 2: Map of Zones Figure 3: Zone Pricing 9
  • 10. 1 2 3 4 5 6 1 - 1.83 1.89 1.73 3.1 2.6 2 1.83 - 1.88 1.19 2.75 2.24 3 1.89 1.88 - 0.87 1.62 1.67 4 1.73 1.19 0.87 - 1.71 1.21 5 3.1 2.75 1.62 1.71 - 1.2 6 2.6 2.24 1.67 1.21 1.2 - Table 1: Distance between Zone Centers (mi) 2.6.1 Prelimary Zone Pricing Analysis To start our zone pricing analysis we calculated the distance from the center of each zone to the center of each other zone, using MapQuest, [6]. Our results are listed in the table above. We then subtracted $2.50, the base price for a cab ride, from the zone prices depicted in Figure 3 and divided the remaining price by the distance between the zone centers. We then averaged these prices to get the average price per mile that would need to be charged for the metered pricing to be roughly equilivalent to the ļ¬xed zone pricing. 2.6.2 Zone Pricing Simulation The problem asked us to leave the revenues of cab companies, rather than prices per trip, relatively the same as they are now. Therefore, in order to more accurately compare the diļ¬€erence in revenue between a ļ¬xed price plan and a variable price plan (for orders placed within the city), we calculate and store the two prices for each trip. From the order infor- mation, we know the two zones that the order is traveling between, as well as the x and y coordinates of the start and end points. Using the zones along with the zone pricing map, [5], we calculate the ļ¬xed price of the order. Similarly, we use the x and y coordinates to calculate the variable price for the trip. Both of these values are returned by ļ¬llOrders for the orders ļ¬lled in the current time step. Like wait time, we concatenate this new vector with the vector holding the previous prices of orders. At the end of the simulation, we are left with a 2 by p matrix, where P(1,i) is the ļ¬xed price for order i, and P(2,i) is the variable price for the same order. 2.7 Modeling Market Share Diļ¬€erences In order to solve part 4 of the problem statement, we needed to set up a simulation in which there are two distinct cab companies operating within the City of Mythical. The ļ¬rst company is considered to be Mythical Dispatch, the conglomerate of 3 companies, while 10
  • 11. Company 2 is assumed to be the group of non-regulated taxicab companies. Because of the way our code was written, it was simple to complete this by performing the following steps: ā€¢ First, we deļ¬ned the total number of cabs in mythical (n) and the market share of company 2 (m). ā€¢ Second, we created separate data structures for Company 2 to hold the data for their cabs, orders, available cabs, wait times, and prices. Then, we modiļ¬ed orders so that if a person is traveling within the City of Mythical, they have probability m of calling Company 2. This assumption follows directly from the deļ¬nition of market share. Using a uniform distribution, we determine which company should get a speciļ¬c order, and then return two lists of orders, one for each company. We then call ļ¬llOrders for each company, using the appropriate data structures for each. At the end of the simulation, we are left with a list of wait times and prices for each company, which we then analyze to determine our results. 3 Results 3.1 Required Number of Taxicabs After using our model to simulate a 24-hour day over 25 trials, we were able to determine the total number of cabs needed to serve the ā€Greater Mythicalā€ area. The graphs on the following page show the average wait time and percent of people who wait longer than 25 minutes as a function of the number of cabs operating. The ļ¬gures show that the average wait time decreases as the number of taxis increases, which is to be expected. The rate of decrease appears to be consistent with logistic decay since the average wait time decreases less as the number of taxis increases. Therefore, deploying more cabs than is necessary to meet the cityā€™s goals does not result in an equivalent increase in productivity. We ran our simulation using both the Euclidean distance, which serves as a lower bound for the number of cabs necessary, and using the right angle distance, which serves as an upper bound for the number of cabs. Our lower and upper bound estimates for the number of cabs necessary to meet the citys goals are 11 and 14 cabs respectively. 11
  • 12. Figure 4: Average Wait Time and % of Wait Times Over 25 min for Euclidean Distance Figure 5: Average Wait Time and % of Wait Times Over 25 min for Right Angle Distance 12
  • 13. 1 2 3 4 5 6 1 - 1.42 1.38 1.50 1.00 1.19 2 1.42 - 1.38 2.18 1.13 1.38 3 1.38 1.38 - 2.99 1.60 1.56 4 1.50 2.18 0.87 - 1.52 2.15 5 1.00 1.13 1.62 1.52 - 2.17 6 1.19 1.38 1.67 2.15 2.17 - Table 2: Distance between Zone Centers (mi) 3.2 Pricing Analysis The results of our preliminary pricing analysis are shown above. We found that the average price per mile from one zone center to another should be approximately $1.64 (average of the values depicted). This is the price per mile needed to keep the trip from one zone center to another roughly equal to what it is currently. 3.2.1 Simulated Pricing Analysis The results of our simulated pricing analysis using 15 cabs and Ī»āˆ— = 0.8 are depicted on the following page. We varied price per mile from $0.50 to $3.00 by $0.10. We ran the simulation for only 5 days for each price per mile and calculated the daily revenue diļ¬€erence for each of these days. This was believed to be suļ¬ƒcient since there are several orders per day and that averaging the daily revenue diļ¬€erence over more days would produce a similar result. Then we averaged these revenue diļ¬€erences to get the average daily price diļ¬€erence for each price per mile. We found that the price of $2.00 per mile minimized the diļ¬€erence between the average daily revenue when it is assumed you can only travel in right angles. We found that the price of $2.50 per mile minimized the diļ¬€erence between the average daily revenue when it is assumed you can travel straight to your ļ¬nal destination, calculated using the Euclidean distance formula. This makes sense because using the right angle distance causes trips to be longer than when you travel straight there causing the price per mile of the right angle distance to be less if we are trying to keep the overall revenue the same. These values are slightly larger than the ones found by our prelimary analysis but still relatively close and we believe that these are more accurate since they take more parameters into account. Therefore, we conclude that the average price per mile should be $2.25 if we want to switch to metered pricing but leave the revenues of taxicab companies roughly the same as they are currently. The advantage to switching to meters is that a cab company could make more money if they are traveling further into a zone than before however, a disadvantage is that 13
  • 14. they could make less money if they are just barely entering a new zone. The cab driverā€™s hapiness likely depends on whether they are making more or less money and the city and county oļ¬ƒcials likely want to keep the cab drivers happy. Figure 6: Right Angle Distance Figure 7: Euclidean Distance 14
  • 15. 3.3 Market Share Results In order to see the eļ¬€ect of market share on wait time, we set the value of n to 20 and Ī»āˆ— to 1.2. We increased the number of cabs and the average number of orders per minute so, it is easier to represent a smaller percentage of the market share by Company 2. Then, we ran MythicalCabs2 for multiple trials for each value of m (market share). This resulted in the following graphs: Figure 8: Average Wait Time for Variable Market Shares Figure 9: % of Wait Times over 25 min for Variable Market Shares 15
  • 16. As you can see, adding a second cab company with a market share of 1/7 drastically increases the average wait time of all customers. From these results, we can easily make a conclusion about the eļ¬€ect of reducing the market share of Company 2. If you reduce the market share of Company 2, the average wait times for everyone will decrease. Therefore, we are in favor of stricter regulations on the unlicensed cab companies operating within the city. 4 Strengths and Weaknesses of the Proposed Model The main strength of our model is its adaptability. This is partly due to the nature of our model, and partly due to the way we broke down our code into functions. For example, writing separate functions for generating orders and ļ¬lling orders made it very easy to add a second cab company and monitor the eļ¬€ect of its market share. Not only was our code compartmentalized well, but the parameters that determine the model are easily adjustable, so it was very easy for us to run the simulation over many trials while varying certain parameters. This allowed us to easily perform sensitivity tests on our data, which will be discussed in the Sensitivity of Ī»āˆ— section. Our model has one main weakness, which is in how the travel time is calculated. While we use the two diļ¬€erent distance formulas to provide an upper and lower bound for our results, it is obvious that our model would be more accurate if we forced cabs to stay on a predetermined set of roads, with designated speed limits for each road. In the city, where the roads are more densely packed, this simpliļ¬cation does not aļ¬€ect our model too much. However, in the town of Ithaca, where roads are more spread out, this simpliļ¬cation will cause more inaccuracy. The distance traveled on these roads could vary from our distance calculations, and our average velocity is probably lower than the actual average velocity when traveling in the town. There is a way to remove this weakness, which will be discussed in the Further Extensions and Considerations section. 5 Robustness - Sensitivity of Ī»āˆ— While we used background data to determine our value for Ī»āˆ— , we wanted to see how changing the value of Ī»āˆ— by a small amount aļ¬€ected the average wait time based on a ļ¬xed number of cabs. In order to do so, we ran multiple trials where we varied Ī»āˆ— from 0 to 2 while keeping the number of cabs constant. Running this experiment helped us to validate our results in the following way: we noticed that as Ī»āˆ— increases, the average wait time grows logistically, which we expect because after a certain point, the wait times are already so large that increasing Ī»āˆ— does not have much of an eļ¬€ect. 16
  • 17. Figure 10: Average Wait Time for Variable Values of Ī»āˆ— Figure 11: % of Wait Times over 25 min for Variable Values of Ī»āˆ— We noticed from earlier experiments that for every Ī»āˆ— , there is a value for n (number of cabs) which is essentially a ā€tipping pointā€. This tipping point represents the number of cabs for which the company is able to keep up with the orders it receives. For n less than this tipping point, the cab company will not be able to keep up with the orders. As the number of unļ¬lled orders increase, the wait times grow exponentially. By keeping n ļ¬xed and running the simulation while varying Ī»āˆ— , this could tell a company with n cabs the average orders per minute that they would be capable of serving. While we did not intend to solve 17
  • 18. this problem, it is an interesting result nonetheless. 6 Further Extensions and Considerations As we discussed in our Strengths and Weaknesses section, our model has one main weakness: the estimation of travel time and distance. There is a simple way to solve this, but it requires a lot of time to gather the appropriate data and write the algorithm. This is how we would approach this problem if we had time: First, we would need to collect data for the intersections and roads of Mythical. We would create a graph, with nodes representing the various intersections throughout Mythical and edges representing the roads between the intersections. The weight of each edge would be the time required to travel the edge, which is the distance of the edge divided by the speed limit of the edge. After determining the starting and ending points of a route, we would use Dijkstras algorithm to ļ¬nd the shortest weighted path from point A to point B, and return the total time and distance of the path. To take this method even further, we could also return the number of nodes on the path and use it to estimate the time waited at lights. For example, we could assume that there is some probability (p) that a node N has a traļ¬ƒc light. So, for each node passed, we could check if there was a traļ¬ƒc light at that node using a uniform distribution. If there is a traļ¬ƒc light, we could model the wait time at the light on a normal distribution, where wait times less than or equal to zero mean the light is green when you pass it. If we added the wait time from each node to the wait time of the trip, the accuracy of our travel time between two points would increase dramatically. 18
  • 19. 7 Appendix 7.1 MATLAB code for Parts 1 and 2 %The following script runs the simulation for N trials on each value of n, %and graphs the results close all N = 25; upper_bound = true; n_s = 5; %Starting number of cabs n = 15; % iterate over n cabs per trials x = []; % x-axis vector avgwait = []; % average wait time perover25 = []; % percentage wait times greater than 25min sum_perover25 = zeros(1,n); sum_avgwait = zeros(1,n); X = 2; %Price per mile for k = 1:N perover25 = []; x = []; avgwait = []; for i=n_s:n+n_s-1 x=[x i]; [wait,price] = MythicalCabs(i,X,upper_bound); avgwait=[avgwait, mean(wait)]; over25=0; for j=1:length(wait) if wait(j)>25 over25=over25+1; end end over25=100*over25/length(wait); perover25=[perover25 over25]; end sum_avgwait = sum_avgwait + avgwait; avg_avgwait = sum_avgwait/N; 19
  • 20. sum_perover25 = sum_perover25 + perover25; avg_perover25 = sum_perover25/N; end figure bar(x,avg_avgwait); xlabel(ā€™Number of Taxisā€™); ylabel(ā€™Average Wait Timeā€™); figure bar(x,avg_perover25); hold on line(ā€™XDataā€™, [0 n+5], ā€™YDataā€™, [10 10], ā€™LineStyleā€™, ā€™-ā€™, ... ā€™LineWidthā€™, 2, ā€™Colorā€™,ā€™rā€™) xlabel(ā€™Number of Taxisā€™); ylabel(ā€™% of Wait Times Greater Than 25minā€™); function [M,I] = PricingGraph() % Displays a graph of the average daily revenue difference based on price % per mile close all r_diff=[]; xax=[]; for X=0.5:0.1:4 % set price values = 0.5,0.6,...,4.0 xax=[xax,X]; r_diffd=[]; for d=1:5 [W,P]=MythicalCabs(15,X,true); % daily revenue difference r_diffd=[r_diffd, sum(P(1,:))-sum(P(2,:))]; end % calculate average revenue difference over 5 days r_diff=[r_diff, mean(r_diffd)]; end [M,I]=min(r_diff); 20
  • 21. bar(xax,r_diff); title(ā€™Average Price Differenceā€™); xlabel(ā€™Price ($/mi)ā€™); ylabel(ā€™Average Price Differenceā€™); end function [W,P] = MythicalCabs(n,X,bound_flag) %The following script simulates the movement of cabs around the city of %Mythical in order to determine the wait times of customers. %If bound_flag is false, use the straight line distance between points %to find the lower bound for the number of cabs. %If bound_flag is true, use the right angle distance between two points %to find the upper bound for the number of cabs. t_stop = 24*60; %The length of the simulation in minutes %The following array holds the information about the position of the cabs, %as well as the remaining time that they are unavailable C = zeros(n,3); W = []; %This vector contains the wait times for all filled orders O = []; %The initially empty vector of orders P = [;]; %Fill in the array C with random starting positions, and a current time %unavailable of 1 for i = 1:n C(i,1) = rand(1)*5.6832; C(i,2) = rand(1)*5.1602; C(i,3) = 1; end %Main simulation loop for t = 1:t_stop C(:,3) = C(:,3)-1; %Each cab has one less minute until available %Generate the list of new orders (O) for this time step, return as a %vector of with width 5 (x1,y1,x2,y2,t) %Concatenate this vector with the vector of remaining orders 21
  • 22. new_O = orders(t); O = [O ; new_O]; %The following vector is the list of indeces for available cabs for %the current time step. If i is in A, then C(i) is available A = []; j = 1; for i = 1:n if C(i,3) <= 0 %If the cab is available A(j) = i; %Store the index in a temp array T j = j + 1; %Increment j end end %Get the updated C and O vectors after filling orders during this time %step. Also get the wait times for filling the orders. if ~isempty(A) && ~isempty(O) [C,O,temp_W,temp_P] = fillOrders(t,A,C,O,X,bound_flag); P = [P temp_P]; W = [W temp_W]; %Add the new wait times to the current list end end end function O = orders(t) current_hr = t/60; % converts t into hours factor = [1.2, .2, 1.6]; % determines percent increase or decrease of opm lambda = .8; % this block of code varies the orders per minute based on % the time of day i.e. hour 0 is midnight, 1 is 1 AM, 2 is 2 AM % etc... so hour 24 corresponds to midnight of next day if current_hr <= 2 % set prob of starting location being cornell or IC to be % a higher probability. % set prob of ending location being somewhere on either of those 22
  • 23. % campuses to be high prob...ie most trips should be a short % distance (downtown,cornell; downtown, ic; cornell, cornell; etc) randOrder = poissrnd(factor(1)*lambda); if randOrder <= 0 % if 0 orders this minute, set O to empty O = []; return; % if randOrder = 0, that means 0 orders in this minute so % return to MythicalCabs and go to next time step end O = zeros(randOrder,7); for i = 1:randOrder position = location(t); O(i,1) = position(1); % starting x-coord of order O(i,2) = position(2); % starting y-coord O(i,3) = position(3); % ending x-coord O(i,4) = position(4); % ending y-coord; O(i,5) = t; % time order placed (in mins) O(i,6) = position(5); % beginning region of order O(i,7) = position(6); % ending region of order end elseif current_hr <= 6 % Decrease orders per minute, i.e. there will be significantly % less orders between 2 AM and 6 AM randOrder = poissrnd(factor(2)*lambda); if randOrder <= 0 % if 0 orders this minute, set O to empty O = []; return; % if randOrder = 0, that means 0 orders in this minute so % return to MythicalCabs and go to next time step end O = zeros(randOrder,7); for i = 1:randOrder position = location(t); 23
  • 24. O(i,1) = position(1); O(i,2) = position(2); O(i,3) = position(3); O(i,4) = position(4); O(i,5) = t; O(i,6) = position(5); O(i,7) = position(6); end elseif current_hr <= 16 % Orders per minute should be higher than 2 AM - 6 AM but lower % than 4 PM to midnight % prob of starting and ending location being the mall or airport % should be much higher for this time interval randOrder = poissrnd(lambda); if randOrder <= 0 % if 0 orders this minute, set O to empty O = []; return; % if randOrder = 0, that means 0 orders in this minute so % return to MythicalCabs and go to next time step end O = zeros(randOrder,7); for i = 1:randOrder position = location(t); O(i,1) = position(1); O(i,2) = position(2); O(i,3) = position(3); O(i,4) = position(4); O(i,5) = t; O(i,6) = position(5); O(i,7) = position(6); end elseif current_hr <= 20 % Orders per minute should be higher than 6 AM - 4 PM but slightly % lower than 8 PM - Midnight % prob of starting and ending location being mall or airport 24
  • 25. % should be lower than for the 6 AM - 4 PM time interval randOrder = poissrnd(factor(1)*lambda); if randOrder <= 0 % if 0 orders this minute, set O to empty O = []; return; % if randOrder = 0, that means 0 orders in this minute so % return to MythicalCabs and go to next time step end O = zeros(randOrder,7); for i = 1:randOrder position = location(t); O(i,1) = position(1); O(i,2) = position(2); O(i,3) = position(3); O(i,4) = position(4); O(i,5) = t; O(i,6) = position(5); O(i,7) = position(6); end elseif current_hr <=24 % Orders per minute should be highest for this time interval % starting and ending locations probabilities should be higher % for collegetown, IC, downtown, i.e. trips should be shorter % (not as many cabs going to/coming from the mall) randOrder = poissrnd(factor(3)*lambda); if randOrder <= 0 % if 0 orders this minute, set O to empty O = []; return; % if randOrder = 0, that means 0 orders in this minute so % return to MythicalCabs and go to next time step end O = zeros(randOrder,7); for i = 1:randOrder 25
  • 26. position = location(t); O(i,1) = position(1); O(i,2) = position(2); O(i,3) = position(3); O(i,4) = position(4); O(i,5) = t; O(i,6) = position(5); O(i,7) = position(6); end end end function [rC,rO,W,P] = fillOrders(t,A,C,O,X,b_f) %This function takes three lists: A - the vector of available cabs, %C - the list of all cabs, and O - the list of orders. Using these %lists, it finds the matching that minimizes the total distance %travelled when fufiling as many orders in O as possible. It returns %three lists: rC - the cab list, updated with new positions and times %of unavailability, rO - the list of remaining orders, and W - the list %of the wait times for each order. rC = C; rO = []; T_O = O; O = []; T = []; W = []; P = [;]; k = 1; %If there are less cabs than orders if length(A) < length(T_O(:,1)); r = find(T_O(:,5) == k,1,ā€™lastā€™); while isempty(r) || r < length(A) k = k + 1; r = find(T_O(:,5) == k,1,ā€™lastā€™); end latest_considered_order_time = k; 26
  • 27. else latest_considered_order_time = max(T_O(:,5)); end k = 1; for i = 1:length(T_O(:,1)) if T_O(i,5) <= latest_considered_order_time O(k,:) = T_O(i,:); k = k + 1; else break end end k = 1; for i = 1:length(A) A_i = A(i); for j = 1:length(O(:,1)) T(k,1) = A_i; %Index of the cab T(k,2) = j; %Index of the order T(k,3) = t - O(j,5); %Time waited since call T(k,4) = travelTime(C(A_i,1),C(A_i,2),O(j,1),O(j,2),b_f); k = k + 1; end end %Sorts the travel time collumn of T and stores the ordering [values,order] = sort(T(:,4)); %Re orders T based on the order of travel time T = T(order,:); %The number of orders that will be filled. If there are less cabs than %available orders, this will equal the number of available cabs. If %there are less orders than available cabs, it will equal the number of %orders. orders_to_fill = min(length(A),length(O(:,1))); filled_orders = 0; %The number of filled orders used_C = []; %The list of cabs that have been used so far filled_O = []; %The list of orders that have been filled 27
  • 28. %The matrix used to store the filled orders for processing later F = zeros(orders_to_fill,4); j = 1; k = 1; while filled_orders < orders_to_fill %If the cab and order for the current edge are not already %used/filled a = find(used_C == T(j,1),1); b = find(filled_O == T(j,2),1); ins_flag = isempty(a) && isempty(b); if ins_flag F(k,:) = T(j,:); %Store the current edge data in F k = k + 1; %Increment k filled_orders = filled_orders + 1; %Increment filled_orders used_C = [used_C T(j,1)]; %Add the current cab to the used list filled_O = [filled_O T(j,2)]; %Add the current order to the filled l end j = j + 1; end for i = 1:length(F(:,1)) F_cab = F(i,1); %The cab used for order i F_order = F(i,2); %The index of the order filled W_time = F(i,3) + F(i,4); [U_time,U_dist] = travelTime(O(F_order,1),O(F_order,2),O(F_order,3),... O(F_order,4),b_f); U_time = U_time + W_time; if O(F_order,6) <= 6 && O(F_order,7) <= 6 [prices(1,1) , prices(2,1)] = pricing(U_dist,X,O(F_order,6),O(F_order,7)); P = [P prices]; end rC(F_cab,1) = O(F_order,3); %Update the x coordinate rC(F_cab,2) = O(F_order,4); %Update the y coordinate rC(F_cab,3) = ceil(U_time); %Update the unavailable time 28
  • 29. W = [W W_time]; end k = 1; for i = 1:length(T_O(:,1)) if isempty(find(filled_O == i,1)) rO(k,:) = T_O(i,:); k = k + 1; end end end function [out] = location( t ) % Used to generate which location an order will be made at and will be % headed to based on a given time and will return the starting and ending x % and y values and zones % region 1: airport % region 2: mall % region 3: Mornell University % region 4: Mythical College % region 5: downtown Mythical % region 6: City of Mythical % region 7: Town of Mythical p=zeros(1,7); %probabilities of being in each region pg=zeros(7,7); %probabilities given in each region if t<2 % btwn 12am and 2am, mainly college students out p(3)=.5; p(4)=.2; p(5)=.2; p(6)=.05; p(7)=.05; pg(3,:)=p; pg(4,:)=p; pg(5,:)=p; pg(6,:)=p; pg(7,:)=p; 29
  • 30. elseif t < 6 % btwn 2am and 6pm only random ppl out p(3)=.2; p(4)=.2; p(5)=.2; p(6)=.2; p(7)=.2; pg(3,:)=p; pg(4,:)=p; pg(5,:)=p; pg(6,:)=p; pg(7,:)=p; elseif t < 10 % btwn 6-10am, airport opens p(1)=.3; p(5)=.25; p(6)=.25; p(7)=.2; pg(1,:)=[0,0,0,0,.35,.35,.3]; pg(5,:)=[.4,0,0,0,.25,.25,.1]; pg(6,:)=[.4,0,0,0,.25,.25,.1]; pg(7,:)=[.4,0,0,0,.25,.25,.1]; elseif t < 5 % btwn 10am-5pm, students in class p(1)=.2; p(2)=.2; p(5)=.2; p(6)=.2; p(7)=.2; pg(1,:)=[0,0,0,0,.4,.3,.3]; pg(2,:)=[0,0,0,0,.4,.3,.3]; pg(5,:)=[.3,.3,0,0,.2,.1,.1]; pg(6,:)=[.3,.3,0,0,.2,.1,.1]; pg(7,:)=[.3,.3,0,0,.2,.1,.1]; elseif t < 9 % btwn 5-9pm, students out of class p(1)=.2; p(2)=.2; p(3)=.2; p(4)=.1; p(5)=.2; p(6)=.05; p(7)=.05; pg(1,:)=[0,0,.3,.2,.3,.1,.1]; 30
  • 31. pg(2,:)=[0,0,.3,.2,.3,.1,.1]; pg(3,:)=[.3,.3,.1,0,.2,.05,.05]; pg(4,:)=[.3,.3,0,1,.2,.05,.05]; pg(5,:)=[.3,.3,.15,.05,.1,.05,.05]; pg(6,:)=[.3,.3,.15,.05,.1,.05,.05]; pg(7,:)=[.3,.3,.15,.05,.1,.05,.05]; elseif t<11 % btwn 9-11pm p(1)=.2; p(3)=.3; p(4)=.1; p(5)=.3; p(6)=.05; p(7)=.05; pg(1,:)=[0,0,.4,.2,.2,.1,.1]; pg(3,:)=[.1,0,.4,.2,.2,.05,.05]; pg(4,:)=[.1,0,.4,.2,.2,.05,.05]; pg(5,:)=[.1,0,.4,.2,.2,.05,.05]; pg(6,:)=[.1,0,.4,.2,.2,.05,.05]; pg(7,:)=[.1,0,.4,.2,.2,.05,.05]; else % after 11pm, mainly college students out p(3)=.5; p(4)=.2; p(5)=.2; p(6)=.05; p(7)=.05; pg(3,:)=[0,0,.4,.2,.2,.1,.1]; pg(4,:)=[0,0,.4,.2,.2,.1,.1]; pg(5,:)=[0,0,.4,.2,.2,.1,.1]; pg(6,:)=[0,0,.4,.2,.2,.1,.1]; pg(7,:)=[0,0,.4,.2,.2,.1,.1]; end r1=path(p); r2=path(pg(r1,:)); [x1,y1,z1]=getXYZone(r1); [x2,y2,z2]=getXYZone(r2); out=[x1,y1,x2,y2,z1,z2]; end 31
  • 32. %Helper function that determines the region based on a list of probabilities pp function [loc]=path(pp) rr=rand(); for i=1:length(pp) if rr<=pp(i) loc=i; break else pp(i+1)=pp(i)+pp(i+1); % cummulates probabilities end end end function [x,y,z] = getXYZone(r) % Calculates a random x and y value within a given region and returns that % x and y values and the pricing zone, z, that this point lies in scale=70.7342; % pixels per mi if r==1 % airport - zone 7 x=364; y=0; z=7; elseif r==2 % mall - zone 8 x=279; y=0; z=8; elseif r==3 % Mornell rndd=rand(); if rndd<.5 % zone 6 x=51*rand()+266; if x<281 y=33*rand()+159; else y=49*rand()+159; end z=6; else % zone 5 x=53*rand()+264; 32
  • 33. y=72*rand()+87; z=5; end elseif r==4 % Mythical College - zone 10 x=15*rand()+201; y=34*rand()+252; z=10; elseif r==5 % downtown Mythical rndd=rand(); if rndd<.5 % zone 4 y=49*rand()+159; if y>192 x=75*rand()+206; else x=60*rand()+206; end z=4; else % zone 3 y=72*rand()+87; x=58*rand()+206; z=3; end elseif r==6 % City of Mythical rndd=rand(); if rndd<.5 % zone 1 y=119*rand()+40; if y<87 x=68*rand()+168; else x=61*rand()+145; end z=1; else % zone 2 x=61*rand()+145; if x<161 y=50*rand()+159; else y=77*rand()+159; end 33
  • 34. z=2; end elseif r==7 % Town of Mythical - zone 9 rndd=rand(); if rndd<.4 x=145*rand(); y=365*rand(); elseif rndd<.7 k=0; while k==0 x=157*rand()+145; y=157*rand()+208; if x<161 || x>206 || y>236 k=1; end end elseif rndd<.9 x=85*rand()+317; y=365*rand(); else x=81*rand()+236; y=87*rand(); end z=9; end x=x/scale; y=y/scale; end function [t,d] = travelTime(x1,y1,x2,y2,b_f) %This function calculates the time it takes to travel between two %points. Eventually, we can update this to be more accurate. v = 25/60; %Velocity X = [x1 y1 ; x2 y2]; if b_f 34
  • 35. d = abs(x2-x1) + abs(y2-y1); else d = pdist(X,ā€™euclideanā€™); end t = d/v; end function [p_fixed,p_variable] = pricing(d,mile_price,z1,z2) %This function returns two prices for a cab trip. The first method uses %the coordinates of the start and end point to find the distance PF = [4.6 5.1 5.1 5.1 5.6 5.6 10 10 15 15.5; 5.1 4.6 5.1 5.1 5.6 5.6 12 12 15 15.5; 5.1 5.1 4.6 5.1 5.1 5.1 16 11.5 13 9.5; 5.1 5.1 5.1 4.6 5.1 5.1 16 11.5 13 9.5; 5.6 5.6 5.1 5.1 4.6 5.1 16 11.5 13 10.5; 5.6 5.6 5.1 5.1 5.1 4.6 16 11.5 13 10.5; 10 12 16 16 16 16 0 16 18 18; 10 12 11.5 11.5 11.5 11.5 0 16 18 15; 15 15 13 13 13 13 18 18 13 15; 15.5 15.5 9.5 9.5 10.5 10.5 18 15 15 5]; p_variable = 2.5 + d*mile_price; p_fixed = PF(z1,z2); end 35
  • 36. 7.2 MATLAB code for Part 4 %Graphs the average wait time based on the market share of the two %companies. n = 20; %# of cabs N = 50; %# of trials lambda = 1.2; upper_bound = false; %false denotes euclidean distance x = []; % x-axis vector avgwait = []; % average wait time perover25 = []; % percentage wait times greater than 25min sum_perover25 = zeros(1,21); sum_avgwait = zeros(1,21); X = 2; %Price per mile for k = 1:N perover25 = []; x = []; avgwait = []; for i=1:21 x=[x i*.025-.025]; [W1,W2,P1,P2] = MythicalCabs2(i,X,upper_bound,i*.025,lambda); wait = W1; avgwait=[avgwait, mean(wait)]; over25=0; for j=1:length(wait) if wait(j)>25 over25=over25+1; end end over25=100*over25/length(wait); perover25=[perover25 over25]; end sum_avgwait = sum_avgwait + avgwait; avg_avgwait = sum_avgwait/N; 36
  • 37. sum_perover25 = sum_perover25 + perover25; avg_perover25 = sum_perover25/N; end figure bar(x,avg_avgwait); title(ā€™Average Wait vs. Market Share of Company 2ā€™); xlabel(ā€™Market Shareā€™); ylabel(ā€™Average Wait Timeā€™); line(ā€™XDataā€™, [0 .5], ā€™YDataā€™, [15 15], ā€™LineStyleā€™, ā€™-ā€™, ... ā€™LineWidthā€™, 2, ā€™Colorā€™,ā€™rā€™) axis tight figure bar(x,avg_perover25); hold on line(ā€™XDataā€™, [0 .5], ā€™YDataā€™, [10 10], ā€™LineStyleā€™, ā€™-ā€™, ... ā€™LineWidthā€™, 2, ā€™Colorā€™,ā€™rā€™) xlabel(ā€™Market Shareā€™); ylabel(ā€™% of Wait Times Greater Than 25minā€™); title(ā€™% of Wait Times Greater Than 25min vs. Market Share of Company 2ā€™); axis tight function [W1,W2,P1,P2] = MythicalCabs2(n,X,bound_flag,market_share,lambda) %The following script simulates the movement of cabs around the city of %Mythical in order to determine the wait times of customers. %If bound_flag is false, use the straight line distance between points %to find the lower bound for the number of cabs. %If bound_flag is true, use the right angle distance between two points %to find the upper bound for the number of cabs. t_stop = 24*60; %The length of the simulation in minutes %The following array holds the information about the position of the cabs, %as well as the remaining time that they are unavailable (for companies %one and two) C1 = zeros(n-ceil(n*market_share),3); C2 = zeros(ceil(n*market_share),3); 37
  • 38. W1 = []; %This vector contains the wait times for all filled orders W2 = []; O1 = []; %The initially empty vector of orders O2 = []; P1 = [;]; %The initially empty revenue vector P2 = [;]; %Fill in the array C1 with random starting positions, and a current time %unavailable of 1 for i = 1:length(C1(:,1)) C1(i,1) = rand(1)*5.6832; C1(i,2) = rand(1)*5.1602; C1(i,3) = 1; end for i = 1:length(C2(:,1)) C2(i,1) = rand(1)*5.6832; C2(i,2) = rand(1)*5.1602; C2(i,3) = 1; end %Main simulation loop for t = 1:t_stop C1(:,3) = C1(:,3)-1; %Each cab has one less minute until available C2(:,3) = C2(:,3)-1; %Generate the list of new orders (O) for this time step, return as a %vector of with width 5 (x1,y1,x2,y2,t) %Concatenate this vector with the vector of remaining orders [new_O1,new_O2] = orders2(t,market_share,lambda); O1 = [O1 ; new_O1]; O2 = [O2 ; new_O2]; %The following vector is the list of indeces for available cabs for %the current time step. If i is in A, then C(i) is available A1 = []; A2 = []; 38
  • 39. j = 1; for i = 1:length(C1(:,1)) if C1(i,3) <= 0 %If the cab is available A1(j) = i; %Store the index in a temp array T j = j + 1; %Increment j end end j = 1; for i = 1:length(C2(:,1)) if C2(i,3) <= 0 %If the cab is available A2(j) = i; %Store the index in a temp array T j = j + 1; %Increment j end end %Get the updated C and O vectors after filling orders during this time %step. Also get the wait times for filling the orders. if ~isempty(A1) && ~isempty(O1) [C1,O1,temp_W,temp_P] = fillOrders(t,A1,C1,O1,X,bound_flag); P1 = [P1 temp_P]; W1 = [W1 temp_W]; %Add the new wait times to the current list end if ~isempty(A2) && ~isempty(O2) [C2,O2,temp_W,temp_P] = fillOrders(t,A2,C2,O2,X,bound_flag); P2 = [P2 temp_P]; W2 = [W2 temp_W]; %Add the new wait times to the current list end end end function [O1,O2] = orders2(t,market_share,lambda) current_hr = t/60; % converts t into hours factor = [1.5, .5, 2]; % determines percent increase or decrease of opm 39
  • 40. O1 = []; O2 = []; % this block of code varies the orders per minute based on % the time of day i.e. hour 0 is midnight, 1 is 1 AM, 2 is 2 AM % etc... so hour 24 corresponds to midnight of next day if current_hr <= 2 % set prob of starting location being cornell or IC to be % a higher probability. % set prob of ending location being somewhere on either of those % campuses to be high prob...ie most trips should be a short % distance (downtown,cornell; downtown, ic; cornell, cornell; etc) randOrder = poissrnd(factor(1)*lambda); if randOrder <= 0 % if 0 orders this minute, set O to empty O = []; return; % if randOrder = 0, that means 0 orders in this minute so % return to MythicalCabs and go to next time step end O = zeros(randOrder,7); for i = 1:randOrder position = location(t); O(i,1) = position(1); % starting x-coord of order O(i,2) = position(2); % starting y-coord O(i,3) = position(3); % ending x-coord O(i,4) = position(4); % ending y-coord; O(i,5) = t; % time order placed (in mins) O(i,6) = position(5); % beginning region of order O(i,7) = position(6); % ending region of order end elseif current_hr <= 6 % Decrease orders per minute, i.e. there will be significantly % less orders between 2 AM and 6 AM randOrder = poissrnd(factor(2)*lambda); 40
  • 41. if randOrder <= 0 % if 0 orders this minute, set O to empty O = []; return; % if randOrder = 0, that means 0 orders in this minute so % return to MythicalCabs and go to next time step end O = zeros(randOrder,7); for i = 1:randOrder position = location(t); O(i,1) = position(1); O(i,2) = position(2); O(i,3) = position(3); O(i,4) = position(4); O(i,5) = t; O(i,6) = position(5); O(i,7) = position(6); end elseif current_hr <= 16 % Orders per minute should be higher than 2 AM - 6 AM but lower % than 4 PM to midnight % prob of starting and ending location being the mall or airport % should be much higher for this time interval randOrder = poissrnd(lambda); if randOrder <= 0 % if 0 orders this minute, set O to empty O = []; return; % if randOrder = 0, that means 0 orders in this minute so % return to MythicalCabs and go to next time step end O = zeros(randOrder,7); for i = 1:randOrder position = location(t); O(i,1) = position(1); O(i,2) = position(2); 41
  • 42. O(i,3) = position(3); O(i,4) = position(4); O(i,5) = t; O(i,6) = position(5); O(i,7) = position(6); end elseif current_hr <= 20 % Orders per minute should be higher than 6 AM - 4 PM but slightly % lower than 8 PM - Midnight % prob of starting and ending location being mall or airport % should be lower than for the 6 AM - 4 PM time interval randOrder = poissrnd(factor(1)*lambda); if randOrder <= 0 % if 0 orders this minute, set O to empty O = []; return; % if randOrder = 0, that means 0 orders in this minute so % return to MythicalCabs and go to next time step end O = zeros(randOrder,7); for i = 1:randOrder position = location(t); O(i,1) = position(1); O(i,2) = position(2); O(i,3) = position(3); O(i,4) = position(4); O(i,5) = t; O(i,6) = position(5); O(i,7) = position(6); end elseif current_hr <=24 % Orders per minute should be highest for this time interval % starting and ending locations probabilities should be higher % for collegetown, IC, downtown, i.e. trips should be shorter % (not as many cabs going to/coming from the mall) 42
  • 43. randOrder = poissrnd(factor(3)*lambda); if randOrder <= 0 % if 0 orders this minute, set O to empty O = []; return; % if randOrder = 0, that means 0 orders in this minute so % return to MythicalCabs and go to next time step end O = zeros(randOrder,7); for i = 1:randOrder position = location(t); O(i,1) = position(1); O(i,2) = position(2); O(i,3) = position(3); O(i,4) = position(4); O(i,5) = t; O(i,6) = position(5); O(i,7) = position(6); end end for i = 1:randOrder if rand(1) <= market_share && O(i,6) <= 6 && O(i,7) <= 6 O2 = [O2 ; O(i,:)]; else O1 = [O1 ; O(i,:)]; end end end 43
  • 44. References [1] ā€Maps - Town of Ithaca.ā€ Maps - Town of Ithaca. N.p., n.d. Web. 17 Nov. 2013. [2] Austin, Drew, and P. Christopher Zegras. ā€The Taxicab as Public Transportation in Boston.ā€ Transport Chicago. N.p., n.d. Web. 17 Nov. 2013. [3] ā€Ithaca Tompkins Regional Airport Flight Schedule.ā€ OMNITRANS. N.p., n.d. Web. 17 Nov. 2013. [4] ā€Center Hours.ā€ The Shops at Ithaca Mall. N.p., n.d. Web. 17 Nov. 2013. [5] ā€City of Ithaca Zones and Pricing.ā€ Ithaca Dispatch, Inc. (City of Ithaca Fares). N.p., n.d. Web. 17 Nov. 2013. [6] ā€MapQuest Maps - Driving Directions - Map.ā€ MapQuest Maps - Driving Directions - Map. N.p., n.d. Web. 17 Nov. 2013. 44