17 #ifndef dealii__graph_coloring_h 18 #define dealii__graph_coloring_h 21 #include <deal.II/base/config.h> 22 #include <deal.II/base/thread_management.h> 23 #include <deal.II/base/std_cxx11/function.h> 24 #include <boost/unordered_map.hpp> 25 #include <boost/unordered_set.hpp> 31 DEAL_II_NAMESPACE_OPEN
51 have_nonempty_intersection (
const std::vector<types::global_dof_index> &indices1,
52 const std::vector<types::global_dof_index> &indices2)
58 std::vector<types::global_dof_index>::const_iterator
61 while ((p != indices1.end()) && (q != indices2.end()))
107 template <
typename Iterator>
108 std::vector<std::vector<Iterator> >
109 create_partitioning(
const Iterator &begin,
110 const typename identity<Iterator>::type &end,
111 const std_cxx11::function<std::vector<types::global_dof_index> (
const Iterator &)> &get_conflict_indices)
114 unsigned int n_iterators = 0;
117 boost::unordered_map<types::global_dof_index,std::vector<Iterator> > indices_to_iterators;
118 for (Iterator it=begin; it!=end; ++it)
120 const std::vector<types::global_dof_index> conflict_indices = get_conflict_indices(it);
121 const unsigned int n_conflict_indices = conflict_indices.size();
122 for (
unsigned int i=0; i<n_conflict_indices; ++i)
123 indices_to_iterators[conflict_indices[i]].push_back(it);
130 std::vector<std::vector<Iterator> > zones(1,std::vector<Iterator> (1,begin));
131 std::set<Iterator> used_it;
132 used_it.insert(begin);
133 while (used_it.size()!=n_iterators)
138 typename std::vector<Iterator>::iterator previous_zone_it(zones.back().begin());
139 typename std::vector<Iterator>::iterator previous_zone_end(zones.back().end());
140 std::vector<Iterator> new_zone;
141 for (; previous_zone_it!=previous_zone_end; ++previous_zone_it)
143 const std::vector<types::global_dof_index>
144 conflict_indices = get_conflict_indices(*previous_zone_it);
146 const unsigned int n_conflict_indices(conflict_indices.size());
147 for (
unsigned int i=0; i<n_conflict_indices; ++i)
149 const std::vector<Iterator> &conflicting_elements
150 = indices_to_iterators[conflict_indices[i]];
151 for (
unsigned int j=0; j<conflicting_elements.size(); ++j)
159 if ((conflicting_elements[j] != *previous_zone_it)
161 (used_it.count(conflicting_elements[j])==0))
163 new_zone.push_back(conflicting_elements[j]);
164 used_it.insert(conflicting_elements[j]);
174 if (new_zone.size()!=0)
175 zones.push_back(new_zone);
177 for (Iterator it=begin; it!=end; ++it)
178 if (used_it.count(it)==0)
180 zones.push_back(std::vector<Iterator> (1,it));
210 template <
typename Iterator>
212 make_dsatur_coloring(std::vector<Iterator> &partition,
213 const std_cxx11::function<std::vector<types::global_dof_index> (
const Iterator &)> &get_conflict_indices,
214 std::vector<std::vector<Iterator> > &partition_coloring)
216 partition_coloring.clear ();
219 const unsigned int partition_size(partition.size());
220 std::vector<unsigned int> sorted_vertices(partition_size);
221 std::vector<int> degrees(partition_size);
222 std::vector<std::vector<types::global_dof_index> > conflict_indices(partition_size);
223 std::vector<std::vector<unsigned int> > graph(partition_size);
227 for (
unsigned int i=0; i<partition_size; ++i)
229 conflict_indices[i] = get_conflict_indices(partition[i]);
230 std::sort(conflict_indices[i].begin(), conflict_indices[i].end());
235 for (
unsigned int i=0; i<partition_size; ++i)
236 for (
unsigned int j=i+1; j<partition_size; ++j)
239 if (have_nonempty_intersection (conflict_indices[i], conflict_indices[j]))
243 graph[i].push_back(j);
244 graph[j].push_back(i);
248 std::vector<int>::iterator degrees_it;
249 for (
unsigned int i=0; i<partition_size; ++i)
252 degrees_it = std::max_element(degrees.begin(),degrees.end());
253 sorted_vertices[i] = degrees_it-degrees.begin();
259 std::vector<boost::unordered_set<unsigned int> > colors_used;
260 for (
unsigned int i=0; i<partition_size; ++i)
262 const unsigned int current_vertex(sorted_vertices[i]);
263 bool new_color(
true);
267 for (
unsigned int j=0; j<partition_coloring.size(); ++j)
272 bool unused_color(
true);
273 for (
unsigned int k=0; k<graph[current_vertex].size(); ++k)
274 if (colors_used[j].count(graph[current_vertex][k])==1)
276 unused_color =
false;
281 partition_coloring[j].push_back(partition[current_vertex]);
282 colors_used[j].insert(current_vertex);
290 partition_coloring.push_back(std::vector<Iterator> (1,
291 partition[current_vertex]));
292 boost::unordered_set<unsigned int> tmp;
293 tmp.insert(current_vertex);
294 colors_used.push_back(tmp);
310 template <
typename Iterator>
311 std::vector<std::vector<Iterator> >
312 gather_colors(
const std::vector<std::vector<std::vector<Iterator> > > &partition_coloring)
314 std::vector<std::vector<Iterator> > coloring;
317 const unsigned int partition_size(partition_coloring.size());
318 std::vector<std::vector<unsigned int> > colors_counter(partition_size);
319 for (
unsigned int i=0; i<partition_size; ++i)
321 const unsigned int n_colors(partition_coloring[i].size());
322 colors_counter[i].resize(n_colors);
323 for (
unsigned int j=0; j<n_colors; ++j)
324 colors_counter[i][j] = partition_coloring[i][j].size();
328 unsigned int i_color(0);
329 unsigned int max_even_n_colors(0);
330 const unsigned int colors_size(colors_counter.size());
331 for (
unsigned int i=0; i<colors_size; i+=2)
333 if (max_even_n_colors<colors_counter[i].size())
335 max_even_n_colors = colors_counter[i].size();
339 coloring.resize(max_even_n_colors);
340 for (
unsigned int j=0; j<colors_counter[i_color].size(); ++j)
341 coloring[j] = partition_coloring[i_color][j];
343 for (
unsigned int i=0; i<partition_size; i+=2)
347 boost::unordered_set<unsigned int> used_k;
348 for (
unsigned int j=0; j<colors_counter[i].size(); ++j)
352 std::vector<unsigned int>::iterator it;
353 it = std::max_element(colors_counter[i].begin(),colors_counter[i].end());
354 unsigned int min_iterators (static_cast<unsigned int>(-1));
358 for (
unsigned int k=0; k<max_even_n_colors; ++k)
359 if (used_k.count(k)==0)
360 if (colors_counter[i_color][k]<min_iterators)
362 min_iterators = colors_counter[i_color][k];
365 colors_counter[i_color][pos] += *it;
367 coloring[pos].insert(coloring[pos].end(),
368 partition_coloring[i][it-colors_counter[i].begin()].begin(),
369 partition_coloring[i][it-colors_counter[i].begin()].end());
379 if (partition_size>1)
381 unsigned int max_odd_n_colors(0);
382 for (
unsigned int i=1; i<partition_size; i+=2)
384 if (max_odd_n_colors<colors_counter[i].size())
386 max_odd_n_colors = colors_counter[i].size();
390 coloring.resize(max_even_n_colors+max_odd_n_colors);
391 for (
unsigned int j=0; j<colors_counter[i_color].size(); ++j)
392 coloring[max_even_n_colors+j] = partition_coloring[i_color][j];
394 for (
unsigned int i=1; i<partition_size; i+=2)
398 boost::unordered_set<unsigned int> used_k;
399 for (
unsigned int j=0; j<colors_counter[i].size(); ++j)
403 std::vector<unsigned int>::iterator it;
404 it = std::max_element(colors_counter[i].begin(),colors_counter[i].end());
405 unsigned int min_iterators(static_cast<unsigned int>(-1));
409 for (
unsigned int k=0; k<max_odd_n_colors; ++k)
410 if (used_k.count(k)==0)
411 if (colors_counter[i_color][k]<min_iterators)
413 min_iterators = colors_counter[i_color][k];
416 colors_counter[i_color][pos] += *it;
418 coloring[max_even_n_colors+pos].insert(coloring[max_even_n_colors+pos].end(),
419 partition_coloring[i][it-colors_counter[i].begin()].begin(),
420 partition_coloring[i][it-colors_counter[i].begin()].end());
513 template <
typename Iterator>
514 std::vector<std::vector<Iterator> >
516 const typename identity<Iterator>::type &end,
517 const std_cxx11::function<std::vector<types::global_dof_index> (
const typename identity<Iterator>::type &)> &get_conflict_indices)
519 Assert (begin != end,
ExcMessage (
"GraphColoring is not prepared to deal with empty ranges!"));
522 std::vector<std::vector<Iterator> >
523 partitioning = internal::create_partitioning (begin,
525 get_conflict_indices);
529 const unsigned int partitioning_size(partitioning.size());
530 std::vector<std::vector<std::vector<Iterator> > >
531 partition_coloring(partitioning_size);
534 for (
unsigned int i=0; i<partitioning_size; ++i)
537 get_conflict_indices,
538 partition_coloring[i]);
542 return internal::gather_colors(partition_coloring);
547 DEAL_II_NAMESPACE_CLOSE
std::vector< std::vector< Iterator > > make_graph_coloring(const Iterator &begin, const typename identity< Iterator >::type &end, const std_cxx11::function< std::vector< types::global_dof_index >(const typename identity< Iterator >::type &)> &get_conflict_indices)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define Assert(cond, exc)
Task< RT > new_task(const std_cxx11::function< RT()> &function)