【问题标题】:Computing a dominator graph using Boost's Lengauer Tarjan algorithm and display it using graphviz使用 Boost 的 Lengauer Tarjan 算法计算支配图并使用 graphviz 显示它
【发布时间】:2016-03-22 16:50:30
【问题描述】:

如果我违反了规则,首先让我道歉,因为我知道我的问题已经在这里以修改后的方式提出:Lengauer Tarjan Algorithm in BGL (boost graph library)。但是,我(仍然)无法使用答案来正确显示结果。

更准确地说:我遵循了链接的答案,并成功地将 Lengauer-Tarjan 算法应用于我的图表(为方便起见,这是 Boost 文档的一部分:http://www.boost.org/doc/libs/1_55_0/libs/graph/test/dominator_tree_test.cpp)。现在,如果正确理解代码,则支配树的相关信息将存储在 PredMap 类型的 domTreePredMap 中:

const int numOfVertices = testSet[i].numOfVertices;
//See example for test_sets - it just the same routine
G g(
  testSet[i].edges.begin(), testSet[i].edges.end(),
  numOfVertices);

typedef graph_traits<G>::vertex_descriptor Vertex;
typedef property_map<G, vertex_index_t>::type IndexMap;
typedef
  iterator_property_map<vector<Vertex>::iterator, IndexMap>
  PredMap;

vector<Vertex> domTreePredVector, domTreePredVector2;
IndexMap indexMap(get(vertex_index, g));
graph_traits<G>::vertex_iterator uItr, uEnd;
int j = 0;
for (tie(uItr, uEnd) = vertices(g); uItr != uEnd; ++uItr, ++j)
{
  put(indexMap, *uItr, j);
}

// Lengauer-Tarjan dominator tree algorithm
domTreePredVector =
  vector<Vertex>(num_vertices(g), graph_traits<G>::null_vertex());
PredMap domTreePredMap =
  make_iterator_property_map(domTreePredVector.begin(), indexMap);

lengauer_tarjan_dominator_tree(g, vertex(0, g), domTreePredMap);`

对我来说,Boost 的主要优势之一是可以使用带有 write_graphviz(cout, g) 的 graphviz 自动生成图形输出,其中 g 是来自 typedef G 的图形:

typedef adjacency_list<
    listS,
    listS,
    bidirectionalS,
    property<vertex_index_t, std::size_t>, no_property> G;

但是,我无法将 DomTreePredMap 翻译成 write_graphviz(cout, X) 可以理解的内容。我感谢任何帮助概述如何从 domTreePredMap 构建图形的帮助,它可以使用 graphviz 打印。

感谢大家阅读所有内容并帮助我。

【问题讨论】:

  • 我建议使用动态属性。看看我的answers using write_graphviz_dp 以获得灵感。
  • 谢谢@sehe。我看你是boost的专家。但是,查看您的链接我不太清楚,如何实际访问存储在 domTreePredMap 中的信息以便将其映射到图形对象中。
  • 听到这个消息我很难过。也许你可以告诉我们你被困在哪里。 MCVE 帮助我们引导我们的能量:)
  • 感谢您的同情@sehe,我已将 MCVE 作为对原始问题的回答。我希望这对stackoverflow语法没问题。谢谢大家的帮助。
  • 我已经能够从 boost 库中检索到所需的信息。再次感谢@sehe。

标签: c++ boost graph-algorithm graphviz boost-graph


【解决方案1】:

很抱歉打扰您 - 我自己在 boost 纪录片中找到了答案:

这是一个最小的工作示例来说明我的问题。基本上我想计算图(左侧)及其支配树(右侧),如下所示:http://www.boost.org/doc/libs/1_40_0/libs/graph/doc/lengauer_tarjan_dominator.htm#fig:dominator-tree-example 并使用 graphviz 打印这两个图。

按照示例,我设法计算和打印原始图并在其上执行 Lengauer-Tarjan 算法。支配树的信息存储在 DomPredMap 中,可以复制到整数向量中。在向量 idom 的位置 i 处,存储节点 i 的父节点的 id。如果不存在父节点,则存储 max_int。此信息可用于将 idom[i] 到 i 的边添加到 testSet 中,最终可以从中构造图 g2。感谢您的所有帮助和耐心。

 #include <iostream>
 #include <boost/graph/graphviz.hpp>
 #include <boost/graph/adjacency_list.hpp>
 #include <boost/graph/dominator_tree.hpp>
 #include <algorithm>
 #include <fstream>
 #include <cstdlib>
 #include <string>
 #include <sstream>
 #include <vector> 
 using namespace std;


 struct DominatorCorrectnessTestSet
    {
      typedef pair<int, int> edge;

      int numOfVertices;
      vector<edge> edges;
      vector<int> correctIdoms;
    };

    using namespace boost;

    typedef adjacency_list<
        listS,
        listS,
        bidirectionalS,
        property<vertex_index_t, std::size_t>, no_property> G;

    int main(int, char*[])
    {



     typedef DominatorCorrectnessTestSet::edge edge;

      DominatorCorrectnessTestSet testSet[1];



      testSet[0].numOfVertices = 8, //Orignal problem see left hand side
      testSet[0].edges.push_back(edge(0, 1));
      testSet[0].edges.push_back(edge(1, 2));
      testSet[0].edges.push_back(edge(1, 3));
      testSet[0].edges.push_back(edge(2, 7));
      testSet[0].edges.push_back(edge(3, 4));
      testSet[0].edges.push_back(edge(4, 5));
      testSet[0].edges.push_back(edge(4, 6));
      testSet[0].edges.push_back(edge(5, 7));
      testSet[0].edges.push_back(edge(6, 4));

      testSet[1].numOfVertices = 8; //Used to create Dominator Tree

    const int numOfVertices = testSet[0].numOfVertices;

    G g(
      testSet[0].edges.begin(), testSet[0].edges.end(),
      numOfVertices);

    typedef graph_traits<G>::vertex_descriptor Vertex;
    typedef property_map<G, vertex_index_t>::type IndexMap;
    typedef
      iterator_property_map<vector<Vertex>::iterator, IndexMap>
      PredMap;

    vector<Vertex> domTreePredVector, domTreePredVector2;
    IndexMap indexMap(get(vertex_index, g));
    graph_traits<G>::vertex_iterator uItr, uEnd;
    int j = 0;
    for (tie(uItr, uEnd) = vertices(g); uItr != uEnd; ++uItr, ++j)
    {
      put(indexMap, *uItr, j);
    }
    write_graphviz(cout, g);
    // Lengauer-Tarjan dominator tree algorithm
    domTreePredVector =
      vector<Vertex>(num_vertices(g), graph_traits<G>::null_vertex());
    PredMap domTreePredMap =
      make_iterator_property_map(domTreePredVector.begin(), indexMap);

    lengauer_tarjan_dominator_tree(g, vertex(0, g), domTreePredMap);
vector<int> idom(num_vertices(g));
         for (tie(uItr, uEnd) = vertices(g); uItr != uEnd; ++uItr)
         {
           if (get(domTreePredMap, *uItr) != graph_traits<G>::null_vertex())
             idom[get(indexMap, *uItr)] =
               get(indexMap, get(domTreePredMap, *uItr));
           else
             idom[get(indexMap, *uItr)] = (numeric_limits<int>::max)();
         }

        for (int k =0; k <idom.size();k++){

             if (k>0){
             cout << idom[k] << " nach " << k << endl;
             int t= idom[k];
             testSet[1].edges.push_back(edge(t, k));
             }
         }

       G g2(testSet[1].edges.begin(), testSet[1].edges.end(),8);
       int jj=0;
       for (tie(uItr, uEnd) = vertices(g2); uItr != uEnd; ++uItr, ++jj)
           {
             put(indexMap, *uItr, jj);
           }

         write_graphviz(cout, g2);
         cout << endl;


return 0;

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2014-06-17
    • 2021-10-26
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多