graphcoloring is a collection of graph coloring algorithms for coloring vertices of a graph such that no two adjacent vertices share the same color. The algorithms are included via the embedded ‘GraphColoring’ C++ library, https://github.com/brrcrites/GraphColoring. The package provide two sets of functions, color_* and graph_coloring_*, which operate on a tidygraph and adjavency lists respectively. Both sets of functions covers all algorithms found in the C++ GraphColoring library.

Algorithms

Here is the list of algorithms found in graphcoloring package:

  • graph_coloring_dsatur
  • graph_coloring_hybrid_dsatur_tabucol
  • graph_coloring_hybrid_lmxrlf_tabucol
  • graph_coloring_lmxrlf
  • graph_coloring_msc
  • graph_coloring_tabucol

Coloring a tidygraph

tidygraph is a powerful abstraction for graph datasets. It envisions a graph as two tidy tables, nodes and edges, and provides ways to activate either set and apply dplyr verbs for manipulation.

color_* functions operate under tidygraph family and can be used to color nodes within mutate context similar to group_* functions in tidygraph. They automatically use the graph that is being computed on, and otherwise passes on its arguments to the relevant coloring function. The return value is always a integer vector of assigned color index so that neighboring nodes never share the same color.

library(graphcoloring)
library(tidygraph)
library(ggraph)

set.seed(42)

play_islands(5, 10, 0.8, 3) %>%
  mutate(color = as.factor(color_dsatur())) %>%
  ggraph(., layout = 'kk') +
  geom_edge_link(aes(alpha = ..index..), show.legend = FALSE) +
  geom_node_point(aes(color = color), size = 7) +
  theme_graph()

Working with Adjacency List

graph_coloring_* functions directly take adjacency lists and returns an integer vector of assigned labels.

Here is a 3-coloring of the famous Petersen Graph:

One common use case for graph coloring is to visualize geographical dataset to color contiguous groupings. For example, this can be used with sf::st_intersects() to color a feature collection for visualization.

Here we look at Bureau of Economic Analysis regions which group US states into 8 regions:

It might be better to choose an 8-color palette in this case but graph coloring can be particularly useful when the number of colors get exceedingly big.

Other Applications

Graph coloring is commonly used in Scheduling and Register Allocation. It can also be used to solve Sudoku puzzles!

A Sudoku puzzle plays on a 9x9 grid where some entries are pre-filled with numbers from 1 to 9. The goal is the fill the entire grid with 1 to 9 such that:

  1. Numbers in each row is not repeated
  2. Numbers in each columns is not repeated
  3. Numbers in each of 3x3 box/block/subgrid is not repeated

A Sudoku puzzle can be converted into a graph by modeling the 9x9 cells into 81 vertices where a pair of vertices are connected if and only if they are on the same row, column, or 3x3 block. Each valid Sudoku solution is therefore a 9-coloring of the Sudoku graph.

generate_sudoku <- function(n, seed) {
  set.seed(seed)
  
  sudoku_graph(n) %>%
    mutate(color = as.factor(color_tabucol(4))) %>%
    ggraph(., layout = "grid") +
    geom_edge_link() +
    geom_node_point(aes(color = color), size = 7, show.legend = TRUE) +
    theme_graph() +
    theme(legend.position = "bottom")
}

generate_sudoku(2, 432)
generate_sudoku(2, 45)