Limbo
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BacktrackColoring.h
Go to the documentation of this file.
1 
8 #ifndef LIMBO_ALGORITHMS_COLORING_BACKTRACKCOLORING
9 #define LIMBO_ALGORITHMS_COLORING_BACKTRACKCOLORING
10 
13 
15 namespace limbo
16 {
18 namespace algorithms
19 {
21 namespace coloring
22 {
23 
27 template <typename GraphType>
28 class BacktrackColoring : public Coloring<GraphType>
29 {
30  public:
33  using typename base_type::graph_type;
34  using typename base_type::graph_vertex_type;
35  using typename base_type::graph_edge_type;
36  using typename base_type::vertex_iterator_type;
37  using typename base_type::edge_iterator_type;
38  using typename base_type::edge_weight_type;
39  using typename base_type::ColorNumType;
40  typedef typename boost::graph_traits<graph_type>::adjacency_iterator adjacency_iterator_type;
42 
45  BacktrackColoring(graph_type const& g)
46  : base_type(g)
47  {}
49  virtual ~BacktrackColoring() {}
50  protected:
52  virtual double coloring();
56  double init_coloring(vector<int8_t>& vColor) const;
65  void coloring_kernel(vector<int8_t>& vBestColor, vector<int8_t>& vColor, double& best_cost, double& cur_cost, graph_vertex_type v, double cost_lb, double cost_ub) const;
66 };
67 
68 template <typename GraphType>
70 {
71  vector<int8_t> vBestColor(this->m_vColor.begin(), this->m_vColor.end());
72  vector<int8_t> vColor (this->m_vColor.begin(), this->m_vColor.end());
73  double best_cost = this->init_coloring(vBestColor);
74  double cur_cost = 0;
75  double actual_cost;
76 
77  //std::cout << "best cost from dsat = " << best_cost << std::endl;
78 
79  // solve coloring problem
80  // heuristic for speedup when graph is large
81  if (boost::num_vertices(this->m_graph) > 50 && best_cost > 0)
82  {
83  double cur_best_cost = best_cost;
84  //double best_cost_lb = 0;
85  for (double tmp_best_cost = 0; tmp_best_cost < cur_best_cost; ++tmp_best_cost)
86  {
87  //best_cost = tmp_best_cost;
88  //best_cost = std::numeric_limits<double>::max();
89  this->coloring_kernel(vBestColor, vColor, best_cost, cur_cost, 0, tmp_best_cost, tmp_best_cost);
90  //actual_cost = this->calc_cost(vBestColor);
91  //std::cout << "tmp_best_cost = " << tmp_best_cost << " best_cost = " << best_cost << " actual_cost = " << actual_cost
92  //<< " best_cost_lb = " << best_cost_lb
93  //<< std::endl;
94  //if (best_cost == actual_cost)
95  if (best_cost <= tmp_best_cost)
96  break;
97  //else best_cost_lb += 1;
98  // reset
99  vColor.assign(this->m_vColor.begin(), this->m_vColor.end());
100  cur_cost = 0;
101  }
102  }
103  else if (best_cost > 0)
104  this->coloring_kernel(vBestColor, vColor, best_cost, cur_cost, 0, 0, best_cost);
105 
106  // apply coloring solution
107  this->m_vColor.swap(vBestColor);
108 
109  // verify solution
110  actual_cost = this->calc_cost(this->m_vColor);
111  assert_msg(best_cost == actual_cost, "best_cost = " << best_cost << ", actual cost = " << actual_cost);
112 
113  return best_cost;
114 }
115 
116 template <typename GraphType>
117 double BacktrackColoring<GraphType>::init_coloring(vector<int8_t>& vColor) const
118 {
119  DsatColoring<graph_type> dc (this->m_graph);
120  dc();
121 
122  vertex_iterator_type vi, vie;
123  for (boost::tie(vi, vie) = boost::vertices(this->m_graph); vi != vie; ++vi)
124  {
125  graph_vertex_type v = *vi;
126  int8_t color = dc.color(v);
127  if (vColor[v] >= 0 && vColor[v] < this->m_color_num) // precolored
128  continue;
129  else if (color >= this->m_color_num)
130  vColor[v] = this->m_color_num-1;
131  else vColor[v] = color;
132  assert(vColor[v] >= 0 && vColor[v] < this->m_color_num);
133  }
134  // calculate cost
135  double cost = this->calc_cost(vColor);
136  return cost;
137 }
138 
139 template <typename GraphType>
140 void BacktrackColoring<GraphType>::coloring_kernel(vector<int8_t>& vBestColor, vector<int8_t>& vColor, double& best_cost, double& cur_cost,
141  BacktrackColoring<GraphType>::graph_vertex_type v, double cost_lb, double cost_ub) const
142 {
143  if (best_cost <= cost_lb) // no conflict or reach to lower bound cost
144  return;
145  if (cur_cost >= best_cost || cur_cost > cost_ub) // branch and bound
146  return;
147  if (v == boost::num_vertices(this->m_graph)) // leaf node in the recursion tree
148  {
149  if (cur_cost < best_cost)
150  {
151  best_cost = cur_cost;
152  vBestColor.assign(vColor.begin(), vColor.end());
153  }
154  return;
155  }
156 
157  int8_t color_begin = 0;
158  int8_t color_end = this->m_color_num;
159  if (this->m_vColor[v] >= 0 && this->m_vColor[v] < this->m_color_num) // precolored vertex
160  {
161  color_begin = this->m_vColor[v];
162  color_end = color_begin+1;
163  }
164  for (int8_t c = color_begin; c < color_end; ++c)
165  {
166  vColor[v] = c;
167  double delta_cost = 0;
168  adjacency_iterator_type vi, vie;
169  for (boost::tie(vi, vie) = boost::adjacent_vertices(v, this->m_graph); vi != vie; ++vi)
170  {
171  graph_vertex_type u = *vi;
172  if (u < v) // only check parent node in the recursion tree
173  {
174  if (vColor[u] == c) // conflict
175  {
176  std::pair<graph_edge_type, bool> e = boost::edge(u, v, this->m_graph);
177  assert_msg(e.second, "failed to find edge with " << u << "--" << v);
178  edge_weight_type w = boost::get(boost::edge_weight, this->m_graph, e.first);
179  assert_msg(w > 0, "only support conflict edges with positive cost"); // only support conflict edges
180  delta_cost += w;
181  }
182  }
183  }
184  cur_cost += delta_cost;
185  this->coloring_kernel(vBestColor, vColor, best_cost, cur_cost, v+1, cost_lb, cost_ub); // recursion
186  cur_cost -= delta_cost;
187  }
188 }
189 
190 } // namespace coloring
191 } // namespace algorithms
192 } // namespace limbo
193 
194 #endif
double init_coloring(vector< int8_t > &vColor) const
namespace for Limbo
Definition: GraphUtility.h:22
coloring a graph with saturation degree based heuristics
base class for all graph coloring algorithms
void coloring_kernel(vector< int8_t > &vBestColor, vector< int8_t > &vColor, double &best_cost, double &cur_cost, graph_vertex_type v, double cost_lb, double cost_ub) const
int color(graph_vertex_type v) const
#define assert_msg(condition, message)
assertion with message
Definition: AssertMsg.h:34