Menu

Output Var of a constraint vs Violation degree.

2012-06-04
2012-06-04
  • Jean-Noël Monette

    Hi,

    Not really a bug, but I propose to include the following invariant in your distribution. It maintains a 0/1 value defined as "f(x)=1 iff x>0, f(x)=0 owise".

    :::scala
    case class As01(x:IntVar) extends IntInvariant{
        var output:IntVar = null;
        registerStaticAndDynamicDependenciesNoID(x);
        finishInitialization();
        override def MyMax = 1;
        override def MyMin = 0;
        override def setOutputVar(v:IntVar){
            output = v
            output.setDefiningInvariant(this)
            output := (if(x.getValue() > 0) 1 else 0)
        }
        override def notifyIntChanged(v:IntVar,OldVal:Int,NewVal:Int){
            if(NewVal<=0 && OldVal > 0)output := 0;
            else if(OldVal<=0 && NewVal > 0)output := 1;
        }
    }
    

    This would be useful among others in the Constraint class to replace the call to the Equal constraint (which uses several other invariant (minus and abs) to get in fact the identity of the violation degree, as we compare it to 0) in the setOutputVar method:

    :::scala
    override def setOutputVar(v: IntVar) {v <== As01(getViolation)}
    

    And it would be also welcome in the Equal constraint where I read:

    :::scala
    //TODO: this is not correct; should be 0/1
      override def setOutputVar(v: IntVar) {v <== Violation.getClone}
    

    I think it may prove useful as well in many different situations in which one is only interested in the satisfaction/violation of a constraint, and not its degree of violation.

    Also, I would be happy if you tell me about any error or poor practice in my code. I'm not always sure to understand completely everything (e.g. is it important to register with both the static AND the dynamic dependency graphs?).

    Cheers,

    Jean-Noël

     
  • Renaud De Landtsheer

    Hello Jean Noël.
    At first reading, your invariant looks fine, you got it :-)

    Both static and dynamic graphs are needed. Dynamic one is a subset of static one, that is: same nodes, but edges of dynamuic graph are included in edges of static graph.

    Static graph can include cycles, dynamic graph cannot.
    Dynamic graph is the one used for the notify methods.
    Static graph is used to find the strognly connected components, and perform the initial topological sort when the model is closed. Strognly connected components are sorted incrementally when the dynamic graph is updated.

     
  • Jean-Noël Monette

    Thank you for your explanations.

    By the way, I just figured out that I was a bit wrong with this line:

    override def setOutputVar(v: IntVar) {v <== As01(getViolation)}

    This will actually return the reverse of the "expected" value, as it is equal to 0 when the constraint is satisfied. But usually, one expects 0 to stand for false, and hence not satisfied. I don't know which exact meaning you want to give to the output variable, but I guess that it really depends on the applications.

    Cheers,

    JN

     
  • Renaud De Landtsheer

    Hi Jean-Noël,

    I comitted Asteroid where I'v put a Step invariant implementing your suggestion [r56] and [r57]. I also removed the Equal from the Constraint class and replaced it by the Step invariant.

     

    Related

    Commit: [r56]
    Commit: [r57]


    Last edit: Renaud De Landtsheer 2012-06-04
  • Renaud De Landtsheer

    To make it more complete,

    :::scala
    registerStaticAndDynamicDependenciesNoID(x)
    

    could be replaced by

    :::scala
    registerStaticAndDynamicDependency(x)
    

    The plural used in the first form is because you can specify several variables as several parameters. The ID taken in the first and second place is -1 by default.

     

    Last edit: Renaud De Landtsheer 2012-06-04

Anonymous
Anonymous

Add attachments
Cancel





MongoDB Logo MongoDB