Topic
2 replies Latest Post - ‏2012-11-14T16:35:14Z by SystemAdmin
SystemAdmin
SystemAdmin
554 Posts
ACCEPTED ANSWER

Pinned topic Setting length of interval variable in custom constraint

‏2012-11-09T22:00:52Z |
Hi!

I'd like to set the minimum length of a interval-type variable within a custom constraint class. Something like this:




class customConstraint : 

public IloPropagatorI 
{ ... 
};   customConstraint::customConstraint(IloIntervalVar X) ... 
{ addVar(X); 
}   customConstraint::execute() 
{ ... setMin(IloLengthOf(X), 10); ... 
}


The documentation tells me that I can come up with a custom search "goal" and then use IlcIntervalVar::setLengthMin(10) to achieve this, but it absolutely escapes me why this is necessary and how I would go about this (since I don't want to define any search goals at all as of now). Maybe it's because I don't understand well enough how interval variables are dealt with behind the scenes!

I'd be thankful for an explanation on why the above can't be done, and even more thankful for a succinct example of how to accomplish the above using IlcIntervalVar.
Updated on 2012-11-14T16:35:14Z at 2012-11-14T16:35:14Z by SystemAdmin
  • ol
    ol
    34 Posts
    ACCEPTED ANSWER

    Re: Setting length of interval variable in custom constraint

    ‏2012-11-14T14:56:28Z  in response to SystemAdmin
    Hello,
    custom constraints do not provide API for intervalVar. You need to access the intVar representing the length, for instance you can do:

    
    
    
    class SetValue10I : 
    
    public IloPropagatorI 
    { 
    
    private: IloIntVar _y; 
    
    public: SetValue10I(IloIntVar y): IloPropagatorI(y.getEnv()), _y(y) 
    { addVar(y); 
    } 
    
    void execute() 
    { setValue(_y, 10); 
    } IloPropagatorI* makeClone(IloEnv env) 
    
    const 
    { 
    
    return 
    
    new (env) SetValue10I(_y); 
    } 
    };   IloConstraint SetValue10(IloIntVar y) 
    { 
    
    return IloCustomConstraint(y.getEnv(), 
    
    new (y.getEnv()) SetValue10I(y)); 
    }   
    
    void Model1(IloEnv env) 
    { IloModel mdl(env); IloIntervalVar itv(env); IloIntVar length(env); mdl.add(length==IloLengthOf(itv)); mdl.add(SetValue10(length)); IloCP cp(mdl); cp.solve(); cp.out()<< cp.domain(itv); 
    }   
    
    int main(
    
    int argc, 
    
    const 
    
    char * argv[]) 
    { IloEnv env; 
    
    try 
    { Model1(env); 
    } 
    
    catch (IloException & ex) 
    { env.out() << 
    "Caught: " << ex << endl; 
    } env.end(); 
    
    return 0; 
    }
    


    Nevertheless, instead of using a custom propagator, you can probably express your need directly with the intervalVar API. In your example:

    
    
    
    void Model1(IloEnv env) 
    { IloModel mdl(env); IloIntervalVar itv(env); mdl.add(IloLengthOf(itv,10)==10); IloCP cp(mdl); cp.solve(); cp.out()<< cp.domain(itv); 
    }
    


    (note the 2nd parameter in IloLengthOf to specify a default value when the interval is absent.)
    Regards,
    ol
    • SystemAdmin
      SystemAdmin
      554 Posts
      ACCEPTED ANSWER

      Re: Setting length of interval variable in custom constraint

      ‏2012-11-14T16:35:14Z  in response to ol
      Excellent answer, if not the one I was hoping for. Thank you!