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

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
    59 Posts

    Re: Setting length of interval variable in custom constraint

    ‏2012-11-14T14:56:28Z  
    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

    Re: Setting length of interval variable in custom constraint

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

    <pre class="jive-pre"> 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; } </pre>

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

    <pre class="jive-pre"> 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); } </pre>

    (note the 2nd parameter in IloLengthOf to specify a default value when the interval is absent.)
    Regards,
    ol
    Excellent answer, if not the one I was hoping for. Thank you!