void nooverlap(Home home, const IntVarArgs& x, const IntArgs& w, const IntVarArgs& y, const IntArgs& h, IntConLevel) { using namespace Int; using namespace NoOverlap; if (x.same(home) || y.same(home)) throw ArgumentSame("Int::nooverlap"); if ((x.size() != w.size()) || (x.size() != y.size()) || (x.size() != h.size())) throw ArgumentSizeMismatch("Int::nooverlap"); for (int i=x.size(); i--; ) { Limits::nonnegative(w[i],"Int::nooverlap"); Limits::nonnegative(h[i],"Int::nooverlap"); Limits::check(static_cast<double>(x[i].max()) + w[i], "Int::nooverlap"); Limits::check(static_cast<double>(y[i].max()) + h[i], "Int::nooverlap"); } if (home.failed()) return; ManBox<FixDim,2>* b = static_cast<Space&>(home).alloc<ManBox<FixDim,2> >(x.size()); for (int i=x.size(); i--; ) { b[i][0] = FixDim(x[i],w[i]); b[i][1] = FixDim(y[i],h[i]); } GECODE_ES_FAIL((NoOverlap::ManProp<FixDim,2>::post(home,b,x.size()))); }
void extensional(Home home, const IntVarArgs& x, const TupleSet& t, IntPropLevel ipl) { using namespace Int; if (!t.finalized()) throw NotYetFinalized("Int::extensional"); if (t.arity() != x.size()) throw ArgumentSizeMismatch("Int::extensional"); GECODE_POST; if (t.tuples()==0) { if (x.size()!=0) { home.fail(); } return; } // Construct view array ViewArray<IntView> xv(home,x); if (ipl & IPL_MEMORY) { if (x.same(home)) { GECODE_ES_FAIL((Extensional::Basic<IntView,true> ::post(home,xv,t))); } else { GECODE_ES_FAIL((Extensional::Basic<IntView,false> ::post(home,xv,t))); } } else { GECODE_ES_FAIL((Extensional::Incremental<IntView> ::post(home,xv,t))); } }
void extensional(Home home, const IntVarArgs& x, const TupleSet& t, ExtensionalPropKind epk, IntConLevel) { using namespace Int; if (!t.finalized()) throw NotYetFinalized("Int::extensional"); if (t.arity() != x.size()) throw ArgumentSizeMismatch("Int::extensional"); if (home.failed()) return; // Construct view array ViewArray<IntView> xv(home,x); switch (epk) { case EPK_SPEED: GECODE_ES_FAIL((Extensional::Incremental<IntView> ::post(home,xv,t))); break; default: if (x.same(home)) { GECODE_ES_FAIL((Extensional::Basic<IntView,true> ::post(home,xv,t))); } else { GECODE_ES_FAIL((Extensional::Basic<IntView,false> ::post(home,xv,t))); } break; } }
void argmin(Home home, const IntVarArgs& x, IntVar y, bool tiebreak, IntConLevel) { using namespace Int; if (x.size() == 0) throw TooFewArguments("Int::argmin"); if (x.same(home,y)) throw ArgumentSame("Int::argmin"); if (home.failed()) return; // Constrain y properly IntView yv(y); GECODE_ME_FAIL(yv.gq(home,0)); GECODE_ME_FAIL(yv.le(home,x.size())); // Construct index view array IdxViewArray<MinusView> ix(home,x.size()); for (int i=x.size(); i--; ) { ix[i].idx=i; ix[i].view=MinusView(x[i]); } if (tiebreak) GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,IntView,true> ::post(home,ix,yv))); else GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,IntView,false> ::post(home,ix,yv))); }
void binpacking(Home home, const IntVarArgs& l, const IntVarArgs& b, const IntArgs& s, IntConLevel) { using namespace Int; if (l.same(home,b)) throw ArgumentSame("Int::binpacking"); if (b.size() != s.size()) throw ArgumentSizeMismatch("Int::binpacking"); for (int i=s.size(); i--; ) Limits::nonnegative(s[i],"Int::binpacking"); if (home.failed()) return; ViewArray<OffsetView> lv(home,l.size()); for (int i=l.size(); i--; ) lv[i] = OffsetView(l[i],0); if (b.size() == 0) { for (int i=l.size(); i--; ) GECODE_ME_FAIL(lv[i].eq(home,0)); return; } ViewArray<BinPacking::Item> bs(home,b.size()); for (int i=bs.size(); i--; ) bs[i] = BinPacking::Item(b[i],s[i]); Support::quicksort(&bs[0], bs.size()); GECODE_ES_FAIL(Int::BinPacking::Pack::post(home,lv,bs)); }
void unary(Home home, const IntVarArgs& s, const IntArgs& p, const BoolVarArgs& m, IntConLevel icl) { using namespace Gecode::Int; using namespace Gecode::Int::Unary; if (s.same(home)) throw Int::ArgumentSame("Int::unary"); if ((s.size() != p.size()) || (s.size() != m.size())) throw Int::ArgumentSizeMismatch("Int::unary"); for (int i=p.size(); i--; ) { Int::Limits::nonnegative(p[i],"Int::unary"); Int::Limits::check(static_cast<double>(s[i].max()) + p[i], "Int::unary"); } bool allMandatory = true; for (int i=m.size(); i--;) { if (!m[i].one()) { allMandatory = false; break; } } if (allMandatory) { unary(home,s,p,icl); } else { if (home.failed()) return; TaskArray<OptFixPTask> t(home,s.size()); for (int i=s.size(); i--; ) t[i].init(s[i],p[i],m[i]); GECODE_ES_FAIL(OptProp<OptFixPTask>::post(home,t)); } }
void count(Home home, const IntVarArgs& x, const IntVarArgs& _c, const IntArgs& _v, IntConLevel icl) { using namespace Int; IntVarArgs c(_c); IntArgs v(_v); if (v.size() != c.size()) throw ArgumentSizeMismatch("Int::count"); if (x.same(home)) throw ArgumentSame("Int::count"); if (home.failed()) return; removeDuplicates(home,c,v); ViewArray<IntView> xv(home, x); ViewArray<GCC::CardView> cv(home, c.size()); // set the cardinality for (int i = v.size(); i--; ) cv[i].init(c[i],v[i]); switch (icl) { case ICL_BND: GECODE_ES_FAIL( (GCC::Bnd<GCC::CardView>::post(home,xv,cv))); break; case ICL_DOM: GECODE_ES_FAIL( (GCC::Dom<GCC::CardView>::post(home,xv,cv))); break; default: GECODE_ES_FAIL( (GCC::Val<GCC::CardView>::post(home,xv,cv))); } }
void distinct(Home home, const IntArgs& c, const IntVarArgs& x, IntPropLevel ipl) { using namespace Int; if (x.same(home)) throw ArgumentSame("Int::distinct"); if (c.size() != x.size()) throw ArgumentSizeMismatch("Int::distinct"); GECODE_POST; ViewArray<OffsetView> cx(home,x.size()); for (int i = c.size(); i--; ) { long long int cx_min = (static_cast<long long int>(c[i]) + static_cast<long long int>(x[i].min())); long long int cx_max = (static_cast<long long int>(c[i]) + static_cast<long long int>(x[i].max())); Limits::check(c[i],"Int::distinct"); Limits::check(cx_min,"Int::distinct"); Limits::check(cx_max,"Int::distinct"); cx[i] = OffsetView(x[i],c[i]); } switch (vbd(ipl)) { case IPL_BND: GECODE_ES_FAIL(Distinct::Bnd<OffsetView>::post(home,cx)); break; case IPL_DOM: GECODE_ES_FAIL(Distinct::Dom<OffsetView>::post(home,cx)); break; default: GECODE_ES_FAIL(Distinct::Val<OffsetView>::post(home,cx)); } }
void extensional(Home home, const IntVarArgs& x, DFA dfa, IntPropLevel) { using namespace Int; if (x.same(home)) throw ArgumentSame("Int::extensional"); GECODE_POST; GECODE_ES_FAIL(Extensional::post_lgp(home,x,dfa)); }
void extensional(Home home, const IntVarArgs& x, DFA dfa, IntConLevel) { using namespace Int; if (x.same(home)) throw ArgumentSame("Int::extensional"); if (home.failed()) return; GECODE_ES_FAIL(Extensional::post_lgp(home,x,dfa)); }
void sorted(Home home, const IntVarArgs& x, const IntVarArgs& y, const IntVarArgs& z, IntConLevel) { using namespace Int; if ((x.size() != y.size()) || (x.size() != z.size())) throw ArgumentSizeMismatch("Int::Sorted"); if (x.same(home,y) || x.same(home,z) || y.same(home,z)) throw ArgumentSame("Int::Sorted"); if (home.failed()) return; if (x.size()==0) return; ViewArray<IntView> x0(home,x), y0(home,y), z0(home,z); GECODE_ES_FAIL( (Sorted::Sorted<IntView,true>::post(home,x0,y0,z0))); }
void distinct(Home home, const BoolVarArgs& b, const IntVarArgs& x, IntPropLevel ipl) { using namespace Int; if (x.same(home)) throw ArgumentSame("Int::distinct"); if (b.size() != x.size()) throw ArgumentSizeMismatch("Int::distinct"); GECODE_POST; int n = x.size(); int min = Limits::max; int max = Limits::min; int m = 0; for (int i=n; i--; ) if (!b[i].zero()) { min = std::min(min,x[i].min()); max = std::max(max,x[i].max()); m++; } if (m < 2) return; int start; if (max < Limits::max-m) start = max+1; else if (min > Limits::min+m) start = min-(m+1); else throw OutOfLimits("Int::distinct"); ViewArray<IntView> y(home,m); int j = 0; for (int i=n; i--; ) if (b[i].one()) { y[j] = x[i]; j++; } else if (b[i].none()) { y[j] = IntVar(home, Limits::min, Limits::max); GECODE_ES_FAIL((Bool::IteDom<IntView,ConstIntView,IntView>::post (home, b[i], x[i], start+j, y[j]))); j++; } assert(j == m); switch (vbd(ipl)) { case IPL_BND: GECODE_ES_FAIL(Distinct::Bnd<IntView>::post(home,y)); break; case IPL_DOM: GECODE_ES_FAIL(Distinct::Dom<IntView>::post(home,y)); break; default: GECODE_ES_FAIL(Distinct::Val<IntView>::post(home,y)); } }
void distinct(Home home, const IntVarArgs& x, int c, IntPropLevel ipl) { using namespace Int; if (x.same(home)) throw ArgumentSame("Int::distinct"); GECODE_POST; int n = x.size(); int min = Limits::max; int max = Limits::min; int m = 0; for (int i=n; i--; ) if (!(x[i].assigned() && (x[i].val() == c))) { min = std::min(min,x[i].min()); max = std::max(max,x[i].max()); m++; } if (m < 2) return; int start; if (max < Limits::max-m) start = max+1; else if (min > Limits::min+m) start = min-(m+1); else throw OutOfLimits("Int::distinct"); ViewArray<IntView> y(home,m); int j = 0; for (int i=n; i--; ) if (!x[i].in(c)) { y[j] = x[i]; j++; } else if (!(x[i].assigned() && (x[i].val() == c))) { y[j] = IntVar(home, Limits::min, Limits::max); GECODE_ES_FAIL(Distinct::EqIte::post (home, x[i], y[j], c, start+j)); j++; } assert(j == m); switch (vbd(ipl)) { case IPL_BND: GECODE_ES_FAIL(Distinct::Bnd<IntView>::post(home,y)); break; case IPL_DOM: GECODE_ES_FAIL(Distinct::Dom<IntView>::post(home,y)); break; default: GECODE_ES_FAIL(Distinct::Val<IntView>::post(home,y)); } }
void circuit(Home home, const IntVarArgs& x, IntConLevel icl) { if (x.same(home)) throw Int::ArgumentSame("Graph::circuit"); if (x.size() == 0) throw Int::TooFewArguments("Graph::circuit"); if (home.failed()) return; ViewArray<Int::IntView> xv(home,x); if (icl == ICL_DOM) { GECODE_ES_FAIL(Graph::Circuit::Dom<Int::IntView>::post(home,xv)); } else { GECODE_ES_FAIL(Graph::Circuit::Val<Int::IntView>::post(home,xv)); } }
void distinct(Home home, const IntVarArgs& x, IntConLevel icl) { if (x.same(home)) throw ArgumentSame("Int::distinct"); if (home.failed()) return; ViewArray<IntView> xv(home,x); switch (icl) { case ICL_BND: GECODE_ES_FAIL(Distinct::Bnd<IntView>::post(home,xv)); break; case ICL_DOM: GECODE_ES_FAIL(Distinct::Dom<IntView>::post(home,xv)); break; default: GECODE_ES_FAIL(Distinct::Val<IntView>::post(home,xv)); } }
void distinct(Home home, const IntVarArgs& x, IntPropLevel ipl) { using namespace Int; if (x.same(home)) throw ArgumentSame("Int::distinct"); GECODE_POST; ViewArray<IntView> xv(home,x); switch (vbd(ipl)) { case IPL_BND: GECODE_ES_FAIL(Distinct::Bnd<IntView>::post(home,xv)); break; case IPL_DOM: GECODE_ES_FAIL(Distinct::Dom<IntView>::post(home,xv)); break; default: GECODE_ES_FAIL(Distinct::Val<IntView>::post(home,xv)); } }
void nooverlap(Home home, const IntVarArgs& x0, const IntVarArgs& w, const IntVarArgs& x1, const IntVarArgs& y0, const IntVarArgs& h, const IntVarArgs& y1, const BoolVarArgs& m, IntConLevel) { using namespace Int; using namespace NoOverlap; if ((x0.size() != w.size()) || (x0.size() != x1.size()) || (x0.size() != y0.size()) || (x0.size() != h.size()) || (x0.size() != y1.size()) || (x0.size() != m.size())) throw ArgumentSizeMismatch("Int::nooverlap"); if (x0.same(home) || w.same(home) || x1.same(home) || y0.same(home) || h.same(home) || y1.same(home) || m.same(home)) throw ArgumentSame("Int::nooverlap"); if (home.failed()) return; for (int i=x0.size(); i--; ) { GECODE_ME_FAIL(IntView(w[i]).gq(home,0)); GECODE_ME_FAIL(IntView(h[i]).gq(home,0)); } if (w.assigned() && h.assigned()) { IntArgs wc(x0.size()), hc(x0.size()); for (int i=x0.size(); i--; ) { wc[i] = w[i].val(); hc[i] = h[i].val(); } nooverlap(home, x0, wc, y0, hc, m); } else if (optional(m)) { OptBox<FlexDim,2>* b = static_cast<Space&>(home).alloc<OptBox<FlexDim,2> >(x0.size()); for (int i=x0.size(); i--; ) { b[i][0] = FlexDim(x0[i],w[i],x1[i]); b[i][1] = FlexDim(y0[i],h[i],y1[i]); b[i].optional(m[i]); } GECODE_ES_FAIL((NoOverlap::OptProp<FlexDim,2>::post(home,b,x0.size()))); } else { ManBox<FlexDim,2>* b = static_cast<Space&>(home).alloc<ManBox<FlexDim,2> >(x0.size()); int n = 0; for (int i=0; i<x0.size(); i++) if (m[i].one()) { b[n][0] = FlexDim(x0[i],w[i],x1[i]); b[n][1] = FlexDim(y0[i],h[i],y1[i]); n++; } GECODE_ES_FAIL((NoOverlap::ManProp<FlexDim,2>::post(home,b,n))); } }
void unary(Home home, const IntVarArgs& s, const IntArgs& p, IntConLevel icl) { using namespace Gecode::Int; using namespace Gecode::Int::Unary; if (s.same(home)) throw Int::ArgumentSame("Int::unary"); if (s.size() != p.size()) throw Int::ArgumentSizeMismatch("Int::unary"); for (int i=p.size(); i--; ) { Int::Limits::nonnegative(p[i],"Int::unary"); Int::Limits::check(static_cast<double>(s[i].max()) + p[i], "Int::unary"); } if (home.failed()) return; bool allOne = true; for (int i=p.size(); i--;) { if (p[i] != 1) { allOne = false; break; } } if (allOne) { ViewArray<IntView> xv(home,s); switch (icl) { case ICL_BND: GECODE_ES_FAIL(Distinct::Bnd<IntView>::post(home,xv)); break; case ICL_DOM: GECODE_ES_FAIL(Distinct::Dom<IntView>::post(home,xv)); break; default: GECODE_ES_FAIL(Distinct::Val<IntView>::post(home,xv)); } } else { TaskArray<ManFixPTask> t(home,s.size()); for (int i=s.size(); i--; ) t[i].init(s[i],p[i]); GECODE_ES_FAIL(ManProp<ManFixPTask>::post(home,t)); } }
void channel(Home home, const IntVarArgs& x, int xoff, const IntVarArgs& y, int yoff, IntConLevel icl) { using namespace Int; using namespace Channel; int n = x.size(); if (n != y.size()) throw ArgumentSizeMismatch("Int::channel"); if (x.same(home) || y.same(home)) throw ArgumentSame("Int::channel"); Limits::check(xoff,"Int::channel"); Limits::check(yoff,"Int::channel"); if ((xoff < 0) || (yoff < 0)) throw OutOfLimits("Int::channel"); if (home.failed()) return; if (n == 0) return; if ((xoff < 2) && (yoff < 2) && (xoff == yoff)) { if (icl == ICL_DOM) { DomInfo<IntView,NoOffset<IntView> >* di = static_cast<Space&>(home). alloc<DomInfo<IntView,NoOffset<IntView> > >(2*(n+xoff)); for (int i=n; i--; ) { di[xoff+i ].init(x[i],n+xoff); di[2*xoff+i+n].init(y[i],n+xoff); } if (xoff == 1) { IntVar x0(home,0,0); di[0].init(x0, n+xoff); IntVar y0(home,0,0); di[n+xoff].init(y0, n+xoff); } NoOffset<IntView> noff; if (x.same(home,y)) { GECODE_ES_FAIL((Dom<IntView,NoOffset<IntView>,true> ::post(home,n+xoff,di,noff,noff))); } else { GECODE_ES_FAIL((Dom<IntView,NoOffset<IntView>,false> ::post(home,n+xoff,di,noff,noff))); } } else { ValInfo<IntView>* vi = static_cast<Space&>(home).alloc<ValInfo<IntView> >(2*(n+xoff)); for (int i=n; i--; ) { vi[xoff+i ].init(x[i],n+xoff); vi[2*xoff+i+n].init(y[i],n+xoff); } if (xoff == 1) { IntVar x0(home,0,0); vi[0].init(x0, n+xoff); IntVar y0(home,0,0); vi[n+xoff].init(y0, n+xoff); } NoOffset<IntView> noff; if (x.same(home,y)) { GECODE_ES_FAIL((Val<IntView,NoOffset<IntView>,true> ::post(home,n+xoff,vi,noff,noff))); } else { GECODE_ES_FAIL((Val<IntView,NoOffset<IntView>,false> ::post(home,n+xoff,vi,noff,noff))); } } } else { if (icl == ICL_DOM) { DomInfo<IntView,Offset>* di = static_cast<Space&>(home).alloc<DomInfo<IntView,Offset> >(2*n); for (int i=n; i--; ) { di[i ].init(x[i],n); di[i+n].init(y[i],n); } Offset ox(-xoff); Offset oy(-yoff); if (x.same(home,y)) { GECODE_ES_FAIL((Dom<IntView,Offset,true> ::post(home,n,di,ox,oy))); } else { GECODE_ES_FAIL((Dom<IntView,Offset,false> ::post(home,n,di,ox,oy))); } } else { ValInfo<IntView>* vi = static_cast<Space&>(home).alloc<ValInfo<IntView> >(2*n); for (int i=n; i--; ) { vi[i ].init(x[i],n); vi[i+n].init(y[i],n); } Offset ox(-xoff); Offset oy(-yoff); if (x.same(home,y)) { GECODE_ES_FAIL((Val<IntView,Offset,true> ::post(home,n,vi,ox,oy))); } else { GECODE_ES_FAIL((Val<IntView,Offset,false> ::post(home,n,vi,ox,oy))); } } } }
// constant cards void count(Home home, const IntVarArgs& x, const IntSetArgs& _c, const IntArgs& _v, IntConLevel icl) { using namespace Int; IntSetArgs c(_c); IntArgs v(_v); if (v.size() != c.size()) throw ArgumentSizeMismatch("Int::count"); if (x.same(home)) throw ArgumentSame("Int::count"); for (int i=c.size(); i--; ) { Limits::check(v[i],"Int::count"); Limits::check(c[i].min(),"Int::count"); Limits::check(c[i].max(),"Int::count"); } if (home.failed()) return; removeDuplicates(home,c,v); ViewArray<IntView> xv(home, x); for (int i = v.size(); i--; ) { if (c[i].ranges() > 1) { // Found hole, so create temporary variables ViewArray<GCC::CardView> cv(home, v.size()); for (int j = v.size(); j--; ) cv[j].init(home,c[j],v[j]); switch (icl) { case ICL_BND: GECODE_ES_FAIL( (GCC::Bnd<GCC::CardView>::post(home, xv, cv))); break; case ICL_DOM: GECODE_ES_FAIL( (GCC::Dom<GCC::CardView>::post(home, xv, cv))); break; default: GECODE_ES_FAIL( (GCC::Val<GCC::CardView>::post(home, xv, cv))); } return; } } // No holes: create CardConsts ViewArray<GCC::CardConst> cv(home, c.size()); for (int i = c.size(); i--; ) cv[i].init(home,c[i].min(),c[i].max(),v[i]); switch (icl) { case ICL_BND: GECODE_ES_FAIL( (GCC::Bnd<GCC::CardConst>::post(home, xv, cv))); break; case ICL_DOM: GECODE_ES_FAIL( (GCC::Dom<GCC::CardConst>::post(home, xv, cv))); break; default: GECODE_ES_FAIL( (GCC::Val<GCC::CardConst>::post(home, xv, cv))); } }
void sequence(Home home, const IntVarArgs& x, const IntSet &s, int q, int l, int u, IntConLevel) { Limits::check(s.min(),"Int::sequence"); Limits::check(s.max(),"Int::sequence"); if (x.size() == 0) throw TooFewArguments("Int::sequence"); Limits::check(q,"Int::sequence"); Limits::check(l,"Int::sequence"); Limits::check(u,"Int::sequence"); if (x.same(home)) throw ArgumentSame("Int::sequence"); if ((q < 1) || (q > x.size())) throw OutOfLimits("Int::sequence"); if (home.failed()) return; // Normalize l and u l=std::max(0,l); u=std::min(q,u); // Lower bound of values taken can never exceed upper bound if (u < l) { home.fail(); return; } // Already subsumed as any number of values taken is okay if ((0 == l) && (q == u)) return; // All variables must take a value in s if (l == q) { for (int i=x.size(); i--; ) { IntView xv(x[i]); IntSetRanges ris(s); GECODE_ME_FAIL(xv.inter_r(home,ris,false)); } return; } // No variable can take a value in s if (0 == u) { for (int i=x.size(); i--; ) { IntView xv(x[i]); IntSetRanges ris(s); GECODE_ME_FAIL(xv.minus_r(home,ris,false)); } return; } ViewArray<IntView> xv(home,x); if (s.size() == 1) { GECODE_ES_FAIL( (Sequence::Sequence<IntView,int>::post (home,xv,s.min(),q,l,u))); } else { GECODE_ES_FAIL( (Sequence::Sequence<IntView,IntSet>::post (home,xv,s,q,l,u))); } }
IntSet binpacking(Home home, int d, const IntVarArgs& l, const IntVarArgs& b, const IntArgs& s, const IntArgs& c, IntConLevel) { using namespace Int; if (l.same(home,b)) throw ArgumentSame("Int::binpacking"); // The number of items int n = b.size(); // The number of bins int m = l.size() / d; // Check input sizes if ((n*d != s.size()) || (m*d != l.size()) || (d != c.size())) throw ArgumentSizeMismatch("Int::binpacking"); for (int i=s.size(); i--; ) Limits::nonnegative(s[i],"Int::binpacking"); for (int i=c.size(); i--; ) Limits::nonnegative(c[i],"Int::binpacking"); if (home.failed()) return IntSet::empty; // Capacity constraint for each dimension for (int k=d; k--; ) for (int j=m; j--; ) { IntView li(l[j*d+k]); if (me_failed(li.lq(home,c[k]))) { home.fail(); return IntSet::empty; } } // Post a binpacking constraint for each dimension for (int k=d; k--; ) { ViewArray<OffsetView> lv(home,m); for (int j=m; j--; ) lv[j] = OffsetView(l[j*d+k],0); ViewArray<BinPacking::Item> bv(home,n); for (int i=n; i--; ) bv[i] = BinPacking::Item(b[i],s[i*d+k]); if (Int::BinPacking::Pack::post(home,lv,bv) == ES_FAILED) { home.fail(); return IntSet::empty; } } // Clique Finding and distinct posting { // First construct the conflict graph Region r(home); BinPacking::ConflictGraph cg(home,r,b,m); for (int i=0; i<n-1; i++) { for (int j=i+1; j<n; j++) { unsigned int nl = 0; unsigned int ds = 0; IntVarValues ii(b[i]), jj(b[j]); while (ii() && jj()) { if (ii.val() < jj.val()) { ++ii; } else if (ii.val() > jj.val()) { ++jj; } else { ds++; for (int k=d; k--; ) if (s[i*d+k] + s[j*d+k] > c[k]) { nl++; break; } ++ii; ++jj; } } if (nl >= ds) cg.edge(i,j); } } if (cg.post() == ES_FAILED) home.fail(); // The clique can be computed even if home is failed return cg.maxclique(); } }