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

Contents summary

In the last chapter, we looked at some tips for scoring and ways to avoid the score trap. In today’s chapter we will learn how to dynamically configure constraint weights so that we can dynamically support constraints when adjusting them.

Determining the correct weight and level for each constraint is not easy. There is a priority balance between constraints. Also, quantifying the impact of soft constraints was a new experience for us, so they needed to adjust several times to find a suitable weight and level.

Provide a UI to reweight constraints and visualize the results of the solution so that you can reweight constraints yourself.

Create a constraint configuration

First, create a new class to hold the weight of the constraint and other constraint parameters. Annotate with @constraintConfiguration.

@ConstraintConfiguration
public class ConferenceConstraintConfiguration {... }Copy the code

Each PlanningSolution will have an instance of this class. PlanningSolution and ConstraintConfig have a one-to-one relationship, but they have different purposes, so they are not combined into a single class. An @constraintConfiguration class can extend a parent @constraintConfiguration class, which is useful in many cases.

Add on PlanningSolution ConstraintConfig and @ ConstraintConfigurationProvider add annotations on the field or property.

@PlanningSolution
public class ConferenceSolution {

    @ConstraintConfigurationProvider
    private ConferenceConstraintConfiguration constraintConfiguration;
    
    // HOS = Hours of service (in terms of driving regulations)
    private long hosWeekDrivingSecondsBudget = 50L * 60L * 60L;
    private int hosWeekConsecutiveDrivingDaysBudget = 7; . }Copy the code

@ ConstraintConfigurationProvider annotation automatically constraintConfiguration as a ProblemFact, so there’s no need to add @ ProblemFactProperty annotation.

The ConstraintConfiguration class holds the weights of the Constraint, but it can also hold the parameters of the Constraint. For example, in meeting scheduling, the minimum meeting interval constraint has a constraint weight (like other constraints), but it also has a constraint parameter that defines the minimum interval between two speeches by the same speaker. The length of the interval depends on the meeting: in some large meetings, 20 minutes is not enough to walk from room to room. This interval length is a field in the constraint configuration, with no @constraintweight annotation.

Constraint add weight

In the ConstraintConfiguration class, add an @constraintweight field or attribute to each constraint.

@ConstraintConfiguration(constraintPackage = "... conferencescheduling.solver")
public class ConferenceConstraintConfiguration {

    @ConstraintWeight("Speaker conflict")
    private HardMediumSoftScore speakerConflict = HardMediumSoftScore.ofHard(10);

    @ConstraintWeight("Theme track conflict")
    private HardMediumSoftScore themeTrackConflict = HardMediumSoftScore.ofSoft(10);
    @ConstraintWeight("Content conflict")
    private HardMediumSoftScore contentConflict = HardMediumSoftScore.ofSoft(100); . }Copy the code

ConstraintConfiguration must be of the same type as Score for PlanningSolution. In meeting case, for example, ConferenceSolution. GetScore () and ConferenceConstraintConfiguration getSpeakerConflict () returns HardMediumSoftScore.

A ConstraintWeight cannot be null. Each ConstraintWeight is given a default value, but can be modified in the interface to adjust them. The above example uses the ofHard()ยท, ofMedium(), and ofSoft() methods.

Each constraint has a ConstraintPackage ConstraintPackage and a ConstraintName ConstraintName, which together form the ID of the ConstraintID constraint. They associate the Weight of the constraint with the implementation of the constraint. For each ConstraintWeight, there must be a constraint implementation with the same package and the same name.

  • @ConstraintConfigurationAnnotations have oneconstraintPackageProperty, defaultConstraintConfigurationClass package. Most calculations using Drools scores need to override this because DRL uses a different package. For example, the following DRL usescom... conferencescheduling.solverPackage, so the constraint configuration above specifies oneconstraintPackage.
  • @ConstraintWeightThe annotation has a value that is the name of the constraint (for example, “Speaker conflict”). It is from@ConstraintConfigurationInherits the constraint package in, but it can override it, for example@ConstraintWeight(constraintPackage = "... region.france", ...)To use constraint packages that are different from some of the other weights.

So each ConstraintWeight ends with a ConstraintPackage and a ConstraintName. Each ConstraintWeight is associated with a constraint implementation, such as in the Drools score calculation:

package. conferencescheduling.solver; rule"Speaker conflict"
    when
        ...
    then
        scoreHolder.penalize(kcontext);
end

rule "Theme track conflict"when ... then scoreHolder.penalize(kcontext, ...) ; end rule"Content conflict"when ... then scoreHolder.penalize(kcontext, ...) ; endCopy the code

Each ConstraintWeight defines the ScoreLevel and ScoreWeight of its constraints. The implementation of the constraint calls reward() or policize(), and the weight of the constraint is automatically matched.

If the constraint implementation provides a matching weight, the MatchWeight MatchWeight is multiplied by the ConstraintWeight ConstraintWeight. For example, the content Conflict constraint weight defaults to 100soft, and the constraint implementation penalizes each match based on the number of shared content tags:

 @ConstraintWeight("Content conflict")
    private HardMediumSoftScore contentConflict = HardMediumSoftScore.ofSoft(100);
Copy the code
rule "Content conflict"
    when
        $talk1 : Talk(...)
        $talk2 : Talk(...)
    then
        scoreHolder.penalize(kcontext,
                $talk2.overlappingContentCount($talk1));
end
Copy the code

Therefore, when 2 conflicting content share only one content tag, the score is affected by -100soft. However, when 2 conflicting content share 3 content tags, the match weight is 3, so the score is affected by -300soft.

conclusion

In this chapter, we learned how to increase the weight of each constraint and how to dynamically adjust the constraint, which is very important, because in previous experience, it is very difficult to adjust the weight of the constraint, and there are often many times of adjustment, so it is very important for the constraint to support dynamic weight adjustment.

conclusion

In the next chapter, we’ll learn how to view each constraint’s score and how it is calculated.

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