Limbo 3.5.4
Loading...
Searching...
No Matches
BacktrackColoring.h
Go to the documentation of this file.
1
7
8#ifndef LIMBO_ALGORITHMS_COLORING_BACKTRACKCOLORING
9#define LIMBO_ALGORITHMS_COLORING_BACKTRACKCOLORING
10
13
15namespace limbo
16{
18namespace algorithms
19{
21namespace coloring
22{
23
27template <typename GraphType>
28class BacktrackColoring : public Coloring<GraphType>
29{
30 public:
32 typedef Coloring<GraphType> base_type;
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;
41 typedef typename boost::graph_traits<graph_type>::edge_descriptor edge_descriptor;
43
46 BacktrackColoring(graph_type const& g)
47 : base_type(g)
48 {}
49
50 virtual ~BacktrackColoring() {}
51 protected:
53 virtual double coloring();
57 double init_coloring(vector<int8_t>& vColor) const;
66 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;
67};
68
69template <typename GraphType>
71{
72 /*
73 // init edge costs
74 // For positive edge, cost = 1; for negative edge cost = this->stitch_weight();
75 edge_iterator_type ei, eie;
76 graph_type *tempGraph = const_cast<graph_type* >(&this->m_graph);
77 for(boost::tie(ei, eie) = boost::edges(*tempGraph); ei != eie; ++ei)
78 {
79 // edge_descriptor ed = *ei;
80 edge_weight_type w = 0;
81 if(this->edge_weight(*ei) >= 0)
82 w = 1;
83 else
84 w = -this->stitch_weight();
85 // (*tempGraph)[ed].weight = w;
86 std::cout << "weight : " << this->edge_weight(*ei) << std::endl;
87 }
88*/
89 vector<int8_t> vBestColor(this->m_vColor.begin(), this->m_vColor.end());
90 vector<int8_t> vColor (this->m_vColor.begin(), this->m_vColor.end());
91 //double best_cost = this->init_coloring(vBestColor);
92 double best_cost = std::numeric_limits<double>::max();
93 double cur_cost = 0;
94 double actual_cost;
95
96 //std::cout << "best cost from dsat = " << best_cost << std::endl;
97
98 // solve coloring problem
99 // heuristic for speedup when graph is large
100 if (boost::num_vertices(this->m_graph) > 50 && best_cost > 0)
101 {
102 double cur_best_cost = best_cost;
103 //double best_cost_lb = 0;
104 for (double tmp_best_cost = 0; tmp_best_cost < cur_best_cost; ++tmp_best_cost)
105 {
106 //best_cost = tmp_best_cost;
107 //best_cost = std::numeric_limits<double>::max();
108 this->coloring_kernel(vBestColor, vColor, best_cost, cur_cost, 0, 0, tmp_best_cost);
109 //actual_cost = this->calc_cost(vBestColor);
110 //std::cout << "tmp_best_cost = " << tmp_best_cost << " best_cost = " << best_cost << " actual_cost = " << actual_cost
111 //<< " best_cost_lb = " << best_cost_lb
112 //<< std::endl;
113 //if (best_cost == actual_cost)
114 if (best_cost <= tmp_best_cost)
115 break;
116 //else best_cost_lb += 1;
117 // reset
118 vColor.assign(this->m_vColor.begin(), this->m_vColor.end());
119 cur_cost = 0;
120 }
121 }
122 else if (best_cost > 0)
123 this->coloring_kernel(vBestColor, vColor, best_cost, cur_cost, 0, 0, best_cost);
124
125 // apply coloring solution
126 this->m_vColor.swap(vBestColor);
127
128 // verify solution
129 actual_cost = this->calc_cost(this->m_vColor);
130 //limboAssertMsg(best_cost == actual_cost, "best_cost = " << best_cost << ", actual cost = " << actual_cost);
131#ifdef DEBUG_LIWEI
132 limboPrint(kDEBUG, "Graph has %lu nodes, with backtracking cost %g\n", boost::num_vertices(this->m_graph), best_cost);
133#endif
134 return best_cost;
135}
136
137template <typename GraphType>
139{
141 dc();
142
143 vertex_iterator_type vi, vie;
144 for (boost::tie(vi, vie) = boost::vertices(this->m_graph); vi != vie; ++vi)
145 {
146 graph_vertex_type v = *vi;
147 int8_t color = dc.color(v);
148 if (vColor[v] >= 0 && vColor[v] < this->m_color_num) // precolored
149 continue;
150 else if (color >= this->m_color_num)
151 vColor[v] = this->m_color_num-1;
152 else vColor[v] = color;
153 limboAssert(vColor[v] >= 0 && vColor[v] < this->m_color_num);
154 }
155 // calculate cost
156 double cost = this->calc_cost(vColor);
157 return cost;
158}
159
160template <typename GraphType>
161void BacktrackColoring<GraphType>::coloring_kernel(vector<int8_t>& vBestColor, vector<int8_t>& vColor, double& best_cost, double& cur_cost,
162 BacktrackColoring<GraphType>::graph_vertex_type v, double cost_lb, double cost_ub) const
163{
164 if (best_cost <= cost_lb) // no conflict or reach to lower bound cost
165 return;
166 if (cur_cost >= best_cost|| cur_cost > cost_ub) // branch and bound
167 return;
168 if (v == boost::num_vertices(this->m_graph)) // leaf node in the recursion tree
169 {
170 if (cur_cost < best_cost)
171 {
172 best_cost = cur_cost;
173 vBestColor.assign(vColor.begin(), vColor.end());
174 }
175 // std::cout << "best_cost : " << best_cost << std::endl;
176 return;
177 }
178
179 int8_t color_begin = 0;
180 int8_t color_end = this->m_color_num;
181 if (this->m_vColor[v] >= 0 && this->m_vColor[v] < this->m_color_num) // precolored vertex
182 {
183 color_begin = this->m_vColor[v];
184 color_end = color_begin+1;
185 }
186 for (int8_t c = color_begin; c < color_end; ++c)
187 {
188 vColor[v] = c;
189 double delta_cost = 0;
190 adjacency_iterator_type vi, vie;
191 for (boost::tie(vi, vie) = boost::adjacent_vertices(v, this->m_graph); vi != vie; ++vi)
192 {
193 graph_vertex_type u = *vi;
194 if (u < v) // only check parent node in the recursion tree
195 {
196 std::pair<graph_edge_type, bool> e = boost::edge(u, v, this->m_graph);
197 limboAssertMsg(e.second, "failed to find edge with " << u << "--" << v);
198 edge_weight_type w = boost::get(boost::edge_weight, this->m_graph, e.first);
199 if (w >= 0) // conflict edge
200 delta_cost += (vColor[u] == c)*w;
201 else // stitch edge
202 delta_cost -= (vColor[u] != c)*w*this->stitch_weight();
203 }
204 }
205 cur_cost += delta_cost;
206 this->coloring_kernel(vBestColor, vColor, best_cost, cur_cost, v+1, cost_lb, cost_ub); // recursion
207 cur_cost -= delta_cost;
208 }
209}
210
211} // namespace coloring
212} // namespace algorithms
213} // namespace limbo
214
215#endif
#define limboAssertMsg(condition, args...)
custom assertion with message
Definition AssertMsg.h:24
#define limboAssert(condition)
custom assertion without message
Definition AssertMsg.h:36
base class for all graph coloring algorithms
coloring a graph with saturation degree based heuristics
double init_coloring(vector< int8_t > &vColor) const
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
virtual int8_t color(graph_vertex_type v) const
Definition Coloring.h:196
graph_type const & m_graph
initial graph
Definition Coloring.h:239
virtual double stitch_weight() const
Definition Coloring.h:184
std::vector< int8_t > m_vColor
coloring solutions
Definition Coloring.h:240
virtual edge_weight_type calc_cost(std::vector< int8_t > const &vColor) const
Definition Coloring.h:397
ColorNumType m_color_num
number of colors
Definition Coloring.h:242
int color(graph_vertex_type v) const
namespace for Limbo.Algorithms.Coloring
namespace for Limbo.algorithms
namespace for Limbo
int limboPrint(MessageType m, const char *format,...)
formatted print with prefix
Definition PrintMsg.h:49