00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #define FREPPLE_CORE
00028 #include "frepple/solver.h"
00029 namespace frepple
00030 {
00031
00032 DECLARE_EXPORT const MetaClass* SolverMRP::metadata;
00033
00034 void LibrarySolver::initialize()
00035 {
00036
00037 static bool init = false;
00038 if (init)
00039 {
00040 logger << "Warning: Calling frepple::LibrarySolver::initialize() more "
00041 << "than once." << endl;
00042 return;
00043 }
00044 init = true;
00045
00046
00047 SolverMRP::metadata = new MetaClass(
00048 "solver",
00049 "solver_mrp",
00050 Object::createString<SolverMRP>,
00051 true);
00052
00053 if (PythonSolverMRP::initialize(PythonInterpreter::getModule()))
00054 throw RuntimeException("Error registering solver_mrp Python type");
00055 }
00056
00057
00058 DECLARE_EXPORT bool SolverMRP::demand_comparison(const Demand* l1, const Demand* l2)
00059 {
00060 if (l1->getPriority() != l2->getPriority())
00061 return l1->getPriority() < l2->getPriority();
00062 else if (l1->getDue() != l2->getDue())
00063 return l1->getDue() < l2->getDue();
00064 else
00065 return l1->getQuantity() < l2->getQuantity();
00066 }
00067
00068
00069 DECLARE_EXPORT void SolverMRP::SolverMRPdata::execute()
00070 {
00071
00072 SolverMRP* Solver = getSolver();
00073 if (Solver->getLogLevel()>0)
00074 logger << "Start solving cluster " << cluster << " at " << Date::now() << endl;
00075
00076
00077 try
00078 {
00079
00080
00081
00082 stable_sort(demands.begin(), demands.end(), demand_comparison);
00083
00084
00085 for (deque<Demand*>::const_iterator i = demands.begin();
00086 i != demands.end(); ++i)
00087
00088 try
00089 {
00090 State* mystate = state;
00091 push();
00092 try { (*i)->solve(*Solver,this); }
00093 catch (...)
00094 {
00095 while (state > mystate) pop();
00096 throw;
00097 }
00098 while (state > mystate) pop();
00099 }
00100 catch (...)
00101 {
00102
00103 logger << "Error: Caught an exception while solving demand '"
00104 << (*i)->getName() << "':" << endl;
00105 try { throw; }
00106 catch (bad_exception&) {logger << " bad exception" << endl;}
00107 catch (exception& e) {logger << " " << e.what() << endl;}
00108 catch (...) {logger << " Unknown type" << endl;}
00109
00110
00111 undo();
00112 }
00113
00114
00115 demands.clear();
00116 }
00117 catch (...)
00118 {
00119
00120
00121
00122
00123
00124
00125 logger << "Error: Caught an exception while solving cluster "
00126 << cluster << ":" << endl;
00127 try { throw; }
00128 catch (bad_exception&){logger << " bad exception" << endl;}
00129 catch (exception& e) {logger << " " << e.what() << endl;}
00130 catch (...) {logger << " Unknown type" << endl;}
00131
00132
00133 for (Operation::iterator f=Operation::begin(); f!=Operation::end(); ++f)
00134 if (f->getCluster() == cluster)
00135 f->deleteOperationPlans();
00136 }
00137
00138
00139 if (Solver->getLogLevel()>0)
00140 logger << "End solving cluster " << cluster << " at " << Date::now() << endl;
00141 }
00142
00143
00144 DECLARE_EXPORT void SolverMRP::solve(void *v)
00145 {
00146
00147 for (Demand::iterator i = Demand::begin(); i != Demand::end(); ++i)
00148 demands_per_cluster[i->getCluster()].push_back(&*i);
00149
00150
00151
00152
00153
00154
00155
00156 if (getLogLevel()>0) logger << "Deleting previous plan" << endl;
00157 for (Operation::iterator e=Operation::begin(); e!=Operation::end(); ++e)
00158
00159 if (demands_per_cluster.find(e->getCluster())!=demands_per_cluster.end())
00160 e->deleteOperationPlans();
00161
00162
00163 int cl = demands_per_cluster.size();
00164 if (cl<1) return;
00165
00166
00167 CommandList threads;
00168
00169
00170 if (getLogLevel()>0)
00171 threads.setMaxParallel(1);
00172 else
00173 threads.setMaxParallel( cl > getMaxParallel() ? getMaxParallel() : cl);
00174
00175
00176 threads.setAbortOnError(false);
00177 for (classified_demand::iterator j = demands_per_cluster.begin();
00178 j != demands_per_cluster.end(); ++j)
00179 threads.add(new SolverMRPdata(this, j->first, j->second));
00180
00181
00182 threads.execute();
00183 }
00184
00185
00186 DECLARE_EXPORT void SolverMRP::writeElement(XMLOutput *o, const Keyword& tag, mode m) const
00187 {
00188
00189 if (m == REFERENCE)
00190 {
00191 o->writeElement
00192 (tag, Tags::tag_name, getName(), Tags::tag_type, getType().type);
00193 return;
00194 }
00195
00196
00197 if (m != NOHEADER) o->BeginObject
00198 (tag, Tags::tag_name, getName(), Tags::tag_type, getType().type);
00199
00200
00201 if (constrts) o->writeElement(Tags::tag_constraints, constrts);
00202 if (maxparallel) o->writeElement(Tags::tag_maxparallel, maxparallel);
00203
00204
00205 Solver::writeElement(o, tag, NOHEADER);
00206 }
00207
00208
00209 DECLARE_EXPORT void SolverMRP::endElement(XMLInput& pIn, const Attribute& pAttr, const DataElement& pElement)
00210 {
00211 if (pAttr.isA(Tags::tag_constraints))
00212 setConstraints(pElement.getInt());
00213 else if (pAttr.isA(Tags::tag_maxparallel))
00214 setMaxParallel(pElement.getInt());
00215 else
00216 Solver::endElement(pIn, pAttr, pElement);
00217 }
00218
00219
00220 DECLARE_EXPORT PyObject* PythonSolverMRP::getattro(const Attribute& attr)
00221 {
00222 if (!obj) return Py_BuildValue("");
00223 if (attr.isA(Tags::tag_constraints))
00224 return PythonObject(obj->getConstraints());
00225 if (attr.isA(Tags::tag_maxparallel))
00226 return PythonObject(obj->getMaxParallel());
00227 return PythonSolver(obj).getattro(attr);
00228 }
00229
00230
00231 DECLARE_EXPORT int PythonSolverMRP::setattro(const Attribute& attr, const PythonObject& field)
00232 {
00233 if (attr.isA(Tags::tag_constraints))
00234 obj->setConstraints(field.getInt());
00235 else if (attr.isA(Tags::tag_maxparallel))
00236 obj->setMaxParallel(field.getInt());
00237 else
00238 return PythonSolver(obj).setattro(attr, field);
00239 return 0;
00240 }
00241
00242 }