bnd-sup.hpp /usr/include/gecode/int/gcc.hh Gecode::Int::GCC::UnReachable Gecode::Int::GCC::Rank Gecode::Int::GCC::MaxInc Gecode::Int::GCC::MinInc Gecode::Int::GCC::MinIdx Gecode::Int::GCC::PartialSum Gecode::Int::GCC::HallInfo Gecode Gecode::Int Gecode::Int::GCC /*-*-mode:C++;c-basic-offset:2;indent-tabs-mode:nil-*-*/ /* *Mainauthors: *PatrickPekczynski<pekczynski@ps.uni-sb.de> * *Contributingauthors: *ChristianSchulte<schulte@gecode.org> *GuidoTack<tack@gecode.org> * *Copyright: *PatrickPekczynski,2004 *ChristianSchulte,2009 *GuidoTack,2009 * *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{namespaceInt{namespaceGCC{ classUnReachable{ public: intminb; intmaxb; inteq; intle; intgr; }; template<classCard> ExecStatus prop_card(Space&home, ViewArray<IntView>&x,ViewArray<Card>&k){ intn=x.size(); intm=k.size(); Regionr(home); UnReachable*rv=r.alloc<UnReachable>(m); for(inti=m;i--;) rv[i].minb=rv[i].maxb=rv[i].le=rv[i].gr=rv[i].eq=0; for(inti=n;i--;){ intmin_idx; if(!lookupValue(k,x[i].min(),min_idx)) returnES_FAILED; if(x[i].assigned()){ rv[min_idx].minb++; rv[min_idx].maxb++; rv[min_idx].eq++; }else{ //countthenumberofvariables //withlowerboundk[min_idx].card() rv[min_idx].minb++; intmax_idx; if(!lookupValue(k,x[i].max(),max_idx)) returnES_FAILED; //countthenumberofvariables //withupperboundk[max_idx].card() rv[max_idx].maxb++; } } rv[0].le=0; intc_min=0; for(inti=1;i<m;i++){ rv[i].le=c_min+rv[i-1].maxb; c_min+=rv[i-1].maxb; } rv[m-1].gr=0; intc_max=0; for(inti=m-1;i--;){ rv[i].gr=c_max+rv[i+1].minb; c_max+=rv[i+1].minb; } for(inti=m;i--;){ intreachable=x.size()-rv[i].le-rv[i].gr; if(!k[i].assigned()){ GECODE_ME_CHECK(k[i].lq(home,reachable)); GECODE_ME_CHECK(k[i].gq(home,rv[i].eq)); }else{ //checkvalidityofthecardinalityvalue if((rv[i].eq>k[i].max())||(k[i].max()>reachable)) returnES_FAILED; } } returnES_OK; } template<classCard> forceinlinebool card_consistent(ViewArray<IntView>&x,ViewArray<Card>&k){ intsmin=0; intsmax=0; for(inti=k.size();i--;){ smax+=k[i].max(); smin+=k[i].min(); } //Consistentifnumberofvariableswithincardinalitybounds return(smin<=x.size())&&(x.size()<=smax); } classRank{ public: intmin; intmax; }; template<classView> classMaxInc{ protected: ViewArray<View>x; public: MaxInc(constViewArray<View>&x0):x(x0){} forceinlinebool operator ()(constinti,constintj){ returnx[i].max()<x[j].max(); } }; template<classView> classMinInc{ protected: ViewArray<View>x; public: MinInc(constViewArray<View>&x0):x(x0){} forceinlinebool operator ()(constinti,constintj){ returnx[i].min()<x[j].min(); } }; template<classCard> classMinIdx{ public: forceinlinebool operator ()(constCard&x,constCard&y){ returnx.card()<y.card(); } }; template<classCard> classPartialSum{ private: int*sum; intsize; public: intfirstValue,lastValue; PartialSum(void); voidinit(Space&home,ViewArray<Card>&k,boolup); voidreinit(void); boolinitialized(void)const; intsumup(intfrom,intto)const; intminValue(void)const; intmaxValue(void)const; intskipNonNullElementsRight(intv)const; intskipNonNullElementsLeft(intv)const; boolcheck_update_min(ViewArray<Card>&k); boolcheck_update_max(ViewArray<Card>&k); }; template<classCard> forceinline PartialSum<Card>::PartialSum(void):sum(NULL),size(-1){} template<classCard> forceinlinebool PartialSum<Card>::initialized(void)const{ returnsize!=-1; } template<classCard> inlinevoid PartialSum<Card>::init(Space&home,ViewArray<Card>&elements,boolup){ inti=0; intj=0; //Determinenumberofholesintheindexset intholes=0; for(i=1;i<elements.size();i++){ if(elements[i].card()!=elements[i-1].card()+1) holes+=elements[i].card()-elements[i-1].card()-1; } //weaddthreeelementsatthebeginningandtwoattheend size=elements.size()+holes+5; //memoryallocation if(sum==NULL){ sum=home.alloc<int>(2*size); } int*ds=&sum[size]; intfirst=elements[0].card(); firstValue=first-3; lastValue=first+elements.size()+holes+1; //thefirstthreeelements for(i=3;i--;) sum[i]=i; /* *copytheboundsintosum,fillingupholeswithzeroes */ intprevCard=elements[0].card()-1; i=0; for(j=2;j<elements.size()+holes+2;j++){ if(elements[i].card()!=prevCard+1){ sum[j+1]=sum[j]; }elseif(up){ sum[j+1]=sum[j]+elements[i].max(); i++; }else{ sum[j+1]=sum[j]+elements[i].min(); i++; } prevCard++; } sum[j+1]=sum[j]+1; sum[j+2]=sum[j+1]+1; //Computedistances,eliminatingzeroes i=elements.size()+holes+3; j=i+1; for(;i>0;){ while(sum[i]==sum[i-1]){ ds[i]=j; i--; } ds[j]=i; i--; j=ds[j]; } ds[j]=0; ds[0]=0; } template<classCard> forceinlinevoid PartialSum<Card>::reinit(void){ size=-1; } template<classCard> forceinlineint PartialSum<Card>::sumup(intfrom,intto)const{ if(from<=to){ returnsum[to-firstValue]-sum[from-firstValue-1]; }else{ assert(to-firstValue-1>=0); assert(to-firstValue-1<size); assert(from-firstValue>=0); assert(from-firstValue<size); returnsum[to-firstValue-1]-sum[from-firstValue]; } } template<classCard> forceinlineint PartialSum<Card>::minValue(void)const{ returnfirstValue+3; } template<classCard> forceinlineint PartialSum<Card>::maxValue(void)const{ returnlastValue-2; } template<classCard> forceinlineint PartialSum<Card>::skipNonNullElementsRight(intvalue)const{ value-=firstValue; int*ds=&sum[size]; return(ds[value]<value?value:ds[value])+firstValue; } template<classCard> forceinlineint PartialSum<Card>::skipNonNullElementsLeft(intvalue)const{ value-=firstValue; int*ds=&sum[size]; return(ds[value]>value?ds[ds[value]]:value)+firstValue; } template<classCard> inlinebool PartialSum<Card>::check_update_max(ViewArray<Card>&k){ intj=0; for(inti=3;i<size-2;i++){ intmax=0; if(k[j].card()==i+firstValue) max=k[j++].max(); if((sum[i]-sum[i-1])!=max) returntrue; } returnfalse; } template<classCard> inlinebool PartialSum<Card>::check_update_min(ViewArray<Card>&k){ intj=0; for(inti=3;i<size-2;i++){ intmin=0; if(k[j].card()==i+firstValue) min=k[j++].min(); if((sum[i]-sum[i-1])!=min) returntrue; } returnfalse; } classHallInfo{ public: intbounds; intt; intd; inth; ints; intps; intnewBound; }; forceinlinevoid pathset_ps(HallInfohall[],intstart,intend,intto){ intk,l; for(l=start;(k=l)!=end;hall[k].ps=to){ l=hall[k].ps; } } forceinlinevoid pathset_s(HallInfohall[],intstart,intend,intto){ intk,l; for(l=start;(k=l)!=end;hall[k].s=to){ l=hall[k].s; } } forceinlinevoid pathset_t(HallInfohall[],intstart,intend,intto){ intk,l; for(l=start;(k=l)!=end;hall[k].t=to){ l=hall[k].t; } } forceinlinevoid pathset_h(HallInfohall[],intstart,intend,intto){ intk,l; for(l=start;(k=l)!=end;hall[k].h=to){ l=hall[k].h; assert(l!=k); } } forceinlineint pathmin_h(constHallInfohall[],inti){ while(hall[i].h<i) i=hall[i].h; returni; } forceinlineint pathmin_t(constHallInfohall[],inti){ while(hall[i].t<i) i=hall[i].t; returni; } forceinlineint pathmax_h(constHallInfohall[],inti){ while(hall[i].h>i) i=hall[i].h; returni; } forceinlineint pathmax_t(constHallInfohall[],inti){ while(hall[i].t>i){ i=hall[i].t; } returni; } forceinlineint pathmax_s(constHallInfohall[],inti){ while(hall[i].s>i) i=hall[i].s; returni; } forceinlineint pathmax_ps(constHallInfohall[],inti){ while(hall[i].ps>i) i=hall[i].ps; returni; } }}} //STATISTICS:int-prop