The Line of Least Resistance
Contents
Project Overview
Research has shown that many of the typical methods for queueing customers are incredibly inefficient [1]. Many businesses choose to use reservation systems, for many reasons, such as space limitations in their waiting areas, preparation for large parties, and because the first-come, first-serve process is proven to be inefficient. We aim to create a mobile app that customers of three sample restaurants (and time permitting, other businesses like tourist attractions) can download and input their name, party size, and desired reservation time and receive a time to arrive in order to be attended to. The goal is to minimize delay time/maximize predictability because businesses like restaurants, tourist attractions, etc. are meant to be enjoyable, and being given an accurate wait time contributes towards a pleasant experience.
Team Members
- Devon Essick
- Andrew Sweren
- Kjartan Brownell (TA)
Objectives
- Create a mobile application (iOS) that mirrors what a potential customer of a business could download to "make a reservation" at a business. The app will be simple with an intuitive user interface for those who might not be tech-savvy, and will only require that the user selects which business they want to make a reservation for from a list of three (a small restaurant, a tourist attraction, and a large restaurant), and input their name, group size, and desired reservation time from pre-determined time slots (e.g. 7pm, 7:30pm, 8pm). On the other side, there will be a server (obtained through Amazon Cloud) where the host can input "current conditions" in the business. Once the user submits their information, this data will be analyzed through an algorithm on when they can next be server, and the information will be sent back to the app and the closest available time to their selection will be displayed. We will code with Swift, Apple's programming language, and create a code that when given the user's inputs, and when taken into account the "current situation" at the businesses, will determine a time that the user should arrive in order to be seated. Each time someone submits information, this reservation will be taken into account for the next time sometime submits a reservation, until we reset the conditions back to original.
- Create multiple "sample" situations for the reservations to be based off of (e.g. a restaurant open from 5pm to 10pm, with 10 tables of various seating capacities)
- Time permitting: Create a representation of what the host would "see" based on new reservation information inside the app (e.g. once a 3-person group reserves a table for 8pm, we see how full the restaurant is)
- Time permitting: add additional features linking the app to other iOS Apps, such as putting the reservation or location in Calendar or Apple Maps
Challenges
- Learning how to create a mobile app, and learning Swift programming language
- Coding the system that determines when a customer should arrive
- Creating an approachable and intuitive mobile app user interface for people with no experience to use
- Utilizing and coding onto the server
- Making sure we take into account important inputs about a given business so that the recommendations are realistic (e.g. understanding even if there are 2 two-person slots available at a given time, a group of four will not split up)
- Taking into account that even if there is a reservation system in place, people are bound to still show up unannounced, and what the impact on the business could be to turn them away
- Accounting for changes disrupting the way the business operates (e.g. making the business only accessible by reservations could change the type of customers, or making reservations only accessible via mobile app could exclude an older generation)
- Taking into account that people may make reservations and not show up, which may disrupt the system
- Making the app reliable (understanding that introducing the app to a business when it does not give accurate times could mean customers do not return)
Budget
- Device with iOS (provided by team members)- $0
- Coding software (provided by school) - $0
- Amazon Cloud server (90 day trial) - $0
Total: $0
Gantt Chart
Design and Solutions
The app was designed to take five distinct steps, starting and ending with the user interface:
- Customers go into the app and choose their restaurant and enter their information (group name, group size, earliest available time and latest available time) and press submit
- Code places the reservation info in queue and determines expected time
- Server takes in reservation
- Code determines if there is an available time within the desired time range
- Customers receive their reservation status in the app
User Interface
- The UI for ReserveNow, the app, was created on Xcode, Apple's app development software, using Swift programming language
- There were View Controllers (i.e. screens on the app) to input reservation info for each restaurant, and for menus of each restaurant
- Three fictitious restaurants were created (Higgins Restaurant, Killer Burger, and Donna's Dumplings)
- Most of the interface was created programmatically, and some was created using the "Utilities" bar, which allows you to make changes like font size without writing a line of code
- The reservation info was put in JSON format to be easily passed onto the algorithm
- The code called upon Amazon Web Services' Cloud Logic Lambda functions
- Customers receive a notification for whether their reservation was successful or not, and what time within their time frame it is for
Algorithm
- Was written in Java
- Had two main parts:
- The code for all the custom objects and their respective methods
- The Lambda function that sends information to the app
- Custom objects were Time (customized because the Time object from Java library did not fit well with the algorithm), Restaurant, and Reservation
- The major methods were in the Restaurant object:
- Increase (a helper method for all others)
- Reserve
- Seat (which ended up being unimplemented)
- Cancel
- Most of the other methods were used to retrieve information about the restaurants and reservations
- Errors were immediately sent back to the UI if the information had been entered incorrectly (e.g. size not an integer value, latest available time entered as earlier than the earliest available time, etc)
The main steps of the algorithm:
- Reservation object is created
- Reserve method is called on reservation in Lambda function. This method places it in the respective queue (corresponding to Restaurant and size)
- Within the reserve method the increase method is called. This compares the reservation to a previous reservation in the queue (number of spaces back is the number of tables of the desired size in the desired restaurant). This updates the expected time
- If the expected time is within the time frame specified by the user, he or she will receive a message saying that the reservation was successful. Otherwise the reservation will be automatically cancelled and the user will get a message saying the reservation was automatically cancelled
The increase method, which was used as a helper method to make sure all the expected times were right in multiple other methods:
// int i represents the place in the queue, int s represents the size of the reservation
public void increase(int i, int s) {
Reservation[] party;
int n;
// based on the size of the reservation, the appropriate queue and number of tables is referenced.
switch(s) {
case 1:
party = this.one;
n = this.num1;
break;
//repeat for case 2-10
default: return;
}
// if statement representing a case where the reservation represents a party that is currenty seated.
if (i < n) {
switch(s) {
case 1:
this.one = party;
this.num1 = n;
break;
//repeat for case 2-10
default: return;
}
return;
}
// if statement representing a case where the party referenced does not exist.
if (party[i] == null) {
switch(s) {
case 1:
this.one = party;
this.num1 = n;
break;
//repeat for case 2-10
default: return;
}
return;
}
else {
// Time object used to reference the expected time of the reservation "above" (see note below) the referenced one.
Time t = new Time(party[i-n].expected.getHours(),party[i-n].expected.getMinutes());
// Changes the time to be at least the average time spent in the restaurant later than the expected time of the reservation above it.
t.changeMinutes(this.avg);
// Sets the target reservation to be the later of its desired early time, and the average time spent in the restaurant after the expected time of the reservation above it.
party[i].changeExpectedTime(t);
// if statement if the reservation "below" is null
if (party[i+n] == null) {
switch(s) {
case 1:
this.one = party;
this.num1 = n;
break;
//repeat for case 2-10
default: return;
}
return;
}
else {
// if there is a reservation below the one targeted, the increase method is called on it.
increase(i+n,s);
}
}
}
Note: each queue is represented by a Reservation array. While one dimensional, they are treated as two dimensional, with each row having a length of the number of tables in the specified restaurant at the specified size.
Server
- Two custom objects (Reservation and Restaurant) are included to represent each restaurant and reservations in its system
- Each reservation object has “name”, three “times” (early, late, and expected), “size”, and “restaurant".
- Each restaurant object has opening and closing time, name, and ten of each of the following: arrays of reservations, integers to represent number of tables and number of reservations in a queue
- Each restaurant has ten queues corresponding to different reservation sizes which are represented by an array of reservation objects of length 1000
Results and Analysis
User Interface
The UI ended up where we wanted it to be, but due to other issues, we didn't have time to add extra features to it. For example, at the beginning of the semester we wanted to add a feature where restaurants could log in through a User Identity feature and see a more attractive interface of current reservations, rather than having to see them through the Amazon Web Services server. We also wanted to do the other "time permitting" objective of linking the app to other iOS Apps. But these proved to be too complicated to implement. A huge issue we faced was the fact that AWS changed their whole protocol for calling functions from Xcode in the middle of the semester. We had figured out how to call them before the second Project Evaluation, but almost right after, they changed it to a much more sophisticated process that was a lot harder to interpret and adapt to our code. Luckily, we figured out a way to trick the system into using an old Lambda function instead of the new APIs, but it took up a lot of valuable time we could have been using to improve the features of the app.
Algorithm
The algorithm, in and of itself, worked to its full purpose. We were able to get the algorithm to accurately calculate expected times based on when people had previously made reservations. We were also able to get it to constantly update the times each time someone was seated and do so in an accurate manner. Additionally, the algorithm was able to send all the necessary information to the server.
We would have liked for each reservation made to come with an approval request. From there, the restaurant could choose to approve, reject, or resize the reservation (e.g. combining two tables of 2 to make a table of 4). However, that proved to be harder than it appeared. The reason for this was because the two reservations had to be kept together. With the algorithm being set up to handle each reservation one at a time, it would have required writing special cases for if two reservations were connected. The other option was to change the number of tables for each size. This, however, would have potentially caused some people's expected times to drastically change. Furthermore, the restaurant would have to do it manually, as it would only be for a specific time when the number of tables for a certain size is different.
Server
While we did have a working algorithm and were able to integrate the app with the server, we were not able to have the app perform all of its features. We were able to have a person make the reservation and see that it was successful, essentially allowing a customer to send information to the restaurant, but the restaurant cannot do anything afterwards. There are a few reasons for this failure. One of them is due to the limitations of the Amazon databases. Because the algorithm used custom Java objects, the Amazon server was not able to recognize them unless they were broken up into parts. This made it extremely difficult to keep track of every queue that the reservation in.
Overall
We had a lot of trouble settling on exactly what we wanted to achieve with the project, and didn't fully understand what we were going to do until after the first Project Evaluation. Even then, we were going into completely uncharted territory because none of us had experience with building an app, and so we weren't sure actually how much we could expect to achieve in a relatively short amount of time. Luckily, everything came together in the end, we were able to get the algorithm completely integrated with the server. Although we wish we achieved more, and got to add features mentioned in our proposal, we integrated three separate components and created a working app, and met our main objectives.