Skip to main content

is_graphical

Function is_graphical 

Source
pub fn is_graphical(
    out_degrees: &[igraph_int_t],
    in_degrees: Option<&[igraph_int_t]>,
    allowed: impl Into<AllowedEdgeTypes>,
) -> Result<bool>
Expand description

Is there a graph with the given degree sequence?

For an undirected graph pass the degrees as out_degrees and in_degrees = None; for a directed graph pass both the out- and the in-degree sequences (of equal length). allowed says which edges the realization may use (anything convertible into AllowedEdgeTypes, e.g. EdgeTypeSw::Simple or AllowedEdgeTypes::ALL). Sequences with negative entries are simply not graphical.

The tests used are, for undirected graphs: the Erdős–Gallai conditions (Cloteaux’s linear-time algorithm) for simple graphs; an even degree sum when loops and multi-edges are allowed; additionally a degree sum at least twice the maximum degree for loopless multigraphs; Cairns–Mendan’s modified Erdős–Gallai conditions for at most one self-loop per vertex. For directed graphs: the Fulkerson–Chen–Anstee theorem with Berger’s relaxation for simple digraphs; equal in- and out-degree sums with loops and multi-edges; additionally an out-degree sum at least the maximum total degree for loopless multigraphs; the Gale–Ryser theorem when single self-loops are allowed.

Binds igraph_is_graphical. See also Graph::realize_degree_sequence, which builds a realization of a graphical sequence (for the edge types it implements: simple, loopless multi- and loopy multigraphs when undirected, simple digraphs when directed, it succeeds exactly when this test says yes; single self-loops without multi-edges, and non-simple digraphs, fail with ErrorKind::Unimplemented), and Graph::degree_sequence_game, which samples one at random.

Time complexity: O(n), n being the length of the sequence(s).

§Errors

ErrorKind::InvalidValue if the out- and in-degree sequences have different lengths, or if the sum of the (non-negative) degrees exceeds i64::MAX / 2: igraph would add them up with signed overflow, which is undefined behavior in C, so such sequences are rejected on the Rust side.

§Examples

use igraph::mixing::{is_graphical, AllowedEdgeTypes};
use igraph::prelude::*;

// (3, 3): two vertices of degree 3 need a triple edge or loops.
assert!(!is_graphical(&[3, 3], None, EdgeTypeSw::Simple)?);
assert!(is_graphical(&[3, 3], None, EdgeTypeSw::Multi)?);
assert!(is_graphical(&[3, 3], None, EdgeTypeSw::Loops)?);
// (1, 2, 5) needs multi-edges *and* loops.
assert!(!is_graphical(&[1, 2, 5], None, EdgeTypeSw::Multi)?);
assert!(is_graphical(&[1, 2, 5], None, AllowedEdgeTypes::ALL)?);
// Directed: a 3-cycle has out- and in-degrees all equal to 1.
assert!(is_graphical(&[1, 1, 1], Some(&[1, 1, 1]), EdgeTypeSw::Simple)?);
assert!(!is_graphical(&[2, 0], Some(&[0, 2]), EdgeTypeSw::Simple)?);

// A graphical sequence can be realized with the same edge types.
let seq = [3, 3, 2, 2, 2, 1, 1];
assert!(is_graphical(&seq, None, AllowedEdgeTypes::SIMPLE)?);
let g = Graph::realize_degree_sequence(
    &seq, None, AllowedEdgeTypes::SIMPLE, RealizeDegseq::Smallest)?;
assert_eq!(g.degree(.., NeighborMode::All, Loops::Twice)?, seq);