Esempio n. 1
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));
   }
 }
Esempio n. 2
0
 void
 unary(Home home, const TaskTypeArgs& t,
       const IntVarArgs& flex, const IntArgs& fix, IntConLevel icl) {
   using namespace Gecode::Int;
   using namespace Gecode::Int::Unary;
   if ((flex.size() != fix.size()) || (flex.size() != t.size()))
     throw Int::ArgumentSizeMismatch("Int::unary");
   for (int i=fix.size(); i--; ) {
     if (t[i] == TT_FIXP)
       Int::Limits::nonnegative(fix[i],"Int::unary");
     else
       Int::Limits::check(fix[i],"Int::unary");
     Int::Limits::check(static_cast<double>(flex[i].max()) + fix[i],
                        "Int::unary");
   }
   if (home.failed()) return;
   bool fixp = true;
   for (int i=t.size(); i--;)
     if (t[i] != TT_FIXP) {
       fixp = false; break;
     }
   if (fixp) {
     unary(home, flex, fix, icl);
   } else {
     TaskArray<ManFixPSETask> tasks(home,flex.size());
     for (int i=flex.size(); i--;)
       tasks[i].init(t[i],flex[i],fix[i]);
     GECODE_ES_FAIL(ManProp<ManFixPSETask>::post(home,tasks));
   }
 }
Esempio n. 3
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())));
  }
Esempio n. 4
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));
   }
 }
Esempio n. 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));
  }
Esempio n. 6
0
void count(Home home, const IntVarArgs& x,
           const IntSet& c, const IntArgs& v,
           IntConLevel icl) {
    IntSetArgs cards(v.size());
    for (int i = v.size(); i--; )
        cards[i] = c;
    count(home, x, cards, v, icl);
}
Esempio n. 7
0
 void
 element(Home home, SetOpType op, const IntArgs& x, SetVar y, SetVar z,
         const IntSet& universe) {
   IntSetArgs xs(x.size());
   for (int i=x.size(); i--;)
     xs[i]=IntSet(x[i],x[i]);
   element(home,op,xs,y,z,universe);
 }
Esempio n. 8
0
 void
 cumulative(Home home, Cap c, const TaskTypeArgs& t,
            const IntVarArgs& s, const IntArgs& p, const IntArgs& u,
            const BoolVarArgs& m, IntConLevel icl) {
   using namespace Gecode::Int;
   using namespace Gecode::Int::Cumulative;
   if ((s.size() != p.size()) || (s.size() != u.size()) ||
       (s.size() != t.size()) || (s.size() != m.size()))
     throw Int::ArgumentSizeMismatch("Int::cumulative");
   long long int w = 0;
   for (int i=p.size(); i--; ) {
     Limits::nonnegative(p[i],"Int::cumulative");
     Limits::nonnegative(u[i],"Int::cumulative");
     Limits::check(static_cast<long long int>(s[i].max()) + p[i],
                   "Int::cumulative");
     mul_check(p[i],u[i]);
     w += s[i].width();
   }
   mul_check(c.max(),w,s.size());
   if (home.failed()) return;
   
   bool allMandatory = true;
   for (int i=m.size(); i--;) {
     if (!m[i].one()) {
       allMandatory = false;
       break;
     }
   }
   if (allMandatory) {
     cumulative(home,c,t,s,p,u,icl);
   } else {
     bool fixp = true;
     for (int i=t.size(); i--;)
       if (t[i] != TT_FIXP) {
         fixp = false; break;
       }
     int nonOptionals = 0;
     for (unsigned int i=u.size(); i--;)
       if (u[i]>0) nonOptionals++;
     if (fixp) {
       TaskArray<OptFixPTask> tasks(home,nonOptionals);
       int cur = 0;
       for (int i=0; i<s.size(); i++)
         if (u[i]>0)
           tasks[cur++].init(s[i],p[i],u[i],m[i]);
       GECODE_ES_FAIL((OptProp<OptFixPTask,Cap>::post(home,c,tasks)));
     } else {
       TaskArray<OptFixPSETask> tasks(home,nonOptionals);
       int cur = 0;
       for (int i=s.size(); i--;)
         if (u[i]>0)
           tasks[cur++].init(t[i],s[i],p[i],u[i],m[i]);
       GECODE_ES_FAIL((OptProp<OptFixPSETask,Cap>::post(home,c,tasks)));
     }
   }
 }
Esempio n. 9
0
 inline void
 TupleSet::add(const IntArgs& tuple) {
   TupleSetI* imp = static_cast<TupleSetI*>(object());
   if (imp == NULL) {
     imp = new TupleSetI;
     object(imp);
   }
   assert(imp->arity == -1 ||
          imp->arity == tuple.size());
   imp->arity = tuple.size();
   imp->add(tuple);
 }
Esempio n. 10
0
  void
  precede(Home home, const IntVarArgs& x, const IntArgs& c, IntConLevel) {
    using namespace Int;
    for (int i=c.size(); i--; )
      Limits::check(c[i],"Int::precede");
    if (home.failed()) return;

    for (int i=c.size()-1; i--; ) {
      ViewArray<IntView> y(home, x);
      GECODE_ES_FAIL(Precede::Single<IntView>::post(home, y, c[i], c[i+1]));
    }
  }
Esempio n. 11
0
  void
  precede(Home home, const SetVarArgs& x, const IntArgs& c) {
    using namespace Set;
    if (c.size() < 2)
      return;
    for (int i=c.size(); i--; )
      Limits::check(c[i],"Set::precede");
    GECODE_POST;

    for (int i=c.size()-1; i--; ) {
      ViewArray<SetView> y(home, x);
      GECODE_ES_FAIL(Precede::Single<SetView>::post(home, y, c[i], c[i+1]));
    }
  }
Esempio n. 12
0
 void
 linear(Home home,
        const IntArgs& a, const IntVarArgs& x, IntRelType r, IntVar y,
        IntConLevel icl) {
   if (a.size() != x.size())
     throw ArgumentSizeMismatch("Int::linear");
   if (home.failed()) return;
   Region re(home);
   Linear::Term<IntView>* t = re.alloc<Linear::Term<IntView> >(x.size()+1);
   for (int i = x.size(); i--; ) {
     t[i].a=a[i]; t[i].x=x[i];
   }
   int min, max;
   estimate(t,x.size(),0,min,max);
   IntView v(y);
   switch (r) {
   case IRT_EQ:
     GECODE_ME_FAIL(v.gq(home,min)); GECODE_ME_FAIL(v.lq(home,max));
     break;
   case IRT_GQ:
     GECODE_ME_FAIL(v.lq(home,max));
     break;
   case IRT_LQ:
     GECODE_ME_FAIL(v.gq(home,min));
     break;
   default: ;
   }
   if (home.failed()) return;
   t[x.size()].a=-1; t[x.size()].x=y;
   Linear::post(home,t,x.size()+1,r,0,icl);
 }
Esempio n. 13
0
  void
  cumulative(Home home, Cap c, const IntVarArgs& s, 
             const IntVarArgs& p, const IntVarArgs& e,
             const IntArgs& u, IntConLevel icl) {
    using namespace Gecode::Int;
    using namespace Gecode::Int::Cumulative;
    if ((s.size() != p.size()) || (s.size() != e.size()) ||
        (s.size() != u.size()))
      throw Int::ArgumentSizeMismatch("Int::cumulative");
    long long int w = 0;
    for (int i=p.size(); i--; ) {
      rel(home, p[i], IRT_GQ, 0);
    }
    for (int i=p.size(); i--; ) {
      Limits::nonnegative(u[i],"Int::cumulative");
      Limits::check(static_cast<long long int>(s[i].max()) + p[i].max(),
                    "Int::cumulative");
      mul_check(p[i].max(),u[i]);
      w += s[i].width();
    }
    mul_check(c.max(),w,s.size());
    if (home.failed()) return;

    bool fixP = true;
    for (int i=p.size(); i--;) {
      if (!p[i].assigned()) {
        fixP = false;
        break;
      }
    }
    if (fixP) {
      IntArgs pp(p.size());
      for (int i=p.size(); i--;)
        pp[i] = p[i].val();
      cumulative(home,c,s,pp,u,icl);
    } else {
      int nonOptionals = 0;
      for (unsigned int i=u.size(); i--;)
        if (u[i]>0) nonOptionals++;
      TaskArray<ManFlexTask> t(home,nonOptionals);
      int cur = 0;
      for (int i=0; i<s.size(); i++)
        if (u[i]>0)
          t[cur++].init(s[i],p[i],e[i],u[i]);
      GECODE_ES_FAIL((ManProp<ManFlexTask,Cap>::post(home,c,t)));
    }
  }
Esempio n. 14
0
  void
  cumulative(Home home, Cap c, const IntVarArgs& s, 
             const IntArgs& p, const IntArgs& u, IntConLevel icl) {
    using namespace Gecode::Int;
    using namespace Gecode::Int::Cumulative;
    if ((s.size() != p.size()) || (s.size() != u.size()))
      throw Int::ArgumentSizeMismatch("Int::cumulative");
    long long int w = 0;
    for (int i=p.size(); i--; ) {
      Limits::nonnegative(p[i],"Int::cumulative");
      Limits::nonnegative(u[i],"Int::cumulative");
      Limits::check(static_cast<long long int>(s[i].max()) + p[i],
                    "Int::cumulative");
      mul_check(p[i],u[i]);
      w += s[i].width();
    }
    mul_check(c.max(),w,s.size());
    if (home.failed()) return;

    int minU = INT_MAX; int minU2 = INT_MAX; int maxU = INT_MIN;
    for (int i=u.size(); i--;) {
      if (u[i] < minU) {
        minU2 = minU;
        minU = u[i];
      } else if (u[i] < minU2)
        minU2 = u[i];
      if (u[i] > maxU)
        maxU = u[i];
    }
    bool disjunctive = 
      (minU > c.max()/2) || (minU2 > c.max()/2 && minU+minU2>c.max());
    if (disjunctive) {
      GECODE_ME_FAIL(c.gq(home,maxU));
      unary(home,s,p,icl);
    } else {
      int nonOptionals = 0;
      for (unsigned int i=u.size(); i--;)
        if (u[i]>0) nonOptionals++;
      TaskArray<ManFixPTask> t(home,nonOptionals);
      int cur = 0;
      for (int i=0; i<s.size(); i++)
        if (u[i]>0)
          t[cur++].init(s[i],p[i],u[i]);
      GECODE_ES_FAIL((ManProp<ManFixPTask,Cap>::post(home,c,t)));
    }
  }
Esempio n. 15
0
  void
  cumulative(Home home, Cap c, const IntVarArgs& s, const IntVarArgs& p,
             const IntVarArgs& e, const IntArgs& u, const BoolVarArgs& m, 
             IntConLevel icl) {
    using namespace Gecode::Int;
    using namespace Gecode::Int::Cumulative;
    if ((s.size() != p.size()) || (s.size() != u.size()) ||
        (s.size() != e.size()) || (s.size() != m.size()))
      throw Int::ArgumentSizeMismatch("Int::cumulative");
    for (int i=p.size(); i--; ) {
      rel(home, p[i], IRT_GQ, 0);
    }
    long long int w = 0;
    for (int i=p.size(); i--; ) {
      Limits::nonnegative(u[i],"Int::cumulative");
      Limits::check(static_cast<long long int>(s[i].max()) + p[i].max(),
                    "Int::cumulative");
      mul_check(p[i].max(),u[i]);
      w += s[i].width();
    }
    mul_check(c.max(),w,s.size());
    if (home.failed()) return;

    bool allMandatory = true;
    for (int i=m.size(); i--;) {
      if (!m[i].one()) {
        allMandatory = false;
        break;
      }
    }
    if (allMandatory) {
      cumulative(home,c,s,p,e,u,icl);
    } else {
      int nonOptionals = 0;
      for (unsigned int i=u.size(); i--;)
        if (u[i]>0) nonOptionals++;
      TaskArray<OptFlexTask> t(home,nonOptionals);
      int cur = 0;
      for (int i=s.size(); i--; )
        if (u[i]>0)
          t[cur++].init(s[i],p[i],e[i],u[i],m[i]);
      GECODE_ES_FAIL((OptProp<OptFlexTask,Cap>::post(home,c,t)));
    }
  }
Esempio n. 16
0
 void
 unary(Home home, const TaskTypeArgs& t,
       const IntVarArgs& flex, const IntArgs& fix, const BoolVarArgs& m,
       IntPropLevel ipl) {
   using namespace Gecode::Int;
   using namespace Gecode::Int::Unary;
   if ((flex.size() != fix.size()) || (flex.size() != t.size()) ||
       (flex.size() != m.size()))
     throw Int::ArgumentSizeMismatch("Int::unary");
   bool fixp = true;
   for (int i=fix.size(); i--; ) {
     if (t[i] == TT_FIXP) {
       Int::Limits::nonnegative(fix[i],"Int::unary");
     } else {
       fixp = false;
       Int::Limits::check(fix[i],"Int::unary");
     }
     Int::Limits::check(static_cast<long long int>(flex[i].max()) + fix[i],
                        "Int::unary");
   }
   GECODE_POST;
   bool allMandatory = true;
   for (int i=m.size(); i--;) {
     if (!m[i].one()) {
       allMandatory = false;
       break;
     }
   }
   if (allMandatory) {
     unary(home,t,flex,fix,ipl);
   } else {
     if (fixp) {
       TaskArray<OptFixPTask> tasks(home,flex.size());
       for (int i=flex.size(); i--; )
         tasks[i].init(flex[i],fix[i],m[i]);
       GECODE_ES_FAIL(optpost(home,tasks,ipl));
     } else {
       TaskArray<OptFixPSETask> tasks(home,flex.size());
       for (int i=flex.size(); i--;)
         tasks[i].init(t[i],flex[i],fix[i],m[i]);
       GECODE_ES_FAIL(optpost(home,tasks,ipl));
     }
   }
 }
Esempio n. 17
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));
   }
 }
Esempio n. 18
0
/*
 * Post the constraint that the rectangles defined by the coordinates
 * x and y and width w and height h do not overlap.
 *
 * This is the function that you will call from your model. The best
 * is to paste the entire file into your model.
 */
void nooverlap(Home home, 
               const IntVarArgs& x, const IntArgs& w,
               const IntVarArgs& y, const IntArgs& h) {
  // Check whether the arguments make sense
  if ((x.size() != y.size()) || (x.size() != w.size()) ||
      (y.size() != h.size()))
    throw ArgumentSizeMismatch("nooverlap");
  // Never post a propagator in a failed space
  if (home.failed()) return;
  // Set up array of views for the coordinates
  ViewArray<IntView> vx(home,x);
  ViewArray<IntView> vy(home,y);
  // Set up arrays (allocated in home) for width and height and initialize
  int* wc = static_cast<Space&>(home).alloc<int>(x.size());
  int* hc = static_cast<Space&>(home).alloc<int>(y.size());
  for (int i=x.size(); i--; ) {
    wc[i]=w[i]; hc[i]=h[i];
  }
  // If posting failed, fail space
  if (NoOverlap::post(home,vx,wc,vy,hc) != ES_OK)
    home.fail();
}
Esempio n. 19
0
 void
 linear(Home home,
        const IntArgs& a, const IntVarArgs& x, IntRelType r, int c, BoolVar b,
        IntConLevel) {
   if (a.size() != x.size())
     throw ArgumentSizeMismatch("Int::linear");
   if (home.failed()) return;
   Region re(home);
   Linear::Term<IntView>* t = re.alloc<Linear::Term<IntView> >(x.size());
   for (int i = x.size(); i--; ) {
     t[i].a=a[i]; t[i].x=x[i];
   }
   Linear::post(home,t,x.size(),r,c,b);
 }
Esempio n. 20
0
 LinExpr::LinExpr(const IntArgs& a, const BoolVarArgs& x) :
   n(new Node) {
   if (a.size() != x.size())
     throw Int::ArgumentSizeMismatch("MiniModel::LinExpr");
   n->n_int = 0;
   n->n_bool = x.size();
   n->t = NT_SUM_BOOL;
   n->l = n->r = NULL;
   if (x.size() > 0) {
     n->sum.tb = heap.alloc<Int::Linear::Term<Int::BoolView> >(x.size());
     for (int i=x.size(); i--; ) {
       n->sum.tb[i].x = x[i];
       n->sum.tb[i].a = a[i];
     }
   }
 }
Esempio n. 21
0
 void
 circuit(Home home, const IntArgs& c, 
         const IntVarArgs& x, const IntVarArgs& y, IntVar z, 
         IntConLevel icl) {
   int n = x.size();
   if ((y.size() != n) || (c.size() != n*n))
     throw Int::ArgumentSizeMismatch("Graph::circuit");
   circuit(home, x, icl);
   if (home.failed()) return;
   IntArgs cx(n);
   for (int i=n; i--; ) {
     for (int j=0; j<n; j++)
       cx[j] = c[i*n+j];
     element(home, cx, x[i], y[i]);
   }
   linear(home, y, IRT_EQ, z);
 }
Esempio n. 22
0
void
linear(Home home,
       const IntArgs& a, const BoolVarArgs& x, IntRelType irt, IntVar y,
       Reify r, IntPropLevel ipl) {
    if (a.size() != x.size())
        throw ArgumentSizeMismatch("Int::linear");
    GECODE_POST;

    int n=x.size();
    Region re(home);
    Linear::Term<BoolView>* t = re.alloc<Linear::Term<BoolView> >(n);
    for (int i=n; i--; ) {
        t[i].a=a[i];
        t[i].x=x[i];
    }

    Linear::post(home,t,n,irt,y,r,ipl);
}
Esempio n. 23
0
 REG::REG(const IntArgs& x) {
   int n = x.size();
   if (n < 1)
     throw MiniModel::TooFewArguments("REG");
   Exp** a = heap.alloc<Exp*>(n);
   // Initialize with symbols
   for (int i=n; i--; ) {
     a[i] = new Exp();
     a[i]->use_cnt     = 1;
     a[i]->_n_pos      = 1;
     a[i]->type        = REG::Exp::ET_SYMBOL;
     a[i]->data.symbol = x[i];
   }
   // Build a balanced tree of alternative nodes
   for (int m=n; m>1; ) {
     if (m & 1) {
       m -= 1;
       Exp* e1 = a[m];
       Exp* e2 = a[0];
       a[0] = new Exp;
       a[0]->use_cnt      = 1;
       a[0]->_n_pos       = e1->n_pos() + e2->n_pos();
       a[0]->type         = REG::Exp::ET_OR;
       a[0]->data.kids[0] = e1;
       a[0]->data.kids[1] = e2;
     } else {
       m >>= 1;
       for (int i=0; i<m; i++) {
         Exp* e1 = a[2*i];
         Exp* e2 = a[2*i+1];
         a[i] = new Exp;
         a[i]->use_cnt      = 1;
         a[i]->_n_pos       = e1->n_pos() + e2->n_pos();
         a[i]->type         = REG::Exp::ET_OR;
         a[i]->data.kids[0] = e1;
         a[i]->data.kids[1] = e2;
       }
     }
   }
   e = a[0];
   heap.free<Exp*>(a,n);
 }
Esempio n. 24
0
void
linear(Home home,
       const IntArgs& a, const BoolVarArgs& x, IntRelType irt, IntVar y,
       IntPropLevel ipl) {
    if (a.size() != x.size())
        throw ArgumentSizeMismatch("Int::linear");

    GECODE_POST;

    int n=x.size();
    Region re(home);
    Linear::Term<BoolView>* t =
        re.alloc<Linear::Term<BoolView> >(n);
    for (int i=n; i--; ) {
        t[i].a=a[i];
        t[i].x=x[i];
    }
    int min, max;
    estimate(t,n,0,min,max);
    IntView v(y);
    switch (irt) {
    case IRT_EQ:
        GECODE_ME_FAIL(v.gq(home,min));
        GECODE_ME_FAIL(v.lq(home,max));
        break;
    case IRT_GQ:
        GECODE_ME_FAIL(v.lq(home,max));
        break;
    case IRT_LQ:
        GECODE_ME_FAIL(v.gq(home,min));
        break;
    default:
        ;
    }
    if (home.failed()) return;
    Linear::post(home,t,n,irt,y,0,ipl);
}
Esempio n. 25
0
 static void init(IntSet& s, const IntArgs& i) {
   if (i.size() > 0)
     s.init(&i[0],i.size());
 }
  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();
    }
  }