示例#1
0
  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())));
  }
示例#2
0
  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)));
    }
  }
示例#3
0
  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;
    }
  }
示例#4
0
 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)));
 }
示例#5
0
  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));
  }
示例#6
0
 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));
   }
 }
示例#7
0
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)));
    }
}
示例#8
0
 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));
   }
 }
示例#9
0
 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));
 }
示例#10
0
 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));
 }
示例#11
0
  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)));
  }
示例#12
0
  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));
    }
  }
示例#13
0
  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));
    }
  }
示例#14
0
文件: circuit.cpp 项目: lquan/CSAI
 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));
   }
 }
示例#15
0
 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));
   }
 }
示例#16
0
 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));
   }
 }
示例#17
0
  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)));
    }
  }
示例#18
0
 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));
   }
 }
示例#19
0
  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)));
        }
      }
    }

  }
示例#20
0
// 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)));
    }
}
示例#21
0
  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();
    }
  }