lemon/lemon_writer.h
changeset 2505 1bb471764ab8
parent 2467 2025a571895e
child 2553 bfced05fa852
equal deleted inserted replaced
22:dbed5069139f 23:11509f65adce
   142       Value operator[](const Key& key) const {
   142       Value operator[](const Key& key) const {
   143 	return map[graph.direct(key, true)];
   143 	return map[graph.direct(key, true)];
   144       }
   144       }
   145 
   145 
   146     private:
   146     private:
       
   147       const Graph& graph;
   147       typename Ref<Map>::Type map;
   148       typename Ref<Map>::Type map;
   148       const Graph& graph;
       
   149     };
   149     };
   150 
   150 
   151     template <typename Graph, typename Map>
   151     template <typename Graph, typename Map>
   152     ForwardComposeMap<Graph, Map>
   152     ForwardComposeMap<Graph, Map>
   153     forwardComposeMap(const Graph& graph, const Map& map) {
   153     forwardComposeMap(const Graph& graph, const Map& map) {
   166       Value operator[](const Key& key) const {
   166       Value operator[](const Key& key) const {
   167 	return map[graph.direct(key, false)];
   167 	return map[graph.direct(key, false)];
   168       }
   168       }
   169 
   169 
   170     private:
   170     private:
       
   171       const Graph& graph;
   171       typename Ref<Map>::Type map;
   172       typename Ref<Map>::Type map;
   172       const Graph& graph;
       
   173     };
   173     };
   174 
   174 
   175     template <typename Graph, typename Map>
   175     template <typename Graph, typename Map>
   176     BackwardComposeMap<Graph, Map>
   176     BackwardComposeMap<Graph, Map>
   177     backwardComposeMap(const Graph& graph, const Map& map) {
   177     backwardComposeMap(const Graph& graph, const Map& map) {
   500   /// If the nodeset contains an \c "label" named map then it will be regarded
   500   /// If the nodeset contains an \c "label" named map then it will be regarded
   501   /// as label map. This map should contain only unique values and when the 
   501   /// as label map. This map should contain only unique values and when the 
   502   /// \c writeLabel() member will be called with a node it will write it's 
   502   /// \c writeLabel() member will be called with a node it will write it's 
   503   /// label. Otherwise if the \c _forceLabelMap constructor parameter is true 
   503   /// label. Otherwise if the \c _forceLabelMap constructor parameter is true 
   504   /// then the label map will be the id in the graph. In addition if the
   504   /// then the label map will be the id in the graph. In addition if the
   505   /// the \c _forceSort is true then the writer will write the edges
   505   /// the \c _forceSort is true then the writer will write the nodes
   506   /// sorted by the labels.
   506   /// sorted by the labels.
   507   ///
   507   ///
   508   /// \relates LemonWriter
   508   /// \relates LemonWriter
   509   template <typename _Graph, typename _Traits = DefaultWriterTraits>
   509   template <typename _Graph, typename _Traits = DefaultWriterTraits>
   510   class NodeSetWriter : public LemonWriter::SectionWriter {
   510   class NodeSetWriter : public LemonWriter::SectionWriter {
   668 
   668 
   669     typedef std::vector<std::pair<std::string, _writer_bits::
   669     typedef std::vector<std::pair<std::string, _writer_bits::
   670 				  MapWriterBase<Node>*> > MapWriters;
   670 				  MapWriterBase<Node>*> > MapWriters;
   671     MapWriters writers;
   671     MapWriters writers;
   672 
   672 
       
   673     _writer_bits::MapWriterBase<Node>* labelMap;
       
   674     bool forceLabelMap;
       
   675     bool forceSort;
       
   676    
       
   677     const Graph& graph;   
       
   678     std::string name;
       
   679 
       
   680   };
       
   681 
       
   682   /// \ingroup section_io
       
   683   /// \brief SectionWriter for writing a bipartite graph's nodeset.
       
   684   ///
       
   685   /// The lemon format can store multiple bipartite graph nodesets
       
   686   /// with several maps.  The nodeset section's header line is \c
       
   687   /// \@bpnodeset \c bpnodeset_name, but the \c bpnodeset_name may be empty.
       
   688   ///
       
   689   /// The first line of the section contains the names of the maps separated
       
   690   /// with white spaces. Each next lines describes a node in the nodeset, and
       
   691   /// contains the mapped values for each map.
       
   692   ///
       
   693   /// If the nodeset contains an \c "label" named map then it will be regarded
       
   694   /// as label map. This map should contain only unique values and when the 
       
   695   /// \c writeLabel() member will be called with a node it will write it's 
       
   696   /// label. Otherwise if the \c _forceLabelMap constructor parameter is true 
       
   697   /// then the label map will be the id in the graph. In addition if the
       
   698   /// the \c _forceSort is true then the writer will write the edges
       
   699   /// sorted by the labels.
       
   700   ///
       
   701   /// \relates LemonWriter
       
   702   template <typename _Graph, typename _Traits = DefaultWriterTraits>
       
   703   class BpNodeSetWriter : public LemonWriter::SectionWriter {
       
   704     typedef LemonWriter::SectionWriter Parent;
       
   705   public:
       
   706 
       
   707     typedef _Graph Graph;
       
   708     typedef _Traits Traits;
       
   709     typedef typename Graph::Node Node;
       
   710 
       
   711     /// \brief Constructor.
       
   712     ///
       
   713     /// Constructor for BpNodeSetWriter. It creates the BpNodeSetWriter and
       
   714     /// attach it into the given LemonWriter. If the \c _forceLabelMap
       
   715     /// parameter is true then the writer will write own label map when
       
   716     /// the user does not give "label" named map. In addition if the
       
   717     /// the \c _forceSort is true then the writer will write the nodes
       
   718     /// sorted by the labels.
       
   719     BpNodeSetWriter(LemonWriter& _writer, const Graph& _graph, 
       
   720 		  const std::string& _name = std::string(), 
       
   721 		  bool _forceLabelMap = true, bool _forceSort = true) 
       
   722       : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap), 
       
   723 	forceSort(_forceSort), graph(_graph), name(_name) {}
       
   724 
       
   725     /// \brief Destructor.
       
   726     ///
       
   727     /// Destructor for BpNodeSetWriter.
       
   728     virtual ~BpNodeSetWriter() {
       
   729       typename MapWriters::iterator it;
       
   730       for (it = writers.begin(); it != writers.end(); ++it) {
       
   731 	delete it->second;
       
   732       }
       
   733     }
       
   734 
       
   735   private:
       
   736     BpNodeSetWriter(const BpNodeSetWriter&);
       
   737     void operator=(const BpNodeSetWriter&);
       
   738   
       
   739   public:
       
   740 
       
   741     /// \brief Add a new A-node map writer command for the writer.
       
   742     ///
       
   743     /// Add a new A-node map writer command for the writer.
       
   744     template <typename Map>
       
   745     BpNodeSetWriter& writeANodeMap(std::string label, const Map& map) {
       
   746       return writeANodeMap<typename Traits::
       
   747 	template Writer<typename Map::Value>, Map>(label, map);
       
   748     }
       
   749 
       
   750     /// \brief Add a new A-node map writer command for the writer.
       
   751     ///
       
   752     /// Add a new A-node map writer command for the writer.
       
   753     template <typename ItemWriter, typename Map>
       
   754     BpNodeSetWriter& writeANodeMap(std::string label, const Map& map, 
       
   755 				   const ItemWriter& iw = ItemWriter()) {
       
   756       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
       
   757       checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
       
   758       if (label == "label") {
       
   759 	throw IoParameterError("Label cannot be A-node map");
       
   760       }
       
   761       awriters.push_back(make_pair(label, new _writer_bits::
       
   762 				   MapWriter<Node, Map, ItemWriter>(map, iw)));
       
   763       return *this;
       
   764     }
       
   765 
       
   766     /// \brief Add a new B-node map writer command for the writer.
       
   767     ///
       
   768     /// Add a new B-node map writer command for the writer.
       
   769     template <typename Map>
       
   770     BpNodeSetWriter& writeBNodeMap(std::string label, const Map& map) {
       
   771       return writeBNodeMap<typename Traits::
       
   772 	template Writer<typename Map::Value>, Map>(label, map);
       
   773     }
       
   774 
       
   775     /// \brief Add a new B-node map writer command for the writer.
       
   776     ///
       
   777     /// Add a new B-node map writer command for the writer.
       
   778     template <typename ItemWriter, typename Map>
       
   779     BpNodeSetWriter& writeBNodeMap(std::string label, const Map& map, 
       
   780 				   const ItemWriter& iw = ItemWriter()) {
       
   781       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
       
   782       checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
       
   783       if (label == "label") {
       
   784 	throw IoParameterError("Label cannot be B-node map");
       
   785       }
       
   786       bwriters.push_back(make_pair(label, new _writer_bits::
       
   787 				   MapWriter<Node, Map, ItemWriter>(map, iw)));
       
   788       return *this;
       
   789     }
       
   790 
       
   791     /// \brief Add a new node map writer command for the writer.
       
   792     ///
       
   793     /// Add a new node map writer command for the writer.
       
   794     template <typename Map>
       
   795     BpNodeSetWriter& writeNodeMap(std::string label, const Map& map) {
       
   796       return writeNodeMap<typename Traits::
       
   797 	template Writer<typename Map::Value>, Map>(label, map);
       
   798     }
       
   799 
       
   800     /// \brief Add a new node map writer command for the writer.
       
   801     ///
       
   802     /// Add a new node map writer command for the writer.
       
   803     template <typename ItemWriter, typename Map>
       
   804     BpNodeSetWriter& writeNodeMap(std::string label, const Map& map, 
       
   805 				  const ItemWriter& iw = ItemWriter()) {
       
   806       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
       
   807       checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
       
   808       writers.push_back(make_pair(label, new _writer_bits::
       
   809 				  MapWriter<Node, Map, ItemWriter>(map, iw)));
       
   810       return *this;
       
   811     }
       
   812 
       
   813   protected:
       
   814 
       
   815     /// \brief The header of the section.
       
   816     ///
       
   817     /// It gives back the header of the section.
       
   818     virtual std::string header() {
       
   819       return "@bpnodeset " + name;
       
   820     }
       
   821 
       
   822     /// \brief Writer function of the section.
       
   823     ///
       
   824     /// Write the content of the section.
       
   825     virtual void write(std::ostream& os) {
       
   826       for (int i = 0; i < int(writers.size()); ++i) {
       
   827 	if (writers[i].first == "label") {
       
   828 	  labelMap = writers[i].second;
       
   829 	  forceLabelMap = false;
       
   830 	  break;
       
   831 	}
       
   832       }
       
   833       {
       
   834 	os << "&anodeset ";
       
   835 	std::vector<Node> items;
       
   836 	for (typename Graph::ANodeIt it(graph); it != INVALID; ++it) {
       
   837 	  items.push_back(it);
       
   838 	}
       
   839 	if (forceSort) {
       
   840 	  if (labelMap) {
       
   841 	    labelMap->sort(items);
       
   842 	  } else {
       
   843 	    typedef IdMap<Graph, Node> Map;
       
   844 	    Map map(graph);
       
   845 	    _writer_bits::ComposeLess<Map> less(map);
       
   846 	    std::sort(items.begin(), items.end(), less);
       
   847 	  }
       
   848 	}
       
   849 	if (forceLabelMap) {
       
   850 	  os << "label\t";
       
   851 	}
       
   852 	for (int i = 0; i < int(writers.size()); ++i) {
       
   853 	  os << writers[i].first << '\t';
       
   854 	}
       
   855 	for (int i = 0; i < int(awriters.size()); ++i) {
       
   856 	  os << awriters[i].first << '\t';
       
   857 	}
       
   858 	os << std::endl;
       
   859 	for (typename std::vector<Node>::iterator it = items.begin();
       
   860 	     it != items.end(); ++it) {
       
   861 	  if (forceLabelMap) {
       
   862 	    os << graph.id(*it) << '\t';
       
   863 	  }
       
   864 	  for (int i = 0; i < int(writers.size()); ++i) {
       
   865 	    writers[i].second->write(os, *it);
       
   866 	    os << '\t';
       
   867 	  }
       
   868 	  for (int i = 0; i < int(awriters.size()); ++i) {
       
   869 	    awriters[i].second->write(os, *it);
       
   870 	    os << '\t';
       
   871 	  }
       
   872 	  os << std::endl;
       
   873 	}
       
   874       }
       
   875       {
       
   876 	os << "&bnodeset ";
       
   877 	std::vector<Node> items;
       
   878 	for (typename Graph::BNodeIt it(graph); it != INVALID; ++it) {
       
   879 	  items.push_back(it);
       
   880 	}
       
   881 	if (forceSort) {
       
   882 	  if (labelMap) {
       
   883 	    labelMap->sort(items);
       
   884 	  } else {
       
   885 	    typedef IdMap<Graph, Node> Map;
       
   886 	    Map map(graph);
       
   887 	    _writer_bits::ComposeLess<Map> less(map);
       
   888 	    std::sort(items.begin(), items.end(), less);
       
   889 	  }
       
   890 	}
       
   891 	if (forceLabelMap) {
       
   892 	  os << "label\t";
       
   893 	}
       
   894 	for (int i = 0; i < int(writers.size()); ++i) {
       
   895 	  os << writers[i].first << '\t';
       
   896 	}
       
   897 	for (int i = 0; i < int(bwriters.size()); ++i) {
       
   898 	  os << bwriters[i].first << '\t';
       
   899 	}
       
   900 	os << std::endl;
       
   901 	for (typename std::vector<Node>::iterator it = items.begin();
       
   902 	     it != items.end(); ++it) {
       
   903 	  if (forceLabelMap) {
       
   904 	    os << graph.id(*it) << '\t';
       
   905 	  }
       
   906 	  for (int i = 0; i < int(writers.size()); ++i) {
       
   907 	    writers[i].second->write(os, *it);
       
   908 	    os << '\t';
       
   909 	  }
       
   910 	  for (int i = 0; i < int(bwriters.size()); ++i) {
       
   911 	    bwriters[i].second->write(os, *it);
       
   912 	    os << '\t';
       
   913 	  }
       
   914 	  os << std::endl;
       
   915 	}
       
   916       }
       
   917     }
       
   918 
       
   919   public:
       
   920 
       
   921     /// \brief Returns true if the nodeset can write the labels of the nodes.
       
   922     ///
       
   923     /// Returns true if the nodeset can write the labels of the nodes.
       
   924     /// It is possible only if a "label" named map was written or the 
       
   925     /// \c _forceLabelMap constructor parameter was true.
       
   926     bool isLabelWriter() const {
       
   927       return labelMap != 0 || forceLabelMap;
       
   928     }
       
   929 
       
   930     /// \brief Write the label of the given node.
       
   931     ///
       
   932     /// It writes the label of the given node. If there was written a "label"
       
   933     /// named map then it will write the map value belongs to the node.
       
   934     /// Otherwise if the \c forceLabel parameter was true it will write
       
   935     /// its label in the graph. 
       
   936     void writeLabel(std::ostream& os, const Node& item) const {
       
   937       if (forceLabelMap) {
       
   938 	os << graph.id(item);
       
   939       } else {
       
   940 	labelMap->write(os, item);
       
   941       }
       
   942     }
       
   943 
       
   944     /// \brief Sorts the given node vector by label.
       
   945     ///
       
   946     /// Sorts the given node vector by label. If there was written an
       
   947     /// "label" named map then the vector will be sorted by the values
       
   948     /// of this map. Otherwise if the \c forceLabel parameter was true
       
   949     /// it will be sorted by its id in the graph.
       
   950     void sortByLabel(std::vector<Node>& nodes) const {
       
   951       if (labelMap) {
       
   952 	labelMap->sort(nodes);
       
   953       } else {
       
   954 	typedef IdMap<Graph, Node> Map;
       
   955 	Map map(graph);
       
   956 	_writer_bits::ComposeLess<Map> less(map);
       
   957 	std::sort(nodes.begin(), nodes.end(), less);
       
   958       }
       
   959     }
       
   960 
       
   961   private:
       
   962 
       
   963     typedef std::vector<std::pair<std::string, _writer_bits::
       
   964 				  MapWriterBase<Node>*> > MapWriters;
       
   965     MapWriters awriters, bwriters, writers;
       
   966     
   673     _writer_bits::MapWriterBase<Node>* labelMap;
   967     _writer_bits::MapWriterBase<Node>* labelMap;
   674     bool forceLabelMap;
   968     bool forceLabelMap;
   675     bool forceSort;
   969     bool forceSort;
   676    
   970    
   677     const Graph& graph;   
   971     const Graph& graph;