Uploaded image for project: 'OptaPlanner'
  1. OptaPlanner
  2. PLANNER-2786

CS: ability to derive a value

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Won't Do
    • Icon: Major Major
    • None
    • None
    • Constraint Streams
    • None
    • 2022 Week 41-43 (from Oct 10), 2022 Week 44-46 (from Oct 31), 2022 Week 47-49 (from Nov 21)
    • 8
    • NEW
    • NEW

      Consider a constraint like this one from the Conference Scheduling example:

      protected Constraint talkMutuallyExclusiveTalksTags(ConstraintFactory factory) {
              return factory.forEachUniquePair(Talk.class,
                      overlapping(t -> t.getTimeslot().getStartDateTime(), 
                              t -> t.getTimeslot().getEndDateTime()),
                      filtering((talk1, talk2) -> 
                              talk2.overlappingMutuallyExclusiveTalksTagCount(talk1) > 0))
                      .penalizeConfigurable(TALK_MUTUALLY_EXCLUSIVE_TALKS_TAGS,
                              (talk1, talk2) ->
                                 talk1.overlappingMutuallyExclusiveTalksTagCount(talk2)                 
                                 * talk1.overlappingDurationInMinutes(talk2));
          }
      

      The overlappingMutuallyExclusiveTalksTagCount() function is called numerous times:

      • It is called every time the filter is called.
      • And it is also called every time the penalty is called, regardless of whether the value changed since the filtering.

      This is inefficient and we can address this by allowing the CS to derive new tuples. Initial proposal:

      protected Constraint talkMutuallyExclusiveTalksTags(ConstraintFactory factory) {
              return factory.forEachUniquePair(Talk.class,
                      overlapping(t -> t.getTimeslot().getStartDateTime(), 
                              t -> t.getTimeslot().getEndDateTime()))
                      .derive((talk1, talk2) ->
                              talk2.overlappingMutuallyExclusiveTalksTagCount(talk1))
                      .filter((talk1, talk2, mutuallyExclusiveTagCount) -     
                              mutuallyExclusiveTagCount > 0)
                      .penalizeConfigurable(TALK_MUTUALLY_EXCLUSIVE_TALKS_TAGS,
                              (talk1, talk2, mutuallyExclusiveTagCount) -> 
                                  mutuallyExclusiveTagCount 
                                  * talk1.overlappingDurationInMinutes(talk2));
          }
      

      This will bring the repetition to a minimum, leading to maximized efficiency.

              lpetrovi@redhat.com Lukáš Petrovický (Inactive)
              lpetrovi@redhat.com Lukáš Petrovický (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated:
                Resolved: