solver.h
Go to the documentation of this file.00001 /*************************************************************************** 00002 file : $URL: https://frepple.svn.sourceforge.net/svnroot/frepple/trunk/include/frepple/solver.h $ 00003 version : $LastChangedRevision: 1315 $ $LastChangedBy: jdetaeye $ 00004 date : $LastChangedDate: 2010-07-17 18:08:53 +0200 (Sat, 17 Jul 2010) $ 00005 ***************************************************************************/ 00006 00007 /*************************************************************************** 00008 * * 00009 * Copyright (C) 2007-2010 by Johan De Taeye * 00010 * * 00011 * This library is free software; you can redistribute it and/or modify it * 00012 * under the terms of the GNU Lesser General Public License as published * 00013 * by the Free Software Foundation; either version 2.1 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 * This library is distributed in the hope that it will be useful, * 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * 00019 * General Public License for more details. * 00020 * * 00021 * You should have received a copy of the GNU Lesser General Public * 00022 * License along with this library; if not, write to the Free Software * 00023 * Foundation Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * 00024 * USA * 00025 * * 00026 ***************************************************************************/ 00027 00028 #ifndef SOLVER_H 00029 #define SOLVER_H 00030 00031 #include "frepple/model.h" 00032 #ifndef DOXYGEN 00033 #include <deque> 00034 #include <cmath> 00035 #endif 00036 00037 namespace frepple 00038 { 00039 00040 /** @brief This solver implements a heuristic algorithm for planning demands. 00041 * 00042 * One by one the demands are processed. The demand will consume step by step 00043 * any upstream materials, respecting all constraints on its path.<br> 00044 * The solver supports all planning constraints as defined in Solver 00045 * class.<br> 00046 * See the documentation of the different solve methods to understand the 00047 * functionality in more detail. 00048 * 00049 * The logging levels have the following meaning: 00050 * - 0: Silent operation. Default logging level. 00051 * - 1: Show solver progress for each demand. 00052 * - 2: Show the complete ask&reply communication of the solver. 00053 * - 3: Trace the status of all entities. 00054 */ 00055 class SolverMRP : public Solver 00056 { 00057 protected: 00058 /** This variable stores the constraint which the solver should respect. 00059 * By default no constraints are enabled. */ 00060 short constrts; 00061 00062 /** Behavior of this solver method is: 00063 * - It will ask the consuming flows for the required quantity. 00064 * - The quantity asked for takes into account the quantity_per of the 00065 * producing flow. 00066 * - The date asked for takes into account the post-operation time 00067 * of the operation. 00068 */ 00069 DECLARE_EXPORT void solve(const Operation*, void* = NULL); 00070 00071 /** Behavior of this solver method is: 00072 * - Asks each of the routing steps for the requested quantity, starting 00073 * with the last routing step.<br> 00074 * The time requested for the operation is based on the start date of 00075 * the next routing step. 00076 */ 00077 DECLARE_EXPORT void solve(const OperationRouting*, void* = NULL); 00078 00079 /** Behavior of this solver method is: 00080 * - The solver loops through each alternate operation in order of 00081 * priority. On each alternate operation, the solver will try to plan 00082 * the quantity that hasn't been planned on higher priority alternates. 00083 * - As a special case, operations with zero priority are skipped in the 00084 * loop. These operations are considered to be temporarily unavailable. 00085 * - The requested operation can be planned over multiple alternates. 00086 * We don't garantuee that a request is planned using a single alternate 00087 * operation. 00088 * - The solver properly considers the quantity_per of all flows producing 00089 * into the requested buffer, if such a buffer is specified. 00090 */ 00091 DECLARE_EXPORT void solve(const OperationAlternate*,void* = NULL); 00092 00093 /** Behavior of this solver method: 00094 * - No propagation to upstream buffers at all, even if a producing 00095 * operation has been specified. 00096 * - Always give an answer for the full quantity on the requested date. 00097 */ 00098 DECLARE_EXPORT void solve(const BufferInfinite*,void* = NULL); 00099 00100 /** Behavior of this solver method: 00101 * - Consider 0 as the hard minimum limit. It is not possible 00102 * to plan with a 'hard' safety stock reservation. 00103 * - Minimum inventory is treated as a 'wish' inventory. When replenishing 00104 * a buffer we try to satisfy the minimum target. If that turns out 00105 * not to be possible we use whatever available supply for satisfying 00106 * the demand first. 00107 * - Planning for the minimum target is part of planning a demand. There 00108 * is no planning run independent of demand to satisfy the minimum 00109 * target.<br> 00110 * E.g. If a buffer has no demand on it, the solver won't try to 00111 * replenish to the minimum target.<br> 00112 * E.g. If the minimum target increases after the latest date required 00113 * for satisfying a certain demand that change will not be considered. 00114 * - The solver completely ignores the maximum target. 00115 */ 00116 DECLARE_EXPORT void solve(const Buffer*, void* = NULL); 00117 00118 /** Behavior of this solver method: 00119 * - When the inventory drops below the minimum inventory level, a new 00120 * replenishment is triggered. 00121 * The replenishment brings the inventory to the maximum level again. 00122 * - The minimum and maximum inventory are soft-constraints. The actual 00123 * inventory can go lower than the minimum or exceed the maximum. 00124 * - The minimum, maximum and multiple size of the replenishment are 00125 * hard constraints, and will always be respected. 00126 * - A minimum and maximum interval between replenishment is also 00127 * respected as a hard constraint. 00128 * - No propagation to upstream buffers at all, even if a producing 00129 * operation has been specified. 00130 * - The minimum calendar isn't used by the solver. 00131 * 00132 * @todo Optimize the solver method as follows for the common case of infinite 00133 * buying capability (ie no max quantity + min time): 00134 * - beyond lead time: always reply OK, without rearranging the operation plans 00135 * - at the end of the solver loop, we revisit the procurement buffers to establish 00136 * the final purchasing profile 00137 */ 00138 DECLARE_EXPORT void solve(const BufferProcure*, void* = NULL); 00139 00140 /** Behavior of this solver method: 00141 * - This method simply passes on the request to the referenced buffer. 00142 * It is called from a solve(Operation*) method and passes on the 00143 * control to a solve(Buffer*) method. 00144 * @see checkOperationMaterial 00145 */ 00146 DECLARE_EXPORT void solve(const Flow*, void* = NULL); 00147 00148 /** Behavior of this solver method: 00149 * - The operationplan is checked for a capacity overload. When detected 00150 * it is moved to an earlier date. 00151 * - This move can be repeated until no capacity is found till a suitable 00152 * time slot is found. If the fence and/or leadtime constraints are 00153 * enabled they can restrict the feasible moving time.<br> 00154 * If a feasible timeslot is found, the method exits here. 00155 * - If no suitable time slot can be found at all, the operation plan is 00156 * put on its original date and we now try to move it to a feasible 00157 * later date. Again, successive moves are possible till a suitable 00158 * slot is found or till we reach the end of the horizon. 00159 * The result of the search is returned as the answer-date to the 00160 * solver. 00161 */ 00162 DECLARE_EXPORT void solve(const Resource*, void* = NULL); 00163 00164 /** Behavior of this solver method: 00165 * - Always return OK. 00166 */ 00167 DECLARE_EXPORT void solve(const ResourceInfinite*,void* = NULL); 00168 00169 /** Behavior of this solver method: 00170 * - This method simply passes on the request to the referenced resource. 00171 * With the current model structure it could easily be avoided (and 00172 * thus gain a bit in performance), but we wanted to include it anyway 00173 * to make the solver as generic and future-proof as possible. 00174 * @see checkOperationCapacity 00175 */ 00176 DECLARE_EXPORT void solve(const Load*, void* = NULL); 00177 00178 /** Behavior of this solver method: 00179 * - Respects the following demand planning policies:<br> 00180 * 1) Maximum allowed lateness 00181 * 2) Minimum shipment quantity 00182 * This method is normally called from within the main solve method, but 00183 * it can also be called independently to plan a certain demand. 00184 * @see solve 00185 */ 00186 DECLARE_EXPORT void solve(const Demand*, void* = NULL); 00187 00188 public: 00189 /** This is the main solver method that will appropriately call the other 00190 * solve methods.<br> 00191 * The demands in the model will all be sorted with the criteria defined in 00192 * the demand_comparison() method. For each of demand the solve(Demand*) 00193 * method is called to plan it. 00194 */ 00195 DECLARE_EXPORT void solve(void *v = NULL); 00196 00197 /** Constructor. */ 00198 SolverMRP(const string& n) : Solver(n), constrts(15), maxparallel(0), 00199 plantype(1), lazydelay(86400L), autocommit(true) 00200 {initType(metadata);} 00201 00202 /** Destructor. */ 00203 virtual ~SolverMRP() {} 00204 00205 DECLARE_EXPORT void writeElement(XMLOutput*, const Keyword&, mode=DEFAULT) const; 00206 DECLARE_EXPORT void endElement(XMLInput& pIn, const Attribute& pAttr, const DataElement& pElement); 00207 virtual DECLARE_EXPORT PyObject* getattro(const Attribute&); 00208 virtual DECLARE_EXPORT int setattro(const Attribute&, const PythonObject&); 00209 static int initialize(); 00210 00211 virtual const MetaClass& getType() const {return *metadata;} 00212 static DECLARE_EXPORT const MetaClass* metadata; 00213 virtual size_t getSize() const {return sizeof(SolverMRP);} 00214 00215 /** Static constant for the LEADTIME constraint type.<br> 00216 * The numeric value is 1. 00217 * @see MATERIAL 00218 * @see CAPACITY 00219 * @see FENCE 00220 */ 00221 static const short LEADTIME = 1; 00222 00223 /** Static constant for the MATERIAL constraint type.<br> 00224 * The numeric value is 2. 00225 * @see LEADTIME 00226 * @see CAPACITY 00227 * @see FENCE 00228 */ 00229 static const short MATERIAL = 2; 00230 00231 /** Static constant for the CAPACITY constraint type.<br> 00232 * The numeric value is 4. 00233 * @see MATERIAL 00234 * @see LEADTIME 00235 * @see FENCE 00236 */ 00237 static const short CAPACITY = 4; 00238 00239 /** Static constant for the FENCE constraint type.<br> 00240 * The numeric value is 8. 00241 * @see MATERIAL 00242 * @see CAPACITY 00243 * @see LEADTIME 00244 */ 00245 static const short FENCE = 8; 00246 00247 /** Update the constraints to be considered by this solver. This field may 00248 * not be applicable for all solvers. */ 00249 void setConstraints(short i) {constrts = i;} 00250 00251 /** Returns the constraints considered by the solve. */ 00252 short getConstraints() const {return constrts;} 00253 00254 /** Returns true if this solver respects the operation release fences. 00255 * The solver isn't allowed to create any operation plans within the 00256 * release fence. 00257 */ 00258 bool isFenceConstrained() const {return (constrts & FENCE)>0;} 00259 00260 /** Returns true if the solver respects the current time of the plan. 00261 * The solver isn't allowed to create any operation plans in the past. 00262 */ 00263 bool isLeadtimeConstrained() const {return (constrts & LEADTIME)>0;} 00264 00265 /** Returns true if the solver respects the material procurement 00266 * constraints on procurement buffers. 00267 */ 00268 bool isMaterialConstrained() const {return (constrts & MATERIAL)>0;} 00269 00270 /** Returns true if the solver respects capacity constraints. */ 00271 bool isCapacityConstrained() const {return (constrts & CAPACITY)>0;} 00272 00273 /** Returns true if any constraint is relevant for the solver. */ 00274 bool isConstrained() const {return constrts>0;} 00275 00276 /** Returns the plan type: 00277 * - 1: Constrained plan.<br> 00278 * This plan doesn't not violate any constraints.<br> 00279 * In case of material or capacity shortages the demand is delayed 00280 * or planned short. 00281 * - 2: Unconstrained plan with alternate search.<br> 00282 * This unconstrained plan leaves material, capacity and operation 00283 * problems when shortages are found. Availability is searched across 00284 * alternates and the remaining shortage is shown on the primary 00285 * alternate.<br> 00286 * The demand is always fully met on time. 00287 * - 3: Unconstrained plan without alternate search.<br> 00288 * This unconstrained plan leaves material, capacity and operation 00289 * problems when shortages are found. It doesn't evaluate availability 00290 * on alternates.<br> 00291 * The demand is always fully met on time. 00292 */ 00293 short getPlanType() const {return plantype;} 00294 00295 void setPlanType(short b) {plantype = b;} 00296 00297 /** This function defines the order in which the demands are being 00298 * planned.<br> 00299 * The following sorting criteria are appplied in order: 00300 * - demand priority: smaller priorities first 00301 * - demand due date: earlier due dates first 00302 * - demand quantity: smaller quantities first 00303 */ 00304 static DECLARE_EXPORT bool demand_comparison(const Demand*, const Demand*); 00305 00306 /** Update the number of parallel solver threads.<br> 00307 * The default value depends on whether the solver is run in verbose mode 00308 * or not: 00309 * - In normal mode the solver uses as many threads as specified by 00310 * the environment variable NUMBER_OF_PROCESSORS. 00311 * - In verbose mode the solver runs in a single thread to avoid 00312 * mangling the debugging output of different threads. 00313 */ 00314 void setMaxParallel(int i) 00315 { 00316 if (i >= 1) maxparallel = i; 00317 else throw DataException("Invalid number of parallel solver threads"); 00318 } 00319 00320 /** Return the number of threads used for planning. */ 00321 int getMaxParallel() const 00322 { 00323 // Or: Explicitly specified number of threads 00324 if (maxparallel) return maxparallel; 00325 // Or: Default number of threads 00326 else return getLogLevel()>0 ? 1 : Environment::getProcessors(); 00327 } 00328 00329 /** Return the time increment between requests when the answered reply 00330 * date isn't usable. */ 00331 TimePeriod getLazyDelay() const {return lazydelay;} 00332 00333 /** Update the time increment between requests when the answered reply 00334 * date isn't usable. */ 00335 void setLazyDelay(TimePeriod l) 00336 { 00337 if (l > 0L) lazydelay = l; 00338 else throw DataException("Invalid lazy delay"); 00339 } 00340 00341 /** Return whether or not we automatically commit the changes after 00342 * planning a demand. */ 00343 bool getAutocommit() const {return autocommit;} 00344 00345 /** Update whether or not we automatically commit the changes after 00346 * planning a demand. */ 00347 void setAutocommit(const bool b) {autocommit = b;} 00348 00349 /** Specify a Python function that is called before solving a flow. */ 00350 DECLARE_EXPORT void setUserExitFlow(const string& n) {userexit_flow = n;} 00351 00352 /** Specify a Python function that is called before solving a flow. */ 00353 DECLARE_EXPORT void setUserExitFlow(PyObject* p) {userexit_flow = p;} 00354 00355 /** Return the Python function that is called before solving a flow. */ 00356 PythonFunction getUserExitFlow() const {return userexit_flow;} 00357 00358 /** Specify a Python function that is called before solving a demand. */ 00359 DECLARE_EXPORT void setUserExitDemand(const string& n) {userexit_demand = n;} 00360 00361 /** Specify a Python function that is called before solving a demand. */ 00362 DECLARE_EXPORT void setUserExitDemand(PyObject* p) {userexit_demand = p;} 00363 00364 /** Return the Python function that is called before solving a demand. */ 00365 PythonFunction getUserExitDemand() const {return userexit_demand;} 00366 00367 /** Specify a Python function that is called before solving a buffer. */ 00368 DECLARE_EXPORT void setUserExitBuffer(const string& n) {userexit_buffer = n;} 00369 00370 /** Specify a Python function that is called before solving a buffer. */ 00371 DECLARE_EXPORT void setUserExitBuffer(PyObject* p) {userexit_buffer = p;} 00372 00373 /** Return the Python function that is called before solving a buffer. */ 00374 PythonFunction getUserExitBuffer() const {return userexit_buffer;} 00375 00376 /** Specify a Python function that is called before solving a resource. */ 00377 DECLARE_EXPORT void setUserExitResource(const string& n) {userexit_resource = n;} 00378 00379 /** Specify a Python function that is called before solving a resource. */ 00380 DECLARE_EXPORT void setUserExitResource(PyObject* p) {userexit_resource = p;} 00381 00382 /** Return the Python function that is called before solving a resource. */ 00383 PythonFunction getUserExitResource() const {return userexit_resource;} 00384 00385 /** Specify a Python function that is called before solving a operation. */ 00386 DECLARE_EXPORT void setUserExitOperation(const string& n) {userexit_operation = n;} 00387 00388 /** Specify a Python function that is called before solving a operation. */ 00389 DECLARE_EXPORT void setUserExitOperation(PyObject* p) {userexit_operation = p;} 00390 00391 /** Return the Python function that is called before solving a operation. */ 00392 PythonFunction getUserExitOperation() const {return userexit_operation;} 00393 00394 /** Python method for running the solver. */ 00395 static DECLARE_EXPORT PyObject* solve(PyObject*, PyObject*); 00396 00397 /** Python method for commiting the plan changes. */ 00398 static DECLARE_EXPORT PyObject* commit(PyObject*, PyObject*); 00399 00400 /** Python method for undoing the plan changes. */ 00401 static DECLARE_EXPORT PyObject* undo(PyObject*, PyObject*); 00402 00403 private: 00404 typedef map < int, deque<Demand*>, less<int> > classified_demand; 00405 typedef classified_demand::iterator cluster_iterator; 00406 classified_demand demands_per_cluster; 00407 00408 /** Number of parallel solver threads.<br> 00409 * The default value depends on whether the solver is run in verbose mode 00410 * or not: 00411 * - In normal mode the solver uses NUMBER_OF_PROCESSORS threads. 00412 * - In verbose mode the solver runs in a single thread to avoid 00413 * mangling the debugging output of different threads. 00414 */ 00415 int maxparallel; 00416 00417 /** Type of plan to be created. */ 00418 short plantype; 00419 00420 /** Time increments for a lazy replan.<br> 00421 * The solver is expected to return always a next-feasible date when the 00422 * request can't be met. The solver can then retry the request with an 00423 * updated request date. In some corner cases and in case of a bug it is 00424 * possible that no valid date is returned. The solver will then try the 00425 * request with a request date incremented by this value.<br> 00426 * The default value is 1 day. 00427 */ 00428 TimePeriod lazydelay; 00429 00430 /** Enable or disable automatically committing the changes in the plan 00431 * after planning each demand.<br> 00432 * The flag is only respected when planning incremental changes, and 00433 * is ignored when doing a complete replan. 00434 */ 00435 bool autocommit; 00436 00437 /** A Python callback function that is called for each alternate 00438 * flow. If the callback function returns false, that alternate 00439 * flow is an invalid choice. 00440 */ 00441 PythonFunction userexit_flow; 00442 00443 /** A Python callback function that is called for each demand. The return 00444 * value is not used. 00445 */ 00446 PythonFunction userexit_demand; 00447 00448 /** A Python callback function that is called for each buffer. The return 00449 * value is not used. 00450 */ 00451 PythonFunction userexit_buffer; 00452 00453 /** A Python callback function that is called for each resource. The return 00454 * value is not used. 00455 */ 00456 PythonFunction userexit_resource; 00457 00458 /** A Python callback function that is called for each operation. The return 00459 * value is not used. 00460 */ 00461 PythonFunction userexit_operation; 00462 00463 protected: 00464 /** @brief This class is used to store the solver status during the 00465 * ask-reply calls of the solver. 00466 */ 00467 struct State 00468 { 00469 /** Points to the demand being planned.<br> 00470 * This field is only non-null when planning the delivery operation. 00471 */ 00472 Demand* curDemand; 00473 00474 /** Points to the current owner operationplan. This is used when 00475 * operations are nested. */ 00476 OperationPlan* curOwnerOpplan; 00477 00478 /** Points to the current buffer. */ 00479 Buffer* curBuffer; 00480 00481 /** A flag to force the resource solver to move the operationplan to 00482 * a later date where it is feasible.<br> 00483 * Admittedly this is an ugly hack... 00484 */ 00485 bool forceLate; 00486 00487 /** This is the quantity we are asking for. */ 00488 double q_qty; 00489 00490 /** This is the date we are asking for. */ 00491 Date q_date; 00492 00493 /** This is the maximum date we are asking for.<br> 00494 * In case of a post-operation time there is a difference between 00495 * q_date and q_date_max. 00496 */ 00497 Date q_date_max; 00498 00499 /** This is the quantity we can get by the requested Date. */ 00500 double a_qty; 00501 00502 /** This is the Date when we can get extra availability. */ 00503 Date a_date; 00504 00505 /** This is a pointer to a LoadPlan. It is used for communication 00506 * between the Operation-Solver and the Resource-Solver. */ 00507 LoadPlan* q_loadplan; 00508 00509 /** This is a pointer to a FlowPlan. It is used for communication 00510 * between the Operation-Solver and the Buffer-Solver. */ 00511 FlowPlan* q_flowplan; 00512 00513 /** A pointer to an operationplan currently being solved. */ 00514 OperationPlan* q_operationplan; 00515 00516 /** Cost of the reply.<br> 00517 * Only the direct cost should be returned in this field. 00518 */ 00519 double a_cost; 00520 00521 /** Penalty associated with the reply.<br> 00522 * This field contains indirect costs and other penalties that are 00523 * not strictly related to the request. Examples are setup costs, 00524 * inventory carrying costs, ... 00525 */ 00526 double a_penalty; 00527 }; 00528 00529 /** @brief This class is a helper class of the SolverMRP class. 00530 * 00531 * It stores the solver state maintained by each solver thread. 00532 * @see SolverMRP 00533 */ 00534 class SolverMRPdata : public CommandList 00535 { 00536 friend class SolverMRP; 00537 public: 00538 /** Return the solver. */ 00539 SolverMRP* getSolver() const {return sol;} 00540 00541 /** Constructor. */ 00542 SolverMRPdata(SolverMRP* s = NULL, int c = 0, deque<Demand*>* d = NULL) 00543 : sol(s), cluster(c), demands(d), constrainedPlanning(true), 00544 state(statestack), prevstate(statestack-1) {} 00545 00546 /** Verbose mode is inherited from the solver. */ 00547 unsigned short getLogLevel() const {return sol ? sol->getLogLevel() : 0;} 00548 00549 /** This function runs a single planning thread. Such a thread will loop 00550 * through the following steps: 00551 * - Use the method next_cluster() to find another unplanned cluster. 00552 * - Exit the thread if no more cluster is found. 00553 * - Sort all demands in the cluster, using the demand_comparison() 00554 * method. 00555 * - Loop through the sorted list of demands and plan each of them. 00556 * During planning the demands exceptions are caught, and the 00557 * planning loop will simply move on to the next demand. 00558 * In this way, an error in a part of the model doesn't ruin the 00559 * complete plan. 00560 * @see demand_comparison 00561 * @see next_cluster 00562 */ 00563 virtual DECLARE_EXPORT void execute(); 00564 00565 virtual const MetaClass& getType() const {return *SolverMRP::metadata;} 00566 virtual size_t getSize() const {return sizeof(SolverMRPdata);} 00567 00568 bool getVerbose() const 00569 { 00570 throw LogicException("Use the method SolverMRPdata::getLogLevel() instead of SolverMRPdata::getVerbose()"); 00571 } 00572 00573 /** Add a new state to the status stack. */ 00574 inline void push(double q = 0.0, Date d = Date::infiniteFuture) 00575 { 00576 if (state >= statestack + MAXSTATES) 00577 throw RuntimeException("Maximum recursion depth exceeded"); 00578 ++state; 00579 ++prevstate; 00580 state->q_qty = q; 00581 state->q_date = d; 00582 state->curOwnerOpplan = NULL; 00583 state->q_loadplan = NULL; 00584 state->q_flowplan = NULL; 00585 state->q_operationplan = NULL; 00586 state->curDemand = NULL; 00587 state->a_cost = 0.0; 00588 state->a_penalty = 0.0; 00589 } 00590 00591 /** Removes a state from the status stack. */ 00592 inline void pop() 00593 { 00594 if (--state < statestack) 00595 throw LogicException("State stack empty"); 00596 --prevstate; 00597 } 00598 00599 private: 00600 static const int MAXSTATES = 256; 00601 00602 /** Points to the solver. */ 00603 SolverMRP* sol; 00604 00605 /** An identifier of the cluster being replanned. Note that it isn't 00606 * always the complete cluster that is being planned. 00607 */ 00608 int cluster; 00609 00610 /** A deque containing all demands to be (re-)planned. */ 00611 deque<Demand*>* demands; 00612 00613 /** Stack of solver status information. */ 00614 State statestack[MAXSTATES]; 00615 00616 /** True when planning in constrained mode. */ 00617 bool constrainedPlanning; 00618 00619 /** Flags whether or not constraints are being tracked. */ 00620 bool logConstraints; 00621 00622 /** Points to the demand being planned. */ 00623 Demand* planningDemand; 00624 00625 public: 00626 /** Pointer to the current solver status. */ 00627 State* state; 00628 00629 /** Pointer to the solver status one level higher on the stack. */ 00630 State* prevstate; 00631 }; 00632 00633 /** When autocommit is switched off, this command structure will contain 00634 * all plan changes. 00635 */ 00636 SolverMRPdata commands; 00637 00638 /** This function will check all constraints for an operationplan 00639 * and propagate it upstream. The check does NOT check eventual 00640 * sub operationplans.<br> 00641 * The return value is a flag whether the operationplan is 00642 * acceptable (sometimes in reduced quantity) or not. 00643 */ 00644 DECLARE_EXPORT bool checkOperation(OperationPlan*, SolverMRPdata& data); 00645 00646 /** Verifies whether this operationplan violates the leadtime 00647 * constraints. */ 00648 DECLARE_EXPORT bool checkOperationLeadtime(OperationPlan*, SolverMRPdata&, bool); 00649 00650 /** Verifies whether this operationplan violates the capacity constraint.<br> 00651 * In case it does the operationplan is moved to an earlier or later 00652 * feasible date. 00653 */ 00654 DECLARE_EXPORT void checkOperationCapacity(OperationPlan*, SolverMRPdata&); 00655 00656 /** Scan the operationplans that are about to be committed to verify that 00657 * they are not creating any excess. 00658 */ 00659 DECLARE_EXPORT void scanExcess(Command*); 00660 }; 00661 00662 00663 /** @brief This class holds functions that used for maintenance of the solver 00664 * code. 00665 */ 00666 class LibrarySolver 00667 { 00668 public: 00669 static void initialize(); 00670 }; 00671 00672 00673 } // end namespace 00674 00675 00676 #endif
Documentation generated for frePPLe by
