@@ -769,3 +769,148 @@ \section{Using Existing Data Structures}
769769Useful defaults have been created using types and containers in the standard library, with the ability
770770to override them for external data structures. This is described in more detail in the paper for Graph Library
771771Containers.
772+
773+ \subsection {Recognized Vertex Patterns }
774+
775+ When a graph type \tcode {G} is itself a \tcode {forward_range} whose elements are also ranges, the
776+ GCI CPOs can detect and adapt to the storage strategy automatically. Two broad categories of vertex
777+ container are recognized, each producing a different descriptor and vertex-id strategy.
778+
779+ \subsubsection {Random-Access Vertex Pattern }
780+ When \tcode {G} satisfies \tcode {random_access_range} and its elements satisfy \tcode {forward_range},
781+ the vertices are assumed to reside in a contiguous or random-access container such as
782+ \tcode {std::vector} or \tcode {std::deque}.
783+
784+ \begin {itemize }
785+ \item \tcode {vertex_id_t<G>} defaults to an integral type (index into the range).
786+ \item \tcode {find_vertex(g, uid)} uses indexed access: \tcode {begin(vertices(g)) + uid},
787+ giving $ \mathcal {O}(1 )$ lookup.
788+ \item \tcode {out_edges(g, u)} returns the inner range at that index.
789+ \end {itemize }
790+
791+ Examples of standard containers matching this pattern:
792+ \begin {itemize }
793+ \item \tcode {vector<vector<int>>} --- vertices in a \tcode {vector}, edges as \tcode {int} target ids.
794+ \item \tcode {vector<list<pair<int,double>>>} --- vertices in a \tcode {vector}, edges as weighted pairs in a \tcode {list}.
795+ \item \tcode {deque<forward_list<int>>} --- vertices in a \tcode {deque}, edges in a \tcode {forward_list}.
796+ \end {itemize }
797+
798+ \subsubsection {Associative Vertex Pattern }
799+ When \tcode {G} is an associative container (\tcode {std::map} or \tcode {std::unordered_map})
800+ whose mapped values are forward ranges, vertices are keyed by an arbitrary id type rather than
801+ a dense index.
802+
803+ \begin {itemize }
804+ \item \tcode {vertex_id_t<G>} defaults to the \tcode {key_type} of the container.
805+ \item \tcode {find_vertex(g, uid)} uses \tcode {g.find(uid)}, giving
806+ $ \mathcal {O}(\log |V|)$ for \tcode {map} or amortized $ \mathcal {O}(1 )$ for
807+ \tcode {unordered_map}.
808+ \item \tcode {out_edges(g, u)} extracts the \tcode {.second} member (the mapped edge
809+ range) from the key-value pair.
810+ \end {itemize }
811+
812+ Examples of standard containers matching this pattern:
813+ \begin {itemize }
814+ \item \tcode {map<int, vector<int>>} --- sparse vertex ids in a sorted \tcode {map}, edges as target ids.
815+ \item \tcode {unordered_map<int, vector<pair<int,double>>>} --- hash-based vertex lookup, weighted edges.
816+ \end {itemize }
817+
818+ \subsubsection {Edge Container Patterns }
819+ The edge range returned by \tcode {out_edges(g, u)} is the inner range stored at (or
820+ referenced by) each vertex. Any standard container satisfying \tcode {forward_range}
821+ whose element type matches a recognized edge element pattern (described below) is
822+ accepted automatically. The library does \emph {not } maintain a fixed list of containers;
823+ it relies on concept-based detection.
824+
825+ Table~\ref {tab:edge_container_patterns } groups the standard containers by category and
826+ summarises their trade-offs when used as edge containers.
827+
828+ \begin {table }[h!]
829+ \begin {center }
830+ \resizebox {\textwidth }{!}
831+ {\begin {tabular }{l l L{7.5cm}}
832+ \hline
833+ \textbf {Category } & \textbf {Container } & \textbf {Characteristics } \\
834+ \hline
835+ Sequence &
836+ \tcode {vector<E>} &
837+ Random-access, cache-friendly, amortized $ \mathcal {O}(1 )$ push-back. \\
838+ &
839+ \tcode {deque<E>} &
840+ Random-access, stable references on push-back. \\
841+ &
842+ \tcode {list<E>} &
843+ Bidirectional, $ \mathcal {O}(1 )$ splice, stable iterators. \\
844+ &
845+ \tcode {forward_list<E>} &
846+ Forward-only, minimal overhead, $ \mathcal {O}(1 )$ push-front. \\
847+ \hdashline
848+ Ordered associative &
849+ \tcode {set<E>} &
850+ Sorted, automatic deduplication, $ \mathcal {O}(\log n)$ lookup; element is the edge itself. \\
851+ &
852+ \tcode {map<VId, EV>} &
853+ Sorted by target id, $ \mathcal {O}(\log n)$ lookup, no parallel edges; \tcode {.first} is
854+ target id, \tcode {.second} is edge value. \\
855+ \hdashline
856+ Unordered associative &
857+ \tcode {unordered_set<E>} &
858+ Hash-based deduplication, amortized $ \mathcal {O}(1 )$ insert/lookup. \\
859+ &
860+ \tcode {unordered_map<VId, EV>} &
861+ Hash-based by target id, amortized $ \mathcal {O}(1 )$ lookup, no parallel edges;
862+ \tcode {.first} is target id, \tcode {.second} is edge value. \\
863+ \hline
864+ \end {tabular }}
865+ \caption {Recognized Edge Container Patterns}
866+ \label {tab:edge_container_patterns }
867+ \end {center }
868+ \end {table }
869+
870+ For associative containers whose \tcode {value_type} is a \tcode {pair<const Key, Mapped>}
871+ (i.e.\ \tcode {map} and \tcode {unordered_map}), the key is
872+ treated as the target vertex id and the mapped type as the edge value. This means that
873+ \tcode {target_id(g,uv)} returns \tcode {.first} and \tcode {edge_value(g,uv)} returns
874+ \tcode {.second}, following the same pair convention described below.
875+
876+ For set-like containers (\tcode {set}, \tcode {unordered_set}), each element is the edge
877+ itself. If the element is integral it serves as the target id directly; if it is a
878+ \tcode {pair} or \tcode {tuple} the element-level rules below apply.
879+
880+ \subsubsection {Edge Element Patterns }
881+ Within each vertex's edge range the GCI recognizes the following element forms and
882+ automatically provides \tcode {target_id(g,uv)} and, where applicable,
883+ \tcode {edge_value(g,uv)}:
884+
885+ \begin {table }[h!]
886+ \begin {center }
887+ {\begin {tabular }{l L{8.5cm}}
888+ \hline
889+ \textbf {Edge Element Type } & \textbf {Automatic CPOs } \\
890+ \hline
891+ \tcode {integral} & \tcode {target_id(g,uv)} returns the value directly.
892+ No \tcode {edge_value}. \\
893+ \tcode {pair<integral, EV>} & \tcode {target_id(g,uv)} returns \tcode {.first};
894+ \tcode {edge_value(g,uv)} returns \tcode {.second}. \\
895+ \tcode {tuple<integral, ...>} & \tcode {target_id(g,uv)} returns \tcode {get<0>(uv)};
896+ remaining elements accessible via \tcode {edge_value}. \\
897+ custom struct &
898+ The user overrides \tcode {target_id(g,uv)} and optionally
899+ \tcode {edge_value(g,uv)} for the type. \\
900+ \hline
901+ \end {tabular }}
902+ \caption {Recognized Edge Element Patterns}
903+ \label {tab:edge_element_patterns }
904+ \end {center }
905+ \end {table }
906+
907+ \noindent
908+ These vertex and edge patterns combine freely: any recognized vertex container can hold
909+ any recognized edge container, and any recognized edge container can hold any recognized
910+ edge element type. For example,
911+ \tcode {vector<vector<pair<int,double>>>} is a random-access graph with weighted edges,
912+ \tcode {vector<set<int>>} is a random-access graph with sorted deduplicated unweighted edges,
913+ \tcode {vector<map<int,double>>} is a random-access graph with $ \mathcal {O}(\log n)$ edge lookup by target,
914+ and \tcode {map<string, list<int>>} is an associative graph with unweighted edges.
915+ When the element type does not match a recognized pattern, the user must override the
916+ appropriate CPOs for the graph type.
0 commit comments