Search code examples
optaplanner

Clarification on using shadow variables in optapy


I am trying to use shadow variables in optapy but I am not sure I understand how I can update their values correctly. The documentation of OptaPlanner suggests that to update a shadow variable, OptaPlanner uses a VariableListener, but they seem not supported in optapy yet. Am I reading this wrong and I do not need a VariableListener?

If I use the example in the optapy documentation:

from optapy import planning_entity, planning_variable
from optapy.types import PlanningVariableGraphType

@planning_entity
class Customer:
    @planning_variable(object, graph_type = PlanningVariableGraphType.CHAINED, ...)
        def get_previous_standstill(self):
        return self.previous_standstill

        def set_previous_standstill(previous_standstill):
        ...

from optapy import planning_entity, inverse_relation_shadow_variable

@planning_entity
class Standstill:
    @inverse_relation_shadow_variable(Customer, source_variable_name ="previous_standstill")
    def get_next_customer(self):
        return self.next_customer

    def set_next_customer(Customer nextCustomer):
        ...

How is variable next_customer updated?


Solution

  • Custom shadow variables (which use custom VariableListeners) are currently not supported (tracking issue: https://github.com/optapy/optapy/issues/75), but builtin shadow variables (which use predefined VariableListeners) are. The builtin shadow variables are: @inverse_relation_shadow_variable, which updates when the source variable takes the object as a value; and @anchor_shadow_variable which updates when the start of a chain for the source chained variable changes.

    In the above example, If I have a Standstill standstill, then whenever OptaPy updates a Customer customer via customer.set_previous_standstill(standstill), standstill.set_next_customer(customer) is called.