• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-----------------------------------------------------------------------------+
2 Interval Container Library
3 Author: Joachim Faulhaber
4 Copyright (c) 2007-2009: Joachim Faulhaber
5 Copyright (c) 1999-2006: Cortex Software GmbH, Kantstrasse 57, Berlin
6 +------------------------------------------------------------------------------+
7    Distributed under the Boost Software License, Version 1.0.
8       (See accompanying file LICENCE.txt or copy at
9            http://www.boost.org/LICENSE_1_0.txt)
10 +-----------------------------------------------------------------------------*/
11 /** Example man_power.cpp \file man_power.cpp
12     \brief Using set style operators to compute with interval sets and maps.
13 
14     Interval sets and maps can be filled and manipulated using
15     set style operation like union (+=), difference (-=) and intersection
16     (&=).
17 
18     In this example 'man_power' a number of those operations are
19     demonstrated in the process of calculation the available working
20     times (man-power) of a company's employees accounting for weekends,
21     holidays, sickness times and vacations.
22 
23     \include man_power_/man_power.cpp
24 */
25 //[example_man_power
26 // The next line includes <boost/gregorian/date.hpp>
27 // and a few lines of adapter code.
28 #include <boost/icl/gregorian.hpp>
29 #include <iostream>
30 #include <boost/icl/discrete_interval.hpp>
31 #include <boost/icl/interval_map.hpp>
32 
33 using namespace std;
34 using namespace boost::gregorian;
35 using namespace boost::icl;
36 
37 
38 // Function weekends returns the interval_set of weekends that are contained in
39 // the date interval 'scope'
weekends(const discrete_interval<date> & scope)40 interval_set<date> weekends(const discrete_interval<date>& scope)
41 {
42     interval_set<date> weekends;
43 
44     date cur_weekend_sat
45         = first(scope)
46           + days(days_until_weekday(first(scope), greg_weekday(Saturday)))
47           - weeks(1);
48     week_iterator week_iter(cur_weekend_sat);
49 
50     for(; week_iter <= last(scope); ++week_iter)
51         weekends += discrete_interval<date>::right_open(*week_iter, *week_iter + days(2));
52 
53     weekends &= scope; // cut off the surplus
54 
55     return weekends;
56 }
57 
58 // The available working time for the employees of a company is calculated
59 // for a period of 3 months accounting for weekends and holidays.
60 //    The available daily working time for the employees is calculated
61 // using interval_sets and interval_maps demonstrating a number of
62 // addition, subtraction and intersection operations.
man_power()63 void man_power()
64 {
65     date someday = from_string("2008-08-01");
66     date thenday = someday + months(3);
67 
68     discrete_interval<date> scope = discrete_interval<date>::right_open(someday, thenday);
69 
70     // ------------------------------------------------------------------------
71     // (1) In a first step, the regular working times are computed for the
72     // company within the given scope. From all available days, the weekends
73     // and holidays have to be subtracted:
74     interval_set<date> worktime(scope);
75     // Subtract the weekends
76     worktime -= weekends(scope);
77     // Subtract holidays
78     worktime -= from_string("2008-10-03"); //German reunification ;)
79 
80     // company holidays (fictitious ;)
81     worktime -= discrete_interval<date>::closed(from_string("2008-08-18"),
82                                                 from_string("2008-08-22"));
83 
84     //-------------------------------------------------------------------------
85     // (2) Now we calculate the individual work times for some employees
86     //-------------------------------------------------------------------------
87     // In the company works Claudia.
88     // This is the map of her regular working times:
89     interval_map<date,int> claudias_working_hours;
90 
91     // Claudia is working 8 hours a day. So the next statement says
92     // that every day in the whole scope is mapped to 8 hours worktime.
93     claudias_working_hours += make_pair(scope, 8);
94 
95     // But Claudia only works 8 hours on regular working days so we do
96     // an intersection of the interval_map with the interval_set worktime:
97     claudias_working_hours &= worktime;
98 
99     // Yet, in addition Claudia has her own absence times like
100     discrete_interval<date> claudias_seminar (from_string("2008-09-16"),
101                                               from_string("2008-09-24"),
102                                               interval_bounds::closed());
103     discrete_interval<date> claudias_vacation(from_string("2008-08-01"),
104                                               from_string("2008-08-14"),
105                                               interval_bounds::closed());
106 
107     interval_set<date> claudias_absence_times(claudias_seminar);
108     claudias_absence_times += claudias_vacation;
109 
110     // All the absence times have to subtracted from the map of her working times
111     claudias_working_hours -= claudias_absence_times;
112 
113     //-------------------------------------------------------------------------
114     // Claudia's boss is Bodo. He only works part time.
115     // This is the map of his regular working times:
116     interval_map<date,int> bodos_working_hours;
117 
118     // Bodo is working 4 hours a day.
119     bodos_working_hours += make_pair(scope, 4);
120 
121     // Bodo works only on regular working days
122     bodos_working_hours &= worktime;
123 
124     // Bodos additional absence times
125     discrete_interval<date>      bodos_flu(from_string("2008-09-19"), from_string("2008-09-29"),
126                                            interval_bounds::closed());
127     discrete_interval<date> bodos_vacation(from_string("2008-08-15"), from_string("2008-09-03"),
128                                            interval_bounds::closed());
129 
130     interval_set<date> bodos_absence_times(bodos_flu);
131     bodos_absence_times += bodos_vacation;
132 
133     // All the absence times have to be subtracted from the map of his working times
134     bodos_working_hours -= bodos_absence_times;
135 
136     //-------------------------------------------------------------------------
137     // (3) Finally we want to calculate the available manpower of the company
138     // for the selected time scope: This is done by adding up the employees
139     // working time maps:
140     interval_map<date,int> manpower;
141     manpower += claudias_working_hours;
142     manpower += bodos_working_hours;
143 
144 
145     cout << first(scope) << " - " << last(scope)
146          << "    available man-power:" << endl;
147     cout << "---------------------------------------------------------------\n";
148 
149     for(interval_map<date,int>::iterator it = manpower.begin();
150         it != manpower.end(); it++)
151     {
152         cout << first(it->first) << " - " << last(it->first)
153              << " -> " << it->second << endl;
154     }
155 }
156 
main()157 int main()
158 {
159     cout << ">>Interval Container Library: Sample man_power.cpp <<\n";
160     cout << "---------------------------------------------------------------\n";
161     man_power();
162     return 0;
163 }
164 
165 // Program output:
166 /*
167 >>Interval Container Library: Sample man_power.cpp <<
168 ---------------------------------------------------------------
169 2008-Aug-01 - 2008-Oct-31    available man-power:
170 ---------------------------------------------------------------
171 2008-Aug-01 - 2008-Aug-01 -> 4
172 2008-Aug-04 - 2008-Aug-08 -> 4
173 2008-Aug-11 - 2008-Aug-14 -> 4
174 2008-Aug-15 - 2008-Aug-15 -> 8
175 2008-Aug-25 - 2008-Aug-29 -> 8
176 2008-Sep-01 - 2008-Sep-03 -> 8
177 2008-Sep-04 - 2008-Sep-05 -> 12
178 2008-Sep-08 - 2008-Sep-12 -> 12
179 2008-Sep-15 - 2008-Sep-15 -> 12
180 2008-Sep-16 - 2008-Sep-18 -> 4
181 2008-Sep-25 - 2008-Sep-26 -> 8
182 2008-Sep-29 - 2008-Sep-29 -> 8
183 2008-Sep-30 - 2008-Oct-02 -> 12
184 2008-Oct-06 - 2008-Oct-10 -> 12
185 2008-Oct-13 - 2008-Oct-17 -> 12
186 2008-Oct-20 - 2008-Oct-24 -> 12
187 2008-Oct-27 - 2008-Oct-31 -> 12
188 */
189 //]
190 
191