FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
coloring.cpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6// includes, FEAT
8#include <kernel/adjacency/coloring.hpp>
9#include <kernel/adjacency/graph.hpp>
10
11// includes, system
12#include <vector>
13#include <utility>
14#include <unordered_set>
15
16namespace FEAT
17{
18 namespace Adjacency
19 {
20 // Default constructor.
22 _num_colors(0),
23 _coloring()
24 {
25 }
26
27 // Allocation Constructor.
29 Index num_nodes,
30 Index num_colors)
31 :
32 _num_colors(num_colors)
33 {
34 _coloring = IndexVector(num_nodes);
35 }
36
37 // Array Constructor
39 Index num_nodes,
40 Index* coloring)
41 {
42
43 std::unordered_set<Index> colors;
44 for (Index i(0) ; i < num_nodes ; ++i)
45 {
46 colors.insert(coloring[i]);
47 }
48 _num_colors = Index(colors.size());
49 colors.clear();
50
51 _coloring =IndexVector(num_nodes);
52 for(Index i(0); i< num_nodes; i++)
53 {
54 _coloring[i] = coloring[i];
55 }
56
57 }
58 //Vector Constructor
59
61 Index num_colors,
62 const IndexVector& coloring) :
63 _num_colors(num_colors),
64 _coloring(coloring)
65 {
66 }
67 // Creation out of a given Graph
68 Coloring::Coloring(const Graph& graph) :
69 Coloring()
70 {
71 // get the graph's data
72 Index num_nodes_domain = graph.get_num_nodes_domain();
73 const Index* domain_ptr = graph.get_domain_ptr();
74 const Index* image_idx = graph.get_image_idx();
75
76 if(num_nodes_domain == Index(0))
77 return;
78
79 // allocate the coloring vector
80 _coloring = IndexVector(num_nodes_domain);
81
82 // highest possible number of colors
83 Index mnc = graph.degree() + 1;
84
85 // number of used colors
86 _num_colors = 0;
87
88 // auxiliary vector storing temporary information about used colors
89 std::vector<Index> col_aux(mnc);
90
91 // auxiliary vector storing the number of color uses
92 std::vector<Index> col_num(mnc, Index(0));
93
94 // auxiliary variables
95 Index lower_bound;
96 Index upper_bound;
97 Index min_color_uses;
98 Index min_color_index;
99
100 // loop over all nodes
101 for(Index i(0); i < num_nodes_domain; ++i)
102 {
103 // reset the auxiliary vector
104 for(Index j(0); j < mnc; ++j)
105 {
106 col_aux[j] = 0;
107 }
108
109 // loop over all adjacencies of the i-th node
110 lower_bound = domain_ptr[i];
111 upper_bound = domain_ptr[i+1];
112 for(Index j(lower_bound); j < upper_bound; ++j)
113 {
114 if(image_idx[j] < i)
115 {
116 // mark the used color
117 col_aux[_coloring[image_idx[j]]] = 1;
118 }
119 }
120
121 // calculate new color:
122
123 // minimum number of color uses so far
124 min_color_uses = num_nodes_domain + 1;
125
126 // color with min_color_uses
127 min_color_index = num_nodes_domain + 1;
128
129 // loop over all colors
130 for(Index j(0); j < _num_colors; ++j)
131 {
132 if(col_aux[j] !=1)
133 {
134 if(col_num[j] < min_color_uses)
135 {
136 min_color_uses = col_num[j];
137 min_color_index = j;
138 }
139 }
140 }
141
142 // check if an old color was found or if a new color is needed
143 if(min_color_index != num_nodes_domain +1)
144 {
145 // if an old color is acceptable
146 _coloring[i] = min_color_index;
147 ++col_num[min_color_index];
148 }
149 else
150 {
151 // if a new color is needed
153 ++col_num[_num_colors];
154 ++_num_colors;
155 }
156 }
157 }
158
159 // Creation out of a given Graph with a prescribed order
160 Coloring::Coloring(const Graph& graph, const Index* order) :
161 Coloring()
162 {
163 // get the graph's data
164 Index num_nodes_domain = graph.get_num_nodes_domain();
165 const Index* domain_ptr = graph.get_domain_ptr();
166 const Index* image_idx = graph.get_image_idx();
167
168 if(num_nodes_domain == Index(0))
169 return;
170
171 // allocate the coloring vector
172 _coloring = IndexVector(num_nodes_domain);
173
174 // highest possible number of colors
175 Index mnc = graph.degree() + 1;
176
177 // number of used colors
178 _num_colors = 0;
179
180 // auxiliary vector storing temporary information about used colors
181 std::vector<Index> col_aux(mnc);
182
183 // auxiliary vector storing the number of color uses
184 std::vector<Index> col_num(mnc, Index(0));
185
186 // auxiliary variables
187 Index lower_bound;
188 Index upper_bound;
189 Index min_color_uses;
190 Index min_color_index;
191
192 // auxiliary index
193 Index i;
194
195 // initialize coloring data
196 for(Index j(0); j < num_nodes_domain; ++j)
197 {
198 _coloring[j] = num_nodes_domain + 1;
199 }
200
201 // loop over all nodes
202 for(Index k(0); k < num_nodes_domain; ++k)
203 {
204 // get index of the current node
205 i = order[k];
206
207 // reset the auxiliary array
208 for(Index j(0); j < mnc; ++j)
209 {
210 col_aux[j] = 0;
211 }
212
213 // loop over all adjacencies of the i-th node
214 lower_bound = domain_ptr[i];
215 upper_bound = domain_ptr[i+1];
216 for(Index j(lower_bound); j < upper_bound; ++j)
217 {
218 if(_coloring[image_idx[j]] != num_nodes_domain + 1)
219 {
220 // mark the used color
221 col_aux[_coloring[image_idx[j]]] = 1;
222 }
223 }
224
225 // calculate new color:
226
227 // minimum number of color uses so far
228 min_color_uses = num_nodes_domain + 1;
229
230 // color with min_color_uses
231 min_color_index = num_nodes_domain + 1;
232
233 // loop over all colors
234 for(Index j(0); j < _num_colors; ++j)
235 {
236 if(col_aux[j] !=1)
237 {
238 if(col_num[j] < min_color_uses)
239 {
240 min_color_uses = col_num[j];
241 min_color_index = j;
242 }
243 }
244 }
245
246 // check if an old color was found or if a new color is needed
247 if(min_color_index != num_nodes_domain +1)
248 {
249 // if an old color is acceptable
250 _coloring[i] = min_color_index;
251 ++col_num[min_color_index];
252 }
253 else
254 {
255 // if a new color is needed
257 ++col_num[_num_colors];
258 ++_num_colors;
259 }
260 }
261 }
262
263 // move ctor
264 Coloring::Coloring(Coloring&& other) noexcept:
265 _num_colors(other._num_colors),
266 _coloring(std::forward<IndexVector>(other._coloring))
267 {
268 other._num_colors = Index(0);
269 other._coloring.clear();
270 }
271
272 // move-assign operator
274 {
275 // avoid self-move
276 if(this == &other)
277 return *this;
278
279 _num_colors = other._num_colors;
280 _coloring = std::forward<IndexVector>(other._coloring);
281
282 other._num_colors = Index(0);
283 other._coloring.clear();
284
285 return *this;
286 }
287
288 // virtual destructor
290 {}
291
293 {
294 // allocate a new graph
296
297 // create domain vector
298 Index* domain_ptr = graph.get_domain_ptr();
299 domain_ptr[0] = Index(0);
300
301 // create image vector
302 Index* image_idx = graph.get_image_idx();
303
304 // index counter
305 Index idx_counter = Index(0);
306
307 // loop over all colors
308 for(Index i(0); i < _num_colors; ++i)
309 {
310 // loop over all nodes
311 for(Index j(0); j < _coloring.size(); ++j)
312 {
313 // if node j has the color i
314 if(i == _coloring[j])
315 {
316 image_idx[idx_counter] = j;
317 ++idx_counter;
318 }
319 }
320 domain_ptr[i+1] = idx_counter;
321 }
322
323 // return graph
324 return graph;
325 }
326
327 } // namespace Adjacency
328} // namespace FEAT
FEAT Kernel base header.
Coloring object implementation.
Definition: coloring.hpp:37
IndexVector _coloring
coloring vector
Definition: coloring.hpp:53
Graph create_partition_graph() const
Creates a color partition graph.
Definition: coloring.cpp:292
Index _num_colors
total number of colors used
Definition: coloring.hpp:42
Index get_num_nodes() const
Returns the total number of nodes.
Definition: coloring.hpp:191
virtual ~Coloring()
virtual destructor
Definition: coloring.cpp:289
Coloring & operator=(Coloring &&other) noexcept
move-assign operator
Definition: coloring.cpp:273
Index get_max_color() const
Returns the maximum color index.
Definition: coloring.hpp:207
Coloring()
Default constructor.
Definition: coloring.cpp:21
Adjacency Graph implementation.
Definition: graph.hpp:34
Index * get_domain_ptr()
Returns the domain pointer array.
Definition: graph.hpp:359
Index * get_image_idx()
Returns the image node index array.
Definition: graph.hpp:374
Index degree(Index domain_node) const
Returns the degree of a domain node.
Definition: graph.hpp:333
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.