Structural properties of graphs.
This module provides checks for various graph classes and regularities.
Algorithms
| Problem | Function | Complexity |
|---|---|---|
| Tree check | tree?/1 | O(V + E) |
| Arborescence check | arborescence?/1 | O(V + E) |
| Forest check | forest?/1 | O(V + E) |
| Branching check | branching?/1 | O(V + E) |
| Complete graph check | complete?/1 | O(V) |
| Regular graph check | regular?/2 | O(V) |
| Connected check | connected?/1 | O(V + E) |
| Strongly connected check | strongly_connected?/1 | O(V + E) |
| Weakly connected check | weakly_connected?/1 | O(V + E) |
| Chordal check | chordal?/1 | O(V + E) |
Key Concepts
- Tree: Connected acyclic undirected graph.
- Arborescence: Directed tree with a unique root.
- Complete Graph (Kn): Every pair of distinct vertices is connected by an edge.
- Regular Graph: Every vertex has the same degree k.
Structural Visualizations
Comparison of an undirected tree and a complete graph.
iex> alias Yog.Property.Structure
iex> tree = Yog.from_edges(:undirected, [{"T1", "T2", 1}, {"T1", "T3", 1}, {"T2", "T4", 1}, {"T2", "T5", 1}])
iex> Structure.tree?(tree)
true
iex> complete = Yog.from_edges(:undirected, [{"K1", "K2", 1}, {"K2", "K3", 1}, {"K3", "K1", 1}])
iex> Structure.complete?(complete)
trueArborescence Visualization
A directed tree with a unique root node.
iex> alias Yog.Property.Structure
iex> arb = Yog.from_edges(:directed, [{"R", "A", 1}, {"R", "B", 1}, {"A", "C", 1}, {"A", "D", 1}])
iex> Structure.arborescence?(arb)
true
iex> Structure.arborescence_root(arb)
"R"Examples
# Simple tree
iex> graph = Yog.undirected()
...> |> Yog.add_node(1, nil)
...> |> Yog.add_node(2, nil)
...> |> Yog.add_edge_ensure(1, 2, 1)
iex> Yog.Property.Structure.tree?(graph)
true
# Complete graph K3 (triangle)
iex> graph = Yog.undirected() |> Yog.add_node(1, nil) |> Yog.add_node(2, nil) |> Yog.add_node(3, nil)
...> |> Yog.add_edge_ensure(1, 2, 1) |> Yog.add_edge_ensure(2, 3, 1) |> Yog.add_edge_ensure(3, 1, 1)
iex> Yog.Property.Structure.complete?(graph)
true
Summary
Functions
Checks if the graph is an arborescence (directed tree with a single root).
Finds the root of an arborescence.
Checks if a directed graph is a branching (a directed forest).
Checks if the graph is chordal using Maximum Cardinality Search.
Checks if the graph is complete (every pair of distinct nodes is connected).
Checks if the graph is connected.
Checks if the graph is a forest (a loopless undirected graph consisting entirely of disjoint trees).
Returns the minimum degree of the graph.
Checks if the graph is k-regular (every node has degree exactly k).
Checks if a directed graph is strongly connected.
Checks if the graph is a tree (connected and acyclic). Works for undirected graphs.
Checks if a directed graph is weakly connected.
Functions
Checks if the graph is an arborescence (directed tree with a single root).
A directed graph is an arborescence iff:
- It has n nodes and n-1 edges
- Exactly one node has in-degree 0 (the root)
- All other nodes have in-degree >= 1
When edges = n-1 and there's exactly one root, reachability is guaranteed (no need for explicit BFS check).
@spec arborescence_root(Yog.graph()) :: Yog.node_id() | nil
Finds the root of an arborescence.
Checks if a directed graph is a branching (a directed forest).
Evaluates to true if every node has an in-degree of 1 or 0, and
the graph contains no directed cycles.
Examples
iex> branch = Yog.directed()
...> |> Yog.add_edge_ensure(1, 2, 1, nil)
...> |> Yog.add_edge_ensure(1, 3, 1, nil)
...> |> Yog.add_edge_ensure(4, 5, 1, nil)
iex> Yog.Property.Structure.branching?(branch)
true
Checks if the graph is chordal using Maximum Cardinality Search.
Checks if the graph is complete (every pair of distinct nodes is connected).
Checks if the graph is connected.
For undirected graphs, every node is reachable from every other node. For directed graphs, this checks for strong connectivity.
Checks if the graph is a forest (a loopless undirected graph consisting entirely of disjoint trees).
A disconnected graph with multiple trees evaluates to true.
Examples
iex> forest = Yog.undirected()
...> |> Yog.add_edge_ensure(1, 2, 1, nil)
...> |> Yog.add_edge_ensure(3, 4, 1, nil)
iex> Yog.Property.Structure.forest?(forest)
true
@spec minimum_degree(Yog.graph()) :: non_neg_integer()
Returns the minimum degree of the graph.
Isolated vertices have degree 0. Returns 0 for an empty graph.
Examples
iex> graph = Yog.from_edges(:undirected, [{1, 2, 1}, {2, 3, 1}])
iex> Yog.Property.Structure.minimum_degree(graph)
1
iex> empty = Yog.undirected()
iex> Yog.Property.Structure.minimum_degree(empty)
0
Checks if the graph is k-regular (every node has degree exactly k).
Checks if a directed graph is strongly connected.
Checks if the graph is a tree (connected and acyclic). Works for undirected graphs.
Time Complexity
O(V + E)
Checks if a directed graph is weakly connected.