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; |