Beispiel #1
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));
   }
 }
 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)));
     }
   }
 }
Beispiel #3
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));
     }
   }
 }
  void
  cumulative(Home home, Cap c, const TaskTypeArgs& t,
             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()) ||
        (s.size() != t.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,t,s,p,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<ManFixPTask> 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]);
        GECODE_ES_FAIL((ManProp<ManFixPTask,Cap>::post(home,c,tasks)));
      } else {
        TaskArray<ManFixPSETask> 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]);
        GECODE_ES_FAIL((ManProp<ManFixPSETask,Cap>::post(home,c,tasks)));
      }
    }
  }