nary.hpp /usr/include/gecode/float/linear.hh Gecode Gecode::Float Gecode::Float::Linear /*-*-mode:C++;c-basic-offset:2;indent-tabs-mode:nil-*-*/ /* *Mainauthors: *ChristianSchulte<schulte@gecode.org> *VincentBarichard<Vincent.Barichard@univ-angers.fr> * *Copyright: *ChristianSchulte,2003 *VincentBarichard,2012 * *Lastmodified: *$Date:2013-02-1316:01:33+0100(Wed,13Feb2013)$by$Author:vbarichard$ *$Revision:13289$ * *ThisfileispartofGecode,thegenericconstraint *developmentenvironment: *http://www.gecode.org * *Permissionisherebygranted,freeofcharge,toanypersonobtaining *acopyofthissoftwareandassociateddocumentationfiles(the *"Software"),todealintheSoftwarewithoutrestriction,including *withoutlimitationtherightstouse,copy,modify,merge,publish, *distribute,sublicense,and/orsellcopiesoftheSoftware,andto *permitpersonstowhomtheSoftwareisfurnishedtodoso,subjectto *thefollowingconditions: * *Theabovecopyrightnoticeandthispermissionnoticeshallbe *includedinallcopiesorsubstantialportionsoftheSoftware. * *THESOFTWAREISPROVIDED"ASIS",WITHOUTWARRANTYOFANYKIND, *EXPRESSORIMPLIED,INCLUDINGBUTNOTLIMITEDTOTHEWARRANTIESOF *MERCHANTABILITY,FITNESSFORAPARTICULARPURPOSEAND *NONINFRINGEMENT.INNOEVENTSHALLTHEAUTHORSORCOPYRIGHTHOLDERSBE *LIABLEFORANYCLAIM,DAMAGESOROTHERLIABILITY,WHETHERINANACTION *OFCONTRACT,TORTOROTHERWISE,ARISINGFROM,OUTOFORINCONNECTION *WITHTHESOFTWAREORTHEUSEOROTHERDEALINGSINTHESOFTWARE. * */ namespaceGecode{namespaceFloat{namespaceLinear{ /* *Linearpropagators * */ template<classP,classN,PropCondpc> forceinline Lin<P,N,pc>::Lin(Homehome,ViewArray<P>&x0,ViewArray<N>&y0,FloatValc0) :Propagator(home),x(x0),y(y0),c(c0){ x.subscribe(home,*this,pc); y.subscribe(home,*this,pc); } template<classP,classN,PropCondpc> forceinline Lin<P,N,pc>::Lin(Space&home,boolshare,Lin<P,N,pc>&p) :Propagator(home,share,p),c(p.c){ x.update(home,share,p.x); y.update(home,share,p.y); } template<classP,classN,PropCondpc> PropCost Lin<P,N,pc>::cost(constSpace&,constModEventDelta&)const{ returnPropCost::linear(PropCost::LO,x.size()+y.size()); } template<classP,classN,PropCondpc> forceinlinesize_t Lin<P,N,pc>::dispose(Space&home){ x.cancel(home,*this,pc); y.cancel(home,*this,pc); (void)Propagator::dispose(home); returnsizeof(*this); } /* *Computingbounds * */ //template<classView> //void //bounds_p(Rounding&r,ModEventDeltamed,ViewArray<View>&x,FloatVal&c,FloatNum&sl,FloatNum&su){ //intn=x.size(); //if(FloatView::me(med)==ME_FLOAT_VAL){ //for(inti=n;i--;){ //if(x[i].assigned()){ //c-=x[i].val();x[i]=x[--n]; //}else{ //sl=r.sub_up(sl,x[i].min());su=r.sub_down(su,x[i].max()); //} //} //x.size(n); //}else{ //for(inti=n;i--;){ //sl=r.sub_up(sl,x[i].min());su=r.sub_down(su,x[i].max()); //} //} //} // //template<classView> //void //bounds_n(Rounding&r,ModEventDeltamed,ViewArray<View>&y,FloatVal&c,FloatNum&sl,FloatNum&su){ //intn=y.size(); //if(FloatView::me(med)==ME_FLOAT_VAL){ //for(inti=n;i--;){ //if(y[i].assigned()){ //c+=y[i].val();y[i]=y[--n]; //}else{ //sl=r.add_up(sl,y[i].max());su=r.add_down(su,y[i].min()); //} //} //y.size(n); //}else{ //for(inti=n;i--;){ //sl=r.add_up(sl,y[i].max());su=r.add_down(su,y[i].min()); //} //} //} template<classView> void eliminate_p(ModEventDeltamed,ViewArray<View>&x,FloatVal&c){ intn=x.size(); if(FloatView::me(med)==ME_FLOAT_VAL){ for(inti=n;i--;){ if(x[i].assigned()){ c-=x[i].val();x[i]=x[--n]; } } x.size(n); } } template<classView> void eliminate_n(ModEventDeltamed,ViewArray<View>&y,FloatVal&c){ intn=y.size(); if(FloatView::me(med)==ME_FLOAT_VAL){ for(inti=n;i--;){ if(y[i].assigned()){ c+=y[i].val();y[i]=y[--n]; } } y.size(n); } } forceinlinebool infty(constFloatNum&n){ return((n==std::numeric_limits<FloatNum>::infinity())|| (n==-std::numeric_limits<FloatNum>::infinity())); } /* *Boundconsistentlinearequation * */ template<classP,classN> forceinline Eq<P,N>::Eq(Homehome,ViewArray<P>&x,ViewArray<N>&y,FloatValc) :Lin<P,N,PC_FLOAT_BND>(home,x,y,c){} template<classP,classN> ExecStatus Eq<P,N>::post(Homehome,ViewArray<P>&x,ViewArray<N>&y,FloatValc){ (void)new(home)Eq<P,N>(home,x,y,c); returnES_OK; } template<classP,classN> forceinline Eq<P,N>::Eq(Space&home,boolshare,Eq<P,N>&p) :Lin<P,N,PC_FLOAT_BND>(home,share,p){} template<classP,classN> Actor* Eq<P,N>::copy(Space&home,boolshare){ returnnew(home)Eq<P,N>(home,share,*this); } template<classP,classN> ExecStatus Eq<P,N>::propagate(Space&home,constModEventDelta&med){ //Eliminatesingletons Roundingr; eliminate_p<P>(med,x,c); eliminate_n<N>(med,y,c); if((FloatView::me(med)==ME_FLOAT_VAL)&&((x.size()+y.size())<=1)){ if(x.size()==1){ GECODE_ME_CHECK(x[0].eq(home,c)); returnhome.ES_SUBSUMED(*this); } if(y.size()==1){ GECODE_ME_CHECK(y[0].eq(home,-c)); returnhome.ES_SUBSUMED(*this); } return(c.in(0.0))?home.ES_SUBSUMED(*this):ES_FAILED; } ExecStatuses=ES_FIX; boolassigned=true; //Propagatemaxboundforpositivevariables for(inti=x.size();i--;){ //Computebound FloatNumsl=c.max(); for(intj=x.size();j--;){ if(i==j)continue; sl=r.sub_up(sl,x[j].min()); } for(intj=y.size();j--;) sl=r.add_up(sl,y[j].max()); ModEventme=x[i].lq(home,sl); if(me_failed(me)) returnES_FAILED; if(me!=ME_FLOAT_VAL) assigned=false; if(me_modified(me)) es=ES_NOFIX; } //Propagateminboundfornegativevariables for(inti=y.size();i--;){ //Computebound FloatNumsl=-c.max(); for(intj=x.size();j--;) sl=r.add_down(sl,x[j].min()); for(intj=y.size();j--;){ if(i==j)continue; sl=r.sub_down(sl,y[j].max()); } ModEventme=y[i].gq(home,sl); if(me_failed(me)) returnES_FAILED; if(me!=ME_FLOAT_VAL) assigned=false; if(me_modified(me)) es=ES_NOFIX; } //Propagateminboundforpositivevariables for(inti=x.size();i--;){ //Computebound FloatNumsu=c.min(); for(intj=x.size();j--;){ if(i==j)continue; su=r.sub_down(su,x[j].max()); } for(intj=y.size();j--;) su=r.add_down(su,y[j].min()); ModEventme=x[i].gq(home,su); if(me_failed(me)) returnES_FAILED; if(me!=ME_FLOAT_VAL) assigned=false; if(me_modified(me)) es=ES_NOFIX; } //Propagatemaxboundfornegativevariables for(inti=y.size();i--;){ //Computebound FloatNumsu=-c.min(); for(intj=x.size();j--;) su=r.add_up(su,x[j].max()); for(intj=y.size();j--;){ if(i==j)continue; su=r.sub_up(su,y[j].min()); } ModEventme=y[i].lq(home,su); if(me_failed(me)) returnES_FAILED; if(me!=ME_FLOAT_VAL) assigned=false; if(me_modified(me)) es=ES_NOFIX; } returnassigned?home.ES_SUBSUMED(*this):es; } /* *Boundconsistentlinearinequation * */ template<classP,classN> forceinline Lq<P,N>::Lq(Homehome,ViewArray<P>&x,ViewArray<N>&y,FloatValc) :Lin<P,N,PC_FLOAT_BND>(home,x,y,c){} template<classP,classN> ExecStatus Lq<P,N>::post(Homehome,ViewArray<P>&x,ViewArray<N>&y,FloatValc){ (void)new(home)Lq<P,N>(home,x,y,c); returnES_OK; } template<classP,classN> forceinline Lq<P,N>::Lq(Space&home,boolshare,Lq<P,N>&p) :Lin<P,N,PC_FLOAT_BND>(home,share,p){} template<classP,classN> Actor* Lq<P,N>::copy(Space&home,boolshare){ returnnew(home)Lq<P,N>(home,share,*this); } template<classP,classN> ExecStatus Lq<P,N>::propagate(Space&home,constModEventDelta&med){ //Eliminatesingletons FloatNumsl=0.0; Roundingr; if(FloatView::me(med)==ME_FLOAT_VAL){ for(inti=x.size();i--;){ if(x[i].assigned()){ c-=x[i].val();x.move_lst(i); }else{ sl=r.sub_up(sl,x[i].min()); } } for(inti=y.size();i--;){ if(y[i].assigned()){ c+=y[i].val();y.move_lst(i); }else{ sl=r.add_up(sl,y[i].max()); } } if((x.size()+y.size())<=1){ if(x.size()==1){ GECODE_ME_CHECK(x[0].lq(home,c.max())); returnhome.ES_SUBSUMED(*this); } if(y.size()==1){ GECODE_ME_CHECK(y[0].gq(home,(-c).min())); returnhome.ES_SUBSUMED(*this); } return(c.max()>=0)?home.ES_SUBSUMED(*this):ES_FAILED; } }else{ for(inti=x.size();i--;) sl=r.sub_up(sl,x[i].min()); for(inti=y.size();i--;) sl=r.add_up(sl,y[i].max()); } sl=r.add_up(sl,c.max()); ExecStatuses=ES_FIX; boolassigned=true; for(inti=x.size();i--;){ assert(!x[i].assigned()); FloatNumslx=r.add_up(sl,x[i].min()); ModEventme=x[i].lq(home,slx); if(me==ME_FLOAT_FAILED) returnES_FAILED; if(me!=ME_FLOAT_VAL) assigned=false; if(me_modified(me)) es=ES_NOFIX; } for(inti=y.size();i--;){ assert(!y[i].assigned()); FloatNumsly=r.sub_up(y[i].max(),sl); ModEventme=y[i].gq(home,sly); if(me==ME_FLOAT_FAILED) returnES_FAILED; if(me!=ME_FLOAT_VAL) assigned=false; if(me_modified(me)) es=ES_NOFIX; } returnassigned?home.ES_SUBSUMED(*this):es; } }}} //STATISTICS:float-prop