【问题标题】:Boost Read_graphml doesn't read xml properly it gives all the vertices but they are emptyBoost Read_graphml 不能正确读取 xml 它给出了所有顶点但它们是空的
【发布时间】:2018-03-01 10:42:45
【问题描述】:

我有一个类型的邻接列表

boost::adjacency_list<boost::setS, boost::vecS, boost::directedS, GraphData>

其中 GraphData 是一个包含名称的结构

struct GraphItem
{
    std::string Name;
}

我可以将图形写入 xml

void WriteGraph() {
     boost::dynamic_properties dp;

     dp.property("Name", make_transform_value_property_map(&Name, 
     boost::get(vertex_bundle, graph)));

     boost::write_graphml(filename, graph, dp, true); 
}

std::string Name(boost::vertex_bundle_type<Graph>::type v) {
    std::ostringstream oss;
    oss << v.Name;
    return oss.str();
}

我得到 XML

<graphml>
  <key id="key0" for="node" attr.name="Name" attr.type="string" />
  <graph id="G" edgedefault="directed" parse.nodeids="canonical" 
   parse.edgeids="canonical" parse.order="nodesfirst">
    <node id="n0">
      <data key="key0">A</data>
    </node>
    <node id="n1">
      <data key="key0">D</data>
    </node>
    <node id="n2">
      <data key="key0">B</data>
    </node>
    <node id="n3">
      <data key="key0">C</data>
    </node>
    <edge id="e0" source="n0" target="n1">
    </edge>
    <edge id="e1" source="n2" target="n3">
    </edge>
  </graph>
</graphml>

当我阅读图表时

void ReadGraph() {
    boost::dynamic_properties dp;
    std::ifstream file(fileName);
    boost::read_graphml(file, graph, dp);
}

这是崩溃说找不到属性名称。 如果我使用 ignore_other_properties 作为属性,

boost::dynamic_properties dp(ignore_other_properties);

它可以工作,但我在图形顶点中没有得到任何图形项。

【问题讨论】:

    标签: c++ boost boost-graph graphml


    【解决方案1】:

    图形不为空,你得到:

    0 --> 1 
    1 --> 
    2 --> 3 
    3 --> 
    

    或者在 XML 中:https://paste.ubuntu.com/p/c4tGmxGssJ/

    当然,您想读取 name 属性。为此,您显然需要使用动态属性映射注册属性。

    注意您可以更简单地访问属性包的成员:

        dp.property("Name", boost::get(&GraphData::Name, graph));
    

    完整演示

    #include <boost/graph/adjacency_list.hpp>
    #include <boost/graph/graphml.hpp>
    
    struct GraphData {
        std::string Name;
    };
    
    using Graph = boost::adjacency_list<boost::setS, boost::vecS, boost::directedS, GraphData>;
    
    Graph ReadGraph(std::string const& fileName) {
        Graph graph;
        boost::dynamic_properties dp;
        dp.property("Name", boost::get(&GraphData::Name, graph));
    
        std::ifstream file(fileName);
        boost::read_graphml(file, graph, dp);
    
        return graph;
    }
    
    void WriteGraph(std::ostream& os, Graph& graph) {
        boost::dynamic_properties dp;
        dp.property("Name", get(&GraphData::Name, graph));
    
        boost::write_graphml(os, graph, dp, true); 
    }
    
    #include <boost/graph/graph_utility.hpp>
    
    int main() {
        Graph g = ReadGraph("input.txt");
        print_graph(g, get(&GraphData::Name, g));
    
        // or as XML
        WriteGraph(std::cout << "==== XML version: ====\n\n", g);
    }
    

    打印

    A --> D 
    D --> 
    B --> C 
    C --> 
    ==== XML version: ====
    
    <?xml version="1.0" encoding="UTF-8"?>
    <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
      <key id="key0" for="node" attr.name="Name" attr.type="string" />
      <graph id="G" edgedefault="directed" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst">
        <node id="n0">
          <data key="key0">A</data>
        </node>
        <node id="n1">
          <data key="key0">D</data>
        </node>
        <node id="n2">
          <data key="key0">B</data>
        </node>
        <node id="n3">
          <data key="key0">C</data>
        </node>
        <edge id="e0" source="n0" target="n1">
        </edge>
        <edge id="e1" source="n2" target="n3">
        </edge>
      </graph>
    </graphml>
    

    【讨论】:

    • 如果我在结构内部有用户定义的属性,在写图时我应该怎么做,以便它应该考虑对象类型而不是原始类型同样用于读取图。
    • 你能改写一下吗?也许您应该发布一个新问题,以便展示示例
    • struct GraphData { std::string Name;学生学生; } 班级学生 { int roll_no; std::string 除法; };我应该如何编写和读取这些属性?
    • 是的,我会提出一个新问题。
    • 如果您发布该问题,我已经编写了包含三种方法的草稿答案。 timelapse 编码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多