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); } }
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); }
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. }
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); }
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); }
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(); }
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(""); }
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(""); }