[/
 / Copyright (C) 2007-2009 Andrew Sutton
 /
 / Distributed under the Boost Software License, Version 1.0. (See accompanying
 / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 /]

[section Adjacency Matrix]

 template <
     typename Directed = directedS,
     typename VertexProperty = no_property,
     typename EdgeProperty = no_property,
     typename GraphProperty = no_property,
     typename Allocator = std::allocator<...> >
 class adjacency_matrix;

The `adjacency_matrix` class implements the Boost.Graph interface using the
traditional adjacency matrix storage format. For a graph with /V/ vertices, a
/V x V/ matrix is used, where each element ['a[sub ij]] is a boolean flag that
says whether there is an edge from vertex /i/ to vertex /j/. Figure 1 shows
the adjacency matrix representation of a graph.

[note TODO: Rebuild image]

The advantage of this matrix format over the adjacency list is that edge insertion
and removal is constant time.  There are several disadvantages. The first is that
the amount of memory used is ['O(V[sup 2])] instead of /O(V + E)/ (where /E/ is
the number of edges). The second is that operations that traverse all the out-edges
of each vertex (such as breadth-first search) run in ['O(V[sup 2])] time instead
of /O(V + E)/ time for the adjacency list. In short, it is better to use the
`adjacency_matrix` for dense graphs (where /E/ is close to ['V[sup 2]]) and it is
better to use [adjacency_list] for sparse graphs (where /E/ is much smaller than
['V[sup2]]).

The `adjacency_matrix` class extends the traditional data structure by allowing
objects to be attached to vertices and edges using the same property template
parameters supported by [adjacency_list]. These may be
[link boost_graph.guide.bundled_properties bundled properties]
or standard (backward-compatible)
[link boost_graph.guide.interior_properties interior properties].
The types of all property values must be [StdRegular].

In the case of an undirected graph, the `adjacency_matrix`. class does not use a
full /V x V/ matrix but instead uses a lower triangle (the diagonal and below)
since the matrix for an undirected graph is symmetric. This reduces the storage
to ['(V[sup 2])/2]. Figure 2</a> shows an adjacency matrix representation of an
undirected graph.

[note TODO: Rebuild image.]

[heading Where Defined]
`boost/graph/adjacency_matrix.hpp`

[heading Template Parameters]
[table
    [[Parameter] [Description] [Default]]
    [
        [`Directed`]
        [
            A selector to choose whether the graph is directed or undirected.
            The options are directedS and undirectedS.
        ]
        [`directedS`]
    ]
    [
        [`VertexProperties`]
        [Specifies internal properties for vertices.]
        [`no_property`]
    ]
    [
        [`EdgeProperties`]
        [Specifies internal properties for edges.]
        [`no_property`]
    ]
    [
        [`GraphProperties`]
        [Specifies internal properties for the graph object.]
        [`no_property`]
    ]
    [
        [`Alloator`]
        [
            The allocator type for the adjacency matrix.
        ]
        [`std::allocator<...>`]
    ]
]

[heading Model Of]
[VertexAndEdgeListGraph], [BidirecitonalGraph], [AdjacencyMatrix],
[MutablePropertyGraph], [SgiCopyConstructible], [SgiAssignable]

[heading Associated Types]
[table
    [[Type] [Description]]
    [
        [`graph_traits<adjancency_list>::vertex_descriptor`]
        [The type of the graph's vertex descriptors.]
    ]
    [
        [`graph_traits<adjancency_list>::edge_descriptor`]
        [The type of the graph's edge descriptors.]
    ]
    [
        [`graph_traits<adjancency_list>::vertex_iterator`]
        [
            The type for iterators returned by `vertices()`, modeling the
            [SgiRandomAccessIterator] concept.
        ]
    ]
    [
        [`graph_traits<adjancency_list>::edge_iterator`]
        [
            The type for iterators returned by `edges()`, modeling the
            [SgiForwardIterator] concept.
        ]
    ]
    [
        [`graph_traits<adjancency_list>::out_edge_iterator`]
        [
            The type for iterators returned by `out_edges()`, modeling the
            [SgiForwardIterator] concept.
        ]
    ]
    [
        [`graph_traits<adjancency_list>::in_edge_iterator`]
        [
            The type for iterators returned by `in_edges()`, modeling the
            [SgiForwardIterator] concept.
        ]
    ]
    [
        [`graph_traits<adjancency_list>::adjacency_iterator`]
        [
            The type for iterators returned by `adjacent_vertices()`, modeling the
            [SgiForwardIterator] concept.
        ]
    ]
    [
        [`graph_traits<adjancency_list>::directed_category`]
        [
            Provides inforamtion about whether the graph is undirected (`undirected_tag`),
            or directed (`directed_tag`).
        ]
    ]
    [
        [`graph_traits<adjacency_list>::edge_parallel_category`]
        [
            Adjacency matrices do not allow the insertion of parallel edges so
            this type is always `disallow_parallel_edges`.
        ]
    ]
    [
        [`graph_traits<adjacency_list>::vertices_size_type`]
        [The type used for dealing with the number of vertices in the graph. ]
    ]
    [
        [`graph_traits<adjacency_list>::edge_size_type`]
        [The type used for dealing with the number of edges in the graph. ]
    ]
    [
        [`graph_traits<adjacency_list>::degree_size_type`]
        [The type used for dealing with the number of edges incident to a vertex in the graph.]
    ]
    [
        [
            `property_map<adjacency_list, Property>::type`

            `property_map<adjacency_list, Property>::const_type`
        ]
        [
            The property map type for vertex or edge properties in the graph. The specific
            property is specified by the `Property` template argument, and must match one of
            the properties specified in the `VertexProperties` or `EdgeProperties` for the
            graph.
        ]
    ]
    [
        [`graph_property<adjacency_list, Property>::type`]
        [
            The value type ofor the graph property specified by the `Property` parameter.
        ]
    ]
]

[heading Member Functions]
[table
    [[Member Function] [Description]]
    [
        [`adjacency_matrix(vertices_size_type n, const GraphProperties& = GraphProperties()`]
        [Construct a graph with `n` vertices and no edges.]
    ]
    [
        [
            ``
            template <typename Iter>
            adjacency_matrix(Iter f, Iter l, vertices_size_type n, const GraphProperties& = GraphProperties())
            ``
        ]
        [
            Construct a graph with `n` vertices and and the edges specified by
            the iterator range \[f, l). The `value_type` of `Iter` must be a
            `std::pair` of `int`s whose values are in the range \[0, n), and
            indicate the given vertex.
        ]
    ]
    [
        [
            ``
            template <typename EdgeIter, typename PropIter>
            adjacency_matrix(Iter f, Iter l, PropIter p, vertices_size_type n, const GraphProperties& = GraphProperties())
            ``
        ]
        [
            Construct a graph with `n` vertices and and the edges specified by
            the iterator range \[f, l), with the edge properties given by the
            iterator range starting at `p`. The `value_type` of `EdgeIter` must
            be a `std::pair` of `int`s whose values are in the range \[0, n), and
            indicate the given vertex. The `value_type` of the `PropIter` must be
            the same as the template parameter `EdgeProperty`.
        ]
    ]
]

[heading Non-Member Observers]
[table
    [[Member Function] [Description]]
    [
        [`vertices_size_type num_vertices(const adjacency_matrix& g)`]
        [Return the number of vertices in `g`.]
    ]
    [
        [`edges_size_type num_edges(const adjacency_matrix& g)`]
        [Return the edges in vertices in `g`.]
    ]
    [
        [`vertex_descriptor vertex(vertices_size_type n, const adjacency_matrix& g)`]
        [Return a descriptor to the `n`th vertex in `g`.]
    ]
    [
        [`pair<edge_descriptor, bool> edge(vertex_descriptor u, vertex_descriptor v, const adjacency_matrix& g)`]
        [
            Returns a pair containing a descriptor for the edge connecting vertices
            `u` and `v` in `g`, and a boolean value that indicates whether the
            edge exists (`true`) or not (`false`).
        ]
    ]
    [
        [`vertex_descriptor source(edge_descriptor e, const adjacency_matrix& g)`]
        [Return the source vertex of the edge `e` in `g`.]
    ]
    [
        [`vertex_descriptor target(edge_descriptor e, const adjacency_matrix& g)`]
        [Return the target vertex of the edge `e` in `g`.]
    ]
    [
        [`pair<vertex_iterator, vertex_iterator> vertices(const adjacency_matrix& g)`]
        [Returns an iterator range to the vertex set of `g`.]
    ]
    [
        [`pair<edge_iterator, edge_iterator> edges(const adjacency_matrix& g)`]
        [Returns an iterator range to the edge set of `g`.]
    ]
    [
        [`pair<out_edge_iterator, out_edge_iterator> out_edges(vertex_descriptor v, const adjacency_matrix& g)`]
        [
            Returns an iterator range to the out-edge set of the vertex `v` in `g`.
            If the graph is undirected, the iterator range provides access to all
            incident edges.
        ]
    ]
    [
        [`pair<in_edge_iterator, in_edge_iterator> in_edges(vertex_descriptor v, const adjacency_matrix& g)`]
        [
            Returns an iterator range to the in-edge set of the vertex `v` in `g`.
            If the graph is undirected, this operation is equivalent to `out_edges`.
        ]
    ]
    [
        [`pair<adjacency_iterator, adjacency_iterator> adjacent_vertices(vertex_descriptor v, const adjacency_matrix& g)`]
        [Returns an iterator range providing access to the adjacent vertices of `v` in `g`.]
    ]
    [
        [`degree_size_type out_degree(vertex_descriptor v, const adjacency_matrix& g)`]
        [
            Return the out-degree of vertex `v` in `g`.

            *Complexity:* /O(|V|)/
        ]
    ]
    [
        [`degree_size_type in_degree(vertex_descriptor v, const adjacency_matrix& g)`]
        [
            Return the in-degree of vertex `v` in `g`.

            *Complexity:* /O(|V|)/
        ]
    ]
]


[heading Non-Member Mutators]
[table
    [[Member Function] [Description]]
    [
        [`pair<edge_descriptor, bool> add_edge(vertex_descriptor u, vertex_descriptor v, adjacency_matrix& g)`]
        []
    ]
    [
        [`pair<edge_descriptor, bool> add_edge(vertex_descriptor u, vertex_descriptor v, EdgeProperty const& p, adjacency_matrix& g)`]
        []
    ]
    [
        [`void remove_edge(vertex_descriptor u, vertex_descriptor v, adjacency_matrix& g)`]
        []
    ]
    [
        [`void remove_edge(edge_descriptor v, adjacency_matrix& g)`]
        []
    ]
    [
        [`void clear_vertex(edge_descriptor v, adjacency_matrix& g)`]
        []
    ]
]

[heading Property Accessors]
[table
    [[Member Function] [Description]]
    [
        [
            ``
            template <typename Property>
            typename property_map<adjancecy_matrix, Property>::type
            get(Property, adjaceny_matrix& g);
            ``
        ]
        []
    ]
    [
        [
            ``
            template <typename Property>
            typename property_map<adjancecy_matrix, Property>::const_type
            get(Property, adjaceny_matrix const& g);
            ``
        ]
        []
    ]
    [
        [
            ``
            template <typename Property, typename X>
            typename property_traits<
                property_map<adjancecy_matrix, Property>::const_type
            >::value_type
            get(Property, adjaceny_matrix const& g, X x);
            ``
        ]
        []
    ]
    [
        [
            ``
            template <typename Property, typename X, typename Value>
            void put(Property, X, adjaceny_matrix const& g, X x, const Value&);
            ``
        ]
        []
    ]
    [
        [
            ``
            template <typename Property>
            void get_property(adjaceny_matrix const& g, Property);
            ``
        ]
        []
    ]
    [
        [
            ``
            template <typename Property, typename Value>
            void set_property(adjaceny_matrix const& g, Property, const Value&);
            ``
        ]
        []
    ]
]


[heading Example]
Create the graph of Figure 1.

 enum { A, B, C, D, E, F, N };
 const char* name = "ABCDEF";

 typedef boost::adjacency_matrix&lt;boost::directedS> Graph;
 Graph g(N);
 add_edge(B, C, g);
 add_edge(B, F, g);
 add_edge(C, A, g);
 add_edge(C, C, g);
 add_edge(D, E, g);
 add_edge(E, D, g);
 add_edge(F, A, g);

 std::cout << "vertex set: ";
 boost::print_vertices(g, name);
 std::cout << std::endl;

 std::cout << "edge set: ";
 boost::print_edges(g, name);
 std::cout << std::endl;

 std::cout << "out-edges: " << std::endl;
 boost::print_graph(g, name);
 std::cout << std::endl;

The output is:
[pre
  vertex set: A B C D E F

  edge set: (B,C) (B,F) (C,A) (C,C) (D,E) (E,D) (F,A)

  out-edges:
  A -->
  B --> C F
  C --> A C
  D --> E
  E --> D
  F --> A
]

Create the graph of Figure 2.

 enum { A, B, C, D, E, F, N };
 const char* name = "ABCDEF";

 typedef boost::adjacency_matrix&lt;boost::undirectedS> UGraph;
 UGraph ug(N);
 add_edge(B, C, ug);
 add_edge(B, F, ug);
 add_edge(C, A, ug);
 add_edge(D, E, ug);
 add_edge(F, A, ug);

 std::cout << "vertex set: ";
 boost::print_vertices(ug, name);
 std::cout << std::endl;

 std::cout << "edge set: ";
 boost::print_edges(ug, name);
 std::cout << std::endl;

 std::cout << "incident edges: " << std::endl;
 boost::print_graph(ug, name);
 std::cout << std::endl;

The output is:

[pre
  vertex set: A B C D E F

  edge set: (C,A) (C,B) (E,D) (F,A) (F,B)

  incident edges:
  A <--> C F
  B <--> C F
  C <--> A B
  D <--> E
  E <--> D
  F <--> A B
]

[endsect]

