Record Class ScoreAnalysis<Score_ extends Score<Score_>>

java.lang.Object
java.lang.Record
ai.timefold.solver.core.api.score.analysis.ScoreAnalysis<Score_>
Type Parameters:
Score_ -
Record Components:
constraintMap - for each constraint identified by its Constraint.getConstraintRef(), the ConstraintAnalysis that describes the impact of that constraint on the overall score. Constraints are present even if they have no matches, unless their weight is zero; zero-weight constraints are not present. Entries in the map have a stable iteration order; items are ordered first by ConstraintAnalysis.weight(), then by ConstraintAnalysis.constraintRef().

public record ScoreAnalysis<Score_ extends Score<Score_>>(@NonNull Score_ extends Score<Score_> score, @NonNull Map<ConstraintRef,ConstraintAnalysis<Score_ extends Score<Score_>>> constraintMap) extends Record
Represents the breakdown of a Score into individual ConstraintAnalysis instances, one for each constraint. Compared to ScoreExplanation, this is JSON-friendly and faster to generate.

In order to be fully serializable to JSON, MatchAnalysis instances must be serializable to JSON and that requires any implementations of ConstraintJustification to be serializable to JSON. This is the responsibility of the user.

For deserialization from JSON, the user needs to provide the deserializer themselves. This is due to the fact that, once the ScoreAnalysis is received over the wire, we no longer know which Score type or ConstraintJustification type was used. The user has all of that information in their domain model, and so they are the correct party to provide the deserializer.

Note: the constructors of this record are off-limits. We ask users to use exclusively SolutionManager.analyze(Object) to obtain instances of this record.

  • Constructor Details

    • ScoreAnalysis

      public ScoreAnalysis(@NonNull Score_ score, @NonNull Map<ConstraintRef,ConstraintAnalysis<Score_>> constraintMap)
      Creates an instance of a ScoreAnalysis record class.
      Parameters:
      score - the value for the score record component
      constraintMap - the value for the constraintMap record component
  • Method Details

    • getConstraintAnalysis

      public @Nullable ConstraintAnalysis<Score_> getConstraintAnalysis(@NonNull ConstraintRef constraintRef)
      Performs a lookup on constraintMap(). Equivalent to constraintMap().get(constraintRef).
      Returns:
      null if no constraint matches of such constraint are present
    • getConstraintAnalysis

      @Deprecated(forRemoval=true, since="1.13.0") public @Nullable ConstraintAnalysis<Score_> getConstraintAnalysis(@NonNull String constraintPackage, @NonNull String constraintName)
      Deprecated, for removal: This API element is subject to removal in a future version.
      As defined by getConstraintAnalysis(ConstraintRef) where the arguments are first composed into a singular constraint ID.
      Returns:
      null if no constraint matches of such constraint are present
    • getConstraintAnalysis

      public @Nullable ConstraintAnalysis<Score_> getConstraintAnalysis(@NonNull String constraintName)
      Returns:
      null if no constraint matches of such constraint are present
      Throws:
      IllegalStateException - if multiple constraints with the same name are present, which is possible if they are in different constraint packages. Constraint packages are deprecated, we recommend avoiding them and instead naming constraints uniquely. If you must use constraint packages, see getConstraintAnalysis(String, String) (also deprecated) and reach out to us to discuss your use case.
    • diff

      public @NonNull ScoreAnalysis<Score_> diff(@NonNull ScoreAnalysis<Score_> other)
      Compare this ScoreAnalysis to another ScoreAnalysis and retrieve the difference between them. The comparison is in the direction of this - other.

      Example: if this has a score of 100 and other has a score of 90, the returned score will be 10. If this and other were inverted, the score would have been -10. The same applies to all other properties of ScoreAnalysis.

      In order to properly diff MatchAnalysis against each other, we rely on the user implementing ConstraintJustification equality correctly. In other words, the diff will consider two justifications equal if the user says they are equal, and it expects the hash code to be consistent with equals.

      If one ScoreAnalysis provides MatchAnalysis and the other doesn't, exception is thrown. Such ScoreAnalysis instances are mutually incompatible.

    • constraintAnalyses

      public Collection<ConstraintAnalysis<Score_>> constraintAnalyses()
      Returns individual ConstraintAnalysis instances that make up this ScoreAnalysis.
      Returns:
      equivalent to constraintMap().values()
    • summarize

      public @NonNull String summarize()
      Returns a diagnostic text that explains the solution through the ConstraintAnalysis API to identify which constraints cause that score quality. The string is built fresh every time the method is called.

      In case of an infeasible solution, this can help diagnose the cause of that.

      Do not parse the return value, its format may change without warning. Instead, provide this information in a UI or a service, use constraintAnalyses() and convert those into a domain-specific API.

    • isSolutionInitialized

      public boolean isSolutionInitialized()
    • toString

      public String toString()
      Returns a string representation of this record class. The representation contains the name of the class, followed by the name and value of each of the record components.
      Specified by:
      toString in class Record
      Returns:
      a string representation of this object
    • hashCode

      public final int hashCode()
      Returns a hash code value for this object. The value is derived from the hash code of each of the record components.
      Specified by:
      hashCode in class Record
      Returns:
      a hash code value for this object
    • equals

      public final boolean equals(Object o)
      Indicates whether some other object is "equal to" this one. The objects are equal if the other object is of the same class and if all the record components are equal. All components in this record class are compared with Objects::equals(Object,Object).
      Specified by:
      equals in class Record
      Parameters:
      o - the object with which to compare
      Returns:
      true if this object is the same as the o argument; false otherwise.
    • score

      public @NonNull Score_ score()
      Returns the value of the score record component.
      Returns:
      the value of the score record component
    • constraintMap

      public @NonNull Map<ConstraintRef,ConstraintAnalysis<Score_>> constraintMap()
      Returns the value of the constraintMap record component.
      Returns:
      the value of the constraintMap record component