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

Design problems with annotation CustomShadowVariable in case of multiple shadow variable

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Duplicate
    • Icon: Critical Critical
    • 6.3.0.CR1
    • 6.2.0.Final
    • None
    • None

      Like said in PLANNER-315:

      In the previous release (6.0.1.FinalI), OptaPlanner did not care about which variables are custom shadow variables. You could register a listener with the annotation @PlanningVariable(variableListenerClasses =...) that computes all shadow variables that depend on the planning variable.

      In the release 6.2.0.Final this has been changed so that you need to annotate the getter of each shadow variable with @CustomShadowVarable(variableListenerClass=).

      We have many shadow variables in our model, e.g. stopNumber, delayedSeconds, timeRestrictionViolated, articlesMissing, weight, etc. (more than 12).

      This had some negative consequences in our model:

      • If we annotate each shadow variable, we get a separate listener instance for each variable. but the computation of all shadow variables can be done more efficient if we compute them together, because everything depends on a single planning variable and we have to go down the chain to update affected entities.
      • In the previous release we called the ScoreDirector-methods beforeVariableChanged + afterVariableChanged for each shadow variable when it changed.
        This is not possible anymore in the current release, when the variable is not known to OptaPlanner (by annotating it). OptaPlanner throws an Exception: (see EntityDescriptor.buildInvalidVariableNameExceptionMessage())
      • We implemented several fact-change APIs. The planning entity class Workload contains several variables, that are neither shadow-variables nor planning variables, but are facts. (e.g. preferredVehicle, preferredStopNumber, latestArrivalTime etc.)
        When the fact-change API changed such a variable, we also called beforeVarableChange/afterVariableChanged, because we could not call beforeFactChanged, because the changed field belongs to a planning entity. This also causes the latest optaplanner to throw an IllegalArgumentException, because the changed
        variable is not known as a shadow variable.

      So we decided not to use @CustomShadowVariable and had to hook our variableListener in a different way, although the previous release of OptaPlanner supported our listener anntated at the planning variable.

      Suggestions:

      • remove the IllegalArgumentException,
      • support null as variableName in beforeVaribleChanged/afterVariableChanged or add a new method to ScoreDirectory.before/afterEntityChanged(Object)
      • support to register a variableListener on a class-level-annotation or like in the 6.0.x release of OptaPlanner.

            gdesmet@redhat.com Geoffrey De Smet (Inactive)
            romanstumm Roman Stumm (Inactive)
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: