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/model.h"
00029
00030 namespace frepple
00031 {
00032
00033
00034 DECLARE_EXPORT PeggingIterator::PeggingIterator(const Demand* d) : downstream(false)
00035 {
00036
00037 first = false;
00038 for (Demand::OperationPlan_list::const_iterator opplaniter = d->getDelivery().begin();
00039 opplaniter != d->getDelivery().end(); ++opplaniter)
00040 followPegging(*opplaniter, 0, (*opplaniter)->getQuantity(), 1.0);
00041 }
00042
00043
00044 DECLARE_EXPORT void PeggingIterator::updateStack
00045 (short l, double q, double f, const FlowPlan* fc, const FlowPlan* fp, bool p)
00046 {
00047
00048 if (q < ROUNDING_ERROR) return;
00049
00050 if (first)
00051 {
00052
00053 state& t = states.top();
00054 t.cons_flowplan = fc;
00055 t.prod_flowplan = fp;
00056 t.qty = q;
00057 t.factor = f;
00058 t.level = l;
00059 t.pegged = p;
00060 first = false;
00061 }
00062 else
00063
00064 states.push(state(l, q, f, fc, fp, p));
00065 }
00066
00067
00068 DECLARE_EXPORT PeggingIterator& PeggingIterator::operator++()
00069 {
00070
00071 if (states.empty())
00072 throw LogicException("Incrementing the iterator beyond it's end");
00073 if (!downstream)
00074 throw LogicException("Incrementing a downstream iterator");
00075 state& st = states.top();
00076
00077
00078 if (!st.pegged)
00079 {
00080 states.pop();
00081 return *this;
00082 }
00083
00084
00085 first = true;
00086
00087
00088 if (st.cons_flowplan)
00089 followPegging(st.cons_flowplan->getOperationPlan()->getTopOwner(),
00090 st.level-1, st.qty, st.factor);
00091
00092
00093 if (first) states.pop();
00094
00095 return *this;
00096 }
00097
00098
00099 DECLARE_EXPORT PeggingIterator& PeggingIterator::operator--()
00100 {
00101
00102 if (states.empty())
00103 throw LogicException("Incrementing the iterator beyond it's end");
00104 if (downstream)
00105 throw LogicException("Decrementing an upstream iterator");
00106 state& st = states.top();
00107
00108
00109 if (!st.pegged)
00110 {
00111 states.pop();
00112 return *this;
00113 }
00114
00115
00116 first = true;
00117
00118
00119 if (st.prod_flowplan)
00120 followPegging(st.prod_flowplan->getOperationPlan()->getTopOwner(),
00121 st.level+1, st.qty, st.factor);
00122
00123
00124 if (first) states.pop();
00125
00126 return *this;
00127 }
00128
00129
00130 DECLARE_EXPORT void PeggingIterator::followPegging
00131 (const OperationPlan* op, short nextlevel, double qty, double factor)
00132 {
00133
00134
00135 if (downstream)
00136 for (OperationPlan::FlowPlanIterator i = op->beginFlowPlans();
00137 i != op->endFlowPlans(); ++i)
00138 {
00139
00140
00141 if (i->getQuantity()>ROUNDING_ERROR)
00142 i->getFlow()->getBuffer()->followPegging(*this, &*i, nextlevel, qty, factor);
00143 }
00144 else
00145 for (OperationPlan::FlowPlanIterator i = op->beginFlowPlans();
00146 i != op->endFlowPlans(); ++i)
00147 {
00148
00149
00150 if (i->getQuantity()<-ROUNDING_ERROR)
00151 i->getFlow()->getBuffer()->followPegging(*this, &*i, nextlevel, qty, factor);
00152 }
00153
00154
00155 if (op->getSubOperationPlan())
00156
00157 followPegging(op->getSubOperationPlan(), nextlevel, qty, factor);
00158 for (OperationPlan::OperationPlanList::const_iterator
00159 j = op->getSubOperationPlans().begin();
00160 j != op->getSubOperationPlans().end(); ++j)
00161
00162 followPegging(*j, nextlevel, qty, factor);
00163 }
00164
00165
00166 int PythonPeggingIterator::initialize(PyObject* m)
00167 {
00168
00169 PythonType& x = PythonExtension<PythonPeggingIterator>::getType();
00170 x.setName("peggingIterator");
00171 x.setDoc("frePPLe iterator for demand pegging");
00172 x.supportiter();
00173 return x.typeReady(m);
00174 }
00175
00176
00177 PyObject* PythonPeggingIterator::iternext()
00178 {
00179 if (!i) return NULL;
00180
00181
00182
00183
00184
00185
00186 PyObject* result = Py_BuildValue("{s:i,s:N,s:N,s:N,s:N,s:N,s:f,s:f,s:i}",
00187 "level", i.getLevel(),
00188 "consuming", static_cast<PyObject*>(PythonObject(i.getConsumingOperationplan())),
00189 "cons_date", static_cast<PyObject*>(PythonObject(i.getConsumingDate())),
00190 "producing", static_cast<PyObject*>(PythonObject(i.getProducingOperationplan())),
00191 "prod_date", static_cast<PyObject*>(PythonObject(i.getProducingDate())),
00192 "buffer", static_cast<PyObject*>(PythonObject(i.getBuffer())),
00193 "quantity_demand", i.getQuantityDemand(),
00194 "quantity_buffer", i.getQuantityBuffer(),
00195 "pegged", i.getPegged() ? 1 : 0
00196 );
00197
00198 --i;
00199 return result;
00200 }
00201
00202
00203 }