One of the products born under Drools umbrella was OptaPlanner, a planning engine. You can use OptaPlanner to get solutions to planning np-problems like job scheduling or traveller salesman route. This kind of tools are, IMHO, one of the biggest advantages of the JVM over any other platform.

Wedding Tables Planner

I wanted to take a look at OptaPlanner but I didn’t view a suitable problem, so I decided to get married =D (just kidding, don’t want to get divorced even before of the wedding!). As every poor married person knows one of the most sensitive moments while you plan that day is the arrangement of the guests at the restaurant. Tables have capacity boundaries and not every guest is interchangeable: many of them are just known, some love each other and some even hate… This looks like a planning problem!

You can check out the Wedding Tables Planner at GitHub. It’s not rocket science, certainly. Since it’s a straightforward application of OptaPlanner it’s really simple. There’s a XML config file where you set some information about your model, and give OptaPlanner some hints about the way it should look for a suitable solution. In my case I set a HARD_SOFT score, which is the number it uses to compare solutions. It’s composed of a hard and a soft score (as you, smart reader, already supposed ;-) ). The hard score is the primary number to minimize. In my case it’s the following formula:

Hard score formula

Java

1

2

3

4

finalinthardScore=

configuration.tableOccupationExceedingCapacity()

+configuration.hatedRelationsInTheSameTable()

+configuration.lovedRelationsNotInTheSameTable();

As you can see, I don’t want anybody to eat on his feet (exceed table capacity), begin a fight with the knives (hated relationships in the same table), or miss the loved one(s). OptaPlanner will try to keep hardScore at 0.

OptaPlanner will try to maximize the following soft score formula:

Soft score formula

Java

1

2

3

4

finalintsoftScore=

4*configuration.closeRelationsInTheSameTable()

+2*configuration.knownRelationsInTheSameTable()

-configuration.neededTables().size();

The most important relation for me is being close, but I also want to keep as many known people together. Since I prefer nobody to be alone, I also try to keep needed tables as low as possible.

That’s pretty much the only thing you need for OptaPlanner to work. It’s launched with the following code

Offtopic: I’ve used Java 8 lambdas. It’s certainly not as clean as Scala’s, type inference is not impressive at all and you must keep NullPointerExceptions in mind, but it’s fat better than what we had to do until now:

Java 8 lambdas

1

2

3

4

5

6

7

8

9

privateSet<Guest>sharingTableGuests(finalGuest guest){

returnguests

.stream()

.filter(aGuest->aGuest.getTable()!=null)

.filter(tableGuest->!guest.equals(tableGuest))

.filter(otherGuest->otherGuest.getTable().equals(

guest.getTable()))

.collect(Collectors.toSet());

}

Wedding Tables Planner Web

The core of the solver is great and simple, but you won’t force a bride-to-be to learn Java one month before her wedding, so I developed an AngularJS + Play + Scala web (my current stack of choice). It’s not the most beautiful or usable piece of software you might’ve seen, but it does the job.

In order to be a little more confortable, the app allows you to create groups, which get translated into “known” relationships (you don’t want your implementation details to get leaked to your users!). There’s one special group, “All users”, which is always active, but clicking other groups switch auto-insertion of guests on and off.

Try deploying it on OpenShift (free java webapp cloud provisioning), so people can just try it out.https://www.openshift.com/
The free account should cover it’s needs untill it becomes a global success :)

Note this is just a JBoss AS gear that then I deploy a java WAR into, but for me who does not play in your ‘stack’ it would be fun to push your example project far and wide (evangelize) if you can make it repeatable. ;)