deba@1137: /* -*- C++ -*- deba@1137: * src/lemon/graph_writer.h - Part of LEMON, a generic C++ optimization library deba@1137: * alpar@1164: * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport alpar@1359: * (Egervary Research Group on Combinatorial Optimization, EGRES). deba@1137: * deba@1137: * Permission to use, modify and distribute this software is granted deba@1137: * provided that this copyright notice appears in all copies. For deba@1137: * precise terms see the accompanying LICENSE file. deba@1137: * deba@1137: * This software is provided "AS IS" with no warranty of any kind, deba@1137: * express or implied, and with no claim as to its suitability for any deba@1137: * purpose. deba@1137: * deba@1137: */ deba@1137: alpar@1287: ///\ingroup io_group deba@1137: ///\file alpar@1287: ///\brief Lemon Graph Format writer. deba@1137: deba@1214: #ifndef LEMON_GRAPH_WRITER_H deba@1214: #define LEMON_GRAPH_WRITER_H deba@1137: deba@1137: #include deba@1137: deba@1137: #include deba@1409: #include deba@1137: deba@1137: namespace lemon { deba@1137: deba@1333: /// \addtogroup io_group deba@1333: /// @{ deba@1333: deba@1137: /// \brief The graph writer class. deba@1137: /// deba@1333: /// The \c GraphWriter class provides the graph output. To write a graph deba@1333: /// you should first give writing commands for the writer. You can declare deba@1333: /// write command as \c NodeMap or \c EdgeMap writing and labeled Node and deba@1333: /// Edge writing. deba@1333: /// deba@1333: /// \code deba@1333: /// GraphWriter writer(std::cout, graph); deba@1333: /// \endcode deba@1333: /// deba@1394: /// The \c writeNodeMap() function declares a \c NodeMap writing deba@1394: /// command in the \c GraphWriter. You should give as parameter deba@1394: /// the name of the map and the map object. The NodeMap writing deba@1394: /// command with name "id" should write a unique map because it deba@1394: /// is regarded as ID map. deba@1333: /// deba@1333: /// \code deba@1333: /// IdMap nodeIdMap; deba@1394: /// writer.writeNodeMap("id", nodeIdMap); deba@1333: /// deba@1394: /// writer.writeNodeMap("x-coord", xCoordMap); deba@1394: /// writer.writeNodeMap("y-coord", yCoordMap); deba@1394: /// writer.writeNodeMap("color", colorMap); deba@1333: /// \endcode deba@1333: /// deba@1394: /// With the \c writeEdgeMap() member function you can give an edge map deba@1333: /// writing command similar to the NodeMaps. deba@1333: /// deba@1333: /// \code deba@1333: /// DescriptorMap > deba@1333: /// edgeDescMap(graph); deba@1394: /// writer.writeEdgeMap("descriptor", edgeDescMap); deba@1333: /// deba@1394: /// writer.writeEdgeMap("weight", weightMap); deba@1394: /// writer.writeEdgeMap("label", labelMap); deba@1333: /// \endcode deba@1333: /// deba@1394: /// With \c writeNode() and \c writeEdge() functions you can deba@1394: /// point out Nodes and Edges in the graph. By example, you can deba@1394: /// write out the source and target of the graph. deba@1333: /// deba@1333: /// \code deba@1394: /// writer.writeNode("source", sourceNode); deba@1394: /// writer.writeNode("target", targetNode); deba@1333: /// deba@1394: /// writer.writeEdge("observed", edge); deba@1333: /// \endcode deba@1333: /// deba@1333: /// After you give all write commands you must call the \c run() member deba@1333: /// function, which execute all the writer commands. deba@1333: /// deba@1333: /// \code deba@1333: /// writer.run(); deba@1333: /// \endcode deba@1333: /// alpar@1287: /// \see DefaultWriterTraits alpar@1287: /// \see QuotedStringWriter deba@1333: /// \see IdMap deba@1333: /// \see DescriptorMap deba@1394: /// \see \ref GraphWriter alpar@1138: /// \see \ref graph-io-page deba@1333: /// \author Balazs Dezso deba@1137: template deba@1137: class GraphWriter { deba@1137: public: deba@1137: deba@1137: typedef _Graph Graph; deba@1137: typedef typename Graph::Node Node; deba@1137: typedef typename Graph::Edge Edge; deba@1137: deba@1137: typedef _WriterTraits WriterTraits; deba@1409: deba@1137: /// \brief Construct a new GraphWriter. deba@1137: /// deba@1409: /// Construct a new GraphWriter. It writes the given graph deba@1409: /// to the given stream. deba@1208: GraphWriter(std::ostream& _os, const Graph& _graph) deba@1409: : writer(new LemonWriter(_os)), own_writer(true), deba@1409: graph(_graph), deba@1409: nodeset_writer(*writer, graph, std::string()), deba@1409: edgeset_writer(*writer, graph, nodeset_writer, std::string()), deba@1409: node_writer(*writer, nodeset_writer, std::string()), deba@1409: edge_writer(*writer, edgeset_writer, std::string()), deba@1409: attribute_writer(*writer, std::string()) {} deba@1137: deba@1409: /// \brief Construct a new GraphWriter. deba@1409: /// deba@1409: /// Construct a new GraphWriter. It writes into the given graph deba@1409: /// to the given file. deba@1409: GraphWriter(const std::string& _filename, const Graph& _graph) deba@1409: : writer(new LemonWriter(_filename)), own_writer(true), deba@1409: graph(_graph), deba@1410: nodeset_writer(*writer, graph, std::string()), deba@1410: edgeset_writer(*writer, graph, nodeset_writer, std::string()), deba@1409: node_writer(*writer, nodeset_writer, std::string()), deba@1409: edge_writer(*writer, edgeset_writer, std::string()), deba@1409: attribute_writer(*writer, std::string()) {} deba@1409: deba@1409: /// \brief Construct a new GraphWriter. deba@1409: /// deba@1409: /// Construct a new GraphWriter. It writes into the given graph deba@1409: /// to given LemonReader. deba@1409: GraphWriter(LemonWriter& _writer, const Graph& _graph) deba@1409: : writer(_writer), own_writer(false), deba@1409: graph(_graph), deba@1409: nodeset_writer(*writer, graph, std::string()), deba@1409: edgeset_writer(*writer, graph, nodeset_writer, std::string()), deba@1409: node_writer(*writer, nodeset_writer, std::string()), deba@1409: edge_writer(*writer, edgeset_writer, std::string()), deba@1409: attribute_writer(*writer, std::string()) {} deba@1137: deba@1137: /// \brief Destruct the graph writer. deba@1137: /// deba@1137: /// Destruct the graph writer. deba@1137: ~GraphWriter() { deba@1409: if (own_writer) deba@1409: delete writer; deba@1137: } deba@1137: deba@1137: /// \brief Add a new node map writer command for the writer. deba@1137: /// deba@1137: /// Add a new node map writer command for the writer. deba@1137: template deba@1394: GraphWriter& writeNodeMap(std::string name, const Map& map) { deba@1409: nodeset_writer.writeMap(name, map); deba@1409: return *this; deba@1137: } deba@1137: deba@1137: /// \brief Add a new node map writer command for the writer. deba@1137: /// deba@1137: /// Add a new node map writer command for the writer. deba@1137: template deba@1394: GraphWriter& writeNodeMap(std::string name, const Map& map, deba@1409: const Writer& writer = Writer()) { deba@1409: nodeset_writer.writeMap(name, map, writer); deba@1137: return *this; deba@1137: } deba@1137: deba@1137: deba@1137: /// \brief Add a new edge map writer command for the writer. deba@1137: /// deba@1137: /// Add a new edge map writer command for the writer. deba@1137: template deba@1394: GraphWriter& writeEdgeMap(std::string name, const Map& map) { deba@1409: edgeset_writer.writeMap(name, map); deba@1409: return *this; deba@1137: } deba@1137: deba@1137: deba@1137: /// \brief Add a new edge map writer command for the writer. deba@1137: /// deba@1137: /// Add a new edge map writer command for the writer. deba@1137: template deba@1409: GraphWriter& writeEdgeMap(std::string name, const Map& map, deba@1409: const Writer& writer = Writer()) { deba@1409: edgeset_writer.writeMap(name, map, writer); deba@1137: return *this; deba@1137: } deba@1137: deba@1137: /// \brief Add a new labeled node writer for the writer. deba@1137: /// deba@1137: /// Add a new labeled node writer for the writer. deba@1394: GraphWriter& writeNode(std::string name, const Node& node) { deba@1409: node_writer.writeNode(name, node); deba@1137: return *this; deba@1137: } deba@1137: deba@1137: /// \brief Add a new labeled edge writer for the writer. deba@1137: /// deba@1137: /// Add a new labeled edge writer for the writer. deba@1394: GraphWriter& writeEdge(std::string name, const Edge& edge) { deba@1409: edge_writer.writeEdge(name, edge); deba@1409: } deba@1409: deba@1409: /// \brief Add a new attribute writer command. deba@1409: /// deba@1409: /// Add a new attribute writer command. deba@1409: template deba@1409: GraphWriter& writeAttribute(std::string name, const Value& value) { deba@1409: attribute_writer.writeAttribute(name, value); deba@1409: return *this; deba@1409: } deba@1409: deba@1409: /// \brief Add a new attribute writer command. deba@1409: /// deba@1409: /// Add a new attribute writer command. deba@1409: template deba@1409: GraphWriter& writeAttribute(std::string name, const Value& value, deba@1409: const Writer& writer) { deba@1409: attribute_writer.writeAttribute(name, value, writer); deba@1137: return *this; deba@1137: } deba@1137: deba@1409: /// \brief Conversion operator to LemonWriter. deba@1409: /// deba@1409: /// Conversion operator to LemonWriter. It make possible deba@1409: /// to access the encapsulated \e LemonWriter, this way deba@1409: /// you can attach to this writer new instances of deba@1409: /// \e LemonWriter::SectionWriter. deba@1409: operator LemonWriter&() { deba@1409: return *writer; deba@1396: } deba@1396: deba@1137: /// \brief Executes the writer commands. deba@1137: /// deba@1137: /// Executes the writer commands. deba@1409: void run() { deba@1409: writer->run(); deba@1137: } deba@1137: deba@1137: private: deba@1137: deba@1409: LemonWriter* writer; deba@1409: bool own_writer; deba@1137: deba@1208: const Graph& graph; deba@1137: deba@1409: NodeSetWriter nodeset_writer; deba@1409: EdgeSetWriter edgeset_writer; deba@1409: deba@1409: NodeWriter node_writer; deba@1409: EdgeWriter edge_writer; deba@1409: deba@1409: AttributeWriter attribute_writer; deba@1137: }; deba@1137: deba@1409: deba@1333: /// \brief Write a graph to the output. deba@1333: /// deba@1333: /// Write a graph to the output. deba@1333: /// \param os The output stream. deba@1333: /// \param g The graph. deba@1333: /// \param capacity The capacity map. deba@1333: /// \param s The source node. deba@1333: /// \param t The target node. deba@1333: /// \param cost The cost map. deba@1208: template deba@1208: void writeGraph(std::ostream& os, const Graph &g, deba@1208: const CapacityMap& capacity, const typename Graph::Node &s, deba@1208: const typename Graph::Node &t, const CostMap& cost) { deba@1394: GraphWriter writer(os, g); deba@1208: IdMap nodeIdMap(g); deba@1394: writer.writeNodeMap("id", nodeIdMap); deba@1208: IdMap edgeIdMap(g); deba@1394: writer.writeEdgeMap("id", edgeIdMap); deba@1394: writer.writeEdgeMap("capacity", capacity); deba@1394: writer.writeEdgeMap("cost", cost); deba@1394: writer.writeNode("source", s); deba@1394: writer.writeNode("target", t); deba@1394: writer.run(); deba@1208: } deba@1208: deba@1333: /// \brief Write a graph to the output. deba@1333: /// deba@1333: /// Write a graph to the output. deba@1333: /// \param os The output stream. deba@1333: /// \param g The graph. deba@1333: /// \param capacity The capacity map. deba@1333: /// \param s The source node. deba@1333: /// \param t The target node. deba@1297: template deba@1208: void writeGraph(std::ostream& os, const Graph &g, deba@1208: const CapacityMap& capacity, const typename Graph::Node &s, deba@1208: const typename Graph::Node &t) { deba@1394: GraphWriter writer(os, g); deba@1208: IdMap nodeIdMap(g); deba@1394: writer.writeNodeMap("id", nodeIdMap); deba@1208: IdMap edgeIdMap(g); deba@1394: writer.writeEdgeMap("id", edgeIdMap); deba@1394: writer.writeEdgeMap("capacity", capacity); deba@1394: writer.writeNode("source", s); deba@1394: writer.writeNode("target", t); deba@1394: writer.run(); deba@1208: } deba@1208: deba@1333: /// \brief Write a graph to the output. deba@1333: /// deba@1333: /// Write a graph to the output. deba@1333: /// \param os The output stream. deba@1333: /// \param g The graph. deba@1333: /// \param capacity The capacity map. deba@1333: /// \param s The source node. deba@1208: template deba@1208: void writeGraph(std::ostream& os, const Graph &g, deba@1208: const CapacityMap& capacity, const typename Graph::Node &s) { deba@1394: GraphWriter writer(os, g); deba@1208: IdMap nodeIdMap(g); deba@1394: writer.writeNodeMap("id", nodeIdMap); deba@1208: IdMap edgeIdMap(g); deba@1394: writer.writeEdgeMap("id", edgeIdMap); deba@1394: writer.writeEdgeMap("capacity", capacity); deba@1394: writer.writeNode("source", s); deba@1394: writer.run(); deba@1208: } deba@1333: deba@1333: /// \brief Write a graph to the output. deba@1333: /// deba@1333: /// Write a graph to the output. deba@1333: /// \param os The output stream. deba@1333: /// \param g The graph. deba@1333: /// \param capacity The capacity map. deba@1208: template deba@1208: void writeGraph(std::ostream& os, const Graph &g, deba@1208: const CapacityMap& capacity) { deba@1394: GraphWriter writer(os, g); deba@1208: IdMap nodeIdMap(g); deba@1394: writer.writeNodeMap("id", nodeIdMap); deba@1208: IdMap edgeIdMap(g); deba@1394: writer.writeEdgeMap("id", edgeIdMap); deba@1394: writer.writeEdgeMap("capacity", capacity); deba@1394: writer.run(); deba@1208: } deba@1333: deba@1333: /// \brief Write a graph to the output. deba@1333: /// deba@1333: /// Write a graph to the output. deba@1333: /// \param os The output stream. deba@1333: /// \param g The graph. deba@1208: template deba@1208: void writeGraph(std::ostream& os, const Graph &g) { deba@1394: GraphWriter writer(os, g); deba@1208: IdMap nodeIdMap(g); deba@1394: writer.writeNodeMap("id", nodeIdMap); deba@1208: IdMap edgeIdMap(g); deba@1394: writer.writeEdgeMap("id", edgeIdMap); deba@1394: writer.run(); deba@1208: } deba@1208: deba@1333: /// @} deba@1137: deba@1137: } deba@1214: deba@1214: #endif