13#ifndef LIMBO_ALGORITHMS_GRAPHSIMPLIFICATION_H
14#define LIMBO_ALGORITHMS_GRAPHSIMPLIFICATION_H
24#include <boost/graph/graph_concepts.hpp>
25#include <boost/graph/graph_utility.hpp>
26#include <boost/graph/adjacency_list.hpp>
27#include <boost/graph/undirected_graph.hpp>
28#include <boost/property_map/property_map.hpp>
43namespace la = ::limbo::algorithms;
49template <
typename GraphType>
54 typedef GraphType graph_type;
55 typedef typename boost::graph_traits<graph_type>::vertex_descriptor graph_vertex_type;
56 typedef typename boost::graph_traits<graph_type>::edge_descriptor graph_edge_type;
57 typedef typename boost::graph_traits<graph_type>::vertex_iterator vertex_iterator;
58 typedef typename boost::graph_traits<graph_type>::adjacency_iterator adjacency_iterator;
59 typedef typename boost::graph_traits<graph_type>::edge_iterator edge_iterator;
97 graph_vertex_type v = 0;
98 for (
typename std::vector<graph_vertex_type>::iterator it =
m_vParent.begin(), ite =
m_vParent.end(); it != ite; ++it, ++v)
101 for (
typename std::vector<std::vector<graph_vertex_type> >::iterator it =
m_vChildren.begin(), ite =
m_vChildren.end(); it != ite; ++it, ++v)
103#ifdef DEBUG_GRAPHSIMPLIFICATION
115 template <
typename Iterator>
119#ifdef DEBUG_GRAPHSIMPLIFICATION
134 std::pair<graph_type, std::map<graph_vertex_type, graph_vertex_type> >
simplified_graph()
const;
149 void get_CompVertex(std::vector<std::vector<graph_vertex_type> >& CompVertex);
162 void recover(std::vector<int8_t>& vColorFlat, std::vector<std::vector<int8_t> >& mColor, std::vector<std::vector<graph_vertex_type> >
const& mSimpl2Orig)
const;
166 void set_isHiden(std::set<graph_vertex_type> is_hidens);
187 void mergeVDD(std::set<graph_vertex_type> vdd_set);
199 void recover_biconnected_component(std::vector<std::vector<int8_t> >& mColor, std::vector<std::vector<graph_vertex_type> >
const& mSimpl2Orig)
const;
218 void get_articulations(std::vector<graph_vertex_type> &art_vec)
220 std::vector<graph_vertex_type>().swap(art_vec);
221 typename std::map<graph_vertex_type, std::set<uint32_t> >::iterator it =
m_mArtiPoint.begin();
224 art_vec.push_back(it->first);
240 std::vector<uint32_t>& vLow, std::vector<graph_vertex_type>& vParent, uint32_t& visit_time,
241 std::stack<std::pair<graph_vertex_type, graph_vertex_type> >& vEdge,
242 std::list<std::pair<graph_vertex_type, std::set<graph_vertex_type> > >& mCompVertex)
const;
248 graph_vertex_type
parent(graph_vertex_type v)
const
250#ifdef DEBUG_GRAPHSIMPLIFICATION
261 graph_vertex_type
parent(uint32_t v, std::vector<uint32_t>
const& vParent)
const
263 while (v != vParent.at(v))
272 graph_vertex_type vp1 = this->
parent(v1);
273 graph_vertex_type vp2 = this->
parent(v2);
274 std::vector<graph_vertex_type>
const& vChildren1 =
m_vChildren.at(vp1);
275 std::vector<graph_vertex_type>
const& vChildren2 =
m_vChildren.at(vp2);
276 for (
typename std::vector<graph_vertex_type>::const_iterator vic1 = vChildren1.begin(); vic1 != vChildren1.end(); ++vic1)
277 for (
typename std::vector<graph_vertex_type>::const_iterator vic2 = vChildren2.begin(); vic2 != vChildren2.end(); ++vic2)
279 std::pair<graph_edge_type, bool> e12 = boost::edge(*vic1, *vic2,
m_graph);
281 if (e12.second && boost::get(boost::edge_weight,
m_graph, e12.first) >= 0)
return true;
290 graph_vertex_type vp1 = this->
parent(v1);
291 graph_vertex_type vp2 = this->
parent(v2);
292 std::vector<graph_vertex_type>
const& vChildren1 =
m_vChildren.at(vp1);
293 std::vector<graph_vertex_type>
const& vChildren2 =
m_vChildren.at(vp2);
294 for (
typename std::vector<graph_vertex_type>::const_iterator vic1 = vChildren1.begin(); vic1 != vChildren1.end(); ++vic1)
295 for (
typename std::vector<graph_vertex_type>::const_iterator vic2 = vChildren2.begin(); vic2 != vChildren2.end(); ++vic2)
297 std::pair<graph_edge_type, bool> e12 = boost::edge(*vic1, *vic2,
m_graph);
299 if (e12.second && boost::get(boost::edge_weight,
m_graph, e12.first) < 0)
return true;
306 std::pair<graph_edge_type, bool>
connected_edge(graph_vertex_type v1, graph_vertex_type v2)
const
308 graph_vertex_type vp1 = this->
parent(v1);
309 graph_vertex_type vp2 = this->
parent(v2);
310 std::vector<graph_vertex_type>
const& vChildren1 =
m_vChildren.at(vp1);
311 std::vector<graph_vertex_type>
const& vChildren2 =
m_vChildren.at(vp2);
312 for (
typename std::vector<graph_vertex_type>::const_iterator vic1 = vChildren1.begin(); vic1 != vChildren1.end(); ++vic1)
313 for (
typename std::vector<graph_vertex_type>::const_iterator vic2 = vChildren2.begin(); vic2 != vChildren2.end(); ++vic2)
315 std::pair<graph_edge_type, bool> e12 = boost::edge(*vic1, *vic2,
m_graph);
316 if (e12.second)
return e12;
318 return std::make_pair(graph_edge_type(),
false);
325#ifdef DEBUG_GRAPHSIMPLIFICATION
334 bool good(graph_vertex_type v1)
const
389template <
typename GraphType>
390std::pair<typename GraphSimplification<GraphType>::graph_type, std::map<typename GraphSimplification<GraphType>::graph_vertex_type,
typename GraphSimplification<GraphType>::graph_vertex_type> >
393 size_t vertex_cnt = 0;
394 std::map<graph_vertex_type, graph_vertex_type> mG2MG;
395 std::map<graph_vertex_type, graph_vertex_type> mMG2G;
396 vertex_iterator vi1, vie1;
397 for (boost::tie(vi1, vie1) = boost::vertices(
m_graph); vi1 != vie1; ++vi1)
399 graph_vertex_type v1 = *vi1;
402 mG2MG[*vi1] = vertex_cnt;
403 mMG2G[vertex_cnt] = v1;
407 graph_type mg (vertex_cnt);
409 edge_iterator ei, eie;
410 for (boost::tie(ei, eie) = boost::edges(
m_graph); ei != eie; ++ei)
412 graph_edge_type e = *ei;
413 graph_vertex_type s = boost::source(e,
m_graph);
414 graph_vertex_type t = boost::target(e,
m_graph);
418 graph_vertex_type sp = this->
parent(s);
419 graph_vertex_type tp = this->
parent(t);
421#ifdef DEBUG_GRAPHSIMPLIFICATION
425 graph_vertex_type msp = mG2MG[sp];
426 graph_vertex_type mtp = mG2MG[tp];
427 std::pair<graph_edge_type, bool> emg = boost::edge(msp, mtp, mg);
430 emg = boost::add_edge(msp, mtp, mg);
432 boost::put(boost::edge_weight, mg, emg.first, boost::get(boost::edge_weight,
m_graph, e));
440 boost::edge_weight, mg, emg.first,
441 boost::get(boost::edge_weight, mg, emg.first) + boost::get(boost::edge_weight,
m_graph, e)
445 return std::make_pair(mg, mMG2G);
448template <
typename GraphType>
451 for (
typename std::vector<std::vector<graph_vertex_type> >::iterator it =
m_mCompVertex.begin(); it !=
m_mCompVertex.end(); it++)
453 CompVertex.push_back(*it);
457template <
typename GraphType>
463template <
typename GraphType>
465 std::vector<
typename GraphSimplification<GraphType>::graph_vertex_type>& vSimpl2Orig)
const
469 std::vector<graph_vertex_type>
const& vCompVertex =
m_mCompVertex[comp_id];
471 graph_type sg (vCompVertex.size());
472 std::map<graph_vertex_type, graph_vertex_type> mOrig2Simpl;
473 vSimpl2Orig.assign(vCompVertex.begin(), vCompVertex.end());
474 for (uint32_t i = 0; i != vCompVertex.size(); ++i)
475 mOrig2Simpl[vCompVertex[i]] = i;
476#ifdef DEBUG_GRAPHSIMPLIFICATION
477 std::cout <<
"Comp " << comp_id <<
": ";
478 for (uint32_t i = 0; i != vCompVertex.size(); ++i)
479 std::cout << vCompVertex[i] <<
" ";
480 std::cout << std::endl;
484 std::cout <<
"\nSimplified Comp " << comp_id <<
" : \n";
485 for (uint32_t i = 0; i != vCompVertex.size(); ++i)
486 std::cout << i <<
" : " << vCompVertex[i] << std::endl;
487 std::cout << std::endl;
489 for (uint32_t i = 0; i != vCompVertex.size(); ++i)
491 std::cout << vCompVertex[i] <<
" : " << i << std::endl;
492 mOrig2Simpl[vCompVertex[i]] = i;
494 std::cout << std::endl;
495 if (vCompVertex[0] == 1 && vCompVertex[1] == 42)
498 for (
typename std::vector<graph_vertex_type>::const_iterator vi = vCompVertex.begin(); vi != vCompVertex.end(); ++vi)
500 graph_vertex_type v = *vi;
502 graph_vertex_type vsg = mOrig2Simpl[v];
509 limboPrint(kDEBUG,
"v : %u ap : %d\n", (uint32_t)v, (
int)ap);
512 std::vector<graph_vertex_type>
const& vChildren =
m_vChildren.at(v);
513 for (
typename std::vector<graph_vertex_type>::const_iterator vic = vChildren.begin(); vic != vChildren.end(); ++vic)
515 graph_vertex_type vc = *vic;
519 std::cout <<
"vc : " << vc << std::endl;
522 typename boost::graph_traits<graph_type>::adjacency_iterator ui, uie;
523 for (boost::tie(ui, uie) = boost::adjacent_vertices(vc,
m_graph); ui != uie; ++ui)
525 graph_vertex_type uc = *ui;
527 if (this->
hidden(uc))
continue;
528 graph_vertex_type u = this->
parent(uc);
532 std::cout <<
"uc : " << uc <<
" parent u : " << u << std::endl;
536 if (!this->
good(u))
continue;
537 else if (v >= u)
continue;
538 else if (ap && !mOrig2Simpl.count(u))
continue;
542 std::pair<graph_edge_type, bool> e = boost::edge(vc, uc,
m_graph);
546 graph_vertex_type usg = mOrig2Simpl[u];
550 std::cout <<
"usg : " << usg <<
" vsg : " << vsg << std::endl;
555 std::pair<graph_edge_type, bool> esg = boost::edge(vsg, usg, sg);
558 esg = boost::add_edge(vsg, usg, sg);
560 boost::put(boost::edge_weight, sg, esg.first, boost::get(boost::edge_weight,
m_graph, e.first));
568 boost::edge_weight, sg, esg.first,
569 boost::get(boost::edge_weight, sg, esg.first) + boost::get(boost::edge_weight,
m_graph, e.first)
577 vertex_iterator vi1, vie1;
580 for (boost::tie(vi1, vie1) = boost::vertices(simplG); vi1 != vie1; ++vi1)
587template <
typename GraphType>
590 for(
typename std::set<graph_vertex_type>::iterator it = vdd_set.begin(); it != vdd_set.end(); it++)
594template <
typename GraphType>
595void GraphSimplification<GraphType>::set_isHiden(std::set<
typename GraphSimplification<GraphType>::graph_vertex_type> is_hidens)
597 for(
typename std::set<graph_vertex_type>::iterator it = is_hidens.begin(); it != is_hidens.end(); it++)
598 m_vStatus[*it] = HIDDEN;
601template <
typename GraphType>
604 typename std::set<graph_vertex_type>::iterator it = vdd_set.begin();
606 graph_vertex_type
parent = *it;
608 for (; it != vdd_set.end(); it++)
613 it = vdd_set.begin();
615 for (; it != vdd_set.end(); it++)
622template <
typename GraphType>
629 bool reconstruct =
true;
645 uint32_t comp_id = 0;
646 for (
typename std::vector<std::vector<graph_vertex_type> >::iterator it =
m_mCompVertex.begin(); it !=
m_mCompVertex.end(); it++, comp_id++)
648 for (
typename std::vector<graph_vertex_type>::iterator its = it->begin(); its != it->end(); its++)
652 limboPrint(kDEBUG,
"comp %u has VDD %u\n", comp_id, (uint32_t)*its);
661 for (graph_vertex_type v = 0, ve = boost::num_vertices(
m_graph); v != ve; ++v)
667template <
typename GraphType>
675 for (uint32_t sub_comp_id = 0; sub_comp_id < mColor.size(); ++sub_comp_id)
677 std::vector<int8_t>
const& vColor = mColor[sub_comp_id];
678 std::vector<graph_vertex_type>
const& vSimpl2Orig = mSimpl2Orig[sub_comp_id];
679 for (uint32_t subv = 0; subv < vColor.size(); ++subv)
681 graph_vertex_type v = vSimpl2Orig[subv];
682 if (vColorFlat[v] >= 0)
685 vColorFlat[v] = vColor[subv];
706template <
typename GraphType>
718 vertex_iterator vi1, vie1;
719 for (boost::tie(vi1, vie1) = boost::vertices(
m_graph); vi1 != vie1; ++vi1)
721 graph_vertex_type v1 = *vi1;
723 if (!this->
good(v1))
continue;
725 std::vector<graph_vertex_type>
const& vChildren1 =
m_vChildren.at(v1);
726 for (
typename std::vector<graph_vertex_type>::const_iterator vic1 = vChildren1.begin(); vic1 != vChildren1.end(); ++vic1)
728#ifdef DEBUG_GRAPHSIMPLIFICATION
731 graph_vertex_type vc1 = *vic1;
732 adjacency_iterator vi2, vie2;
733 for (boost::tie(vi2, vie2) = boost::adjacent_vertices(vc1,
m_graph); vi2 != vie2; ++vi2)
736 if (this->
hidden(*vi2))
continue;
738 std::pair<graph_edge_type, bool> e12 = boost::edge(vc1, *vi2,
m_graph);
740 if (boost::get(boost::edge_weight,
m_graph, e12.first) < 0)
continue;
742 graph_vertex_type v2 = this->
parent(*vi2);
744 std::vector<graph_vertex_type>
const& vChildren2 =
m_vChildren.at(v2);
745 for (
typename std::vector<graph_vertex_type>::const_iterator vic2 = vChildren2.begin(); vic2 != vChildren2.end(); ++vic2)
747 graph_vertex_type vc2 = *vic2;
748 adjacency_iterator vi3, vie3;
749 for (boost::tie(vi3, vie3) = boost::adjacent_vertices(vc2,
m_graph); vi3 != vie3; ++vi3)
752 if (this->
hidden(*vi3))
continue;
754 std::pair<graph_edge_type, bool> e23 = boost::edge(vc2, *vi3,
m_graph);
756 if (boost::get(boost::edge_weight,
m_graph, e23.first) < 0)
continue;
758 graph_vertex_type v3 = this->
parent(*vi3);
760 if (v3 == v1)
continue;
765 std::vector<graph_vertex_type>
const& vChildren3 =
m_vChildren.at(v3);
766 for (
typename std::vector<graph_vertex_type>::const_iterator vic3 = vChildren3.begin(); vic3 != vChildren3.end(); ++vic3)
768 graph_vertex_type vc3 = *vic3;
769 adjacency_iterator vi4, vie4;
770 for (boost::tie(vi4, vie4) = boost::adjacent_vertices(vc3,
m_graph); vi4 != vie4; ++vi4)
775 std::pair<graph_edge_type, bool> e34 = boost::edge(vc3, *vi4,
m_graph);
777 if (boost::get(boost::edge_weight,
m_graph, e34.first) < 0)
continue;
779 graph_vertex_type v4 = this->
parent(*vi4);
781 if (v4 == v1 || v4 == v2 || this->
precolored(v4))
continue;
793#ifdef DEBUG_GRAPHSIMPLIFICATION
799 if (merge_flag)
break;
801 if (merge_flag)
break;
803 if (merge_flag)
break;
805 if (merge_flag)
break;
807 if (merge_flag)
break;
809 if (merge_flag)
break;
811 }
while (merge_flag);
815template <
typename GraphType>
826 vertex_iterator vi1, vie1;
827 for (boost::tie(vi1, vie1) = boost::vertices(
m_graph); vi1 != vie1; ++vi1)
829 graph_vertex_type v1 = *vi1;
832 size_t conflictPreVDD_degree = 0;
833 size_t stitchPreVDD_degree = 0;
835 std::vector<graph_vertex_type>
const& vChildren1 =
m_vChildren.at(v1);
837 for (
typename std::vector<graph_vertex_type>::const_iterator vic1 = vChildren1.begin(); vic1 != vChildren1.end(); ++vic1)
839#ifdef DEBUG_GRAPHSIMPLIFICATION
842 graph_vertex_type vc1 = *vic1;
843 adjacency_iterator vi2, vie2;
844 for (boost::tie(vi2, vie2) = boost::adjacent_vertices(vc1,
m_graph); vi2 != vie2; ++vi2)
847 if (this->
hidden(*vi2))
continue;
849 std::pair<graph_edge_type, bool> e12 = boost::edge(vc1, *vi2,
m_graph);
851 if (boost::get(boost::edge_weight,
m_graph, e12.first) < 0)
853 stitchPreVDD_degree += 1;
858 if (isVdd && bFind)
continue;
859 if (isVdd) bFind =
true;
861 conflictPreVDD_degree += 1;
864 if (conflictPreVDD_degree <
m_color_num && stitchPreVDD_degree ==0)
872 std::vector<graph_vertex_type>
const& vChildren1 =
m_vChildren.at(v1);
873 for (
typename std::vector<graph_vertex_type>::const_iterator vic1 = vChildren1.begin(); vic1 != vChildren1.end(); ++vic1)
875#ifdef DEBUG_GRAPHSIMPLIFICATION
876 std::cout <<
"std::stack +" << v1 << std::endl;
889template <
typename GraphType>
892 uint32_t vertex_num = boost::num_vertices(
m_graph);
893 std::stack<graph_vertex_type> vStack;
895 std::deque<bool> vVisited (vertex_num,
false);
896 std::vector<graph_vertex_type> vParent (vertex_num);
897 std::vector<uint32_t> vChildrenCnt (vertex_num, 0);
900 std::vector<uint32_t> vLow (vertex_num, std::numeric_limits<uint32_t>::max());
901 std::vector<uint32_t> vDisc(vertex_num, std::numeric_limits<uint32_t>::max());
902 std::deque<bool> vArtiPoint (vertex_num,
false);
903 std::stack<std::pair<graph_vertex_type, graph_vertex_type> > vEdge;
904 std::list<std::pair<graph_vertex_type, std::set<graph_vertex_type> > > mCompVertex;
905 uint32_t visit_time = 0;
908 vertex_iterator vi, vie;
909 for (boost::tie(vi, vie) = boost::vertices(
m_graph); vi != vie; ++vi)
912 for (boost::tie(vi, vie) = boost::vertices(
m_graph); vi != vie; ++vi)
914 graph_vertex_type source = *vi;
915 if (!vVisited[source])
922 mCompVertex.push_back(std::make_pair(std::numeric_limits<graph_vertex_type>::max(), std::set<graph_vertex_type>()));
925 mCompVertex.back().second.insert(vEdge.top().first);
926 mCompVertex.back().second.insert(vEdge.top().second);
928 }
while (!vEdge.empty());
932 uint32_t comp_id = 0;
935 m_mCompVertex.assign(mCompVertex.size(), std::vector<graph_vertex_type>());
936 for (
typename std::list<std::pair<graph_vertex_type, std::set<graph_vertex_type> > >::const_iterator it = mCompVertex.begin(); it != mCompVertex.end(); ++it, ++comp_id)
938 graph_vertex_type vap = it->first;
939 std::set<graph_vertex_type>
const& sComp = it->second;
940 if (vap < std::numeric_limits<graph_vertex_type>::max())
941 m_mArtiPoint.insert(std::make_pair(vap, std::set<uint32_t>()));
945 for (
typename std::list<std::pair<graph_vertex_type, std::set<graph_vertex_type> > >::const_iterator it = mCompVertex.begin(); it != mCompVertex.end(); ++it, ++comp_id)
948 std::set<graph_vertex_type>
const& sComp = it->second;
949 for (
typename std::set<graph_vertex_type>::const_iterator itc = sComp.begin(); itc != sComp.end(); ++itc)
951 graph_vertex_type v = *itc;
958 for (
typename std::map<graph_vertex_type, std::set<uint32_t> >::iterator it =
m_mArtiPoint.begin(); it !=
m_mArtiPoint.end(); it++)
962 limboPrint(kNONE,
"AP : %u\nwith comps : ", (uint32_t)it->first);
963 for (
typename std::set<uint32_t>::iterator its = it->second.begin(); its != it->second.end(); its++)
968 for (
typename std::vector<std::vector<graph_vertex_type> >::iterator it =
m_mCompVertex.begin(); it !=
m_mCompVertex.end(); it++, comp_id++)
971 for (
typename std::vector<graph_vertex_type>::iterator its = it->begin(); its != it->end(); its++)
981#ifdef DEBUG_GRAPHSIMPLIFICATION
983 for (
typename std::list<std::pair<graph_vertex_type, std::set<graph_vertex_type> > >::const_iterator it = mCompVertex.begin(); it != mCompVertex.end(); ++it, ++comp_id)
985 graph_vertex_type vap = it->first;
986 std::set<graph_vertex_type>
const& sComp = it->second;
987 std::cout <<
"+ articulation point " << vap <<
" --> comp " << comp_id <<
": ";
988 for (
typename std::set<graph_vertex_type>::const_iterator itc = sComp.begin(); itc != sComp.end(); ++itc)
989 std::cout << *itc <<
" ";
990 std::cout << std::endl;
992 for (
typename std::map<graph_vertex_type, std::set<uint32_t> >::const_iterator it =
m_mArtiPoint.begin(); it !=
m_mArtiPoint.end(); ++it)
994 graph_vertex_type vap = it->first;
995 std::set<uint32_t>
const& sComp = it->second;
996 std::cout <<
"ap " << vap <<
": ";
997 for (
typename std::set<uint32_t>::const_iterator itc = sComp.begin(); itc != sComp.end(); ++itc)
998 std::cout << *itc <<
" ";
999 std::cout << std::endl;
1004template <
typename GraphType>
1006 std::vector<uint32_t>& vLow, std::vector<graph_vertex_type>& vParent, uint32_t& visit_time,
1007 std::stack<std::pair<graph_vertex_type, graph_vertex_type> >& vEdge,
1008 std::list<std::pair<graph_vertex_type, std::set<graph_vertex_type> > >& mCompVertex)
const
1017 vDisc[v] = vLow[v] = visit_time++;
1021 if (!this->
good(v))
return;
1023 bool isolate =
true;
1025 std::vector<graph_vertex_type>
const& vChildren =
m_vChildren.at(v);
1026 for (
typename std::vector<graph_vertex_type>::const_iterator vic = vChildren.begin(); vic != vChildren.end(); ++vic)
1028 graph_vertex_type vc = *vic;
1031 if (this->
hidden(vc))
continue;
1033 adjacency_iterator ui, uie;
1034 for (boost::tie(ui, uie) = boost::adjacent_vertices(vc,
m_graph); ui != uie; ++ui)
1036 graph_vertex_type uc = *ui;
1038 if (this->
hidden(uc))
continue;
1041 graph_vertex_type u = this->
parent(uc);
1050 vEdge.push(std::make_pair(std::min(v, u), std::max(v, u)));
1055 vLow[v] = std::min(vLow[v], vLow[u]);
1062 if ((vParent[v] == v &&
children > 1)
1063 || (vParent[v] != v && vLow[u] >= vDisc[v]))
1065 mCompVertex.push_back(std::make_pair(v, std::set<graph_vertex_type>()));
1066 while (vEdge.top().first != std::min(v, u) || vEdge.top().second != std::max(v, u))
1068 mCompVertex.back().second.insert(vEdge.top().first);
1069 mCompVertex.back().second.insert(vEdge.top().second);
1072 mCompVertex.back().second.insert(vEdge.top().first);
1073 mCompVertex.back().second.insert(vEdge.top().second);
1078 else if (u != vParent[v] && vDisc[u] < vLow[v])
1080 vLow[v] = std::min(vLow[v], vDisc[u]);
1081 vEdge.push(std::make_pair(std::min(v, u), std::max(v, u)));
1088 mCompVertex.push_back(std::make_pair(std::numeric_limits<graph_vertex_type>::max(), std::set<graph_vertex_type>()));
1089 mCompVertex.back().second.insert(v);
1093template <
typename GraphType>
1099 uint32_t vertex_num = boost::num_vertices(
m_graph);
1100 std::stack<graph_vertex_type> vStack;
1102 std::deque<bool> vVisited (vertex_num,
false);
1103 uint32_t comp_id = 0;
1104 std::vector<uint32_t> vComponent (vertex_num, std::numeric_limits<uint32_t>::max());
1107 vertex_iterator vi, vie;
1108 for (boost::tie(vi, vie) = boost::vertices(
m_graph); vi != vie; ++vi)
1110 graph_vertex_type source = *vi;
1111 if (this->
hidden(source))
continue;
1114 if (vVisited[source])
continue;
1115 vStack.push(source);
1116 vVisited[source] =
true;
1117 while (!vStack.empty())
1119 graph_vertex_type v = vStack.top();
1121#ifdef DEBUG_GRAPHSIMPLIFICATION
1122 std::cout << v <<
" ";
1125 vComponent[v] = comp_id;
1131 vVisited[v] =
false;
1135 adjacency_iterator ui, uie;
1136 for (boost::tie(ui, uie) = boost::adjacent_vertices(v,
m_graph); ui != uie; ++ui)
1138 graph_vertex_type u = *ui;
1139 if (this->
hidden(u))
continue;
1141#ifdef DEBUG_GRAPHSIMPLIFICATION
1142 std::pair<graph_edge_type, bool> e = boost::edge(u, v,
m_graph);
1155#ifdef DEBUG_GRAPHSIMPLIFICATION
1156 std::cout << std::endl;
1160 for (
typename std::map<graph_vertex_type, std::set<uint32_t> >::const_iterator vapi =
m_mArtiPoint.begin(); vapi !=
m_mArtiPoint.end(); ++vapi)
1162 graph_vertex_type v = vapi->first;
1165 adjacency_iterator ui, uie;
1166 for (boost::tie(ui, uie) = boost::adjacent_vertices(v,
m_graph); ui != uie; ++ui)
1168 graph_vertex_type u = *ui;
1169 if (this->
hidden(u))
continue;
1175#ifdef DEBUG_GRAPHSIMPLIFICATION
1176 std::cout <<
"detect " << v <<
", " << u <<
" ==> comp " << comp_id << std::endl;
1187 m_mCompVertex.assign(comp_id, std::vector<graph_vertex_type>());
1188 for (boost::tie(vi, vie) = boost::vertices(
m_graph); vi != vie; ++vi)
1190 graph_vertex_type v = *vi;
1196 for (
typename std::map<graph_vertex_type, std::set<uint32_t> >::const_iterator vapi =
m_mArtiPoint.begin(); vapi !=
m_mArtiPoint.end(); ++vapi)
1198 graph_vertex_type vap = vapi->first;
1199 std::set<uint32_t>
const& sComp = vapi->second;
1200 for (
typename std::set<uint32_t>::const_iterator itc = sComp.begin(); itc != sComp.end(); ++itc)
1207template <
typename GraphType>
1210 vertex_iterator vi, vie;
1211 for (boost::tie(vi, vie) = boost::vertices(
m_graph); vi != vie; ++vi)
1213 graph_vertex_type v = *vi;
1217 for (uint32_t j = 0; j !=
m_vChildren[v].size(); ++j)
1221 vColor[u] = vColor[v];
1228template <
typename GraphType>
1236 std::vector<std::map<graph_vertex_type, graph_vertex_type> > mApOrig2Simpl (mSimpl2Orig.size());
1237 for (uint32_t i = 0; i < mSimpl2Orig.size(); ++i)
1239 std::vector<graph_vertex_type>
const& vSimpl2Orig = mSimpl2Orig[i];
1240 std::map<graph_vertex_type, graph_vertex_type>& vApOrig2Simpl = mApOrig2Simpl[i];
1242 for (uint32_t j = 0; j < vSimpl2Orig.size(); ++j)
1245 vApOrig2Simpl[vSimpl2Orig[j]] = j;
1251 std::vector<std::set<graph_vertex_type> > vCompAp (
m_mCompVertex.size());
1253 for (
typename std::map<graph_vertex_type, std::set<uint32_t> >::const_iterator vapi =
m_mArtiPoint.begin(); vapi !=
m_mArtiPoint.end(); ++vapi)
1255 graph_vertex_type vap = vapi->first;
1256 std::set<uint32_t>
const& sComp = vapi->second;
1257 for (
typename std::set<uint32_t>::const_iterator itc = sComp.begin(); itc != sComp.end(); ++itc)
1259 uint32_t comp = *itc;
1260 vCompAp[comp].insert(vap);
1266 for (uint32_t comp_id = 0; comp_id < vCompAp.size(); ++comp_id)
1268 if (!vVisited[comp_id])
1270 std::stack<uint32_t> vStack;
1271 vStack.push(comp_id);
1272 vVisited[comp_id] =
true;
1273 while (!vStack.empty())
1275 uint32_t c = vStack.top();
1278 for (
typename std::set<graph_vertex_type>::const_iterator vapi = vCompAp[c].begin(); vapi != vCompAp[c].end(); ++vapi)
1280 graph_vertex_type vap = *vapi;
1281 std::set<uint32_t>
const& sComp =
m_mArtiPoint.at(vap);
1283 for (
typename std::set<uint32_t>::const_iterator itcc = sComp.begin(); itcc != sComp.end(); ++itcc)
1285 uint32_t cc = *itcc;
1289 vVisited[cc] =
true;
1290 int8_t color_c = mColor[c][mApOrig2Simpl[c][vap]];
1291 int8_t color_cc = mColor[cc][mApOrig2Simpl[cc][vap]];
1292 vRotation[cc] += vRotation[c] + color_c - color_cc;
1301 for (uint32_t comp_id = 0; comp_id < mColor.size(); ++comp_id)
1303 int32_t Non_color_count = 0;
1304 std::vector<int8_t>& vColor = mColor[comp_id];
1305 int32_t rotation = vRotation[comp_id];
1310 for (uint32_t v = 0; v < vColor.size(); ++v)
1314 vColor[v] = (vColor[v] + rotation) % (int32_t)
m_color_num;
1319 vColor[v] = (vColor[v] + rotation) % (int32_t)
m_color_num;
1325#ifdef DEBUG_GRAPHSIMPLIFICATION
1326 for (
typename std::map<graph_vertex_type, std::set<uint32_t> >::const_iterator vapi =
m_mArtiPoint.begin(); vapi !=
m_mArtiPoint.end(); ++vapi)
1328 graph_vertex_type vap = vapi->first;
1329 std::set<uint32_t>
const& sComp = vapi->second;
1331 int8_t prev_color = -1;
1332 for (
typename std::set<uint32_t>::const_iterator itc = sComp.begin(); itc != sComp.end(); ++itc)
1334 uint32_t comp = *itc;
1335 int8_t color = mColor[comp][mApOrig2Simpl[comp][vap]];
1336 if (itc == sComp.begin())
1339 "%u: comp %u, c[%u] = %u; prev_color = %u", vap, comp, mApOrig2Simpl[comp][vap], color, prev_color);
1345template <
typename GraphType>
1354 std::vector<char> vUnusedColor (
m_color_num,
true);
1355 std::vector<char> vStitchColor (
m_color_num,
false);
1356 typename boost::graph_traits<graph_type>::adjacency_iterator vi, vie;
1357 for (boost::tie(vi, vie) = boost::adjacent_vertices(v, this->
m_graph); vi != vie; ++vi)
1359 graph_vertex_type u = *vi;
1363 std::pair<graph_edge_type, bool> e12 = boost::edge(v, u, this->
m_graph);
1365 if (boost::get(boost::edge_weight, this->
m_graph, e12.first) < 0)
1367 vStitchColor[vColor[u]] =
true;
1371 vUnusedColor[vColor[u]] =
false;
1375 bool find_flag =
false;
1379 if (vUnusedColor[i] && vStitchColor[i])
1391 if (vUnusedColor[i])
1402template <
typename GraphType>
1405 std::ofstream out((filename+
".gv").c_str());
1406 out <<
"graph D { \n"
1408 <<
" size=\"4, 3\"\n"
1409 <<
" ratio=\"fill\"\n"
1410 <<
" edge[style=\"bold\",fontsize=200]\n"
1411 <<
" node[shape=\"circle\",fontsize=200]\n";
1414 vertex_iterator vi1, vie1;
1415 for (boost::tie(vi1, vie1) = boost::vertices(
m_graph); vi1 != vie1; ++vi1)
1417 graph_vertex_type v1 = *vi1;
1418 if (!this->
good(v1))
continue;
1420 out <<
" " << v1 <<
"[shape=\"circle\"";
1422 out <<
",label=\"" << v1 <<
":(";
1423 for (
typename std::vector<graph_vertex_type>::const_iterator it1 =
m_vChildren[v1].begin(); it1 !=
m_vChildren[v1].end(); ++it1)
1433 for (boost::tie(vi1, vie1) = boost::vertices(
m_graph); vi1 != vie1; ++vi1)
1435 graph_vertex_type v1 = *vi1;
1436 if (!this->
good(v1))
continue;
1438 vertex_iterator vi2, vie2;
1439 for (boost::tie(vi2, vie2) = boost::vertices(
m_graph); vi2 != vie2; ++vi2)
1441 graph_vertex_type v2 = *vi2;
1442 if (!this->
good(v2))
continue;
1443 if (v1 >= v2)
continue;
1445 std::pair<graph_edge_type, bool> e = this->
connected_edge(v1, v2);
1451 out <<
" " << v1 <<
"--" << v2 <<
"[color=\"black\",style=\"solid\",penwidth=3]\n";
1453 out <<
" " << v1 <<
"--" << v2 <<
"[color=\"black\",style=\"dashed\",penwidth=3]\n";
1455 out <<
" " << v1 <<
"--" << v2 <<
"[color=\"black\",style=\"dotted\",penwidth=1]\n";
1462 la::graphviz2pdf(filename);
1464template <
typename GraphType>
1467 std::ofstream out((filename+
".gv").c_str());
1468 out <<
"graph D { \n"
1470 <<
" size=\"4, 3\"\n"
1471 <<
" ratio=\"fill\"\n"
1472 <<
" edge[style=\"bold\",fontsize=200]\n"
1473 <<
" node[shape=\"circle\",fontsize=200]\n";
1475 uint32_t offset = 0;
1477 for (uint32_t comp_id = 0; comp_id !=
m_mCompVertex.size(); ++comp_id)
1480 std::vector<graph_vertex_type> vSimpl2Orig;
1485 vertex_iterator vi1, vie1;
1486 for (boost::tie(vi1, vie1) = boost::vertices(sg); vi1 != vie1; ++vi1)
1488 graph_vertex_type mv1 = *vi1;
1489 graph_vertex_type v1 = vSimpl2Orig[mv1];
1492 out <<
" " << offset+mv1 <<
"[shape=\"circle\"";
1494 out <<
",label=\"" << mv1 <<
":(";
1495 for (
typename std::vector<graph_vertex_type>::const_iterator it1 =
m_vChildren[v1].begin(); it1 !=
m_vChildren[v1].end(); ++it1)
1501 out <<
"):" << comp_id <<
"\"]\n";
1504 edge_iterator ei, eie;
1505 for (boost::tie(ei, eie) = boost::edges(sg); ei != eie; ++ei)
1507 graph_edge_type e = *ei;
1508 graph_vertex_type mv1 = boost::source(e, sg);
1509 graph_vertex_type mv2 = boost::target(e, sg);
1510 int32_t w = boost::get(boost::edge_weight, sg, e);
1515 sprintf(buf,
" %lu--%lu[label=%d,color=\"black\",style=\"solid\",penwidth=3]", offset+mv1, offset+mv2, w);
1517 sprintf(buf,
" %lu--%lu[label=%d,color=\"black\",style=\"dashed\",penwidth=3]", offset+mv1, offset+mv2, w);
1518 out << buf << std::endl;
1520 offset += boost::num_vertices(sg);
1527 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.
mathematical utilities such as abs
void mergeVDD(std::set< graph_vertex_type > vdd_set)
added by Qi Sun, used to merge VDD nodes
void recover_biconnected_component(std::vector< std::vector< int8_t > > &mColor, std::vector< std::vector< graph_vertex_type > > const &mSimpl2Orig) const
recover color for biconnected components
bool check_max_merge_level(uint32_t l) const
bool good(graph_vertex_type v1) const
bool articulation_point(graph_vertex_type v) const
bool has_precolored() const
void recover_hide_small_degree(std::vector< int8_t > &vColor)
bool whether_VDDGND(graph_vertex_type id)
return whether vertex with 'id' is VDDGND
graph_vertex_type parent(graph_vertex_type v) const
void get_CompVertex(std::vector< std::vector< graph_vertex_type > > &CompVertex)
added by Qi Sun, to get m_mCompVertex
uint32_t num_component() const
added by Qi Sun, also get the original edge relationships
bool hidden(graph_vertex_type v1) const
std::vector< vertex_status_type > m_vStatus
status of each vertex
void write_graph_dot(std::string const &filename) const
strategy_type
simplification strategies available. These strategies are order-sensitive. It is recommended to cal...
@ MERGE_SUBK4
merge 4-clique structures, no longer optimal
@ BICONNECTED_COMPONENT
divide graph by biconnected components
@ HIDE_SMALL_DEGREE
hide vertices whose degree is smaller than number of colors available
std::map< graph_vertex_type, std::set< uint32_t > > m_mArtiPoint
map of (vertex of articulation point, set of components split by the vertex)
std::stack< graph_vertex_type > const & hidden_vertices() const
GraphSimplification(graph_type const &g, uint32_t color_num)
std::vector< vertex_status_type > const & status() const
void connected_component()
compute connected components
void recover(std::vector< int8_t > &vColorFlat, std::vector< std::vector< int8_t > > &mColor, std::vector< std::vector< graph_vertex_type > > const &mSimpl2Orig) const
void biconnected_component_recursion(graph_vertex_type v, std::deque< bool > &vVisited, std::vector< uint32_t > &vDisc, std::vector< uint32_t > &vLow, std::vector< graph_vertex_type > &vParent, uint32_t &visit_time, std::stack< std::pair< graph_vertex_type, graph_vertex_type > > &vEdge, std::list< std::pair< graph_vertex_type, std::set< graph_vertex_type > > > &mCompVertex) const
std::vector< std::vector< graph_vertex_type > > m_vChildren
children verices of current vertex, a vertex is the child of itself if it is not merged
void write_simplified_graph_dot(std::string const &filename) const
bool connected_conflict(graph_vertex_type v1, graph_vertex_type v2) const
bool precolored(graph_vertex_type v1) const
void precolor(Iterator first, Iterator last)
uint32_t m_level
simplification level
std::vector< std::vector< graph_vertex_type > > const & children() const
graph_vertex_type parent(uint32_t v, std::vector< uint32_t > const &vParent) const
bool connected_stitch(graph_vertex_type v1, graph_vertex_type v2) const
std::pair< graph_edge_type, bool > connected_edge(graph_vertex_type v1, graph_vertex_type v2) const
void hide_small_degree()
hide vertices whose degree is no larger than number of colors - 1
vertex_status_type
status of vertex.
@ HIDDEN
vertex is hidden by simplification
@ MERGED
vertex is merged to other vertex
std::vector< graph_vertex_type > const & parents() const
bool merged(graph_vertex_type v1) const
bool simplified_graph_component(uint32_t comp_id, graph_type &sg, std::vector< graph_vertex_type > &vSimpl2Orig) const
std::vector< int8_t > m_vPrecolor
precolor information, if uncolored, std::set to -1
void biconnected_component()
find all articulation points and biconnected components
std::vector< bool > m_isVDDGND
used in graph simplification, whether it's VDDGND, added by Qi Sun
void max_merge_level(int32_t l)
void set_isVDDGND(std::set< graph_vertex_type > vdd_set)
construct m_isVDDGND
std::vector< graph_vertex_type > m_vParent
parent vertex of current vertex
graph_type const & m_graph
original graph
void recover_merge_subK4(std::vector< int8_t > &vColor) const
GraphSimplification(GraphSimplification const &rhs)
uint32_t m_color_num
number of colors
uint32_t m_max_merge_level
in MERGE_SUBK4, any merge that results in the children number of a vertex larger than m_max_merge_lev...
std::pair< graph_type, std::map< graph_vertex_type, graph_vertex_type > > simplified_graph() const
void simplify(uint32_t level)
std::vector< std::vector< graph_vertex_type > > m_mCompVertex
group vertices by components
std::stack< graph_vertex_type > m_vHiddenVertex
a std::stack that keeps a reverse order of vertices hidden, useful for color recovery
namespace for Limbo.Algorithms.Coloring
namespace for Limbo.algorithms
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
T abs(T const &t)
generalized api can handle both integer and floating points