PandA-2024.02
maxclique_dsatur_coloring.hpp
Go to the documentation of this file.
1 /*
2  *
3  * _/_/_/ _/_/ _/ _/ _/_/_/ _/_/
4  * _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
5  * _/_/_/ _/_/_/_/ _/ _/_/ _/ _/ _/_/_/_/
6  * _/ _/ _/ _/ _/ _/ _/ _/ _/
7  * _/ _/ _/ _/ _/ _/_/_/ _/ _/
8  *
9  * ***********************************************
10  * PandA Project
11  * URL: http://panda.dei.polimi.it
12  * Politecnico di Milano - DEIB
13  * System Architectures Group
14  * ***********************************************
15  * Copyright (C) 2004-2024 Politecnico di Milano
16  *
17  * This file is part of the PandA framework.
18  *
19  * The PandA framework is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
49 #ifndef MAXCLIQUE_DSATUR_COLORING_HPP
50 #define MAXCLIQUE_DSATUR_COLORING_HPP
51 
52 #include <boost/config.hpp>
53 #include <boost/graph/properties.hpp>
54 #include <boost/version.hpp>
55 #if BOOST_VERSION >= 104000
56 #include <boost/property_map/property_map.hpp>
57 #else
58 #include <boost/property_map.hpp>
59 #endif
60 #include <boost/graph/graph_traits.hpp>
61 #include <boost/graph/visitors.hpp>
62 #include <boost/limits.hpp>
63 #if BOOST_VERSION >= 106400
64 #include <boost/serialization/array_wrapper.hpp>
65 #endif
66 #include <algorithm>
67 #include <boost/numeric/ublas/matrix.hpp>
68 #include <cassert>
69 #include <vector>
70 
71 #include "custom_set.hpp"
72 #include <boost/graph/filtered_graph.hpp>
73 
94 namespace boost
95 {
96  template <typename size_type>
98  {
99  public:
100  bool operator()(size_type i1, size_type i2) const
101  {
102  size_type c1 = ColorCount[i1], c2 = ColorCount[i2];
103  return !((c1 > c2) || ((c1 == c2) && (DegreeCount[i1] > DegreeCount[i2])));
104  }
105  heap_compare_functor(const std::vector<size_type>& _ColorCount, const std::vector<size_type>& _DegreeCount)
106  : ColorCount(_ColorCount), DegreeCount(_DegreeCount)
107  {
108  }
109 
110  private:
111  const std::vector<size_type>& ColorCount;
112  const std::vector<size_type>& DegreeCount;
113  };
114  template <class VertexListGraph, class ColorMap>
115  typename property_traits<ColorMap>::value_type unsorted_coloring(const VertexListGraph& G, ColorMap color)
116  {
117  using GraphTraits = graph_traits<VertexListGraph>;
118  using Vertex = typename GraphTraits::vertex_descriptor;
119  using size_type = typename property_traits<ColorMap>::value_type;
120 
121  size_type max_color = 0;
122  const size_type V = num_vertices(G);
123 
124  // We need to keep track of which colors are used by
125  // adjacent vertices. We do this by marking the colors
126  // that are used. The mark array contains the mark
127  // for each color. The length of mark is the
128  // number of vertices since the maximum possible number of colors
129  // is the number of vertices.
130  std::vector<size_type> mark(V, std::numeric_limits<size_type>::max BOOST_PREVENT_MACRO_SUBSTITUTION());
131 
132  // Initialize colors
133  typename GraphTraits::vertex_iterator v, vend;
134  for(boost::tie(v, vend) = vertices(G); v != vend; ++v)
135  {
136  put(color, *v, V - 1);
137  }
138 
139  // Determine the color for every vertex one by one
140  size_type i = 0;
141  for(boost::tie(v, vend) = vertices(G); v != vend; ++v)
142  {
143  Vertex current = *v;
144  typename GraphTraits::adjacency_iterator v1, vend1;
145 
146  // Mark the colors of vertices adjacent to current.
147  // i can be the value for marking since i increases successively
148  for(boost::tie(v1, vend1) = adjacent_vertices(current, G); v1 != vend1; ++v1)
149  {
150  mark[get(color, *v1)] = i;
151  }
152 
153  // Next step is to assign the smallest un-marked color
154  // to the current vertex.
155  size_type j = 0;
156 
157  // Scan through all usable colors, find the smallest possible
158  // color that is not used by neighbors. Note that if mark[j]
159  // is equal to i, color j is used by one of the current vertex's
160  // neighbors.
161  while(j < max_color && mark[j] == i)
162  {
163  ++j;
164  }
165 
166  if(j == max_color)
167  { // All colors are used up. Add one more color
168  ++max_color;
169  }
170 
171  // At this point, j is the smallest possible color
172  put(color, current, j); // Save the color of vertex current
173  ++i;
174  }
175  return max_color;
176  }
177 
181  template <typename SET_container>
183  {
184  select_vertex() : support(0)
185  {
186  }
187  explicit select_vertex(SET_container* _support) : support(_support)
188  {
189  }
191  {
192  support = sv.support;
193  }
194  select_vertex& operator=(const select_vertex&) = delete;
195  void init(SET_container* _support)
196  {
197  support = _support;
198  }
199  template <typename Vertex>
200  bool operator()(const Vertex& v) const
201  {
202  // printf("bool = %d\n", support->find(v) != support->end() ? 1 : 0);
203  return support->find(v) != support->end();
204  }
205  SET_container* support;
206  };
207 
208  template <typename VertexListGraph, typename ColorMap, typename size_type, typename SET_container>
210  {
211  private:
212  using GraphTraits = graph_traits<VertexListGraph>;
213  using Vertex = typename GraphTraits::vertex_descriptor;
214  const size_type num_node;
215  size_type BestColoring;
216  std::vector<size_type> ColorClass;
217  std::vector<bool> valid;
218  //, boost::numeric::ublas::row_major, std::vector<size_type>
219  typename boost::numeric::ublas::matrix<size_type> ColorAdj;
220  std::vector<size_type> ColorCount;
221  std::vector<size_type> DegreeCount;
222  size_type& lb;
223  const VertexListGraph& G;
224  ColorMap& CM;
225  size_type* heap_container;
227  const unsigned int clique_size;
229  SET_container support;
230  SET_container C;
231  SET_container BestClique;
232  using Induced_Graph = filtered_graph<VertexListGraph, keep_all, select_vertex<SET_container>>;
234  using IG_GraphTraits = graph_traits<Induced_Graph>;
235  using IG_Vertex = typename IG_GraphTraits::vertex_descriptor;
236 
237  public:
238  maxclique_dsatur_coloring_helper(const VertexListGraph& _G, ColorMap& _CM, const size_type _num_node,
239  size_type& _lb)
240  : num_node(_num_node),
241  BestColoring(_num_node + 1),
242  ColorClass(_num_node, _num_node - 1),
243  valid(_num_node, true),
244  ColorAdj(_num_node, _num_node),
245  ColorCount(_num_node, 0),
246  DegreeCount(_num_node),
247  lb(_lb),
248  G(_G),
249  CM(_CM),
250  HCF(ColorCount, DegreeCount),
251  clique_size(0),
252  filter(&support),
253  FG(G, keep_all(), filter)
254  {
255  unsigned int i, iheap = 0;
256  heap_container = new size_type[_num_node - clique_size];
257  for(i = 0; i < num_node; i++)
258  {
259  Vertex v = vertex(i, G);
260  support.insert(v);
261  DegreeCount[i] = degree(v, G);
262  heap_container[iheap] = i;
263  iheap++;
264  }
265  boost::numeric::ublas::noalias(ColorAdj) = boost::numeric::ublas::zero_matrix<size_type>(_num_node, _num_node);
266  }
268  {
269  delete[] heap_container;
270  }
271  // no copy constructor
274  size_type MaxCliqueGreedy()
275  {
276  SET_container GreedySupport, G1_support;
277  typename IG_GraphTraits::vertex_iterator vstart, v, vend;
278  boost::tie(vstart, vend) = vertices(FG);
279  v = vstart;
280  while(v != vend)
281  {
282  GreedySupport.insert(*v);
283  ++v;
284  }
285  std::swap(GreedySupport, support);
286  do
287  {
288  v = vstart;
289  IG_Vertex selected = *v;
290  size_type maxdegree = out_degree(*v, FG);
291  ;
292  ++v;
293  while(v != vend)
294  {
295  size_type tmpdegree = out_degree(*v, FG);
296  if(tmpdegree > maxdegree)
297  {
298  maxdegree = tmpdegree;
299  selected = *v;
300  }
301  ++v;
302  }
303  BestClique.insert(selected);
304  typename IG_GraphTraits::adjacency_iterator v1, v1end;
305  boost::tie(v1, v1end) = adjacent_vertices(selected, FG);
306  G1_support.insert(v1, v1end);
307  support = G1_support;
308  G1_support.clear();
309  boost::tie(vstart, vend) = vertices(FG);
310  } while(vstart != vend);
311  std::swap(GreedySupport, support);
312  return BestClique.size();
313  }
314  size_type MaxCliqueRec(size_type ub)
315  {
316  typename IG_GraphTraits::vertex_iterator vstart, v, vend;
317  boost::tie(vstart, vend) = vertices(FG);
318  if(vstart == vend)
319  {
320  if(BestClique.size() < C.size())
321  {
322  BestClique = C;
323  // printf("Best clique is %ld (A)\n", BestClique.size());
324  }
325  return C.size();
326  }
327 
328  std::vector<size_type> color_vec(num_node);
329  ColorMap color(&color_vec.front(), get(vertex_index, FG));
330  size_type k = unsorted_coloring(FG, color);
332  if(support.size() == num_node && k < BestColoring)
333  {
334  BestColoring = k;
335  for(size_type i = 0; i < num_node; ++i)
336  {
337  put(CM, vertex(i, G), get(color, vertex(i, G)));
338  }
339  // printf("Best coloring is %ld\n", BestColoring);
340  }
341  ub = ub <= k + C.size() ? ub : k + C.size();
342  if(ub <= BestClique.size())
343  {
344  return BestClique.size();
345  }
346 
348  v = vstart;
349  IG_Vertex selected = *v;
350  size_type FG_cardinality = 1;
351  size_type mindegree = out_degree(*v, FG);
352  size_type maxdegree = mindegree;
353  ++v;
354  while(v != vend)
355  {
356  size_type tmpdegree = out_degree(*v, FG);
357  if(tmpdegree > maxdegree)
358  {
359  maxdegree = tmpdegree;
360  selected = *v;
361  }
362  if(tmpdegree < mindegree)
363  {
364  mindegree = tmpdegree;
365  }
366  ++v;
367  ++FG_cardinality;
368  }
370  if(FG_cardinality + C.size() <= BestClique.size())
371  {
372  return BestClique.size();
373  }
375  if(mindegree + 1 == FG_cardinality)
376  {
377  if(BestClique.size() < C.size() + FG_cardinality)
378  {
379  BestClique = C;
380  BestClique.insert(vstart, vend);
381  // printf("Best clique is %ld (B)\n", BestClique.size());
382  }
383  return BestClique.size();
384  }
386  SET_container G1_support;
387  typename IG_GraphTraits::adjacency_iterator v1, v1end;
388  boost::tie(v1, v1end) = adjacent_vertices(selected, FG);
389  G1_support.insert(v1, v1end);
390  std::swap(G1_support, support);
391  C.insert(selected);
392  size_type sizeG1 = MaxCliqueRec(ub);
393  C.erase(selected);
394  std::swap(G1_support, support);
395  if(ub == sizeG1)
396  {
397  return sizeG1;
398  }
399  support.erase(selected);
400  size_type sizeG0 = MaxCliqueRec(ub);
401  support.insert(selected);
402  return sizeG0;
403  }
404  void save_colors()
405  {
406  size_type i;
407  // printf("Best coloring is %ld\n", BestColoring);
408  for(i = 0; i < num_node; i++)
409  {
410  put(CM, vertex(i, G), ColorClass[i]);
411  }
412  }
413 
414  void AssignColor(size_type node, size_type color)
415  {
416  size_type node1;
417 
418  ColorClass[node] = color;
419  typename GraphTraits::adjacency_iterator v, vend;
420  for(boost::tie(v, vend) = adjacent_vertices(vertex(node, G), G); v != vend; ++v)
421  {
422  node1 = get(vertex_index, G, *v);
423  if(ColorAdj(node1, color) == 0)
424  {
425  ColorCount[node1]++;
426  }
427  ColorAdj(node1, color) += 1;
428  DegreeCount[node1]--;
429  assert(DegreeCount[node1] >= 0);
430  }
431  }
432 
433  void RemoveColor(size_type node, size_type color)
434  {
435  size_type node1;
436  ColorClass[node] = 0;
437  typename GraphTraits::adjacency_iterator v, vend;
438  for(boost::tie(v, vend) = adjacent_vertices(vertex(node, G), G); v != vend; ++v)
439  {
440  node1 = get(vertex_index, G, *v);
441  assert(ColorAdj(node1, color) != 0);
442  ColorAdj(node1, color) -= 1;
443  if(ColorAdj(node1, color) == 0)
444  {
445  ColorCount[node1]--;
446  }
447  DegreeCount[node1]++;
448  }
449  }
450 
451  size_type SeqColorRec(size_type i, size_type current_color)
452  {
453  size_type j, new_val, place;
454  // int k, count;
455 
456  // prob_count++;
457  if(current_color + 1 >= BestColoring)
458  {
459  return (current_color + 1);
460  }
461  if(BestColoring <= lb)
462  {
463  return (BestColoring);
464  }
465 
466  if(i >= num_node)
467  {
468  return (current_color + 1);
469  }
470  /* printf("Node %ld, num_color %ld\n",i,current_color);*/
471 
472  /* Find node with maximum color_adj */
473  std::make_heap(heap_container + i - clique_size, heap_container + num_node - clique_size, HCF);
474  place = heap_container[i];
475 
476  /* printf("Using node %ld at level %ld\n",place,i);*/
477  for(j = 0; j <= current_color; j++)
478  {
479  if(ColorAdj(place, j) == 0)
480  {
481  AssignColor(place, j);
482  new_val = SeqColorRec(i + 1, current_color);
483  if(new_val < BestColoring)
484  {
485  BestColoring = new_val;
486  save_colors();
487  }
488  RemoveColor(place, j);
489  if(BestColoring <= current_color)
490  {
491  return (BestColoring);
492  }
493  }
494  }
495  if(current_color + 2 < BestColoring)
496  {
497  AssignColor(place, current_color + 1);
498  new_val = SeqColorRec(i + 1, current_color + 1);
499  if(new_val < BestColoring)
500  {
501  BestColoring = new_val;
502  save_colors();
503  }
504 
505  RemoveColor(place, current_color + 1);
506  }
507  return (BestColoring);
508  }
509  };
510 
511  template <typename VertexListGraph, typename ColorMap>
512  typename property_traits<ColorMap>::value_type maxclique_dsatur_coloring(const VertexListGraph& G, ColorMap color)
513  {
514  using GraphTraits = graph_traits<VertexListGraph>;
515  using Vertex = typename GraphTraits::vertex_descriptor;
516  using size_type = typename property_traits<ColorMap>::value_type;
517 
518  const size_type num_node = num_vertices(G);
519  if(num_node == 0)
520  {
521  return 0;
522  }
523  size_type lb = 0, val;
524  using SET_container = CustomUnorderedSet<Vertex>;
526  lb);
527 
528  // size_type best_clique=0;
529  // unsigned int num_prob = 0, max_prob = 10000;
530  // unsigned int prob_count = 0;
531  size_type place = 0;
532  lb = MDCH.MaxCliqueGreedy();
533  // printf("Lower bound is %ld\n", lb);
534  lb = MDCH.MaxCliqueRec(num_node);
535  // printf("Lower bound is %ld\n", lb);
536  val = MDCH.SeqColorRec(place, place);
537  // printf("Best coloring has value %ld, subproblems: %d\n", val, prob_count);
538  return val;
539  }
540 } // namespace boost
541 
542 #endif
property_traits< ColorMap >::value_type unsorted_coloring(const VertexListGraph &G, ColorMap color)
TVMArray c2[1]
This algorithm is to find coloring of a graph Algorithm: Let G = (V,E) be a graph with vertices v_1...
TVMArray c1[1]
heap_compare_functor(const std::vector< size_type > &_ColorCount, const std::vector< size_type > &_DegreeCount)
#define C
Definition: generate.c:15
maxclique_dsatur_coloring_helper(const VertexListGraph &_G, ColorMap &_CM, const size_type _num_node, size_type &_lb)
size_type SeqColorRec(size_type i, size_type current_color)
void init(SET_container *_support)
boost::numeric::ublas::matrix< size_type > ColorAdj
void AssignColor(size_type node, size_type color)
#define max
Definition: backprop.h:17
bool operator()(const Vertex &v) const
filtered_graph< VertexListGraph, keep_all, select_vertex< SET_container > > Induced_Graph
void RemoveColor(size_type node, size_type color)
property_traits< ColorMap >::value_type maxclique_dsatur_coloring(const VertexListGraph &G, ColorMap color)
static const uint32_t k[]
Definition: sha-256.c:22
redefinition of set to manage ordered/unordered structures
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
Definition: graph.hpp:1303
Predicate functor object used to select the proper set of vertices.
typename IG_GraphTraits::vertex_descriptor IG_Vertex
bool operator()(size_type i1, size_type i2) const
const std::vector< size_type > & DegreeCount
select_vertex(const select_vertex &sv)
const std::vector< size_type > & ColorCount
typename GraphTraits::vertex_descriptor Vertex
select_vertex(SET_container *_support)

Generated on Mon Feb 12 2024 13:02:50 for PandA-2024.02 by doxygen 1.8.13