4

I have been trying to implement a shadow variable so that one of my problem facts can keep track of which planning entity is relevant to it, the end goal being to simplify/speed up my rules.

I am looking at the optaplanner doc about shadow variables, particularly the cloudBalancing example. In the "normal" cloudBalancing, the class CloudComputer is not a planningEntity. But in the example below, it is annotated as a planningEntity.

Are we to understand that the class "hosting" the shadow variable should be a planning entity? I thought a planningEntity had to have a planningVariable, but CloudComputer does not. If the answer is yes, I suggest being more explicit about it in the documentation. If the answer is no, then there is a mistake in this example (the @PlanningEntity annotation should be removed from CloudComputer).

The following example is from the doc:

For a non-chained planning variable, the bi-directional relationship must be a many to one relationship. To map a bi-directional relationship between two planning variables, annotate the master side (which is the genuine side) as a normal planning variable:

@PlanningEntity
public class CloudProcess {

    @PlanningVariable(...)
    public CloudComputer getComputer() {
        return computer;
    }
    public void setComputer(CloudComputer computer) {...}

}

And:

@PlanningEntity
public class CloudComputer {

    @InverseRelationShadowVariable(sourceVariableName = "computer")
    public List<CloudProcess> getProcessList() {
        return processList;
    }

}

Also, is this really all that is needed so that processList is kept up to date even when CloudProcess is cloned during solving?

Laurel
  • 5,965
  • 14
  • 31
  • 57
asachet
  • 6,620
  • 2
  • 30
  • 74
  • Can you point out the bits in the docs where's there's confusion that a planning enitity can also contain shadow vars instead of `@PlanningVariable`? I'd like to fix that. – Geoffrey De Smet Jun 12 '16 at 07:14
  • @GeoffreyDeSmet In 4.3.3 (section about planning entities) it states: "Each planning entity class has one or more planning variables." Also, I don't think I saw any mention of planning entities in the sections about shadow variables, when it is quite a crucial point that they should be in a planning entity class. I realized this was why my code was not working only when I tried to replicate the example and noticed the extra annotation. – asachet Jun 13 '16 at 08:46
  • Fixed for 7.0 docs – Geoffrey De Smet Jun 14 '16 at 07:49

1 Answers1

3

There are 2 kinds of planning variables: genuine (@PlanningVariable) and shadow variables. Any class that has either or combination thereof needs to be annotated as a @PlanningEntity (and added to the solver config unless you're using scanAnnotatedClasses).

Yes, this is because of the planning cloning. With the shadow variable, CloudComputer doesn't change during the planning so it doesn't need to be planning cloned. With the shadow variable, it changes during planning, so it needs to be cloned. If it wouldn't be planning cloned, the best solution would get corrupted when the internal working solution changes. That in turn would affect score calculation (if it uses the inverse list) and any consumer of best solution events or the best solution result returned by solve().

Geoffrey De Smet
  • 26,223
  • 11
  • 73
  • 120
  • What about annotating the class for deep-cloning? (for the case when class does not contain any genuine planning variable) – asachet Jun 13 '16 at 09:00
  • 1
    Any class with `@PlanningEntity` is automatically deep cloned, even if it has only shadow vars (because they are the cause for it to be deep cloned). – Geoffrey De Smet Jun 13 '16 at 15:36