diff -r d8475431bbbb -r 8e85e6bbefdf lemon/graph_writer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lemon/graph_writer.h Mon May 23 04:48:14 2005 +0000 @@ -0,0 +1,683 @@ +/* -*- C++ -*- + * lemon/graph_writer.h - Part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\ingroup io_group +///\file +///\brief Lemon Graph Format writer. + +#ifndef LEMON_GRAPH_WRITER_H +#define LEMON_GRAPH_WRITER_H + +#include + +#include +#include + +namespace lemon { + + /// \addtogroup io_group + /// @{ + + /// \brief The graph writer class. + /// + /// The \c GraphWriter class provides the graph output. To write a graph + /// you should first give writing commands for the writer. You can declare + /// write command as \c NodeMap or \c EdgeMap writing and labeled Node and + /// Edge writing. + /// + /// \code + /// GraphWriter writer(std::cout, graph); + /// \endcode + /// + /// The \c writeNodeMap() function declares a \c NodeMap writing + /// command in the \c GraphWriter. You should give as parameter + /// the name of the map and the map object. The NodeMap writing + /// command with name "id" should write a unique map because it + /// is regarded as ID map. + /// + /// \code + /// IdMap nodeIdMap; + /// writer.writeNodeMap("id", nodeIdMap); + /// + /// writer.writeNodeMap("coords", coords); + /// writer.writeNodeMap("color", colorMap); + /// \endcode + /// + /// With the \c writeEdgeMap() member function you can give an edge map + /// writing command similar to the NodeMaps. + /// + /// \code + /// DescriptorMap > + /// edgeDescMap(graph); + /// writer.writeEdgeMap("descriptor", edgeDescMap); + /// + /// writer.writeEdgeMap("weight", weightMap); + /// writer.writeEdgeMap("label", labelMap); + /// \endcode + /// + /// With \c writeNode() and \c writeEdge() functions you can + /// point out Nodes and Edges in the graph. By example, you can + /// write out the source and target of the graph. + /// + /// \code + /// writer.writeNode("source", sourceNode); + /// writer.writeNode("target", targetNode); + /// + /// writer.writeEdge("observed", edge); + /// \endcode + /// + /// After you give all write commands you must call the \c run() member + /// function, which execute all the writer commands. + /// + /// \code + /// writer.run(); + /// \endcode + /// + /// \see DefaultWriterTraits + /// \see QuotedStringWriter + /// \see IdMap + /// \see DescriptorMap + /// \see \ref GraphReader + /// \see \ref graph-io-page + /// \author Balazs Dezso + template + class GraphWriter { + public: + + typedef _Graph Graph; + typedef typename Graph::Node Node; + typedef typename Graph::Edge Edge; + + typedef _WriterTraits WriterTraits; + + /// \brief Construct a new GraphWriter. + /// + /// Construct a new GraphWriter. It writes the given graph + /// to the given stream. + GraphWriter(std::ostream& _os, const Graph& _graph) + : writer(new LemonWriter(_os)), own_writer(true), + nodeset_writer(*writer, _graph, std::string()), + edgeset_writer(*writer, _graph, nodeset_writer, std::string()), + node_writer(*writer, nodeset_writer, std::string()), + edge_writer(*writer, edgeset_writer, std::string()), + attribute_writer(*writer, std::string()) {} + + /// \brief Construct a new GraphWriter. + /// + /// Construct a new GraphWriter. It writes into the given graph + /// to the given file. + GraphWriter(const std::string& _filename, const Graph& _graph) + : writer(new LemonWriter(_filename)), own_writer(true), + nodeset_writer(*writer, _graph, std::string()), + edgeset_writer(*writer, _graph, nodeset_writer, std::string()), + node_writer(*writer, nodeset_writer, std::string()), + edge_writer(*writer, edgeset_writer, std::string()), + attribute_writer(*writer, std::string()) {} + + /// \brief Construct a new GraphWriter. + /// + /// Construct a new GraphWriter. It writes into the given graph + /// to given LemonReader. + GraphWriter(LemonWriter& _writer, const Graph& _graph) + : writer(_writer), own_writer(false), + nodeset_writer(*writer, _graph, std::string()), + edgeset_writer(*writer, _graph, nodeset_writer, std::string()), + node_writer(*writer, nodeset_writer, std::string()), + edge_writer(*writer, edgeset_writer, std::string()), + attribute_writer(*writer, std::string()) {} + + /// \brief Destruct the graph writer. + /// + /// Destruct the graph writer. + ~GraphWriter() { + if (own_writer) + delete writer; + } + + /// \brief Add a new node map writer command for the writer. + /// + /// Add a new node map writer command for the writer. + template + GraphWriter& writeNodeMap(std::string name, const Map& map) { + nodeset_writer.writeNodeMap(name, map); + return *this; + } + + /// \brief Add a new node map writer command for the writer. + /// + /// Add a new node map writer command for the writer. + template + GraphWriter& writeNodeMap(std::string name, const Map& map, + const Writer& writer = Writer()) { + nodeset_writer.writeNodeMap(name, map, writer); + return *this; + } + + + /// \brief Add a new edge map writer command for the writer. + /// + /// Add a new edge map writer command for the writer. + template + GraphWriter& writeEdgeMap(std::string name, const Map& map) { + edgeset_writer.writeEdgeMap(name, map); + return *this; + } + + + /// \brief Add a new edge map writer command for the writer. + /// + /// Add a new edge map writer command for the writer. + template + GraphWriter& writeEdgeMap(std::string name, const Map& map, + const Writer& writer = Writer()) { + edgeset_writer.writeEdgeMap(name, map, writer); + return *this; + } + + /// \brief Add a new labeled node writer for the writer. + /// + /// Add a new labeled node writer for the writer. + GraphWriter& writeNode(std::string name, const Node& node) { + node_writer.writeNode(name, node); + return *this; + } + + /// \brief Add a new labeled edge writer for the writer. + /// + /// Add a new labeled edge writer for the writer. + GraphWriter& writeEdge(std::string name, const Edge& edge) { + edge_writer.writeEdge(name, edge); + } + + /// \brief Add a new attribute writer command. + /// + /// Add a new attribute writer command. + template + GraphWriter& writeAttribute(std::string name, const Value& value) { + attribute_writer.writeAttribute(name, value); + return *this; + } + + /// \brief Add a new attribute writer command. + /// + /// Add a new attribute writer command. + template + GraphWriter& writeAttribute(std::string name, const Value& value, + const Writer& writer) { + attribute_writer.writeAttribute(name, value, writer); + return *this; + } + + /// \brief Conversion operator to LemonWriter. + /// + /// Conversion operator to LemonWriter. It make possible + /// to access the encapsulated \e LemonWriter, this way + /// you can attach to this writer new instances of + /// \e LemonWriter::SectionWriter. + operator LemonWriter&() { + return *writer; + } + + /// \brief Executes the writer commands. + /// + /// Executes the writer commands. + void run() { + writer->run(); + } + + /// \brief Write the id of the given node. + /// + /// It writes the id of the given node. If there was written an "id" + /// named node map then it will write the map value belongs to the node. + void writeId(std::ostream& os, const Node& item) const { + nodeset_writer.writeId(os, item); + } + + /// \brief Write the id of the given edge. + /// + /// It writes the id of the given edge. If there was written an "id" + /// named edge map then it will write the map value belongs to the edge. + void writeId(std::ostream& os, const Edge& item) const { + edgeset_writer.writeId(os, item); + } + + private: + + LemonWriter* writer; + bool own_writer; + + NodeSetWriter nodeset_writer; + EdgeSetWriter edgeset_writer; + + NodeWriter node_writer; + EdgeWriter edge_writer; + + AttributeWriter attribute_writer; + }; + + + /// \brief Write a graph to the output. + /// + /// Write a graph to the output. + /// \param os The output stream. + /// \param g The graph. + /// \param capacity The capacity map. + /// \param s The source node. + /// \param t The target node. + /// \param cost The cost map. + template + void writeGraph(std::ostream& os, const Graph &g, + const CapacityMap& capacity, const typename Graph::Node &s, + const typename Graph::Node &t, const CostMap& cost) { + GraphWriter writer(os, g); + IdMap nodeIdMap(g); + writer.writeNodeMap("id", nodeIdMap); + IdMap edgeIdMap(g); + writer.writeEdgeMap("id", edgeIdMap); + writer.writeEdgeMap("capacity", capacity); + writer.writeEdgeMap("cost", cost); + writer.writeNode("source", s); + writer.writeNode("target", t); + writer.run(); + } + + /// \brief Write a graph to the output. + /// + /// Write a graph to the output. + /// \param os The output stream. + /// \param g The graph. + /// \param capacity The capacity map. + /// \param s The source node. + /// \param t The target node. + template + void writeGraph(std::ostream& os, const Graph &g, + const CapacityMap& capacity, const typename Graph::Node &s, + const typename Graph::Node &t) { + GraphWriter writer(os, g); + IdMap nodeIdMap(g); + writer.writeNodeMap("id", nodeIdMap); + IdMap edgeIdMap(g); + writer.writeEdgeMap("id", edgeIdMap); + writer.writeEdgeMap("capacity", capacity); + writer.writeNode("source", s); + writer.writeNode("target", t); + writer.run(); + } + + /// \brief Write a graph to the output. + /// + /// Write a graph to the output. + /// \param os The output stream. + /// \param g The graph. + /// \param capacity The capacity map. + /// \param s The source node. + template + void writeGraph(std::ostream& os, const Graph &g, + const CapacityMap& capacity, const typename Graph::Node &s) { + GraphWriter writer(os, g); + IdMap nodeIdMap(g); + writer.writeNodeMap("id", nodeIdMap); + IdMap edgeIdMap(g); + writer.writeEdgeMap("id", edgeIdMap); + writer.writeEdgeMap("capacity", capacity); + writer.writeNode("source", s); + writer.run(); + } + + /// \brief Write a graph to the output. + /// + /// Write a graph to the output. + /// \param os The output stream. + /// \param g The graph. + /// \param capacity The capacity map. + template + void writeGraph(std::ostream& os, const Graph &g, + const CapacityMap& capacity) { + GraphWriter writer(os, g); + IdMap nodeIdMap(g); + writer.writeNodeMap("id", nodeIdMap); + IdMap edgeIdMap(g); + writer.writeEdgeMap("id", edgeIdMap); + writer.writeEdgeMap("capacity", capacity); + writer.run(); + } + + /// \brief Write a graph to the output. + /// + /// Write a graph to the output. + /// \param os The output stream. + /// \param g The graph. + template + void writeGraph(std::ostream& os, const Graph &g) { + GraphWriter writer(os, g); + IdMap nodeIdMap(g); + writer.writeNodeMap("id", nodeIdMap); + IdMap edgeIdMap(g); + writer.writeEdgeMap("id", edgeIdMap); + writer.run(); + } + + /// \brief The undirected graph writer class. + /// + /// The \c UndirGraphWriter class provides the undir graph output. To write + /// a graph you should first give writing commands for the writer. You can + /// declare write command as \c NodeMap, \c EdgeMap or \c UndirEdgeMap + /// writing and labeled Node, Edge or UndirEdge writing. + /// + /// \code + /// UndirGraphWriter writer(std::cout, graph); + /// \endcode + /// + /// The \c writeNodeMap() function declares a \c NodeMap writing + /// command in the \c UndirGraphWriter. You should give as parameter + /// the name of the map and the map object. The NodeMap writing + /// command with name "id" should write a unique map because it + /// is regarded as ID map. + /// + /// \code + /// IdMap nodeIdMap; + /// writer.writeNodeMap("id", nodeIdMap); + /// + /// writer.writeNodeMap("coords", coords); + /// writer.writeNodeMap("color", colorMap); + /// \endcode + /// + /// With the \c writeUndirEdgeMap() member function you can give an + /// undirected edge map writing command similar to the NodeMaps. + /// + /// \code + /// DescriptorMap > + /// edgeDescMap(graph); + /// writer.writeUndirEdgeMap("descriptor", edgeDescMap); + /// + /// writer.writeUndirEdgeMap("weight", weightMap); + /// writer.writeUndirEdgeMap("label", labelMap); + /// \endcode + /// + /// The EdgeMap handling is just a syntactical sugar. It writes + /// two undirected edge map with '+' and '-' prefix in the name. + /// + /// \code + /// writer.writeEdgeMap("capacity", capacityMap); + /// \endcode + /// + /// + /// With \c writeNode() and \c writeUndirEdge() functions you can + /// point out nodes and undirected edges in the graph. By example, you can + /// write out the source and target of the graph. + /// + /// \code + /// writer.writeNode("source", sourceNode); + /// writer.writeNode("target", targetNode); + /// + /// writer.writeUndirEdge("observed", undirEdge); + /// \endcode + /// + /// After you give all write commands you must call the \c run() member + /// function, which execute all the writer commands. + /// + /// \code + /// writer.run(); + /// \endcode + /// + /// \see DefaultWriterTraits + /// \see QuotedStringWriter + /// \see IdMap + /// \see DescriptorMap + /// \see \ref GraphWriter + /// \see \ref graph-io-page + /// \author Balazs Dezso + template + class UndirGraphWriter { + public: + + typedef _Graph Graph; + typedef typename Graph::Node Node; + typedef typename Graph::Edge Edge; + typedef typename Graph::UndirEdge UndirEdge; + + typedef _WriterTraits WriterTraits; + + /// \brief Construct a new UndirGraphWriter. + /// + /// Construct a new UndirGraphWriter. It writes the given graph + /// to the given stream. + UndirGraphWriter(std::ostream& _os, const Graph& _graph) + : writer(new LemonWriter(_os)), own_writer(true), + nodeset_writer(*writer, _graph, std::string()), + undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()), + node_writer(*writer, nodeset_writer, std::string()), + undir_edge_writer(*writer, undir_edgeset_writer, std::string()), + attribute_writer(*writer, std::string()) {} + + /// \brief Construct a new UndirGraphWriter. + /// + /// Construct a new UndirGraphWriter. It writes into the given graph + /// to the given file. + UndirGraphWriter(const std::string& _filename, const Graph& _graph) + : writer(new LemonWriter(_filename)), own_writer(true), + nodeset_writer(*writer, _graph, std::string()), + undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()), + node_writer(*writer, nodeset_writer, std::string()), + undir_edge_writer(*writer, undir_edgeset_writer, std::string()), + attribute_writer(*writer, std::string()) {} + + /// \brief Construct a new UndirGraphWriter. + /// + /// Construct a new UndirGraphWriter. It writes into the given graph + /// to given LemonReader. + UndirGraphWriter(LemonWriter& _writer, const Graph& _graph) + : writer(_writer), own_writer(false), + nodeset_writer(*writer, _graph, std::string()), + undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()), + node_writer(*writer, nodeset_writer, std::string()), + undir_edge_writer(*writer, undir_edgeset_writer, std::string()), + attribute_writer(*writer, std::string()) {} + + /// \brief Destruct the graph writer. + /// + /// Destruct the graph writer. + ~UndirGraphWriter() { + if (own_writer) + delete writer; + } + + /// \brief Add a new node map writer command for the writer. + /// + /// Add a new node map writer command for the writer. + template + UndirGraphWriter& writeNodeMap(std::string name, const Map& map) { + nodeset_writer.writeNodeMap(name, map); + return *this; + } + + /// \brief Add a new node map writer command for the writer. + /// + /// Add a new node map writer command for the writer. + template + UndirGraphWriter& writeNodeMap(std::string name, const Map& map, + const Writer& writer = Writer()) { + nodeset_writer.writeNodeMap(name, map, writer); + return *this; + } + + /// \brief Add a new edge map writer command for the writer. + /// + /// Add a new edge map writer command for the writer. + template + UndirGraphWriter& writeEdgeMap(std::string name, const Map& map) { + undir_edgeset_writer.writeEdgeMap(name, map); + return *this; + } + + /// \brief Add a new edge map writer command for the writer. + /// + /// Add a new edge map writer command for the writer. + template + UndirGraphWriter& writeEdgeMap(std::string name, const Map& map, + const Writer& writer = Writer()) { + undir_edgeset_writer.writeEdgeMap(name, map, writer); + return *this; + } + + /// \brief Add a new undirected edge map writer command for the writer. + /// + /// Add a new undirected edge map writer command for the writer. + template + UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map) { + undir_edgeset_writer.writeUndirEdgeMap(name, map); + return *this; + } + + /// \brief Add a new undirected edge map writer command for the writer. + /// + /// Add a new edge undirected map writer command for the writer. + template + UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map, + const Writer& writer = Writer()) { + undir_edgeset_writer.writeUndirEdgeMap(name, map, writer); + return *this; + } + + /// \brief Add a new labeled node writer for the writer. + /// + /// Add a new labeled node writer for the writer. + UndirGraphWriter& writeNode(std::string name, const Node& node) { + node_writer.writeNode(name, node); + return *this; + } + + /// \brief Add a new labeled edge writer for the writer. + /// + /// Add a new labeled edge writer for the writer. + UndirGraphWriter& writeEdge(std::string name, const Edge& edge) { + undir_edge_writer.writeEdge(name, edge); + } + + /// \brief Add a new labeled undirected edge writer for the writer. + /// + /// Add a new labeled undirected edge writer for the writer. + UndirGraphWriter& writeUndirEdge(std::string name, const UndirEdge& edge) { + undir_edge_writer.writeUndirEdge(name, edge); + } + + /// \brief Add a new attribute writer command. + /// + /// Add a new attribute writer command. + template + UndirGraphWriter& writeAttribute(std::string name, const Value& value) { + attribute_writer.writeAttribute(name, value); + return *this; + } + + /// \brief Add a new attribute writer command. + /// + /// Add a new attribute writer command. + template + UndirGraphWriter& writeAttribute(std::string name, const Value& value, + const Writer& writer) { + attribute_writer.writeAttribute(name, value, writer); + return *this; + } + + /// \brief Conversion operator to LemonWriter. + /// + /// Conversion operator to LemonWriter. It make possible + /// to access the encapsulated \e LemonWriter, this way + /// you can attach to this writer new instances of + /// \e LemonWriter::SectionWriter. + operator LemonWriter&() { + return *writer; + } + + /// \brief Executes the writer commands. + /// + /// Executes the writer commands. + void run() { + writer->run(); + } + + /// \brief Write the id of the given node. + /// + /// It writes the id of the given node. If there was written an "id" + /// named node map then it will write the map value belongs to the node. + void writeId(std::ostream& os, const Node& item) const { + nodeset_writer.writeId(os, item); + } + + /// \brief Write the id of the given edge. + /// + /// It writes the id of the given edge. If there was written an "id" + /// named edge map then it will write the map value belongs to the edge. + void writeId(std::ostream& os, const Edge& item) const { + undir_edgeset_writer.writeId(os, item); + } + + /// \brief Write the id of the given undirected edge. + /// + /// It writes the id of the given undirected edge. If there was written + /// an "id" named edge map then it will write the map value belongs to + /// the edge. + void writeId(std::ostream& os, const UndirEdge& item) const { + undir_edgeset_writer.writeId(os, item); + } + + + private: + + LemonWriter* writer; + bool own_writer; + + NodeSetWriter nodeset_writer; + UndirEdgeSetWriter undir_edgeset_writer; + + NodeWriter node_writer; + UndirEdgeWriter undir_edge_writer; + + AttributeWriter attribute_writer; + }; + + + /// \brief Write an undirected graph to the output. + /// + /// Write an undirected graph to the output. + /// \param os The output stream. + /// \param g The graph. + /// \param capacity The capacity undirected map. + template + void writeUndirGraph(std::ostream& os, const Graph &g, + const CapacityMap& capacity) { + UndirGraphWriter writer(os, g); + writer.writeUndirEdgeMap("capacity", capacity); + writer.run(); + } + + /// \brief Write an undirected graph to the output. + /// + /// Write an undirected graph to the output. + /// \param os The output stream. + /// \param g The graph. + template + void writeUndirGraph(std::ostream& os, const Graph &g) { + UndirGraphWriter writer(os, g); + writer.run(); + } + + /// @} + +} + +#endif