Documentation

CslibFrontier.Algorithms.Lean.Kruskal.SimpleGraph

SimpleGraph Bridge for Kruskal's Algorithm #

This module connects the multigraph and DisjointSet.Partition formulation of Kruskal's algorithm in CslibFrontier.Algorithms.Lean.Kruskal.Basic to Mathlib's SimpleGraph, SimpleGraph.IsAcyclic, maximal acyclic subgraphs (Maximal (fun H => H ≤ G ∧ H.IsAcyclic)), and SimpleGraph.IsTree.

Main definitions #

Main results #

Cost model and limitations #

kruskalGraphM G w := kruskalM (graphEdges G w) charges only the List.mergeSortM weight comparisons (Cost.comparisons) and post-initialization DisjointSet.UnionFind forest steps (Cost.ufSteps) performed on the extracted m-edge list. The pure graphEdges G w enumeration pass (which inspects all n² ordered pairs in List.finRange n, evaluating decide (G.Adj u v) and w s(u, v) on matching edges) and DisjointSet.UnionFind.init n (O(n) initialization) carry 0 TimeM Cost charge; callers that already hold an explicit edge list should invoke kruskalM directly.

References #

Edge-list projection to SimpleGraph (Fin n) #

Unordered endpoint pair s(e.u, e.v) of a weighted edge.

Instances For

    Simple graph on Fin n spanned by es (discarding self-loops and collapsing parallel edges).

    Instances For
      theorem Cslib.Algorithms.Lean.Kruskal.toSimpleGraph_append {n : ℕ} {W : Type} (es₁ es₂ : List (WeightedEdge n W)) :
      toSimpleGraph (es₁ ++ es₂) = toSimpleGraph es₁ ⊔ toSimpleGraph es₂
      theorem Cslib.Algorithms.Lean.Kruskal.Perm.toSimpleGraph_eq {n : ℕ} {W : Type} {es₁ es₂ : List (WeightedEdge n W)} (h : es₁.Perm es₂) :

      Permuting an edge list preserves toSimpleGraph.

      theorem Cslib.Algorithms.Lean.Kruskal.Subperm.toSimpleGraph_le {n : ℕ} {W : Type} {es₁ es₂ : List (WeightedEdge n W)} (h : es₁.Subperm es₂) :

      A sub-multiset (Subperm) spans a subgraph.

      Reachability, connectedness, and acyclicity correspondence #

      Exact correspondence between partition equivalence in edgePartition es and walk reachability in toSimpleGraph es.

      Two edge lists induce the same edgePartition iff their simple graphs have the same Reachable relation.

      edgePartition es has a single connected component iff toSimpleGraph es is Connected (including the empty-graph boundary n = 0, where both sides are false).

      Exact equivalence between edge-list acyclicity IsAcyclic F and simple-graph acyclicity (toSimpleGraph F).IsAcyclic without parallel edges or self-loops.

      When es has no self-loops, (toSimpleGraph es).edgeFinset is (es.map sym2).toFinset.

      An acyclic edge list F has (toSimpleGraph F).edgeFinset.card = F.length.

      theorem Cslib.Algorithms.Lean.Kruskal.IsAcyclic.sum_edgeFinset_toSimpleGraph {n : ℕ} {W : Type} [AddCommMonoid W] {F : List (WeightedEdge n W)} (hF : IsAcyclic F) (w : Sym2 (Fin n) → W) (hw : ∀ e ∈ F, e.weight = w e.sym2) :
      ∑ z ∈ (toSimpleGraph F).edgeFinset, w z = totalWeight F

      When F is acyclic and every edge in F carries weight w e.sym2, totalWeight F equals ∑ z ∈ (toSimpleGraph F).edgeFinset, w z.

      Every IsSpanningForest es F projects to a Mathlib maximal acyclic subgraph of toSimpleGraph es.

      toSimpleGraph (kruskalEdges es) is a maximal acyclic subgraph of toSimpleGraph es.

      When toSimpleGraph es is connected, toSimpleGraph (kruskalEdges es) is a SimpleGraph.IsTree with (kruskalEdges es).length + 1 = n.

      Canonical Kruskal runner on weighted SimpleGraph (Fin n) #

      Canonical computable enumeration of the undirected edges of G : SimpleGraph (Fin n): pairs (u, v) with u < v and G.Adj u v, weighted by w s(u, v). Each undirected edge in G.edgeFinset appears once.

      Instances For
        theorem Cslib.Algorithms.Lean.Kruskal.mem_graphEdges {n : ℕ} {W : Type} (G : SimpleGraph (Fin n)) [DecidableRel G.Adj] (w : Sym2 (Fin n) → W) (e : WeightedEdge n W) :
        e ∈ graphEdges G w ↔ e.u < e.v ∧ G.Adj e.u e.v ∧ e.weight = w s(e.u, e.v)

        Exact membership predicate for graphEdges G w.

        (graphEdges G w) contains no duplicate edges.

        Unordered endpoint pairs in graphEdges G w have no duplicates.

        s(x, y) appears in (graphEdges G w).map sym2 iff G.Adj x y.

        @[simp]

        toSimpleGraph (graphEdges G w) recovers G exactly.

        G.edgeFinset agrees with ((graphEdges G w).map sym2).toFinset for any Fintype G.edgeSet instance.

        @[simp]

        (graphEdges G w) has length G.edgeFinset.card.

        theorem Cslib.Algorithms.Lean.Kruskal.graphEdges_subperm_of_le {n : ℕ} {W : Type} {F G : SimpleGraph (Fin n)} [DecidableRel F.Adj] [DecidableRel G.Adj] (hle : F ≤ G) (w : Sym2 (Fin n) → W) :

        If F ≤ G, graphEdges F w is a sub-multiset of graphEdges G w.

        For any subgraph F, totalWeight (graphEdges F w) equals ∑ e ∈ F.edgeFinset, w e.

        Every Mathlib maximal acyclic subgraph F of G corresponds to an IsSpanningForest of graphEdges G w.

        Pure Kruskal runner on a weighted SimpleGraph (Fin n).

        Instances For

          toSimpleGraph (kruskalGraph G w) is a Mathlib maximal acyclic subgraph (spanning forest) of G.

          The edge-finset weight sum of toSimpleGraph (kruskalGraph G w) equals totalWeight (kruskalGraph G w).

          Simple-graph Kruskal spanning-forest optimality (generalizing Cormen et al., Section 23.2, MST-KRUSKAL, p. 631 from connected real-weighted graphs to arbitrary finite simple graphs over [AddCommMonoid W] [LinearOrder W] [IsOrderedAddMonoid W]): toSimpleGraph (kruskalGraph G w) minimizes ∑ e ∈ F.edgeFinset, w e over all Mathlib spanning forests F of G (without requiring DecidableRel F.Adj on competing subgraphs F).

          When G is connected, toSimpleGraph (kruskalGraph G w) is a SimpleGraph.IsTree with n - 1 edges ((kruskalGraph G w).length + 1 = n).

          theorem Cslib.Algorithms.Lean.Kruskal.sum_edgeFinset_kruskalGraph_le_of_isTree {n : ℕ} {W : Type} [AddCommMonoid W] [LinearOrder W] [IsOrderedAddMonoid W] {G : SimpleGraph (Fin n)} [DecidableRel G.Adj] (hconn : G.Connected) (w : Sym2 (Fin n) → W) (T : SimpleGraph (Fin n)) [Fintype ↑T.edgeSet] (hle : T ≤ G) (hT : T.IsTree) :
          ∑ z ∈ (toSimpleGraph (kruskalGraph G w)).edgeFinset, w z ≤ ∑ z ∈ T.edgeFinset, w z

          Simple-graph Kruskal minimum spanning tree optimality (Cormen et al., Section 23.2, p. 631): on a connected graph G, toSimpleGraph (kruskalGraph G w) minimizes ∑ e ∈ T.edgeFinset, w e over all spanning trees T ≤ G.

          theorem Cslib.Algorithms.Lean.Kruskal.eq_toSimpleGraph_kruskalGraph_of_injOn {n : ℕ} {W : Type} [AddCancelCommMonoid W] [LinearOrder W] [IsOrderedCancelAddMonoid W] (G : SimpleGraph (Fin n)) [DecidableRel G.Adj] (w : Sym2 (Fin n) → W) (hinj : Set.InjOn w G.edgeSet) {F : SimpleGraph (Fin n)} [Fintype ↑F.edgeSet] (hF : Maximal (fun (H : SimpleGraph (Fin n)) => H ≤ G ∧ H.IsAcyclic) F) (hopt : ∑ z ∈ F.edgeFinset, w z ≤ ∑ z ∈ (toSimpleGraph (kruskalGraph G w)).edgeFinset, w z) :

          Distinct-weight uniqueness on simple graphs (generalizing Kruskal, Opening paragraph, Construction A, and uniqueness proof, pp. 48–50): when w is injective on G.edgeSet, any minimum-weight spanning forest F of G is equal as a SimpleGraph (Fin n) to toSimpleGraph (kruskalGraph G w).

          theorem Cslib.Algorithms.Lean.Kruskal.eq_toSimpleGraph_kruskalGraph_of_isTree_of_injOn {n : ℕ} {W : Type} [AddCancelCommMonoid W] [LinearOrder W] [IsOrderedCancelAddMonoid W] {G : SimpleGraph (Fin n)} [DecidableRel G.Adj] (hconn : G.Connected) (w : Sym2 (Fin n) → W) (hinj : Set.InjOn w G.edgeSet) {T : SimpleGraph (Fin n)} [Fintype ↑T.edgeSet] (hle : T ≤ G) (hT : T.IsTree) (hopt : ∑ z ∈ T.edgeFinset, w z ≤ ∑ z ∈ (toSimpleGraph (kruskalGraph G w)).edgeFinset, w z) :

          Connected specialization of eq_toSimpleGraph_kruskalGraph_of_injOn: when G is connected and w is injective on G.edgeSet, toSimpleGraph (kruskalGraph G w) is the unique minimum-weight spanning tree of G.

          TimeM Cost Kruskal runner on SimpleGraph (Fin n) #

          Execute Kruskal's algorithm in TimeM Cost on the canonical edge list graphEdges G w. Note that Cost charges sorting comparisons and post-initialization UnionFind forest steps on the extracted m-edge list; the pure graphEdges G w enumeration (Θ(n²) adjacency/weight checks) and DisjointSet.UnionFind.init n carry 0 TimeM Cost charge.

          Instances For

            Sorting comparison bound for kruskalGraphM in terms of m = G.edgeFinset.card: at most m * ⌈log₂ m⌉ weight comparisons.

            Disjoint-set forest step bound for kruskalGraphM in terms of m = G.edgeFinset.card and n: at most m * (2 * ⌊log₂ n⌋ + 3) union-find steps.

            Combined bound on (kruskalGraphM G w).time.total in terms of m = G.edgeFinset.card and n.