⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compressed_row_matrix_graph.hpp

📁 图论必用
💻 HPP
📖 第 1 页 / 共 2 页
字号:
#ifndef YASMIC_COMPRESSED_ROW_MATRIX_GRAPH
#define YASMIC_COMPRESSED_ROW_MATRIX_GRAPH

#if _MSC_VER >= 1400
    // disable the warning for deprecated c++ commands
    #pragma warning( push )
	#pragma warning( disable : 4996 )
#endif // _MSC_VER >= 1400

#include <boost/iterator.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/pending/integer_range.hpp>
#include <boost/graph/detail/adj_list_edge_iterator.hpp>
#include <boost/graph/properties.hpp>
#include <boost/property_map.hpp>

#include <yasmic/compressed_row_matrix.hpp>
#include <yasmic/tuple_utility.hpp>


namespace boost
{
	struct yasmic_compressed_row_matrix_traversal_category : 
		public vertex_list_graph_tag,
		public adjacency_graph_tag,
		public incidence_graph_tag,
		public edge_list_graph_tag { };

	// forward declarations (prototypes) for the detailed implementation


	namespace impl 
	{
		//template <class EdgeList> struct val_out_edge_ret;
		template <class RowIter, class ColIter, class ValIter> class crm_graph_edge_iter;
		template <class RowIter, class ColIter, class ValIter> struct crm_graph_edge;

		template <class RowIter, class ColIter, class ValIter>
		struct crm_graph
		{
			typedef yasmic::compressed_row_matrix<RowIter, ColIter, ValIter> type;
			typedef yasmic::smatrix_traits<type> traits;
		};

		/*template <class RowIter, class ColIter, class ValIter>
		struct nonzero_to_edge_transform
		{
			typedef
				typename impl::crm_graph_edge<RowIter, ColIter, ValIter>::type result_type;

			typedef 
				const typename crm_graph<RowIter, ColIter, ValIter>::traits::row_nonzero_descriptor argument_type;

			result_type operator() (argument_type arg) const
			{
				return (result_type(arg._row, arg._column, arg._nzi));
			}
		};*/

		template <class RowIter, class ColIter, class ValIter>
		struct nonzero_to_adjacency_transform
		{
			typedef
				typename crm_graph<RowIter, ColIter, ValIter>::traits::index_type result_type;
			typedef 
				const typename crm_graph<RowIter, ColIter, ValIter>::traits::row_nonzero_descriptor argument_type;

			result_type operator() (argument_type arg) const
			{
				return (arg._column);
			}
		};
	}


	template <class RowIter, class ColIter, class ValIter>
	struct graph_traits< yasmic::compressed_row_matrix<RowIter, ColIter, ValIter> >
	{
		typedef yasmic::compressed_row_matrix<RowIter, ColIter, ValIter> smatrix_type; 

		typedef typename yasmic::smatrix_traits<smatrix_type>::index_type vertex_descriptor;
		typedef typename yasmic::smatrix_traits<smatrix_type>::row_nonzero_descriptor edge_descriptor;
		
		typedef 
			boost::transform_iterator< 
				impl::nonzero_to_adjacency_transform<RowIter, ColIter, ValIter>,
				typename yasmic::smatrix_traits<smatrix_type>::row_nonzero_iterator > 
			adjacency_iterator;

		typedef typename yasmic::smatrix_traits<smatrix_type>::row_nonzero_iterator
			out_edge_iterator;
		
		typedef void in_edge_iterator;
    
		typedef typename yasmic::smatrix_traits<smatrix_type>::row_iterator vertex_iterator;
    
		typedef typename yasmic::smatrix_traits<smatrix_type>::nonzero_iterator edge_iterator;
		
		typedef directed_tag directed_category;
		typedef allow_parallel_edge_tag edge_parallel_category;
		typedef yasmic_compressed_row_matrix_traversal_category traversal_category;
		typedef typename yasmic::smatrix_traits<smatrix_type>::index_type vertices_size_type;
		typedef typename yasmic::smatrix_traits<smatrix_type>::size_type edges_size_type;
		typedef typename yasmic::smatrix_traits<smatrix_type>::size_type degree_size_type;

        static vertex_descriptor null_vertex()
        {
            return std::numeric_limits<vertex_descriptor>::max();
        }
	};

	namespace impl
	{
		

		template <class V, class S>
		class crm_graph_edge_type :
	    	public std::pair<V,V>
		{
		public:
    		crm_graph_edge_type() { }
    		crm_graph_edge_type(V s, V d, S id) 
    			: std::pair<V,V>(s, d), _id(id) { }
    	
    		S id() { return (_id); }
    	
		protected:
	    	S _id;
	    };

		template <class RowIter, class ColIter, class ValIter>
		struct crm_graph_edge
		{
			typedef typename yasmic::smatrix_traits<typename impl::crm_graph<RowIter, ColIter, ValIter>::type >::index_type V;
			typedef typename yasmic::smatrix_traits<typename impl::crm_graph<RowIter, ColIter, ValIter>::type >::size_type S;
	  
			typedef crm_graph_edge_type<V,S> type;
		};

		template <class RowIter, class ColIter, class ValIter>
		class crm_graph_edge_iter
		: public boost::iterator_facade<
            crm_graph_edge_iter<RowIter, ColIter, ValIter>,
			typename crm_graph_edge<RowIter, ColIter, ValIter>::type const,
            boost::forward_traversal_tag, 
            typename crm_graph_edge<RowIter, ColIter, ValIter>::type const >
		{
		public:
            crm_graph_edge_iter() {}

			crm_graph_edge_iter(
                RowIter ri, RowIter rend, ColIter ci)
            : _ri(ri), _rend(rend), _ci(ci), _id(0), _row(0)
            {
				_ri++;
            	// skip over any empty rows
            	while ( _ri != _rend && *(_ri) == _id )
                {
                   	// keep incrementing the row 
                   	++_ri; ++_row;
                }
            }

			crm_graph_edge_iter(
                RowIter ri, RowIter rend, ColIter ci, 
				typename std::iterator_traits<RowIter>::value_type id)
			: _ri(ri), _rend(rend), _ci(ci), _id(id), _row(0)
			{
			}

		private:
            friend class boost::iterator_core_access;

            void increment() 
            {  
            	// just increment everything!
            	++_ci; ++_id;
            	
                if (_id == *_ri)
                {
                	++_ri; ++_row;
                	
                	// while we aren't at the end and the row isn't empty
                	// (if *_ri == _id, then the row is empty because _id 
                	// is the current index in the column/val array.)
                	while ( _ri != _rend && *(_ri) == _id )
                    {
                    	// keep incrementing the row 
                    	++_ri; ++_row;
                    }
                }
            }

			bool equal(crm_graph_edge_iter const& other) const
            {
				return (_ri == other._ri && _ci == other._ci);
            }
            
            typename crm_graph_edge<RowIter, ColIter, ValIter>::type
            dereference() const 
            { 
            	//return boost::make_tuple(_row, *_ci, *_vi);
				return edge_type(_row, *_ci, _id);
            }


			typedef typename crm_graph_edge<RowIter, ColIter, ValIter>::type edge_type;
            typename std::iterator_traits<RowIter>::value_type _row;
            typename std::iterator_traits<RowIter>::value_type _id;
            RowIter _ri, _rend;
            ColIter _ci;
		};
		
		template <class RowIter, class ColIter, class ValIter>
		struct crm_graph_ret
		{
			typedef yasmic::compressed_row_matrix<RowIter, ColIter, ValIter> smatrix_type; 
			typedef yasmic::smatrix_traits<smatrix_type> smatrix_traits;

			typedef boost::graph_traits<smatrix_type> g_traits;

			typedef std::pair< typename g_traits::vertex_iterator, typename g_traits::vertex_iterator > 
				vertices_ret;

			typedef std::pair< typename g_traits::adjacency_iterator, typename g_traits::adjacency_iterator >
				adjacent_ret;

			typedef std::pair < typename g_traits::out_edge_iterator, typename g_traits::out_edge_iterator >
				out_edges_ret;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -