Annotation Interface ShadowVariablesInconsistent
Specifies that a boolean property (or field) of a
PlanningEntity
tracks if any of its supplier variables
are inconsistent.
A supplier variable is inconsistent if:
- One of its source variables include it as a source (for example, `a` depends on `b` and `b` depends on `a`).
- One of its source variables is inconsistent (for example, `c` depends on `a`, which depends on `b`, and `b` depends on `a`).
Should be used in a filter for a hard Constraint to penalize
inconsistent entities, since PlanningSolution with inconsistent entities are
typically not valid.
There are three ways an inconsistency may be introduced:
-
Source-induced, when two declarative shadow variables' sources refer to each other:
@PlanningEntity public class Entity { @ShadowVariable(supplierName = "variable1Supplier") String variable1; @ShadowVariable(supplierName = "variable2Supplier") String variable2; // ... @ShadowSources("variable2") String variable1Supplier() { // ... } @ShadowSources("variable1") String variable2Supplier() { // ... } } -
Fact-induced, when a shadow variable has itself as a direct or transitive dependency via a fact:
@PlanningEntity public class Entity { Entity dependency; @ShadowVariable(supplierName = "variableSupplier") String variable; @ShadowSources("dependency.variable") String variableSupplier() { // ... } // ... } Entity a = new Entity(); Entity b = new Entity(); a.setDependency(b); b.setDependency(a); // a depends on b, and b depends on a, which is invalid. -
Variable-induced, when a shadow variable has itself as a direct or transitive dependency via a variable:
@PlanningEntity public class Entity { Entity dependency; @PreviousElementShadowVariable() Entity previous; @ShadowVariable(supplierName = "variableSupplier") String variable; @ShadowSources({ "previous.variable", "dependency.variable" }) String variableSupplier() { // ... } // ... } Entity a = new Entity(); Entity b = new Entity(); b.setDependency(a); a.setPrevious(b); // b depends on a via a fact, and a depends on b via a variable // The solver can break this loop by moving a after b.
Important:
Do not use a ShadowVariablesInconsistent property in a method annotated
with ShadowSources. ShadowSources marked methods do not need to check
ShadowVariablesInconsistent properties, since they are only called if all
their dependencies are consistent.