8#ifndef LIMBO_ALGORITHMS_COLORING_COLORING
9#define LIMBO_ALGORITHMS_COLORING_COLORING
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>
35namespace la = limbo::algorithms;
39template <
typename GraphType>
43 typedef GraphType graph_type;
44 typedef la::VertexLabelWriter<graph_type> base_type;
45 typedef typename base_type::vertex_descriptor vertex_descriptor;
58 std::string
label(vertex_descriptor v)
const
60 std::ostringstream oss;
61 oss << v <<
":" << (int32_t)
vColor[v];
68template <
typename GraphType>
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;
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
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);
99 if (w >= 0 && conflict_flag)
106 std::string
style(edge_descriptor e)
const {
return (boost::get(boost::edge_weight, this->
g, e) >= 0)?
"solid" :
"dashed";}
113template <
typename GraphType>
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;
125 typedef typename boost::property_traits<typename boost::property_map<graph_type, boost::edge_weight_t>::const_type>::value_type edge_weight_type;
129 typedef typename boost::property_traits<typename boost::property_map<graph_type, boost::edge_index_t>::const_type>::value_type edge_index_type;
141 struct EdgeHashType : std::unary_function<graph_edge_type, std::size_t>
147 std::size_t seed = 0;
148 boost::hash_combine(seed, e.m_source);
149 boost::hash_combine(seed, e.m_target);
202 inline virtual edge_weight_type
edge_weight(graph_edge_type
const& e)
const {
return boost::get(boost::edge_weight,
m_graph, e);}
207 virtual edge_weight_type
calc_cost(std::vector<int8_t>
const& vColor)
const;
213 void check_edge_weight(graph_type
const& g, edge_weight_type lb, edge_weight_type ub)
const;
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);
234 virtual void write_graph(std::string
const& filename, graph_type
const& g, std::vector<int8_t>
const& vColor)
const;
248 int32_t m_stitch_index;
250 int32_t m_big_edge_num;
251 std::vector<int32_t> m_stitch_relation_set;
253 std::vector<int32_t> m_edge_index_vector;
256template <
typename GraphType>
268template <
typename GraphType>
272 uint32_t stitch_edge_num = 0;
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)
286 graph_vertex_type v = *vi;
287 if(visited[(int32_t)v])
continue;
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);
297 m_edge_index_vector.assign(m_stitch_index*m_stitch_index,-1);
298 bool is_legal =
true;
302 boost::tie(vi, vie) = vertices(
m_graph);
303 for (next = vi; vi != vie; vi = 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){
311 graph_vertex_type v2 = *vi2;
312 std::pair<graph_edge_type, bool> e12 = boost::edge(v, v2,
m_graph);
314 if(boost::get(boost::edge_weight,
m_graph, e12.first) > 0){
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;
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;
325 std::vector<int32_t> stitch_relation_to_color(m_stitch_index,-1);
326 std::vector<bool> unused_color(
color_num(),
true);
329 if (boost::num_vertices(
m_graph) <=
color_num()+stitch_edge_num && is_legal)
333 for (int32_t i = 0, ie =
m_vColor.size(); i != ie; ++i)
337 stitch_relation_to_color[m_stitch_relation_set[i]] =
m_vColor[i];
343 for (int32_t i = 0, ie =
m_vColor.size(); i != ie; ++i)
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]];
354 stitch_relation_to_color[m_stitch_relation_set[i]] = c;
364 std::cout<<
"Heustical calcuted";
369 std::cout<<
"selected coloring solver calcuted"<<cost;
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)
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){
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);
386 if (boost::get(boost::edge_weight, m_graph, e12.first) < 0) {
387 visited[(int32_t)v2] =
true;
389 stitch_relation_set[(int32_t)v2] = stitch_index;
390 depth_first_search_stitch(v2,stitch_relation_set,visited,stitch_edge_num,stitch_index);
396template <
typename GraphType>
399 limboAssert(vColor.size() == boost::num_vertices(this->m_graph));
401 edge_iterator_type ei, eie;
402 for (boost::tie(ei, eie) = boost::edges(
m_graph); ei != eie; ++ei)
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);
411 cost += (vColor[s] == vColor[t])*w;
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
424 edge_iterator_type ei, eie;
425 for (boost::tie(ei, eie) = boost::edges(g); ei != eie; ++ei)
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);
432template <
typename GraphType>
435 edge_iterator_type ei, eie;
436 for (boost::tie(ei, eie) = boost::edges(g); ei != eie; ++ei)
438 edge_weight_type w = boost::get(boost::edge_weight,
m_graph, *ei);
446template <
typename GraphType>
452template <
typename GraphType>
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));
459 la::graphviz2pdf(filename);
#define limboAssertMsg(condition, args...)
custom assertion with message
#define limboAssert(condition)
custom assertion without message
some graph utilities such as compute complement graph and graphviz writer.
Coloring(graph_type const &g)
virtual double operator()()
virtual ~Coloring()
destructor
virtual void color_num(int8_t cn)
void check_edge_weight(graph_type const &g, edge_weight_type lb, edge_weight_type ub) const
virtual int8_t color(graph_vertex_type v) const
graph_type const & m_graph
initial graph
virtual edge_weight_type edge_weight(graph_edge_type const &e) const
virtual void precolor(graph_vertex_type v, int8_t c)
int32_t m_threads
control number of threads for ILP solver
ColorNumType
number of colors
bool m_has_precolored
whether contain precolored vertices
virtual double stitch_weight() const
virtual ColorNumType color_num() const
void print_edge_weight(graph_type const &g) const
double m_stitch_weight
stitch weight
virtual bool has_precolored() const
virtual void stitch_weight(double w)
std::vector< int8_t > m_vColor
coloring solutions
virtual edge_weight_type calc_cost(std::vector< int8_t > const &vColor) const
ColorNumType m_color_num
number of colors
virtual double coloring()=0
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)
virtual void color_num(ColorNumType cn)
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,...
std::iterator_traits< Iterator >::value_type max(Iterator first, Iterator last)
get max of an array
int limboPrint(MessageType m, const char *format,...)
formatted print with prefix
graph_type const & g
bind graph object
graph_type const & g
bind graph object
hasher class for graph_edge_type
std::size_t operator()(graph_edge_type const &e) const
std::string style(edge_descriptor e) const
std::string color(edge_descriptor e) const
edge_weight_type label(edge_descriptor e) const
ColoringEdgeLabelWriter(graph_type const &g, std::vector< int8_t > const &vc)
std::vector< int8_t > const & vColor
coloring solutions
ColoringVertexLabelWriter(graph_type const &g, std::vector< int8_t > const &vc)
std::vector< int8_t > const & vColor
coloring solutions
std::string label(vertex_descriptor v) const