예제 #1
0
DECLARE_EXPORT Calendar::~Calendar()
{
  // De-allocate all the dynamic memory used for the bucket objects
  while (firstBucket)
  {
    CalendarBucket* tmp = firstBucket;
    firstBucket = firstBucket->nextBucket;
    delete tmp;
  }

  // Remove all references from locations
  for (Location::iterator l = Location::begin(); l != Location::end(); ++l)
  {
    if (l->getAvailable() == this)
      l->setAvailable(NULL);
  }

  // Remove reference from buffers
  for (Buffer::iterator b = Buffer::begin(); b != Buffer::end(); ++b)
  {
    if (b->getMaximumCalendar() == this)
      b->setMaximumCalendar(NULL);
    if (b->getMinimumCalendar() == this)
      b->setMinimumCalendar(NULL);
  }

  // Remove references from resources
  for (Resource::iterator r = Resource::begin(); r != Resource::end(); ++r)
  {
    if (r->getMaximumCalendar() == this)
      r->setMaximumCalendar(NULL);
  }
}
예제 #2
0
DECLARE_EXPORT SetupMatrix::~SetupMatrix()
{
  // Destroy the rules.
  // Note that the rule destructor updates the firstRule field.
  while (firstRule) delete firstRule;

  // Remove all references to this setup matrix from resources
  for (Resource::iterator m = Resource::begin(); m != Resource::end(); ++m)
    if (m->getSetupMatrix() == this) m->setSetupMatrix(NULL);
}
예제 #3
0
Location::~Location()
{
  // Remove all references from buffers to this location
  for (Buffer::iterator buf = Buffer::begin();
      buf != Buffer::end(); ++buf)
    if (buf->getLocation() == this)
      buf->setLocation(nullptr);

  // Remove all references from resources to this location
  for (Resource::iterator res = Resource::begin();
      res != Resource::end(); ++res)
    if (res->getLocation() == this)
      res->setLocation(nullptr);

  // Remove all references from operations to this location
  for (Operation::iterator oper = Operation::begin();
      oper != Operation::end(); ++oper)
    if (oper->getLocation() == this)
      oper->setLocation(nullptr);

  // Remove all references from demands to this location
  for (Demand::iterator dmd = Demand::begin();
      dmd != Demand::end(); ++dmd)
    if (dmd->getLocation() == this)
      dmd->setLocation(nullptr);

  // Remove all item suppliers referencing this location
  for (Supplier::iterator sup = Supplier::begin();
    sup != Supplier::end(); ++sup)
  {
    for (Supplier::itemlist::const_iterator it = sup->getItems().begin();
      it != sup->getItems().end(); )
    {
      if (it->getLocation() == this)
      {
        const ItemSupplier *itemsup = &*it;
        ++it;   // Advance iterator before the delete
        delete itemsup;
      }
      else
        ++it;
    }
  }

  // The ItemDistribution objects are automatically deleted by the
  // destructor of the Association list class.
}
예제 #4
0
DECLARE_EXPORT Location::~Location()
{
  // Remove all references from buffers to this location
  for (Buffer::iterator buf = Buffer::begin();
      buf != Buffer::end(); ++buf)
    if (buf->getLocation() == this) buf->setLocation(NULL);

  // Remove all references from resources to this location
  for (Resource::iterator res = Resource::begin();
      res != Resource::end(); ++res)
    if (res->getLocation() == this) res->setLocation(NULL);

  // Remove all references from operations to this location
  for (Operation::iterator oper = Operation::begin();
      oper != Operation::end(); ++oper)
    if (oper->getLocation() == this) oper->setLocation(NULL);
}
예제 #5
0
void ResourceSkill::writer(const MetaCategory* c, XMLOutput* o)
{
  bool first = true;
  for (Resource::iterator i = Resource::begin(); i != Resource::end(); ++i)
    for (Resource::skilllist::const_iterator j = i->getSkills().begin(); j != i->getSkills().end(); ++j)
    {
      if (first)
      {
        o->BeginObject(Tags::tag_resourceskills);
        first = false;
      }
      // We use the FULL mode, to force the flows being written regardless
      // of the depth in the XML tree.
      o->writeElement(Tags::tag_resourceskill, &*j, FULL);
    }
  if (!first) o->EndObject(Tags::tag_resourceskills);
}
예제 #6
0
DECLARE_EXPORT void SolverMRP::solve(void *v)
{
  // Count how many clusters we have to plan
  int cl = HasLevel::getNumberOfClusters() + 1;

  // Categorize all demands in their cluster
  demands_per_cluster.resize(cl);
  for (Demand::iterator i = Demand::begin(); i != Demand::end(); ++i)
    demands_per_cluster[i->getCluster()].push_back(&*i);

  // Delete of operationplans of the affected clusters
  // This deletion is not multi-threaded... But on the other hand we need to
  // loop through the operations only once (rather than as many times as there
  // are clusters)
  if (getErasePreviousFirst())
  {
    if (getLogLevel()>0) logger << "Deleting previous plan" << endl;
    for (Operation::iterator e=Operation::begin(); e!=Operation::end(); ++e)
      e->deleteOperationPlans();
  }

  // Solve in parallel threads.
  // When not solving in silent and autocommit mode, we only use a single
  // solver thread.
  // Otherwise we use as many worker threads as processor cores.
  ThreadGroup threads;
  if (getLogLevel()>0 || !getAutocommit())
    threads.setMaxParallel(1);

  // Register all clusters to be solved
  for (int j = 0; j < cl; ++j)
    threads.add(
      SolverMRPdata::runme,
      new SolverMRPdata(this, j, &(demands_per_cluster[j]))
      );

  // Run the planning command threads and wait for them to exit
  threads.execute();

  // @todo Check the resource setups that were broken - needs to be removed
  for (Resource::iterator gres = Resource::begin(); gres != Resource::end(); ++gres)
    if (gres->getSetupMatrix()) gres->updateSetups();
}
예제 #7
0
DECLARE_EXPORT PyObject* printModelSize(PyObject* self, PyObject* args)
{
  // Free Python interpreter for other threads
  Py_BEGIN_ALLOW_THREADS

  // Execute and catch exceptions
  size_t count, memsize;
  try
  {

    // Intro
    logger << endl << "Size information of frePPLe " << PACKAGE_VERSION
        << " (" << __DATE__ << ")" << endl << endl;

    // Print current locale
#if defined(HAVE_SETLOCALE) || defined(_MSC_VER)
    logger << "Locale: " << setlocale(LC_ALL,NULL) << endl << endl;
#else
    logger << endl;
#endif

    // Print loaded modules
    Environment::printModules();

    // Print the number of clusters
    logger << "Clusters: " << HasLevel::getNumberOfClusters()
        << " (hanging: " << HasLevel::getNumberOfHangingClusters() << ")"
        << endl << endl;

    // Header for memory size
    logger << "Memory usage:" << endl;
    logger << "Model        \tNumber\tMemory" << endl;
    logger << "-----        \t------\t------" << endl;

    // Plan
    size_t total = Plan::instance().getSize();
    logger << "Plan         \t1\t"<< Plan::instance().getSize() << endl;

    // Locations
    memsize = 0;
    for (Location::iterator l = Location::begin(); l != Location::end(); ++l)
      memsize += l->getSize();
    logger << "Location     \t" << Location::size() << "\t" << memsize << endl;
    total += memsize;

    // Customers
    memsize = 0;
    for (Customer::iterator c = Customer::begin(); c != Customer::end(); ++c)
      memsize += c->getSize();
    logger << "Customer     \t" << Customer::size() << "\t" << memsize << endl;
    total += memsize;

    // Buffers
    memsize = 0;
    for (Buffer::iterator b = Buffer::begin(); b != Buffer::end(); ++b)
      memsize += b->getSize();
    logger << "Buffer       \t" << Buffer::size() << "\t" << memsize << endl;
    total += memsize;

    // Setup matrices
    memsize = 0;
    for (SetupMatrix::iterator s = SetupMatrix::begin(); s != SetupMatrix::end(); ++s)
      memsize += s->getSize();
    logger << "Setup matrix \t" << SetupMatrix::size() << "\t" << memsize << endl;
    total += memsize;

    // Resources
    memsize = 0;
    for (Resource::iterator r = Resource::begin(); r != Resource::end(); ++r)
      memsize += r->getSize();
    logger << "Resource     \t" << Resource::size() << "\t" << memsize << endl;
    total += memsize;

    // Skills and resourceskills
    size_t countResourceSkills(0), memResourceSkills(0);
    memsize = 0;
    for (Skill::iterator sk = Skill::begin(); sk != Skill::end(); ++sk)
    {
      memsize += sk->getSize();
      for (Skill::resourcelist::const_iterator rs = sk->getResources().begin();
          rs != sk->getResources().end(); ++rs)
      {
        ++countResourceSkills;
        memResourceSkills += rs->getSize();
      }
    }
    logger << "Skill     \t" << Skill::size() << "\t" << memsize << endl;
    logger << "ResourceSkill     \t" << countResourceSkills << "\t" << memResourceSkills << endl;
    total += memsize;

    // Operations, flows and loads
    size_t countFlows(0), memFlows(0), countLoads(0), memLoads(0);
    memsize = 0;
    for (Operation::iterator o = Operation::begin(); o != Operation::end(); ++o)
    {
      memsize += o->getSize();
      for (Operation::flowlist::const_iterator fl = o->getFlows().begin();
          fl != o->getFlows().end(); ++ fl)
      {
        ++countFlows;
        memFlows += fl->getSize();
      }
      for (Operation::loadlist::const_iterator ld = o->getLoads().begin();
          ld != o->getLoads().end(); ++ ld)
      {
        ++countLoads;
        memLoads += ld->getSize();
      }
    }
    logger << "Operation    \t" << Operation::size() << "\t" << memsize << endl;
    logger << "Flow         \t" << countFlows << "\t" << memFlows  << endl;
    logger << "Load         \t" << countLoads << "\t" << memLoads  << endl;
    total += memsize + memFlows + memLoads;

    // Calendars (which includes the buckets)
    memsize = 0;
    for (Calendar::iterator cl = Calendar::begin(); cl != Calendar::end(); ++cl)
      memsize += cl->getSize();
    logger << "Calendar     \t" << Calendar::size() << "\t" << memsize  << endl;
    total += memsize;

    // Items
    memsize = 0;
    for (Item::iterator i = Item::begin(); i != Item::end(); ++i)
      memsize += i->getSize();
    logger << "Item         \t" << Item::size() << "\t" << memsize  << endl;
    total += memsize;

    // Demands
    memsize = 0;
    size_t c_count = 0, c_memsize = 0;
    for (Demand::iterator dm = Demand::begin(); dm != Demand::end(); ++dm)
    {
      memsize += dm->getSize();
      for (Problem::const_iterator cstrnt(dm->getConstraints().begin());
        cstrnt != dm->getConstraints().end(); ++cstrnt)
      {
        ++c_count;
        c_memsize += cstrnt->getSize();
      }
    }
    logger << "Demand       \t" << Demand::size() << "\t" << memsize  << endl;
    logger << "Constraints  \t" << c_count << "\t" << c_memsize  << endl;
    total += memsize + c_memsize;

    // Operationplans
    size_t countloadplans(0), countflowplans(0);
    memsize = count = 0;
    for (OperationPlan::iterator j = OperationPlan::begin();
        j!=OperationPlan::end(); ++j)
    {
      ++count;
      memsize += sizeof(*j);
      countloadplans += j->sizeLoadPlans();
      countflowplans += j->sizeFlowPlans();
    }
    total += memsize;
    logger << "OperationPlan\t" << count << "\t" << memsize << endl;

    // Flowplans
    memsize = countflowplans * sizeof(FlowPlan);
    total +=  memsize;
    logger << "FlowPlan     \t" << countflowplans << "\t" << memsize << endl;

    // Loadplans
    memsize = countloadplans * sizeof(LoadPlan);
    total +=  memsize;
    logger << "LoadPlan     \t" << countloadplans << "\t" << memsize << endl;

    // Problems
    memsize = count = 0;
    for (Problem::const_iterator pr = Problem::begin(); pr!=Problem::end(); ++pr)
    {
      ++count;
      memsize += pr->getSize();
    }
    total += memsize;
    logger << "Problem      \t" << count << "\t" << memsize << endl;

    // TOTAL
    logger << "Total        \t\t" << total << endl << endl;
  }
  catch (...)
  {
    Py_BLOCK_THREADS;
    PythonType::evalException();
    return NULL;
  }
  Py_END_ALLOW_THREADS   // Reclaim Python interpreter
  return Py_BuildValue("");
}
예제 #8
0
DECLARE_EXPORT PyObject* savePlan(PyObject* self, PyObject* args)
{
  // Pick up arguments
  const char *filename = "plan.out";
  int ok = PyArg_ParseTuple(args, "s:saveplan", &filename);
  if (!ok) return NULL;

  // Free Python interpreter for other threads
  Py_BEGIN_ALLOW_THREADS

  // Execute and catch exceptions
  ofstream textoutput;
  try
  {
    // Open the output file
    textoutput.open(filename, ios::out);

    // Write the buffer summary
    for (Buffer::iterator gbuf = Buffer::begin();
        gbuf != Buffer::end(); ++gbuf)
    {
      if (!gbuf->getHidden())
        for (Buffer::flowplanlist::const_iterator
            oo=gbuf->getFlowPlans().begin();
            oo!=gbuf->getFlowPlans().end();
            ++oo)
          if (oo->getType() == 1 && oo->getQuantity() != 0.0)
          {
            textoutput << "BUFFER\t" << *gbuf << '\t'
                << oo->getDate() << '\t'
                << oo->getQuantity() << '\t'
                << oo->getOnhand() << endl;
          }
    }

    // Write the demand summary
    for (Demand::iterator gdem = Demand::begin();
        gdem != Demand::end(); ++gdem)
    {
      if (!gdem->getHidden())
      {
        for (Demand::OperationPlan_list::const_iterator
            pp = gdem->getDelivery().begin();
            pp != gdem->getDelivery().end();
            ++pp)
          textoutput << "DEMAND\t" << (*gdem) << '\t'
              << (*pp)->getDates().getEnd() << '\t'
              << (*pp)->getQuantity() << endl;
      }
    }

    // Write the resource summary
    for (Resource::iterator gres = Resource::begin();
        gres != Resource::end(); ++gres)
    {
      if (!gres->getHidden())
        for (Resource::loadplanlist::const_iterator
            qq=gres->getLoadPlans().begin();
            qq!=gres->getLoadPlans().end();
            ++qq)
          if (qq->getType() == 1 && qq->getQuantity() != 0.0)
          {
            textoutput << "RESOURCE\t" << *gres << '\t'
                << qq->getDate() << '\t'
                << qq->getQuantity() << '\t'
                << qq->getOnhand() << endl;
          }
    }

    // Write the operationplan summary.
    for (OperationPlan::iterator rr = OperationPlan::begin();
        rr != OperationPlan::end(); ++rr)
    {
      if (rr->getOperation()->getHidden()) continue;
      textoutput << "OPERATION\t" << rr->getOperation() << '\t'
          << rr->getDates().getStart() << '\t'
          << rr->getDates().getEnd() << '\t'
          << rr->getQuantity() << endl;
    }

    // Write the problem summary.
    for (Problem::const_iterator gprob = Problem::begin();
        gprob != Problem::end(); ++gprob)
    {
      textoutput << "PROBLEM\t" << gprob->getType().type << '\t'
          << gprob->getDescription() << '\t'
          << gprob->getDates() << endl;
    }

    // Write the constraint summary
    for (Demand::iterator gdem = Demand::begin();
        gdem != Demand::end(); ++gdem)
    {
      if (!gdem->getHidden())
      {
        for (Problem::const_iterator i = gdem->getConstraints().begin();
            i != gdem->getConstraints().end();
            ++i)
          textoutput << "DEMAND CONSTRAINT\t" << (*gdem) << '\t'
              << i->getDescription() << '\t'
              << i->getDates() << '\t' << endl;
      }
    }

    // Close the output file
    textoutput.close();
  }
  catch (...)
  {
    if (textoutput.is_open())
      textoutput.close();
    Py_BLOCK_THREADS;
    PythonType::evalException();
    return NULL;
  }
  Py_END_ALLOW_THREADS   // Reclaim Python interpreter
  return Py_BuildValue("");
}