|
2 | 2 | // This file is part of the CPP-GL project (https://github.com/SpectraL519/cpp-gl). |
3 | 3 | // Licensed under the MIT License. See the LICENSE file in the project root for full license information. |
4 | 4 |
|
| 5 | +/// @file gl/algorithm/topology/coloring.hpp |
| 6 | +/// @brief Algorithms for detecting and computing graph colorings. |
| 7 | + |
5 | 8 | #pragma once |
6 | 9 |
|
7 | 10 | #include "gl/algorithm/core.hpp" |
8 | 11 | #include "gl/algorithm/templates/bfs.hpp" |
9 | 12 |
|
10 | 13 | namespace gl::algorithm { |
11 | 14 |
|
| 15 | +/// @ingroup GL GL-Algorithm |
| 16 | +/// @brief Alias for a container mapping vertex indices to their calculated binary (bipartite) colors. |
12 | 17 | using bicoloring_type = std::vector<binary_color>; |
13 | 18 |
|
| 19 | +/// @ingroup GL GL-Algorithm |
| 20 | +/// @brief Attempts to compute a valid bipartite (2-color) coloring for the given graph. |
| 21 | +/// |
| 22 | +/// This algorithm utilizes the generic @ref gl::algorithm::bfs "bfs" template to traverse the graph and |
| 23 | +/// alternate colors between adjacent vertices. If an edge connects two vertices of the same color |
| 24 | +/// (indicating an odd-length cycle), the graph is not bipartite, and the search immediately aborts. |
| 25 | +/// |
| 26 | +/// ### Example Usage |
| 27 | +/// ```cpp |
| 28 | +/// if (auto coloring = gl::algorithm::bipartite_coloring(graph)) // (1)! |
| 29 | +/// gl::algorithm::apply_coloring(graph, *coloring); // (2)! |
| 30 | +/// else |
| 31 | +/// std::cout << "Graph contains an odd cycle and is not bipartite.\n"; |
| 32 | +/// ``` |
| 33 | +/// |
| 34 | +/// 1\. Attempts to find a valid 2-coloring for the graph. Returns `std::nullopt` if impossible. |
| 35 | +/// |
| 36 | +/// 2\. If successful, directly modifies the graph's internal vertex properties to store the colors. |
| 37 | +/// **NOTE:** This operation is only available if the property type of the graph's vertices satisfies [**c_binary_color_properties_type**](gl_concepts.md#gl-traits-c-binary-color-properties-type). |
| 38 | +/// |
| 39 | +/// > [!INFO] Algorithmic Complexity |
| 40 | +/// > |
| 41 | +/// > The time complexity depends entirely on the underlying representation of `GraphType`: |
| 42 | +/// > |
| 43 | +/// > - **Adjacency List Representations**: \f$O(|V| + |E|)\f$ |
| 44 | +/// > - *Includes:* @ref gl::impl::list_t "list_t" and @ref gl::impl::flat_list_t "flat_list_t". |
| 45 | +/// > |
| 46 | +/// > - **Dense Adjacency Matrix Representations**: \f$O(|V|^2)\f$ |
| 47 | +/// > - *Includes:* @ref gl::impl::matrix_t "matrix_t" and @ref gl::impl::flat_matrix_t "flat_matrix_t". |
| 48 | +/// > - *Note:* Iterating over adjacent vertices requires scanning the entire \f$|V|\f$-length matrix row. |
| 49 | +/// |
| 50 | +/// ### Template Parameters |
| 51 | +/// | Parameter | Description | |
| 52 | +/// | :-------- | :--- | |
| 53 | +/// | G | The type of the graph being traversed. | |
| 54 | +/// | PreVisitCallback | Type of the callable executed immediately before a vertex is officially visited. | |
| 55 | +/// | PostVisitCallback | Type of the callable executed after all adjacent edges of a vertex are evaluated. | |
| 56 | +/// |
| 57 | +/// @param graph The graph to evaluate. |
| 58 | +/// @param pre_visit Hook executed immediately before the internal visit logic. |
| 59 | +/// @param post_visit Hook executed after all adjacent edges of the current vertex have been enqueued. |
| 60 | +/// @return An `std::optional` containing the @ref gl::algorithm::bicoloring_type "bicoloring_type" map if the graph is bipartite. Returns `std::nullopt` otherwise. |
| 61 | +/// ### See Also |
| 62 | +/// - @ref gl::algorithm::is_bipartite "is_bipartite" |
| 63 | +/// - @ref gl::algorithm::apply_coloring "apply_coloring" |
14 | 64 | template < |
15 | 65 | traits::c_graph G, |
16 | 66 | traits::c_optional_callback<void, typename G::id_type> PreVisitCallback = empty_callback, |
@@ -64,10 +114,30 @@ template < |
64 | 114 | return coloring; |
65 | 115 | } |
66 | 116 |
|
| 117 | +/// @ingroup GL GL-Algorithm |
| 118 | +/// @brief Convenience wrapper for the @ref gl::algorithm::bipartite_coloring "bipartite_coloring" algorithm to check if a graph is bipartite without extracting the exact coloring map. |
| 119 | +/// @param graph The graph to evaluate. |
| 120 | +/// @return `true` if the graph is bipartite (2-colorable), `false` otherwise. |
| 121 | +/// @see @ref gl::algorithm::apply_coloring "apply_coloring" |
67 | 122 | [[nodiscard]] gl_attr_force_inline bool is_bipartite(const traits::c_graph auto& graph) { |
68 | 123 | return bipartite_coloring(graph).has_value(); |
69 | 124 | } |
70 | 125 |
|
| 126 | +/// @ingroup GL GL-Algorithm |
| 127 | +/// @brief Applies a computed range of binary colors to the property payload of each vertex in the graph. |
| 128 | +/// |
| 129 | +/// ### Template Parameters |
| 130 | +/// | Parameter | Description | |
| 131 | +/// | :-------- | :--- | |
| 132 | +/// | `G` | The type of the graph to modify. Must have compatible color properties. | |
| 133 | +/// | `ColorRange` | The type of the range containing the computed colors. | |
| 134 | +/// |
| 135 | +/// @param graph The mutable graph instance whose properties will be updated. |
| 136 | +/// @param color_range A sized range (e.g., @ref gl::algorithm::bicoloring_type "bicoloring_type") matching the vertex count. |
| 137 | +/// @return `true` if the coloring was successfully applied, `false` if the size of the range does not match the graph's vertex count. |
| 138 | +/// ### See Also |
| 139 | +/// - @ref gl::algorithm::bipartite_coloring "bipartite_coloring" |
| 140 | +/// - @ref gl::algorithm::is_bipartite "is_bipartite" |
71 | 141 | template <traits::c_graph G, traits::c_sized_range_of<binary_color> ColorRange> |
72 | 142 | requires(traits::c_binary_color_properties_type<typename G::vertex_properties_type>) |
73 | 143 | bool apply_coloring(G& graph, const ColorRange& color_range) { |
|
0 commit comments