 Hi, I'm Jeffrey de Smit. I'm going to show you how to optimize vaccination appointment scheduling with our open source AI software. This will include dealing with challenges such as injecting the second dose in time, dealing with age restrictions, respecting vaccination center capacity and of course minimizing the travel distance for the people who need to get vaccinated. This is what we need to create a vaccinations schedule. In this case we're signing Zara to get a vaccination on Monday the 8th of February at 9 o'clock. Otto gets one at 9.30, Noah gets one at 10 o'clock and so forth. As you can see we're scheduling not just Mondays but also Tuesday, Wednesday, Thursday and Friday. In this case the planning window is only five days. We can inject in three different vaccination centers and we have five lines in there in total. The first vaccination center alpha has three lines, line 0, 1 and 2. The beta vaccination center just has one line and the gamma center also just has one line. That means we can actually inject five people in parallel as we are doing here. You can see that Ray is getting his vaccination at the same time as Zara do and these three other people. We have three vaccination types up to now and of course more are coming. Right now we have the Pfizer, the Moderna and AstraZeneca vaccines being injected. We want to make sure that people live close by their vaccination center. Here the circles are where the people live and you can see the three big vaccination centers here. The top right one is a big one and the other two are smaller. The top right one has three lines while the other two just have one line. You can see that also means that the top right one gets far more people assigned to it. This has a side effect that people who live over here are actually technically closer to the top bottom vaccination center. We actually want to get them injected into the big one because that's more efficient for everybody. There might also be far more people to inject than we have doses of these vaccines. We might actually have some people who are not assigned to an appointment. Of course we want to make sure these are the young people because we want to prioritize the elderly first. What are our goals? Our main goal is of course to end this pandemic as quickly as possible and to reopen the pubs. How do we do that? We do that by maximizing the vaccination throughput. That means we don't want to waste vaccines. If we open a Pfizer bottle that contains six doses, we have four hours to inject those six doses into people. We want to cluster, especially for the Pfizer case, the vaccinations together such that we don't waste vaccines. We want to keep in mind the vaccination center capacity, how many people we can vaccinate at the same time, how many dosages of each vaccine they have available at a particular date based on their dosages which are coming in and so forth. We want to take into account the fact that for most vaccines people need a second shot. That second shot needs to be the same vaccine. If we injected somebody with Pfizer the first time, the second shot needs to be Pfizer again. We cannot switch vaccine types there. We want to do that particular days later. For example, in the Pfizer vaccine that's 21 days later, in the Moderna vaccine that's 28 days later, that's the ideal time to actually deliver that second shot. We want to prioritize the elderly and priority groups. This might differ from country to country or from region to region. Whatever the case, whatever the government decides to do there, we want to make sure we respect those rules. We want to minimize the driving distance for all of the people to get to those vaccination centers. There's basically two techniques to do this. One is the ticketmaster approach and the other is the central allocation approach. In the ticketmaster approach, the user goes to an application and picks her favorite or his favorite appointment. In the central allocation approach, we give them an appointment with our scheduler. The ticketmaster approach, even though it seems quite user-friendly, has a few major challenges. One is there's a high concurrency on a few spots. Literally thousands of people who want maybe a handful of spots on that Monday morning shot to get that shot as quickly as possible. While they're looking at the spot, you need to log the spot. Because you don't want to get them to go through a wizard and in the end they don't actually get their spot because it's already booked by somebody else. So it's far more difficult than selling concert tickets because every spot is unique and the ratio of people who want the spot versus the number of spots available is far more detrimental. The second problem there is it's fair to use the first out approach because people might not have access to the website at the time that the website goes open, you can start reserving spots. In general, it's far from optimal too based on traveling distance as potentially also the second shots injections as well as the not-to-waste vaccines. So in this video I'm actually going to focus more on the central allocation approach. We have some challenges there of course too. It might be an inconvenient time, but we can actually solve that by dealing with rejections and calculations. If an appointment is rejected or canceled, we open it up again and we just reschedule it the next day before. And this is of course before a couple of days or a couple of weeks before we actually send out the schedule. And furthermore there's constraint optimization intelligence there. Let's take a look at the implementation. So for this implementation I've of course used our opto planner which is an open source AI constraint solver used across the globe for all kinds of planning problems such as the vehicle routing problem, employee rostering, maintenance scheduling, task assignment, school timetabling, timetabling and many more. I'm using this in combination with the Quarkus stack which is an open source Java stack or Kotlin stack to open for example rest interfaces and connect databases or all kinds of reactive streams and so forth. And with that I've built this application, the Quarkus opto planner vaccination schedule quick start. And let's take a look what it does. So here I have all of the injections on the sign still you can see. So we're going to assign these to these people which are not assigned to any of the injections yet. And when I click the solve button these will get assigned. Now before I do that I want you to notice that some of the constraints are already automatically implemented. So for example I'm making sure that we schedule nothing but Pfizer injections in this second line here. So that means that by pulling these by clustering these together we don't waste any Pfizer injections there. Similarly I'm taking into account the fact based upon how many dosage of each vaccine they have available at these vaccination centers. So for example on Tuesday I'm not scheduling any AstraZeneca injections because you don't have enough dosages but I am scheduling two lines of Moderna because they have enough dosages for that. That's pretty straightforward. You simply look at what's available in Stockholm or it's going to be available in Stockholm that particular day and that's what you create injection spots for. As you see we don't have any people assigned to these yet. Now for now I've just enabled one constraint and that's to make sure that each person gets assigned to exactly one injection. This is a five-day planning schedule so there's no need to inject one person twice in this planning window. It's too short for that. When I click the solve button which I do right now I see that Optiplanar starts scheduling and starts assigning these people into these shots. Now like I've said I've just enabled only one of the constraints. You can see a couple of issues here already. The first one being that for example here Sue gets her second shot but her first shot was Moderna. Now the second shot is actually Pfizer as you can see so that's a really bad idea. Let's take a look at how we can actually fix that. What we're going to do is we're going to go through the constraints which I've written here in Java. Again you can also write them in Kotlin or in other languages that run into the GVM. I'm going to here enable the second shot invalid vaccine constraint which is just making sure that the second shot is the same as the first shot. We actually have a filter in case. It's not the case. Let's take a look here. Let's refresh this. Here we go. We can see all of them are on the signs. We solve this and this time we actually get a schedule where let's take a look here. We don't have anybody who's like Sue who actually gets the shot of the same one as she was the first time. Here I think this was Sue, her second shot. She had her first shot was Moderna, her second shot is also Moderna. There's no errors popping up here. One thing we do notice is that in many cases it might be too soon. Like in here in her case it's three days too soon. Here it's two days too early. Sometimes it might be a few days too late like this one, one day too late and so forth. What are we going to do is we're going to go back to our constraints and we're going to first of all make sure that the second shots are... Well, let's first put them on the ideal date. Make sure they're on the ideal date. We do this. At the same time let's also make sure that the second shots are assigned. As I've said earlier, if you actually look at the signed here, we might actually have second shots which are not assigned. These get a priority. It's even more a higher priority than actually age in most cases because we need to close down those people who have had their first shot. If in this planning window they need to get their second shot, let's make sure that happens. So I'm going to enable this constraint too. So the second shots must be assigned and we want to aim them at the ideal date. So when we do a refresh and we start solving this, what we'll see now is that, again, each person is just assigned to one injection as before, but also on top of that we have... Let me look at the end assigned. We don't see anybody with a second shot anymore. So all the second shutters are actually assigned to an injection. We get prioritized over the first shutters, basically. And we also get far more of them being on the ideal date. So most of these second shots, as you can see, are on the ideal. We still have a couple of cases where we can't actually do that. And you see if we give opt-in a bit more time, it's finding better and better schedules until we stop solving to not do that. In this case we still have 72 days where it's actually not the case that we deviate from the ideal date, but in most of the cases we can actually do that. Why is that? Well, because if the ideal date for, let's say in AstraZeneca, what would be on Tuesday, there is no way we can get that second shot happening on Tuesday because we simply don't have any inject... We don't plan to do any injections of AstraZeneca on this date, right? So there might be circumstances why you cannot do this. Okay, let's go back to our constraints and let's add one more. Yeah, if you look at the assigned people, we can see some elderly people still here, the 78 years old, 60 years old. While at the same time we have in our schedule, we have people of much younger ages here, 23 being assigned. It's not a good thing. Or that's not something we want. So let's enable this constraint. Make sure that all the older people are assigned. Okay, and of course keep this one in there. So when we do refresh, everything is assigned. We start solving again. We start from scratch again. And this time, OPTIPAN will take care that he assigns the elderly people first. You can see it's still working through it. This is the medium constraint. But if we look through the unassigned now, what you will see is these are typically younger people. We don't see anybody anymore here above the age of 40 or something like that. And that's simply because he's making sure that these people are still assigned. You can still see some exceptions. If you give him more time to solve, he will fix this too. So we might actually still have a moment ago, I saw a 23 year old in there. But you'll see that those will actually go away as he solves longer. Why do we still have them? Well, here, this, let's solve, stop it. Actually, this is normal. The 23 year old should be in here because it's his second shot. You won't see any young people with their first shot in here. Like go again 23, but this is his second shot. So he needs to be in there. Okay, what else do you want to do? Well, if we look at the map, we see that we're basically telling people to go from the other side of the city all the way to the center. People coming from this location going all the way to that center. That's not ideal. So we won't actually minimize the travel distance. So if we actually go to this over here and we minimize the distance cost and we add that too. We can go again. We can start solving again. And we'll see that our plan starts to get into account too. So we're taking into account that the second shots are the ideal date, are the correct vaccine and the second shots are definitely assigned. The elderly people are assigned before the younger people. And now, of course, let's take a look at the map. So if you look at the map now, we can see it's already much better. We still have a couple of exceptions. Like, oh, look, and if we give up the plan on more time, you're actually working away these. Now, this is an interesting challenge because if you say that older people need to be assigned before younger people, regardless of the distance of the vaccination centers, you might get some weird effects. Think about it. If this area is full of elderly people and you might actually start pushing them towards this vaccination center while all of the maybe just 10 years younger people over here do not get scheduled at all. So sometimes you want to do trade-offs. And with Optopheny, you can do that. You can weight this. You can say, for example, I want to treat the elderly people first, let's say one or two years, but I want to also weight that against the distance. So if the distance is more than, say, 10 kilometers, 10 miles, more than 100 kilometers, 100 miles, then I don't want, at that age difference, I want to ignore that, right? It's not a bad thing anymore. So we can add constraints like that if need be. OK. And yes, as stated before, you can clearly see that based upon the capacity of the vaccination centers, we will be sending people to not necessarily their closest location, but to the one that's best for the entire population. Like these people over here, they're being sent to that center. But in general, this will actually reduce the overall traffic time for everybody. Because if these people actually scheduled their appointments first and they all pick this lower left vaccination center, then people who actually live closer and then these people come into the system in the first-in-first-out system and they start scheduling, they'll have to go to the other vaccination center because this one is full. So we create a lot more traffic and a lot more, a lot less, not so good of a schedule as it is right now. OK. So thank you for listening. And if you want more information on OptiPlaner, please go to www.optiplanner.org.