Skip to content

Commit 5afec4f

Browse files
committed
hgl quick start page
1 parent 805d242 commit 5afec4f

3 files changed

Lines changed: 94 additions & 2 deletions

File tree

docs/gl/quick_start.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ Path: 0 -> 2 -> 3 -> 1 -> 4
7171
### Understanding the Code
7272

7373
- **Traits (`gl::list_graph_traits`):** CPP-GL relies heavily on template abstraction. Instead of passing multiple arguments to the `gl::graph` constructor, you pass a single *Traits* struct as its template parameter. This strictly dictates whether the graph uses an adjacency list or matrix, if it is directed, what custom properties (like `gl::weight_property`) exist on its elements and what id type is used for its elements.
74+
7475
- **Property Access (`->weight`):** Adding an edge returns a descriptor handle. You access the specific payload fields associated with that edge by using the overloaded `->` operator, ensuring highly performant and type-safe data manipulation.
76+
7577
- **Algorithm Separation:** Search engines and algorithms (like `dijkstra_shortest_paths`) exist entirely outside the graph class. They accept the graph as a `const` reference, mathematically guaranteeing that algorithms will never accidentally mutate your topology.
78+
7679
- **Formatting (`gl::io::range_formatter`):** The library includes lightweight utility formatters so you can easily stream sequences, paths, and standard ranges directly to the console with complete control over delimiters and brackets.

docs/hgl/quick_start.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,90 @@
11
# Quick Start
2+
3+
This guide provides a rapid introduction to the **HGL** (Hypergraph) module. In just a few minutes, you will define a hypergraph, populate it with vertices and weighted hyperedges, and run a Breadth-First B-Search (B-BFS) algorithm to evaluate reachability across its generalized graph topology.
4+
5+
## Basic Usage Example
6+
7+
The following C++ program demonstrates the standard workflow of the CPP-GL hypergraph library:
8+
9+
1. **Defining Traits:** Selecting the directionality model, memory layout, and payload types.
10+
2. **Building Topology:** Adding vertices and defining hyperedges that map sets of tail vertices to sets of head vertices.
11+
3. **Execution:** Running a decoupled B-reachability traversal algorithm.
12+
4. **Reconstruction & Output:** Querying the resulting search tree and formatting the hypergraph natively to the standard output.
13+
14+
```cpp
15+
#include <hgl/hypergraph.hpp> // (1)!
16+
#include <hgl/algorithm/traversal/backward_search.hpp>
17+
#include <hgl/io/core.hpp>
18+
19+
#include <iostream>
20+
#include <vector>
21+
22+
int main() {
23+
using traits_t = hgl::hypergraph_traits< // (2)!
24+
hgl::bf_directed_t,
25+
gl::name_property,
26+
gl::weight_property<double>,
27+
hgl::impl::list_t<hgl::impl::bidirectional_t>>;
28+
29+
hgl::hypergraph<traits_t> hg(4); // (3)!
30+
31+
auto v0 = hg.vertex(0); v0->name = "Source"; // (4)!
32+
auto v1 = hg.vertex(1); v1->name = "Router A";
33+
auto v2 = hg.vertex(2); v2->name = "Router B";
34+
auto v3 = hg.vertex(3); v3->name = "Target";
35+
36+
hg.add_hyperedge({0}, {1, 2})->weight = 10.5; // (5)!
37+
hg.add_hyperedge({v1, v2}, {v3})->weight = 5.0;
38+
39+
std::vector<hgl::default_id_type> roots = {0u};
40+
auto search_tree = hgl::algorithm::backward_bfs(hg, roots); // (7)!
41+
42+
if (hgl::algorithm::is_reachable(search_tree, 3u)) // (8)!
43+
std::cout << "Target is B-reachable from the Source.\n\n";
44+
else
45+
std::cout << "Target is NOT B-reachable from the Source.\n\n";
46+
47+
std::cout << hgl::io::verbose << hgl::io::with_properties; // (9)!
48+
std::cout << "Hypergraph Topology:\n" << hg << '\n';
49+
50+
return 0;
51+
}
52+
```
53+
54+
1. Include the necessary core hypergraph, algorithm, and I/O headers.
55+
2. Define the hypergraph's memory layout (bidirectional incidence list), directionality, and element payloads via a single traits structure. <br/> **NOTE:** Alternatively, you can use one of the provided [generic hypergraph type aliases](../cpp-gl/group__HGL-Core.md#public-types).
56+
3. Instantiate the generic `hypergraph` class, pre-allocating it with 4 vertices (IDs 0 through 3), using the defined traits.
57+
4. Retrieve stable vertex descriptors using `.vertex(id)` to assign property payloads safely.
58+
5. BF-directed hyperedges connect a set of *tail* vertices to a set of *head* vertices. An edge can be added using vertex IDs or descriptors. <br/> **NOTE:** You can alternatively instantiate the hypergraph with a given number of hyperedges and simply *bind* vertices to them using the dedicated binding methods. <br/> **IMPORTANT:** Property Access Safety <br/> Assigning properties inline via the returned descriptor is safe here because the temporary descriptor is immediately discarded, meaning no dangling references are kept. The same bahaviour can be achieved using the `add_hyperedge_with` methods.
59+
6. Execute a Breadth-First Backward Search (B-BFS) to compute B-reachability semantics from the source vertex.
60+
7. Query the resulting search tree to validate if the Target vertex was successfully reached.
61+
8. Standard GL stream manipulators inject persistent formatting state to output the hypergraph's structure in a verbose format, including the element properties.
62+
63+
**Output:**
64+
65+
```text
66+
Target is B-reachable from the Source.
67+
68+
Hypergraph Topology:
69+
type: BF-directed, |V| = 4, |E| = 2
70+
vertices:
71+
- [id: 0 | "Source"]
72+
- [id: 1 | "Router A"]
73+
- [id: 2 | "Router B"]
74+
- [id: 3 | "Target"]
75+
hyperedges:
76+
- [id: 0 | tail: {0}, head: {1, 2} | 10.5]
77+
- [id: 1 | tail: {1, 2}, head: {3} | 5]
78+
```
79+
80+
## Understanding the Code
81+
82+
- **Generic Traits:** Similar to the standard GL module, the HGL module relies entirely on template abstraction. By passing a [**hgl::hypergraph_traits**](../cpp-gl/structhgl_1_1hypergraph__traits.md) struct to the [**hgl::hypergraph**](../cpp-gl/classhgl_1_1hypergraph.md) constructor, you dictate whether the hypergraph is undirected or BF-directed ([**hgl::bf_directed_t**](../cpp-gl/structhgl_1_1bf__directed__t.md)), what custom properties exist on vertices and hyperedges, and which underlying memory architecture it utilizes (e.g., [**hgl::impl::list_t**](../cpp-gl/structhgl_1_1impl_1_1list__t.md)).
83+
84+
- **Generalized Incidence:** Unlike standard graphs where an edge connects exactly two vertices, hyperedges connect sets of vertices of arbitrary sizes. In a BF-directed hypergraph, `add_hyperedge` accepts an iterable range of *tail* (source) vertices and *head* (destination) vertices and represents a single connection from all tail vertices to all head vertices simultaneously.
85+
86+
- **Property Access:** Because the internal memory can shift during insertion, it is best practice to pre-allocate memory for vertices and hyperedges in the hypergraph's constructor and then fetch them using accessors like `.vertex(id)`. However, you access specific payload fields directly, e.g. through the overloaded `->` operator on the returned descriptor.
87+
88+
- **Algorithm Separation:** Algorithms exist entirely outside the hypergraph class. In this example, [**hgl::algorithm::backward_bfs**](../cpp-gl/group__HGL-Algorithm.md#function-backward_bfs) applies strict B-reachability rules: a hyperedge is only fully traversed (and its head vertices discovered) if all of its tail vertices have already been visited. The [**hgl::algorithm::is_reachable**](../cpp-gl/group__HGL-Algorithm.md#function-is_reachable) utility then checks the resulting search tree to evaluate whether the Target vertex is B-reachable in the defined hypergraph in $O(1)$ time.
89+
90+
- **Formatting:** The HGL module provides custom stream manipulators (e.g. [**hgl::io::verbose**](../cpp-gl/group__HGL-IO.md#variable-verbose), [**hgl::io::with_properties**](../cpp-gl/group__HGL-IO.md#variable-with_properties)) allowing you to effortlessly format or serialize the complex topology and payloads straight to `std::cout` or other I/O streams.

include/hgl/impl/impl_tags.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace hgl::impl {
2323
/// ### Layout Implications
2424
/// The chosen layout significantly impacts memory usage and query performance:
2525
///
26-
/// - @ref hgl::impl::bidirectional_t "bidirectional_t" (Default): Maintains two internal lists (vertex-to-hyperedges and hyperedge-to-vertices). Provides optimal $O(1)$ degree/size lookups and fast traversals in both directions at the cost of doubled memory consumption.
26+
/// - @ref hgl::impl::bidirectional_t "bidirectional_t" (Default): Maintains two internal lists (vertex-to-hyperedges and hyperedge-to-vertices). Provides optimal \f$O(1)\f$ degree/size lookups and fast traversals in both directions at the cost of doubled memory consumption.
2727
/// - @ref hgl::impl::vertex_major_t "vertex_major_t": Maintains only a vertex-to-hyperedges list. Highly memory efficient and fast for querying vertex degrees or incident hyperedge sets, but querying hyperedge sizes or incident vertex setss requires expensive full-hypergraph scans.
2828
/// - @ref hgl::impl::hyperedge_major_t "hyperedge_major_t": Maintains only a hyperedge-to-vertices list. Memory efficient and fast for hyperedge-centric queries, but querying vertex degrees or incident hyperedge sets requires full-hypergraph scans.
2929
///
@@ -52,7 +52,7 @@ struct list_t {
5252
/// ### Layout Implications
5353
/// The chosen layout significantly impacts memory usage and query performance:
5454
///
55-
/// - @ref hgl::impl::bidirectional_t "bidirectional_t" (Default): Maintains two internal flattened lists (vertex-to-hyperedges and hyperedge-to-vertices). Provides optimal $O(1)$ degree/size lookups and fast traversals in both directions at the cost of doubled memory consumption.
55+
/// - @ref hgl::impl::bidirectional_t "bidirectional_t" (Default): Maintains two internal flattened lists (vertex-to-hyperedges and hyperedge-to-vertices). Provides optimal \f$O(1)\f$ degree/size lookups and fast traversals in both directions at the cost of doubled memory consumption.
5656
/// - @ref hgl::impl::vertex_major_t "vertex_major_t": Maintains only a vertex-to-hyperedges flattened list. Highly memory efficient and fast for querying vertex degrees or incident hyperedge sets, but querying hyperedge sizes or incident vertex sets requires expensive full-graph scans.
5757
/// - @ref hgl::impl::hyperedge_major_t "hyperedge_major_t": Maintains only a hyperedge-to-vertices flattened list. Memory efficient and fast for hyperedge-centric queries, but querying vertex degrees or incident hyperedge sets requires full-graph scans.
5858
///

0 commit comments

Comments
 (0)