We were approached to co-construct a system to optimize bookings in real time for an event planning company.
We built a system that maximizes the number of people at a restaurant. We also constructed a recommender system to help them accomodate customers. When a restaurant becomes full, you might want to refuse one group to be able to accept another - bigger - group at a later time. The overall result was an increase of around 20% in the number of customers.
The following image depicts a fictive restaurant with 12 tables (one per row) during a 6 hour period (each column corresponds to a 15 minutes timeslot). The blue boxes are bookings accepted by our system in real time.
The system had to take into account not only phone and online bookings but also people who show up with no reservation. Also, reservation management can be quite tricky. For instance, someone might book for a table of 6 at 7pm but in reality, only 4 people show up at 7:30pm! Moreover, you estimate that they will stay for an hour while they stay for one and a half hour!
Very soon, we realized that it was in the best interest of restaurants that fill up quickly to sometimes refuse people. We thus constructed a recommender system combining ML and OR that helped them to reschedule some groups.
A good mathematical optimization is not necessarily a good solution for our customers. Our first version of the booking system provided highly optimized solutions. See the following figure for an example.
In that solution, our system learned to fill some tables and keep some tables (tables 4 to 7) quite empty. Mathematically, this was a very good solution, especially to accommodate groups without reservation. But from the customer's perspective (as well as the restaurant employees and their clients), the solution gave the false impression that the restaurant was quite empty. We backtracked and introduced a policy to forbid tables to be empty over a certain period of time.