Commit dcece27
authored
Adding edge coloring algorithm for bipartite graphs (#1026)
### Summary
This PR adds a graph edge-coloring algorithm ``graph_bipartite_edge_color`` for **bipartite** graphs based on the paper "A simple algorithm for edge-coloring bipartite multigraphs" by Noga Alon, 2003.
The above function first checks whether the graph is indeed bipartite, and raises an exception of type ``GraphNotBipartite`` if this is not the case. Otherwise, the function edge-colors the graph and returns a dictionary with key being the edge index and value being the assigned color. This is the same output format as produced by other recently added edge-coloring functions ``graph_greedy_edge_color`` and ``graph_misra_gries_edge_color``. The algorithm uses exactly `d` colors when `d` is the maximum degree of a node in the graph.
Usage example:
```
import rustworkx as rx
graph = rx.generators.heavy_hex_graph(9)
edge_colors = rx.graph_bipartite_edge_color(graph)
num_colors = max(edge_colors.values()) + 1
assert num_colors == 3
```
The algorithm has a runtime of `O(m log m)` where `m` is the number of edges in the graph.
### A few technical details:
Internally this works with an undirected regular bipartite multigraph that
- keeps an explicit partition of its nodes into "left nodes" and "right nodes"
- only the edges connecting a left node to a right node are allowed (this is what _bipartite_ means)
- each node in the graph has the same degree `r` (this is what _regular_ means)
- each edge keeps additional data representing its _multiplicity_ (aka _weight_) and whether or not the edge is _bad_ (it is important that multiple edges connecting the same pairs of nodes are grouped into a single edges with multiplicity)
The internal data structure for the above is called `RegularBipartiteMultiGraph`. I don't foresee it being used anywhere outside of this PR, and so it's not marked as ``pub``.
There is one possible optimization that is mentioned in the paper but which I have not implemented. Let `r` be the maximum degree of a node in the original graph. If the original bipartite graph is not regular (i.e. some of its nodes have degree less than `r`), then extra vertices and edges are inserted to make it regular (and of degree `r`) with the final edge-coloring is obtained by restricting the edge-coloring of the multi-graph to original edges. In addition (this is the mentioned possible optimization), one could group multiple "left" vertices with total degree not exceeding `r` into a _single_ node in the multigraph; the same applies for subsets of right vertices.
The implementation also contains a function ``euler_cycles`` that might be useful in general, however the flavor needed here is somewhat non-standard, and so I did not expose it. The standard definition assumes that the graph is connected and an _Euler cycle_ is a path that visits each edge exactly once and comes back to the starting vertex. In our case, however, the graph may be disconnected and the function ``euler_cycles`` returns a list of Euler cycles that visit each edge exactly once (however this is not an Euler cycle for the standard definition).
* very messy initial implementation
* adding random_bipartite_graph and some tests
* tests
* fix correctness checking functions
* imports in test module
* starting cleanup
* minor
* cleaning pass
* fmt
* fix for empty graphs
* python tests + fmt
* release notes
* first round of clippy
* clippy
* minor
* pylint
* fmt
* renaming
* more renaming
* api docs
* release notes fix
* correct release notes fix
* yet another fix
* Add Python type annotation to stub files
* Fix stubs
* adding python interface for creating random bipartite graphs, both directed and undirected
* stubs
* updating runtime complexity to include the number of nodes
* derive(Clone)
* panic! -> unreachable!
* making bipartite_edge_color_with_partitions non-public, cleaning and polishing tests1 parent e39ecc6 commit dcece27
File tree
14 files changed
+1573
-1
lines changed- docs/source/api
- algorithm_functions
- releasenotes/notes
- rustworkx-core/src
- generators
- rustworkx
- src
- tests
- graph
14 files changed
+1573
-1
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
10 | 11 | | |
11 | 12 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| 16 | + | |
| 17 | + | |
Lines changed: 42 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
0 commit comments