This is the 14th day of my participation in Gwen Challenge

Contents summary

So far, we’ve covered many of OptaPlanner’s concepts. Starting today, we’ll look at two common ways to write constraint rules scores. The others are much less scalable and easy to use, so we’ll just look at the two common ways. Today we’re going to start learning about ConstraintStream.

Constraint Stream

Constraint Stream is a functional programming method for incremental score calculations in pure Java that is easy to read, write, and debug. It’s easy to get started if you’ve ever worked with Java 8 Streams or SQL.

ConstraintStreams/ConstraintProvider API is a in development projects. It works, but it has a lot of API white space. Therefore, it is not rich enough to handle complex constraints. The content of the constraint may not perform properly, but it is usually sufficient for us.

Introduction to the

Using the Streams API of Java 8, we can implement a simple score calculation using a functional method:

    private int doNotAssignAnn(a) {
        int softScore = 0;
        schedule.getShiftList().stream()
                .filter(Shift::isEmployeeAnn)
                .forEach(shift -> {
                    softScore -= 1;
                });
        return softScore;
    }
Copy the code

However, this approach scales poorly because it doesn’t do incremental calculations. When a single Shift’s PlanningVariable ** changes, the normal Streams API must execute the entire stream from scratch in order to recalculate the score.

The ConstraintStreams API lets you write similar code in pure Java with the performance benefits of incremental fractional computation. Here is an example of the same code using the Constraint Streams API:

    private Constraint doNotAssignAnn(ConstraintFactory factory) {
        return factory.from(Shift.class)
                .filter(Shift::isEmployeeAnn)
                .penalize("Don't assign Ann", HardSoftScore.ONE_SOFT);
    }
Copy the code

This constraint flows through all the Shift class instances in ProblemFact and the PlanningEntity in the PlanningProblem **. It finds each Shift assigned to person Ann, and for each such instance (also known as a match), it adds a soft penalty of one to the total score. The following figure illustrates this process on a problem with four different shifts:

If any PlanningEntity instances change during the solution, the Constraint Stream will automatically detect the change and recalculate only the minimum necessary portion of the problem affected by the change. The following figure illustrates this incremental score calculation:

It can be seen from the figure that only 2 need to be calculated. Some people may ask that 3Feb is changed from Ann to Beth, but there is no calculation of bonus points in our incremental calculation. When we call Score to calculate the Score value again, a Listener will listen and record the matching information and the Score value. If the planning variable changes and does not match the constraint condition, the previous Score value will be backtracked.

conclusion

In this chapter, you need to understand the logic of ConstraintStream’s incremental calculation, which is critical for writing constraints.

conclusion

In the next chapter we’ll learn how to write a ConstraintStream and how to test a constraint.

Creation is not easy, unauthorized reprint is prohibited. If my article is helpful to you, please like/favorites/follow it to encourage and support 💕💕💕💕 college