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' |
40 | interval_set<date> weekends(const discrete_interval<date>& scope) |
41 | { |
42 | interval_set<date> weekends; |
43 | |
44 | date cur_weekend_sat |
45 | = first(object: scope) |
46 | + days(days_until_weekday(d: first(object: scope), wd: greg_weekday(Saturday))) |
47 | - weeks(1); |
48 | week_iterator week_iter(cur_weekend_sat); |
49 | |
50 | for(; week_iter <= last(object: scope); ++week_iter) |
51 | weekends += discrete_interval<date>::right_open(lo: *week_iter, up: *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. |
63 | void man_power() |
64 | { |
65 | date someday = from_string(s: "2008-08-01" ); |
66 | date thenday = someday + months(3); |
67 | |
68 | discrete_interval<date> scope = discrete_interval<date>::right_open(lo: someday, up: 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(s: "2008-10-03" ); //German reunification ;) |
79 | |
80 | // company holidays (fictitious ;) |
81 | worktime -= discrete_interval<date>::closed(lo: from_string(s: "2008-08-18" ), |
82 | up: from_string(s: "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(x&: scope, y: 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(s: "2008-09-16" ), |
101 | from_string(s: "2008-09-24" ), |
102 | interval_bounds::closed()); |
103 | discrete_interval<date> claudias_vacation(from_string(s: "2008-08-01" ), |
104 | from_string(s: "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(x&: scope, y: 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(s: "2008-09-19" ), from_string(s: "2008-09-29" ), |
126 | interval_bounds::closed()); |
127 | discrete_interval<date> bodos_vacation(from_string(s: "2008-08-15" ), from_string(s: "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(object: scope) << " - " << last(object: 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(object: it->first) << " - " << last(object: it->first) |
153 | << " -> " << it->second << endl; |
154 | } |
155 | } |
156 | |
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 | |