C++ Boost

Graph Input/Output

BGL provides functions to read and write graphs in various standard formats. This allows you to exchange graph data with other tools, load test cases, or persist graphs to disk.

Supported File Formats

Format Description Read Function Write Function
GraphML XML-based graph format with properties read_graphml write_graphml
GraphViz DOT Text-based visualization format read_graphviz write_graphviz
DIMACS Max-flow/min-cut problem format read_dimacs_max_flow write_dimacs_max_flow

Reading GraphML Files

GraphML is an XML-based format that supports both graph structure and properties. It's the recommended format for general graph data exchange.

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphml.hpp>
#include <fstream>

using namespace boost;

typedef adjacency_list<vecS, vecS, directedS,
    property<vertex_name_t, std::string>,
    property<edge_weight_t, double> > Graph;

int main()
{
    Graph g;
    dynamic_properties dp;
    
    // Tell dynamic_properties about the properties we want to read
    dp.property("name", get(vertex_name, g));
    dp.property("weight", get(edge_weight, g));
    
    // Read the graph
    std::ifstream infile("graph.graphml");
    read_graphml(infile, g, dp);
    
    std::cout << "Loaded " << num_vertices(g) << " vertices and "
              << num_edges(g) << " edges\n";
    
    return 0;
}

Key points:

Writing GraphML Files

#include <boost/graph/graphml.hpp>
#include <fstream>

int main()
{
    Graph g;
    // ... build graph ...
    
    dynamic_properties dp;
    dp.property("name", get(vertex_name, g));
    dp.property("weight", get(edge_weight, g));
    
    // Write the graph
    std::ofstream outfile("output.graphml");
    write_graphml(outfile, g, dp);
    
    return 0;
}

Reading GraphViz DOT Files

The DOT format is widely used for graph visualization with Graphviz tools.

#include <boost/graph/graphviz.hpp>
#include <fstream>

int main()
{
    Graph g;
    dynamic_properties dp;
    dp.property("node_id", get(vertex_name, g));
    dp.property("weight", get(edge_weight, g));
    
    std::ifstream infile("graph.dot");
    read_graphviz(infile, g, dp);
    
    return 0;
}

Writing GraphViz DOT Files

You can write graphs in DOT format for visualization:

#include <boost/graph/graphviz.hpp>
#include <fstream>

int main()
{
    Graph g;
    // ... build graph ...
    
    // Simple version: just structure, no properties
    std::ofstream outfile("graph.dot");
    write_graphviz(outfile, g);
    
    return 0;
}

For custom vertex/edge labels in the output:

// Write with vertex labels
write_graphviz(outfile, g,
    make_label_writer(get(vertex_name, g)));

// Write with vertex and edge labels
write_graphviz(outfile, g,
    make_label_writer(get(vertex_name, g)),
    make_label_writer(get(edge_weight, g)));

DIMACS Max-Flow Format

DIMACS format is used for max-flow and min-cut problems. It's a specialized format used in algorithm competitions and benchmarks.

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/read_dimacs.hpp>

typedef adjacency_list<vecS, vecS, directedS,
    no_property,
    property<edge_capacity_t, int> > FlowGraph;

int main()
{
    FlowGraph g;
    
    typedef graph_traits<FlowGraph>::vertex_descriptor Vertex;
    Vertex source, sink;
    
    property_map<FlowGraph, edge_capacity_t>::type capacity 
        = get(edge_capacity, g);
    
    // Read DIMACS max-flow file from stdin
    read_dimacs_max_flow(g, capacity, source, sink);
    
    std::cout << "Source: " << source << ", Sink: " << sink << "\n";
    std::cout << "Edges: " << num_edges(g) << "\n";
    
    return 0;
}

Using dynamic_properties for Flexible I/O

The dynamic_properties class allows you to read/write properties without knowing their types at compile time:

#include <boost/graph/graphml.hpp>
#include <boost/property_map/dynamic_property_map.hpp>

int main()
{
    typedef adjacency_list<vecS, vecS, directedS> Graph;
    Graph g;
    
    // Create maps for storing properties externally
    std::map<graph_traits<Graph>::vertex_descriptor, std::string> vertex_names;
    std::map<graph_traits<Graph>::edge_descriptor, double> edge_weights;
    
    // Wrap maps in associative property maps
    auto name_map = make_assoc_property_map(vertex_names);
    auto weight_map = make_assoc_property_map(edge_weights);
    
    // Create dynamic_properties object
    dynamic_properties dp;
    dp.property("name", name_map);
    dp.property("weight", weight_map);
    
    // Read graph
    std::ifstream infile("graph.graphml");
    read_graphml(infile, g, dp);
    
    // Access properties
    auto vp = vertices(g);
    for (auto vi = vp.first; vi != vp.second; ++vi) {
        std::cout << "Vertex " << *vi 
                  << " name: " << vertex_names[*vi] << "\n";
    }
    
    return 0;
}

Example GraphML File

Here's what a simple GraphML file looks like:

<?xml version="1.0" encoding="UTF-8"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns">
  <key id="name" for="node" attr.name="name" attr.type="string"/>
  <key id="weight" for="edge" attr.name="weight" attr.type="double"/>
  
  <graph id="G" edgedefault="directed">
    <node id="n0">
      <data key="name">Alice</data>
    </node>
    <node id="n1">
      <data key="name">Bob</data>
    </node>
    
    <edge source="n0" target="n1">
      <data key="weight">3.14</data>
    </edge>
  </graph>
</graphml>

Example DOT File

digraph G {
  0 [label="Alice"];
  1 [label="Bob"];
  2 [label="Charlie"];
  
  0 -> 1 [label="3.14"];
  0 -> 2 [label="2.71"];
  1 -> 2 [label="1.41"];
}

Error Handling

I/O functions can throw exceptions on error:

#include <boost/graph/graphml.hpp>

try {
    std::ifstream infile("graph.graphml");
    if (!infile) {
        throw std::runtime_error("Could not open file");
    }
    
    read_graphml(infile, g, dp);
    
} catch (const boost::parse_error& e) {
    std::cerr << "Parse error: " << e.what() << "\n";
} catch (const boost::directed_graph_error& e) {
    std::cerr << "Graph type mismatch: " << e.what() << "\n";
} catch (const boost::graph_exception& e) {
    std::cerr << "Graph error: " << e.what() << "\n";
} catch (const std::exception& e) {
    std::cerr << "Error: " << e.what() << "\n";
}

Format Comparison

Feature GraphML DOT DIMACS
Human-readable Semi (XML) Yes Yes
Properties support Full Full Limited
Directed graphs Yes Yes Yes
Undirected graphs Yes Yes Limited
Tool support Good Excellent (Graphviz) Benchmarks
Best for Data exchange Visualization Flow problems

Recommendations


For more details, see:

Copyright © 2000-2001 Jeremy Siek, Indiana University