Limbo 3.5.4
Loading...
Searching...
No Matches
Coloring.h
Go to the documentation of this file.
1
7
8#ifndef LIMBO_ALGORITHMS_COLORING_COLORING
9#define LIMBO_ALGORITHMS_COLORING_COLORING
10
11#include <fstream>
12#include <vector>
13#include <boost/cstdint.hpp>
14#include <boost/functional/hash.hpp>
15#include <boost/graph/graph_concepts.hpp>
16#include <boost/graph/adjacency_list.hpp>
17#include <boost/property_map/property_map.hpp>
20
22namespace limbo
23{
25namespace algorithms
26{
28namespace coloring
29{
30
31using boost::uint32_t;
32using boost::int32_t;
33using boost::int8_t;
34
35namespace la = limbo::algorithms;
36
39template <typename GraphType>
40struct ColoringVertexLabelWriter : public la::VertexLabelWriter<GraphType>
41{
43 typedef GraphType graph_type;
44 typedef la::VertexLabelWriter<graph_type> base_type;
45 typedef typename base_type::vertex_descriptor vertex_descriptor;
47
48 std::vector<int8_t> const& vColor;
49
53 ColoringVertexLabelWriter(graph_type const& g, std::vector<int8_t> const& vc) : base_type(g), vColor(vc) {}
54
58 std::string label(vertex_descriptor v) const
59 {
60 std::ostringstream oss;
61 oss << v << ":" << (int32_t)vColor[v];
62 return oss.str();
63 }
64};
65
68template <typename GraphType>
69struct ColoringEdgeLabelWriter : public la::EdgeLabelWriter<GraphType>
70{
72 typedef GraphType graph_type;
73 typedef la::EdgeLabelWriter<graph_type> base_type;
74 typedef typename base_type::edge_descriptor edge_descriptor;
75 typedef typename base_type::edge_weight_type edge_weight_type;
76 typedef typename boost::graph_traits<graph_type>::vertex_descriptor vertex_descriptor;
78
79 std::vector<int8_t> const& vColor;
80
84 ColoringEdgeLabelWriter(graph_type const& g, std::vector<int8_t> const& vc) : base_type(g), vColor(vc) {}
85
89 edge_weight_type label(edge_descriptor e) const {return boost::get(boost::edge_weight, this->g, e);}
93 std::string color(edge_descriptor e) const
94 {
95 vertex_descriptor s = boost::source(e, this->g);
96 vertex_descriptor t = boost::target(e, this->g);
97 edge_weight_type w = boost::get(boost::edge_weight, this->g, e);
98 bool conflict_flag = (vColor[s] >= 0 && vColor[s] == vColor[t]);
99 if (w >= 0 && conflict_flag) // conflict
100 return "red";
101 else return "black";
102 }
103
106 std::string style(edge_descriptor e) const {return (boost::get(boost::edge_weight, this->g, e) >= 0)? "solid" : "dashed";}
107};
108
113template <typename GraphType>
115{
116 public:
118 typedef GraphType graph_type;
119 typedef typename boost::graph_traits<graph_type>::vertex_descriptor graph_vertex_type;
120 typedef typename boost::graph_traits<graph_type>::edge_descriptor graph_edge_type;
121 typedef typename boost::graph_traits<graph_type>::vertex_iterator vertex_iterator_type;
122 typedef typename boost::graph_traits<graph_type>::edge_iterator edge_iterator_type;
123 typedef typename boost::graph_traits<graph_type>::adjacency_iterator adjacency_iterator;
124 // value type for edge weight, integer or double...
125 typedef typename boost::property_traits<typename boost::property_map<graph_type, boost::edge_weight_t>::const_type>::value_type edge_weight_type;
126 // edge weight is used to differentiate conflict edge and stitch edge
127 // non-negative weight implies conflict edge
128 // negative weight implies stitch edge
129 typedef typename boost::property_traits<typename boost::property_map<graph_type, boost::edge_index_t>::const_type>::value_type edge_index_type;
130
132
135 {
136 TWO = 2,
137 THREE = 3,
138 FOUR = 4
139 };
140
141 struct EdgeHashType : std::unary_function<graph_edge_type, std::size_t>
142 {
145 std::size_t operator()(graph_edge_type const& e) const
146 {
147 std::size_t seed = 0;
148 boost::hash_combine(seed, e.m_source);
149 boost::hash_combine(seed, e.m_target);
150 return seed;
151 }
152 };
153
154
157 Coloring(graph_type const& g);
159 virtual ~Coloring() {};
160
161 // member functions
164 virtual double operator()();
165
168 virtual void color_num(ColorNumType cn) {m_color_num = cn;}
171 virtual void color_num(int8_t cn) {m_color_num = (cn == 3)? THREE : (cn == 2)? TWO : FOUR;}
173 virtual ColorNumType color_num() const {return m_color_num;}
174
178 virtual void precolor(graph_vertex_type v, int8_t c) {m_vColor[v] = c; m_has_precolored = true;}
179
181 virtual bool has_precolored() const {return m_has_precolored;}
182
184 virtual double stitch_weight() const {return m_stitch_weight;}
187 virtual void stitch_weight(double w) {m_stitch_weight = w;}
188
191 virtual void threads(int32_t t) {m_threads = t;}
192
196 virtual int8_t color(graph_vertex_type v) const {return m_vColor[v];}
197
198 // helper functions
202 inline virtual edge_weight_type edge_weight(graph_edge_type const& e) const {return boost::get(boost::edge_weight, m_graph, e);}
203
207 virtual edge_weight_type calc_cost(std::vector<int8_t> const& vColor) const;
208
213 void check_edge_weight(graph_type const& g, edge_weight_type lb, edge_weight_type ub) const;
214
217 void print_edge_weight(graph_type const& g) const;
218
219 // search vertexes in stitch relation
220 // @param v vertex
221 // @param stitch_relatiin_set recording for each vertex indicating the stitch relation
222 // @param visited is visited in DFS
223 // @param stitch_edge_num total stitch edge number in graph
224 void depth_first_search_stitch(graph_vertex_type v, std::vector<int32_t>& stitch_relation_set,
225 std::vector<bool>& visited,uint32_t& stitch_edge_num,int32_t stitch_index);
226 // for debug
229 virtual void write_graph(std::string const& filename) const;
234 virtual void write_graph(std::string const& filename, graph_type const& g, std::vector<int8_t> const& vColor) const;
235 protected:
237 virtual double coloring() = 0;
238
239 graph_type const& m_graph;
240 std::vector<int8_t> m_vColor;
241
244 int32_t m_threads;
246
247 // node num in big graph
248 int32_t m_stitch_index;
249 // edge num in big graph
250 int32_t m_big_edge_num;
251 std::vector<int32_t> m_stitch_relation_set;
252 //a verctor of len(stitch_index*stitch_index)
253 std::vector<int32_t> m_edge_index_vector;
254};
255
256template <typename GraphType>
257Coloring<GraphType>::Coloring(Coloring<GraphType>::graph_type const& g)
258 : m_graph(g)
259 , m_vColor(boost::num_vertices(g), -1)
260 , m_color_num(THREE)
261 , m_stitch_weight(0.1)
262 , m_threads(std::numeric_limits<int32_t>::max())
263 , m_has_precolored(false)
264 , m_stitch_index(0)
265 , m_big_edge_num(0)
266{}
267
268template <typename GraphType>
270{
271 double cost ;
272 uint32_t stitch_edge_num = 0;
273 //total wo-stitch node number
274
275 //parent node in non-stitch graph index of each node in stitch graph
276
277
278 //Step 1. Firstly, count the number of stitch edges and store all of the stitch relations
279 vertex_iterator_type vi, vie,next;
280 boost::tie(vi, vie) = vertices(m_graph);
281 std::vector<bool> visited(boost::num_vertices(m_graph), false);
282 m_stitch_relation_set.assign(boost::num_vertices(m_graph),-1);
283 for (next = vi; vi != vie; vi = next)
284 {
285 ++next;
286 graph_vertex_type v = *vi;
287 if(visited[(int32_t)v]) continue;
288 else{
289 visited[(int32_t)v] = true;
290 m_stitch_relation_set[(int32_t)v] = m_stitch_index;
291 depth_first_search_stitch(v,m_stitch_relation_set,visited,stitch_edge_num,m_stitch_index);
292 m_stitch_index ++;
293 }
294 }
295
296
297 m_edge_index_vector.assign(m_stitch_index*m_stitch_index,-1);
298 bool is_legal = true;
299
300 //Step 2. Verify the feasibility of this method(no conflict should be introduced when inserting stitch)
301 // Also, record the edge_index_vector
302 boost::tie(vi, vie) = vertices(m_graph);
303 for (next = vi; vi != vie; vi = next)
304 {
305 ++next;
306 graph_vertex_type v = *vi;
307 adjacency_iterator vi2, vie2,next2;
308 boost::tie(vi2, vie2) = boost::adjacent_vertices(v, m_graph);
309 for (next2 = vi2; vi2 != vie2; vi2 = next2){
310 ++next2;
311 graph_vertex_type v2 = *vi2;
312 std::pair<graph_edge_type, bool> e12 = boost::edge(v, v2, m_graph);
313 limboAssert(e12.second);
314 if(boost::get(boost::edge_weight, m_graph, e12.first) > 0){
315 //if the big_edge is not considered, consider it and add 1
316 if(m_edge_index_vector[m_stitch_relation_set[(int32_t)v]*m_stitch_index + m_stitch_relation_set[(int32_t)v2]] == -1){
317 m_edge_index_vector[m_stitch_relation_set[(int32_t)v]*m_stitch_index + m_stitch_relation_set[(int32_t)v2]] = m_big_edge_num;
318 m_big_edge_num++;
319 }
320 }
321 if (boost::get(boost::edge_weight, m_graph, e12.first) > 0 && m_stitch_relation_set[(int32_t)v] == m_stitch_relation_set[(int32_t)v2]) is_legal = false;
322 }
323 }
324 //Step 3. Assign the colors
325 std::vector<int32_t> stitch_relation_to_color(m_stitch_index,-1);
326 std::vector<bool> unused_color(color_num(),true);
327
328
329 if (boost::num_vertices(m_graph) <= color_num()+stitch_edge_num && is_legal) // if vertex number is no larger than color number, directly assign color
330 {
331 //Step 3.1: Assign pre-defined color firstly
332 limboAssert(m_stitch_index <= color_num());
333 for (int32_t i = 0, ie = m_vColor.size(); i != ie; ++i)
334 {
335 if (m_vColor[i] >= 0) // if not precolored, assign to an unused color
336 {
337 stitch_relation_to_color[m_stitch_relation_set[i]] = m_vColor[i];
338 unused_color[m_vColor[i]] = false;
339 }
340 }
341
342 //Step 3.2: Assign un-pre-defined color and keep colors of stitch vertexes same.
343 for (int32_t i = 0, ie = m_vColor.size(); i != ie; ++i)
344 {
345 if (m_vColor[i] < 0) // if not precolored, assign to an unused color
346 {
347 if(stitch_relation_to_color[m_stitch_relation_set[i]] != -1){
348 m_vColor[i] = stitch_relation_to_color[m_stitch_relation_set[i]];
349 }
350 else{
351 for(int32_t c= 0;c<color_num();c++){
352 if(unused_color[c]){
353 m_vColor[i] = c;
354 stitch_relation_to_color[m_stitch_relation_set[i]] = c;
355 unused_color[m_vColor[i]] = false;
356 break;
357 }
358 }
359 }
360
361 }
362 }
363 cost = calc_cost(m_vColor);
364 std::cout<<"Heustical calcuted";
365 limboAssert(cost == 0);
366 }
367 else // perform coloring algorithm
368 cost = this->coloring();
369 std::cout<<"selected coloring solver calcuted"<<cost;
370 // clock_t sub_comp_end = clock();
371 return cost;
372}
373
374template <typename GraphType>
375void Coloring<GraphType>::depth_first_search_stitch(graph_vertex_type v, std::vector<int32_t>& stitch_relation_set,\
376std::vector<bool>& visited,uint32_t& stitch_edge_num, int32_t stitch_index)
377{
378 adjacency_iterator vi2, vie2,next2;
379 boost::tie(vi2, vie2) = boost::adjacent_vertices(v, m_graph);
380 for (next2 = vi2; vi2 != vie2; vi2 = next2){
381 ++next2;
382 graph_vertex_type v2 = *vi2;
383 if(visited[(int32_t)v2]) continue;
384 std::pair<graph_edge_type, bool> e12 = boost::edge(v, v2, m_graph);
385 limboAssert(e12.second);
386 if (boost::get(boost::edge_weight, m_graph, e12.first) < 0) {
387 visited[(int32_t)v2] = true;
388 stitch_edge_num ++;
389 stitch_relation_set[(int32_t)v2] = stitch_index;
390 depth_first_search_stitch(v2,stitch_relation_set,visited,stitch_edge_num,stitch_index);
391 }
392 }
393}
394
395
396template <typename GraphType>
397typename Coloring<GraphType>::edge_weight_type Coloring<GraphType>::calc_cost(std::vector<int8_t> const& vColor) const
398{
399 limboAssert(vColor.size() == boost::num_vertices(this->m_graph));
400 double cost = 0;
401 edge_iterator_type ei, eie;
402 for (boost::tie(ei, eie) = boost::edges(m_graph); ei != eie; ++ei)
403 {
404 edge_weight_type w = boost::get(boost::edge_weight, m_graph, *ei);
405 graph_vertex_type s = boost::source(*ei, m_graph);
406 graph_vertex_type t = boost::target(*ei, m_graph);
407 if (s == t) // skip self edges
408 continue;
409 if (w >= 0) // conflict edge
410 {
411 cost += (vColor[s] == vColor[t])*w;
412 }
413 else // stitch edge
414 {
415 cost -= (vColor[s] != vColor[t])*w*this->stitch_weight();
416 }
417 }
418 return cost;
419}
420
421template <typename GraphType>
422void Coloring<GraphType>::check_edge_weight(typename Coloring<GraphType>::graph_type const& g, typename Coloring<GraphType>::edge_weight_type lb, typename Coloring<GraphType>::edge_weight_type ub) const
423{
424 edge_iterator_type ei, eie;
425 for (boost::tie(ei, eie) = boost::edges(g); ei != eie; ++ei)
426 {
427 edge_weight_type w = boost::get(boost::edge_weight, m_graph, *ei);
428 limboAssertMsg(w >= lb && w <= ub, "edge weight out of range: " << w);
429 }
430}
431
432template <typename GraphType>
433void Coloring<GraphType>::print_edge_weight(typename Coloring<GraphType>::graph_type const& g) const
434{
435 edge_iterator_type ei, eie;
436 for (boost::tie(ei, eie) = boost::edges(g); ei != eie; ++ei)
437 {
438 edge_weight_type w = boost::get(boost::edge_weight, m_graph, *ei);
439 limboPrint(kNONE, "%g ", (double)w);
440 }
441 limboPrint(kNONE, "\n");
442}
443
444// it seems doxygen cannot handle template functions with the same name correctly
446template <typename GraphType>
447void Coloring<GraphType>::write_graph(std::string const& filename) const
448{
449 write_graph(filename, m_graph, m_vColor);
450}
451
452template <typename GraphType>
453void Coloring<GraphType>::write_graph(std::string const& filename, Coloring<GraphType>::graph_type const& g, std::vector<int8_t> const& vColor) const
454{
455 std::ofstream out ((filename+".gv").c_str());
456 limboPrint(kINFO, "write_graph : %s\n", filename.c_str());
457 la::write_graph(out, g, ColoringVertexLabelWriter<graph_type>(g, vColor), ColoringEdgeLabelWriter<graph_type>(g, vColor));
458 out.close();
459 la::graphviz2pdf(filename);
460}
462
463} // namespace coloring
464} // namespace algorithms
465} // namespace limbo
466
467#endif
assertion with message
#define limboAssertMsg(condition, args...)
custom assertion with message
Definition AssertMsg.h:24
#define limboAssert(condition)
custom assertion without message
Definition AssertMsg.h:36
some graph utilities such as compute complement graph and graphviz writer.
virtual void color_num(int8_t cn)
Definition Coloring.h:171
void check_edge_weight(graph_type const &g, edge_weight_type lb, edge_weight_type ub) const
Definition Coloring.h:422
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 edge_weight_type edge_weight(graph_edge_type const &e) const
Definition Coloring.h:202
virtual void precolor(graph_vertex_type v, int8_t c)
Definition Coloring.h:178
int32_t m_threads
control number of threads for ILP solver
Definition Coloring.h:244
bool m_has_precolored
whether contain precolored vertices
Definition Coloring.h:245
virtual double stitch_weight() const
Definition Coloring.h:184
virtual ColorNumType color_num() const
Definition Coloring.h:173
void print_edge_weight(graph_type const &g) const
Definition Coloring.h:433
double m_stitch_weight
stitch weight
Definition Coloring.h:243
virtual bool has_precolored() const
Definition Coloring.h:181
virtual void stitch_weight(double w)
Definition Coloring.h:187
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
virtual void write_graph(std::string const &filename, graph_type const &g, std::vector< int8_t > const &vColor) const
virtual void write_graph(std::string const &filename) const
virtual void threads(int32_t t)
Definition Coloring.h:191
virtual void color_num(ColorNumType cn)
Definition Coloring.h:168
Boost.Geometry.
Definition GdsObjects.h:740
namespace for Limbo.Algorithms.Coloring
namespace for Limbo.algorithms
void write_graph(std::ofstream &out, GraphType const &g, VertexLabelType const &vl, EdgeLabelType const &el)
write graph to graphviz format and convert to pdf. Although Boost.Graph has write_graphviz component,...
namespace for Limbo
std::iterator_traits< Iterator >::value_type max(Iterator first, Iterator last)
get max of an array
Definition Math.h:61
int limboPrint(MessageType m, const char *format,...)
formatted print with prefix
Definition PrintMsg.h:49
graph_type const & g
bind graph object
graph_type const & g
bind graph object
std::size_t operator()(graph_edge_type const &e) const
Definition Coloring.h:145
std::string style(edge_descriptor e) const
Definition Coloring.h:106
std::string color(edge_descriptor e) const
Definition Coloring.h:93
edge_weight_type label(edge_descriptor e) const
Definition Coloring.h:89
ColoringEdgeLabelWriter(graph_type const &g, std::vector< int8_t > const &vc)
Definition Coloring.h:84
std::vector< int8_t > const & vColor
coloring solutions
Definition Coloring.h:79
ColoringVertexLabelWriter(graph_type const &g, std::vector< int8_t > const &vc)
Definition Coloring.h:53
std::vector< int8_t > const & vColor
coloring solutions
Definition Coloring.h:48
std::string label(vertex_descriptor v) const
Definition Coloring.h:58