disjoint.hpp /usr/include/gecode/set/element.hh Gecode Gecode::Set Gecode::Set::Element /*-*-mode:C++;c-basic-offset:2;indent-tabs-mode:nil-*-*/ /* *Mainauthors: *GuidoTack<tack@gecode.org> *ChristianSchulte<schulte@gecode.org> * *Copyright: *GuidoTack,2004 *ChristianSchulte,2004 * *Lastmodified: *$Date:2012-09-0717:31:22+0200(Fri,07Sep2012)$by$Author:schulte$ *$Revision:13068$ * *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{namespaceSet{namespaceElement{ template<classSView,classRView> forceinline ElementDisjoint<SView,RView>::ElementDisjoint(Homehome, IdxViewArray&iv0, RViewy1) :Propagator(home),iv(iv0),x1(y1){ x1.subscribe(home,*this,PC_SET_ANY); iv.subscribe(home,*this,PC_SET_ANY); } template<classSView,classRView> forceinline ElementDisjoint<SView,RView>::ElementDisjoint(Space&home,boolshare, ElementDisjoint&p) :Propagator(home,share,p){ x1.update(home,share,p.x1); iv.update(home,share,p.iv); } template<classSView,classRView> forceinlineExecStatus ElementDisjoint<SView,RView>::post(Homehome,IdxViewArray&xs, RViewx1){ intn=xs.size(); //s2\subseteq{0,...,n-1} Iter::Ranges::Singletons(0,n-1); GECODE_ME_CHECK(x1.intersectI(home,s)); (void)new(home) ElementDisjoint(home,xs,x1); returnES_OK; } template<classSView,classRView> PropCost ElementDisjoint<SView,RView>::cost(constSpace&,constModEventDelta&)const{ returnPropCost::quadratic(PropCost::LO,iv.size()+2); } template<classSView,classRView> forceinlinesize_t ElementDisjoint<SView,RView>::dispose(Space&home){ x1.cancel(home,*this,PC_SET_ANY); iv.cancel(home,*this,PC_SET_ANY); (void)Propagator::dispose(home); returnsizeof(*this); } template<classSView,classRView> Actor* ElementDisjoint<SView,RView>::copy(Space&home,boolshare){ returnnew(home)ElementDisjoint(home,share,*this); } template<classSView,classRView> ExecStatus ElementDisjoint<SView,RView>::propagate(Space&home,constModEventDelta&){ intn=iv.size(); Regionr(home); boolfix_flag=false; do{ fix_flag=false; //Computeunionofallselectedelements'lowerbounds GlbRanges<RView>x1lb(x1); Iter::Ranges::ToValues<GlbRanges<RView>>vx1lb(x1lb); GLBndSetunionOfSelected(home); for(inti=0;vx1lb();++vx1lb){ while(iv[i].idx<vx1lb.val())i++; GlbRanges<SView>clb(iv[i].view); unionOfSelected.includeI(home,clb); } { LubRanges<RView>x1ub(x1); Iter::Ranges::ToValues<LubRanges<RView>>vx1ub(x1ub); inti=0; intj=0; //Cancelallelementsthatarenolongerintheupperbound while(vx1ub()){ if(iv[i].idx<vx1ub.val()){ iv[i].view.cancel(home,*this,PC_SET_ANY); i++; continue; } iv[j]=iv[i]; ++vx1ub; ++i;++j; } //cancelthevariableswithindexgreaterthan //maxoflub(x1) for(intk=i;k<n;k++){ iv[k].view.cancel(home,*this,PC_SET_ANY); } n=j; iv.size(n); } { UnknownRanges<RView>x1u(x1); Iter::Ranges::Cachex1uc(r,x1u); Iter::Ranges::ToValues<Iter::Ranges::Cache> vx1u(x1uc); inti=0; intj=0; while(vx1u()){ while(iv[i].idx<vx1u.val()){ iv[j]=iv[i]; i++;j++; } assert(iv[i].idx==vx1u.val()); SViewcandidate=iv[i].view; intcandidateInd=iv[i].idx; GlbRanges<SView>clb(candidate); BndSetRangesuos(unionOfSelected); Iter::Ranges::Inter<GlbRanges<SView>,BndSetRanges> inter(clb,uos); if(inter()){ ModEventme=x1.exclude(home,candidateInd); fix_flag|=me_modified(me); GECODE_ME_CHECK(me); candidate.cancel(home,*this,PC_SET_ANY); ++i; ++vx1u; continue; } iv[j]=iv[i]; ++vx1u; ++i;++j; } unionOfSelected.dispose(home); //copyremainingvariables for(intk=i;k<n;k++){ iv[j]=iv[k]; j++; } n=j; iv.size(n); } if(x1.cardMax()==0){ //Selectorisempty,we'redone returnhome.ES_SUBSUMED(*this); } { //removeallelementsinaselectedvariablefrom //allotherselectedvariables GlbRanges<RView>x1lb(x1); Iter::Ranges::ToValues<GlbRanges<RView>>vx1lb(x1lb); inti=0; for(;vx1lb();++vx1lb){ while(iv[i].idx<vx1lb.val())i++; assert(iv[i].idx==vx1lb.val()); GlbRanges<RView>x1lb2(x1); Iter::Ranges::ToValues<GlbRanges<RView>>vx1lb2(x1lb2); for(intj=0;vx1lb2();++vx1lb2){ while(iv[j].idx<vx1lb2.val())j++; assert(iv[j].idx==vx1lb2.val()); if(iv[i].idx!=iv[j].idx){ GlbRanges<SView>xilb(iv[i].view); ModEventme=iv[j].view.excludeI(home,xilb); fix_flag|=me_modified(me); GECODE_ME_CHECK(me); } } } } //removeallelementsfromtheselectorthatoverlap //withallotherpossiblyselectedelements,if //atleasttwomoreelementsneedtobeselected if(x1.cardMin()-x1.glbSize()>1){ UnknownRanges<RView>x1u(x1); Iter::Ranges::Cachex1uc(r,x1u); Iter::Ranges::ToValues<Iter::Ranges::Cache> vx1u(x1uc); for(;vx1u()&&x1.cardMin()-x1.glbSize()>1;++vx1u){ inti=0; while(iv[i].idx<vx1u.val())i++; assert(iv[i].idx==vx1u.val()); boolflag=true; UnknownRanges<RView>x1u2(x1); Iter::Ranges::ToValues<UnknownRanges<RView>>vx1u2(x1u2); for(;vx1u2();++vx1u2){ intj=0; while(iv[j].idx<vx1u2.val())j++; assert(iv[j].idx==vx1u2.val()); if(iv[i].idx!=iv[j].idx){ GlbRanges<SView>xjlb(iv[j].view); GlbRanges<SView>xilb(iv[i].view); Iter::Ranges::Inter<GlbRanges<SView>,GlbRanges<SView>> inter(xjlb,xilb); if(!inter()){ flag=false; gotohere; } } } here: if(flag){ ModEventme=x1.exclude(home,iv[i].idx); fix_flag|=me_modified(me); GECODE_ME_CHECK(me); } } } //ifexactlytwomoreelementsneedtobeselected //andthereisapossibleelementisuchthatallotherpairsof //elementsoverlap,selecti UnknownRanges<RView>x1u(x1); Iter::Ranges::Cachex1uc(r,x1u); Iter::Ranges::ToValues<Iter::Ranges::Cache> vx1u(x1uc); for(;x1.cardMin()-x1.glbSize()==2&&vx1u();++vx1u){ inti=0; while(iv[i].idx<vx1u.val())i++; assert(iv[i].idx==vx1u.val()); boolflag=true; UnknownRanges<RView>x1u2(x1); Iter::Ranges::ToValues<UnknownRanges<RView>>vx1u2(x1u2); for(;vx1u2();++vx1u2){ intj=0; while(iv[j].idx<vx1u2.val())j++; assert(iv[j].idx==vx1u2.val()); if(iv[i].idx!=iv[j].idx){ UnknownRanges<RView>x1u3(x1); Iter::Ranges::ToValues<UnknownRanges<RView>>vx1u3(x1u3); for(;vx1u3();++vx1u3){ intk=0; while(iv[k].idx<vx1u3.val())k++; assert(iv[k].idx==vx1u3.val()); if(iv[j].idx!=iv[k].idx&&iv[i].idx!=iv[k].idx){ GlbRanges<SView>xjlb(iv[j].view); GlbRanges<SView>xilb(iv[k].view); Iter::Ranges::Inter<GlbRanges<SView>,GlbRanges<SView>> inter(xjlb,xilb); if(!inter()){ flag=false; gotohere2; } } } } } here2: if(flag){ ModEventme=x1.include(home,iv[i].idx); fix_flag|=me_modified(me); GECODE_ME_CHECK(me); } } }while(fix_flag); boolallAssigned=true; for(inti=iv.size();i--;) if(!iv[i].view.assigned()){ allAssigned=false; break; } if(!x1.assigned()) allAssigned=false; returnallAssigned?home.ES_SUBSUMED(*this):ES_FIX; } }}} //STATISTICS:set-prop