problems_resource.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * *
3  * Copyright (C) 2007-2013 by Johan De Taeye, frePPLe bvba *
4  * *
5  * This library is free software; you can redistribute it and/or modify it *
6  * under the terms of the GNU Affero General Public License as published *
7  * by the Free Software Foundation; either version 3 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This library is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU Affero General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU Affero General Public *
16  * License along with this program. *
17  * If not, see <http://www.gnu.org/licenses/>. *
18  * *
19  ***************************************************************************/
20 
21 #define FREPPLE_CORE
22 #include "frepple/model.h"
23 
24 namespace frepple
25 {
26 
27 
29 {
30  // Delete existing problems for this resource
32 
33  // Problem detection disabled on this resource
34  if (!getDetectProblems()) return;
35 
36  // Loop through the loadplans
37  Date excessProblemStart;
38  Date shortageProblemStart;
39  bool excessProblem = false;
40  bool shortageProblem = false;
41  double curMax(0.0);
42  double shortageQty(0.0);
43  double curMin(0.0);
44  double excessQty(0.0);
45  for (loadplanlist::const_iterator iter = loadplans.begin();
46  iter != loadplans.end(); )
47  {
48  // Process changes in the maximum or minimum targets
49  if (iter->getType() == 4)
50  curMax = iter->getMax();
51  else if (iter->getType() == 3)
52  curMin = iter->getMin();
53 
54  // Only consider the last loadplan for a certain date
55  const TimeLine<LoadPlan>::Event *f = &*(iter++);
56  if (iter!=loadplans.end() && iter->getDate()==f->getDate()) continue;
57 
58  // Check against minimum target
59  double delta = f->getOnhand() - curMin;
60  if (delta < -ROUNDING_ERROR)
61  {
62  if (!shortageProblem)
63  {
64  shortageProblemStart = f->getDate();
65  shortageQty = delta;
66  shortageProblem = true;
67  }
68  else if (delta < shortageQty)
69  // New shortage qty
70  shortageQty = delta;
71  }
72  else
73  {
74  if (shortageProblem)
75  {
76  // New problem now ends
77  if (f->getDate() != shortageProblemStart)
78  new ProblemCapacityUnderload(this, DateRange(shortageProblemStart,
79  f->getDate()), -shortageQty);
80  shortageProblem = false;
81  }
82  }
83 
84  // Note that theoretically we can have a minimum and a maximum problem for
85  // the same moment in time.
86 
87  // Check against maximum target
88  delta = f->getOnhand() - curMax;
89  if (delta > ROUNDING_ERROR)
90  {
91  if (!excessProblem)
92  {
93  excessProblemStart = f->getDate();
94  excessQty = delta;
95  excessProblem = true;
96  }
97  else if (delta > excessQty)
98  excessQty = delta;
99  }
100  else
101  {
102  if (excessProblem)
103  {
104  // New problem now ends
105  if (f->getDate() != excessProblemStart)
106  new ProblemCapacityOverload(this, excessProblemStart,
107  f->getDate(), excessQty);
108  excessProblem = false;
109  }
110  }
111 
112  } // End of for-loop through the loadplans
113 
114  // The excess lasts till the end of the horizon...
115  if (excessProblem)
116  new ProblemCapacityOverload(this, excessProblemStart,
117  Date::infiniteFuture, excessQty);
118 
119  // The shortage lasts till the end of the horizon...
120  if (shortageProblem)
121  new ProblemCapacityUnderload(this, DateRange(shortageProblemStart,
122  Date::infiniteFuture), -shortageQty);
123 }
124 
125 
127 {
128  ostringstream ch;
129  ch << "Resource '" << getResource() << "' has excess capacity of " << qty;
130  return ch.str();
131 }
132 
133 
135 {
136  ostringstream ch;
137  ch << "Resource '" << getResource() << "' has capacity shortage of " << qty;
138  return ch.str();
139 }
140 
141 }