Solving Flight Rebooking Challenge With and Without Programming Constructs

DMCommunity.orgFlightRebookingImage announced its Challenge “Rebooking Passengers from Cancelled Flights” in Oct-2016 and until now 4 different solutions have been submitted. It is a relatively complex use case for decision modeling. In this post I will describe different implementation approaches for this challenge and will discuss good and not so good DMN constructs used to support the underlying decisioning logic. I hope this post will initiate more discussions which may lead to the future DMN improvements by replacing the existing programming constructs to more business-friendly representations.

Here is the “business” problem:

A flight was cancelled and we need to re-book passengers to other flights considering their frequent flyer status, miles, and seat availability. How the re-booking logic can be formulated by a subject matter expert?

Probably using plain English similar to this one:

First, order all passengers using their GOLD, SILVER or BRONZE status. If two passengers have the same status use miles as a tiebreaker. Then, choose the first passenger from the sorted list and try to find a suitable flight for this passenger. A “suitable” flight should have the same departure and arrival airports as the cancelled flight and it also should still have an available seat. If there are two suitable flights, choose the one with an earlier departure time. Do the same for the second passenger from the sorted list, then for the third passenger, etc.

While it is sounds like a quite clear description of the “business logic”,  its representation as an executable decision model is not a simple task. Really, you need to sort lists of passengers and flights,  use tiebreakers, iterate through passenger and flight lists while controlling seat availability. No wonder that well-known DMN experts selected this challenge to demonstrate the most complex DMN constructs. Please take a closer look at the complete, working solutions provided by Bruce Silver and Edson Tirelli. Here I will reproduce only a fragment from Bruce’s DMN-based solution:

Edson’s solution is using similar logic and DMN constructs but looks somewhat different:

Whether you like these solutions or not, the important fact is that they both work and produce correct results. Being an experienced software developer myself, I can appreciate how they use typical programming constructs such as:

  • if-then-else statements and for-loops
  • functions with formal parameters
  • filters
  • dynamically built lists
  • elegant sorting facilities and
  • even a hidden recursion.

At the same time, I have to admit that it took me several reads to understand how these DMN FEEL Level 3 constructions might work. Probably most of us would not even dare to show these “not so business friendly” DMN examples to potential business users unless someone wants to discredit the young standard. But what do software developers think about them?

For example, one of OpenRules developers was very upset with both these solutions. I told him: “It is easy to criticize someone’s solution, but your critique should be constructive. Could you offer a better solution in OpenRules?” Instead, he quickly submitted his pure Java solution to the DMCommunity Challenge. I had to admit that it did look simpler to compare with above DMN-based solutions. The business rules approach always has to fight against pure Java solutions, and in this case my defense of the DMN-based solutions sounded like this:

At the very least you don’t want to hard-code in Java such business logic as comparison of passengers. Look how nicely Edson presented the comparison logic in this decision table:

If a customer decides to add more comparison criteria like ‘US Veteran’ or ‘Passenger traveling with a child’, one can naturally extend this decision table but multiple embedded IF-THEN-ELSE statements in your Java code would look ugly.”

He responded: “In this case keep the passenger comparison logic in a decision table but use basic Java instead of this strange programming language to represent above algorithms.”

So, I decided to try my own implementation of this Challenge. Finally, last week I found time to do it using our latest OpenRules DMN-implementation. I started with a pure passengers sorting decision model and then I expanded it to the complete flight re-booking decision model.

My challenge was to avoid using complex DMN programming constructs while trying to stay as close as possible to the commonly used DMN decision tables.

I would not say that I am satisfied with what I managed to do so far. However, I decided to share my current implementation with the readers and let them decide if I am at least moving in the right direction.  So, be patient and follow my explanations below.

============ OpenRules-based Implementation  =============

DRD

My objective was to build a decision model called “DecisionFlightRebooking” which on the top-level can be described using the following Decision Requirement Diagram (DRD):

FlightRebookingDRD

Java Classes

To deal with this problem, we will need two arrays Passengers and Flights, which I decided to present in the Java class Problem:

I also added two Java beans Passenger and Flight that extend the standard OpenRules class ComparableDecisionVariable: 

public class Passenger extends ComparableDecisionVariable {
    String name;
    String status;
    int miles;
    // Getters and Setters
}

public class Flight extends ComparableDecisionVariable {
    String number;
    String from;
    String to;
    Date departureTime;
    Date arrivaTime;
    int capacity;
    String status;
    boolean suitable; // for a particular passenger
    int flightScore;
    // Getters and Setters
}

High-Level Decision

On the very high level we can define the decision table “DetermineFlightRebooking” the unconditionally execute two actions:

FlightRebookingDetermine

The first action will sort all passengers and the second action will iterate over already sorted passengers and rebook them one by one.

Sorting Passengers

The ActionSort will use the following passenger comparison decision table “ComparePassengers” (that it is very similar to the Edson’s decision table above):

This table will be used to compare any two passengers: a passenger with the higher score has a preference during sorting. Here the elements of the array “Passengers” have type “Passenger”.

Rebooking One Passenger

The second action of the high-level decision table “DetermineFlightRebooking” will iterate over already sorted array of “Passengers” and rebook them one by one by executing the rules “RebookOnePassenger”.  In plain English it should do the following for each considered passenger:

  1. Evaluate all flights by marking them as suitable or not for this passenger
  2. Sort all flights for this passenger
  3. Select the very first flight from the sorted list of flights
  4. If it is suitable, assign it as a new flight to the considered passenger and decrement the remaining capacity of this flight. If it is not suitable, this passenger cannot be re-booked (a new flight is “?”).

This logic can be represented in the following decision table:

FlightRebookingOnePassenger

The first action iterates over the array “Passenger Flights” applying to each flight the following rules:

FlightRebookingFlightSuitability

The second action sorts “Passenger Flights” by every two flights using the following decision table:

This table uses comparison operators such as “< time” to compare Flight 1 Arrival with Flight 2 Arrival. Here we added the word “time” to the operators because by default the operators “<“, “>”, and “=” compare dates without considering time, but in this particular case arrival time is also important.

After flights are sorted, the very first flight is the one, which we want to assign to the current passenger. So, the third action iterates over the array “Passenger Flights” applying to each flight the following rules:

FlightRebookingAssignNewFlight

Only the first flight will be assigned (of course if it is suitable) and Flight Capacity for this flight will be decremented by removing an assigned seat.

Glossary

To make it all work, I needed to add more business concepts and decision variables to the table Glossary:

When I ran this decision model, I received the expected results:

==== Rebooked Passengers
Passenger [name=Jenny, status=GOLD, miles=500000, flight=UA123] - rebooked to UA456
Passenger [name=Harry, status=GOLD, miles=100000, flight=UA123] - rebooked to UA456
Passenger [name=Igor, status=GOLD, miles=50000, flight=UA123] - rebooked to UA789
Passenger [name=Dick, status=SILVER, miles=100, flight=UA123] - rebooked to UA789
Passenger [name=Tom, status=BRONZE, miles=10, flight=UA123] - rebooked to ?

Conclusion. I believe that the described implementation demonstrates that it is possible to implement even quite complex decision logic using the basic DMN-like decision tables and to avoid complex programming constructs currently included in the DMN FEEL. Hopefully, future DMN releases will find better solutions while avoiding programming.

2 comments on “Solving Flight Rebooking Challenge With and Without Programming Constructs

  1. Jacob,

    While I value the discussion you are raising, I think there are a few misconceptions in your article. Here are my thoughts:

    * the perceived complexity you mention does not come from the language itself, but from the problem. Real world problems are not trivial. The alternative solutions presented in the article are not “removing” what you call “programming constructs”, they are just moving them from the decision model to Java or OpenRules API. The same constructs are still there, but now instead of being in single model, they are spread between decision tables, java code and product APIs.

    * the solutions are not mutually exclusive. The choice of using one tool or another should be driven by requirements (functional or not). If this decision needs to be implemented into a java program one is free to use a java solution. But if one is delivering this decision as a service into a Decision Management platform, that is self-contained and dynamic, the ability to do so all in DMN is a great benefit.

    * DMN defines several compliance levels as you know. If OpenRules is happy to provide compliance level 2 and direct customers to use java whenever they need to go beyond DMN level 2 capabilities, there is nothing wrong about it. It is a perfectly valid choice. Having said that, the additional language expressiveness that compliance level 3 brings is important for those that want to take a different approach, sticking to a known standard. We should not scrap one in favour of another. Both level 2 and level 3 have their place.

    * You said: “Probably most of us would not even dare to show these “not so business friendly” DMN examples to potential business users unless someone wants to discredit the young standard”. Isn’t this a bit of FUD? 🙂 Customer/user’s skill is a continuum, not a binary attribute: some users might be comfortable with diagrams only, while others might be comfortable with excel macros, and everything in between. Some might be happy to stick with compliance level 1-2, while others will appreciate level 3. Nothing wrong with that either.

    Anyway, just wanted to share a different perspective here.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.