From 182b0c43509789273af3ab0f78b0621067db1bd9 Mon Sep 17 00:00:00 2001 From: gsv Date: Fri, 29 May 2026 11:31:35 +0300 Subject: [PATCH 01/13] Compilable version of Maggs-Plotkin MST. --- QuadTree/Maggs_Plotkin_MST.fs | 59 +++++++++++++++++++++++++++++++++++ QuadTree/QuadTree.fsproj | 1 + 2 files changed, 60 insertions(+) create mode 100644 QuadTree/Maggs_Plotkin_MST.fs diff --git a/QuadTree/Maggs_Plotkin_MST.fs b/QuadTree/Maggs_Plotkin_MST.fs new file mode 100644 index 0000000..fd82552 --- /dev/null +++ b/QuadTree/Maggs_Plotkin_MST.fs @@ -0,0 +1,59 @@ +module Graph.Maggs_Plotkin_MST + +open Common +open Result +open Matrix + + +type Error = + | DiagAdditionProblem of Matrix.Error + | MSTComputationProblem of Matrix.Error + | ClosureComputationProblem of LinearAlgebra.Error + +let mst (graph: Matrix.SparseMatrix<'a>) = + + let diag = + let zero = Unchecked.defaultof<'a> + Matrix.fromCoordinateList ( + Matrix.CoordinateList( + graph.nrows, + graph.ncols, + [ for i in 0UL .. uint64 graph.nrows -> (i * 1UL, i * 1UL, zero)] + ) + ) + let _max x y = + match (x,y) with + | Some x, Some y -> max x y |> Some + | _ -> None + + let _min x y = + match (x,y) with + | Some x, Some y -> min x y |> Some + | Some x , None + | None, Some x -> Some x + | _ -> None + + resultM { + let! graph = + Matrix.map2 graph diag (fun x y -> match y with None -> x | _ -> y) + |> Result.mapError DiagAdditionProblem + + let! closure = + let rec compute (matrix:SparseMatrix<_>) = + let nnz = matrix.nvals + resultM{ + + let! step = LinearAlgebra.mxm _min _max matrix matrix + if nnz = step.nvals && matrix.storage = step.storage + then return step + else return! compute step + } + compute graph + |> Result.mapError ClosureComputationProblem + + let! mst = + Matrix.map2i graph closure (fun i j x y -> if uint64 i = uint64 j then None else if x = y then x else None) + |> Result.mapError MSTComputationProblem + return mst + } + diff --git a/QuadTree/QuadTree.fsproj b/QuadTree/QuadTree.fsproj index 438678c..abfc6ec 100644 --- a/QuadTree/QuadTree.fsproj +++ b/QuadTree/QuadTree.fsproj @@ -14,6 +14,7 @@ + From 6ac040ee62a1af899bb19b170cd5fc9c2a20fb81 Mon Sep 17 00:00:00 2001 From: gsv Date: Fri, 29 May 2026 11:52:26 +0300 Subject: [PATCH 02/13] Tests on Maggs-Plotkin MST. --- QuadTree.Tests/QuadTree.Tests.fsproj | 2 +- .../{Tests.Boruvka.fs => Tests.MST.fs} | 534 ++++++++---------- 2 files changed, 241 insertions(+), 295 deletions(-) rename QuadTree.Tests/{Tests.Boruvka.fs => Tests.MST.fs} (80%) diff --git a/QuadTree.Tests/QuadTree.Tests.fsproj b/QuadTree.Tests/QuadTree.Tests.fsproj index 4de3d64..bc76cf2 100644 --- a/QuadTree.Tests/QuadTree.Tests.fsproj +++ b/QuadTree.Tests/QuadTree.Tests.fsproj @@ -13,7 +13,7 @@ - + diff --git a/QuadTree.Tests/Tests.Boruvka.fs b/QuadTree.Tests/Tests.MST.fs similarity index 80% rename from QuadTree.Tests/Tests.Boruvka.fs rename to QuadTree.Tests/Tests.MST.fs index 6f2e2a0..258fc46 100644 --- a/QuadTree.Tests/Tests.Boruvka.fs +++ b/QuadTree.Tests/Tests.MST.fs @@ -1,11 +1,7 @@ module Graph.Boruvka.Tests -open System open Xunit - open Matrix -open Vector -open Common let checkResult name actual expected = match actual with @@ -20,11 +16,11 @@ let checkResult name actual expected = | _ -> None) Assert.Equal(expected, actual) - | x -> Assert.Fail(sprintf "Boruvka failed: %A" x) + | x -> Assert.Fail(sprintf "MST failed: %A" x) -[] -let ``Boruvka MST 2 nodes.`` () = +// ============== Shared test data ============== +let private ``test 2 nodes`` () = let graph = let clist = Matrix.CoordinateList( @@ -35,22 +31,9 @@ let ``Boruvka MST 2 nodes.`` () = Matrix.fromCoordinateList clist - let expected = - let clist = - Matrix.CoordinateList( - 2UL, - 2UL, - [ 0UL, 1UL, 5UL; 1UL, 0UL, 5UL ] - ) - - Matrix.fromCoordinateList clist |> Ok - - checkResult (Graph.Boruvka.mst graph) expected - - -[] -let ``Boruvka MST 3 nodes line.`` () = + graph, Ok graph +let private ``test 3 nodes line`` () = let graph = let clist = Matrix.CoordinateList( @@ -64,26 +47,9 @@ let ``Boruvka MST 3 nodes line.`` () = Matrix.fromCoordinateList clist - let expected = - let clist = - Matrix.CoordinateList( - 3UL, - 3UL, - [ 0UL, 1UL, 1UL - 1UL, 0UL, 1UL - 1UL, 2UL, 2UL - 2UL, 1UL, 2UL ] - ) - - Matrix.fromCoordinateList clist |> Ok - - checkResult (Graph.Boruvka.mst graph) expected - - - -[] -let ``Boruvka MST 4 nodes line.`` () = + graph, Ok graph +let private ``test 4 nodes line`` () = let graph = let clist = Matrix.CoordinateList( @@ -99,27 +65,9 @@ let ``Boruvka MST 4 nodes line.`` () = Matrix.fromCoordinateList clist - let expected = - let clist = - Matrix.CoordinateList( - 4UL, - 4UL, - [ 0UL, 1UL, 1UL - 1UL, 0UL, 1UL - 1UL, 2UL, 2UL - 2UL, 1UL, 2UL - 2UL, 3UL, 3UL - 3UL, 2UL, 3UL ] - ) - - Matrix.fromCoordinateList clist |> Ok - - checkResult (Graph.Boruvka.mst graph) expected - - -[] -let ``Boruvka MST 5 nodes line.`` () = + graph, Ok graph +let private ``test 5 nodes line`` () = let graph = let clist = Matrix.CoordinateList( @@ -137,29 +85,9 @@ let ``Boruvka MST 5 nodes line.`` () = Matrix.fromCoordinateList clist - let expected = - let clist = - Matrix.CoordinateList( - 5UL, - 5UL, - [ 0UL, 1UL, 1UL - 1UL, 0UL, 1UL - 1UL, 2UL, 2UL - 2UL, 1UL, 2UL - 2UL, 3UL, 3UL - 3UL, 2UL, 3UL - 3UL, 4UL, 4UL - 4UL, 3UL, 4UL ] - ) - - Matrix.fromCoordinateList clist |> Ok - - checkResult (Graph.Boruvka.mst graph) expected - - -[] -let ``Boruvka MST 5 nodes star.`` () = + graph, Ok graph +let private ``test 5 nodes star`` () = let graph = let clist = Matrix.CoordinateList( @@ -177,29 +105,9 @@ let ``Boruvka MST 5 nodes star.`` () = Matrix.fromCoordinateList clist - let expected = - let clist = - Matrix.CoordinateList( - 5UL, - 5UL, - [ 0UL, 1UL, 5UL - 1UL, 0UL, 5UL - 0UL, 2UL, 4UL - 2UL, 0UL, 4UL - 0UL, 3UL, 3UL - 3UL, 0UL, 3UL - 0UL, 4UL, 2UL - 4UL, 0UL, 2UL ] - ) - - Matrix.fromCoordinateList clist |> Ok - - checkResult (Graph.Boruvka.mst graph) expected - - -[] -let ``Boruvka MST 5 nodes complete.`` () = + graph, Ok graph +let private ``test 5 nodes complete`` () = let graph = let clist = Matrix.CoordinateList( @@ -246,12 +154,9 @@ let ``Boruvka MST 5 nodes complete.`` () = Matrix.fromCoordinateList clist |> Ok - checkResult (Graph.Boruvka.mst graph) expected - - -[] -let ``Boruvka MST two components.`` () = + graph, expected +let private ``test two components`` () = let graph = let clist = Matrix.CoordinateList( @@ -293,12 +198,9 @@ let ``Boruvka MST two components.`` () = Matrix.fromCoordinateList clist |> Ok - checkResult (Graph.Boruvka.mst graph) expected - - -[] -let ``Boruvka MST cycle graph 6 nodes.`` () = + graph, expected +let private ``test cycle graph 6 nodes`` () = let graph = let clist = Matrix.CoordinateList( @@ -339,11 +241,9 @@ let ``Boruvka MST cycle graph 6 nodes.`` () = Matrix.fromCoordinateList clist |> Ok - checkResult (Graph.Boruvka.mst graph) expected - -[] -let ``Boruvka MST complete bipartite K3,3.`` () = + graph, expected +let private ``test complete bipartite K3,3`` () = let graph = let clist = Matrix.CoordinateList( @@ -400,11 +300,9 @@ let ``Boruvka MST complete bipartite K3,3.`` () = Matrix.fromCoordinateList clist |> Ok - checkResult (Graph.Boruvka.mst graph) expected - -[] -let ``Boruvka MST random weights.`` () = + graph, expected +let private ``test random weights`` () = let graph = let clist = Matrix.CoordinateList( @@ -466,11 +364,9 @@ let ``Boruvka MST random weights.`` () = Matrix.fromCoordinateList clist |> Ok - checkResult (Graph.Boruvka.mst graph) expected - -[] -let ``Boruvka MST 8 nodes grid.`` () = + graph, expected +let private ``test 8 nodes grid`` () = let graph = let clist = Matrix.CoordinateList( @@ -527,11 +423,9 @@ let ``Boruvka MST 8 nodes grid.`` () = Matrix.fromCoordinateList clist |> Ok - checkResult (Graph.Boruvka.mst graph) expected - -[] -let ``Boruvka MST 10 nodes random.`` () = + graph, expected +let private ``test 10 nodes random`` () = let graph = let clist = Matrix.CoordinateList( @@ -567,47 +461,9 @@ let ``Boruvka MST 10 nodes random.`` () = Matrix.fromCoordinateList clist - let expected = - let clist = - Matrix.CoordinateList( - 10UL, - 10UL, - [ 0UL, 1UL, 4UL - 1UL, 0UL, 4UL - 0UL, 5UL, 2UL - 5UL, 0UL, 2UL - 1UL, 2UL, 3UL - 2UL, 1UL, 3UL - 1UL, 6UL, 5UL - 6UL, 1UL, 5UL - 2UL, 3UL, 1UL - 3UL, 2UL, 1UL - 2UL, 7UL, 4UL - 7UL, 2UL, 4UL - 3UL, 4UL, 2UL - 4UL, 3UL, 2UL - 3UL, 8UL, 6UL - 8UL, 3UL, 6UL - 4UL, 9UL, 3UL - 9UL, 4UL, 3UL - 5UL, 6UL, 1UL - 6UL, 5UL, 1UL - 6UL, 7UL, 2UL - 7UL, 6UL, 2UL - 7UL, 8UL, 1UL - 8UL, 7UL, 1UL - 8UL, 9UL, 4UL - 9UL, 8UL, 4UL ] - ) - - Matrix.fromCoordinateList clist |> Ok - - checkResult (Graph.Boruvka.mst graph) expected - - -[] -let ``Boruvka MST simple triangle.`` () = + graph, Ok graph +let private ``test simple triangle`` () = let graph = let clist = Matrix.CoordinateList( @@ -620,14 +476,11 @@ let ``Boruvka MST simple triangle.`` () = 2UL, 0UL, 1UL 1UL, 2UL, 1UL - 2UL, 1UL, 1UL - - ] + 2UL, 1UL, 1UL ] ) Matrix.fromCoordinateList clist - let expected = let clist = Matrix.CoordinateList( @@ -642,12 +495,9 @@ let ``Boruvka MST simple triangle.`` () = Matrix.fromCoordinateList clist |> Ok - checkResult (Graph.Boruvka.mst graph) expected - - -[] -let ``Boruvka MST simple square.`` () = + graph, expected +let private ``test simple square`` () = let graph = let clist = Matrix.CoordinateList( @@ -663,14 +513,11 @@ let ``Boruvka MST simple square.`` () = 3UL, 2UL, 1UL 0UL, 3UL, 1UL - 3UL, 0UL, 1UL - - ] + 3UL, 0UL, 1UL ] ) Matrix.fromCoordinateList clist - let expected = let clist = Matrix.CoordinateList( @@ -688,14 +535,9 @@ let ``Boruvka MST simple square.`` () = Matrix.fromCoordinateList clist |> Ok - checkResult (Graph.Boruvka.mst graph) expected - - - - -[] -let ``Boruvka MST simple square in two steps.`` () = + graph, expected +let private ``test simple square in two steps`` () = let graph = let clist = Matrix.CoordinateList( @@ -711,14 +553,11 @@ let ``Boruvka MST simple square in two steps.`` () = 3UL, 2UL, 2UL 0UL, 3UL, 1UL - 3UL, 0UL, 1UL - - ] + 3UL, 0UL, 1UL ] ) Matrix.fromCoordinateList clist - let expected = let clist = Matrix.CoordinateList( @@ -736,14 +575,9 @@ let ``Boruvka MST simple square in two steps.`` () = Matrix.fromCoordinateList clist |> Ok - checkResult (Graph.Boruvka.mst graph) expected - - - - -[] -let ``Boruvka MST.`` () = + graph, expected +let private ``test 7 nodes`` () = let graph = let clist = Matrix.CoordinateList( @@ -785,7 +619,6 @@ let ``Boruvka MST.`` () = Matrix.fromCoordinateList clist - let expected = let clist = Matrix.CoordinateList( @@ -807,19 +640,14 @@ let ``Boruvka MST.`` () = 5UL, 4UL, 6UL 6UL, 3UL, 8UL - 3UL, 6UL, 8UL - - ] + 3UL, 6UL, 8UL ] ) Matrix.fromCoordinateList clist |> Ok - checkResult (Graph.Boruvka.mst graph) expected - - -[] -let ``Boruvka MST big.`` () = + graph, expected +let private ``test big`` () = let graph = let clist = Matrix.CoordinateList( @@ -877,14 +705,11 @@ let ``Boruvka MST big.`` () = 11UL, 10UL, 3UL 5UL, 4UL, 3UL - 4UL, 5UL, 3UL - - ] + 4UL, 5UL, 3UL ] ) Matrix.fromCoordinateList clist - let expected = let clist = Matrix.CoordinateList( @@ -921,19 +746,14 @@ let ``Boruvka MST big.`` () = 10UL, 5UL, 2UL 4UL, 5UL, 3UL - 5UL, 4UL, 3UL - - ] + 5UL, 4UL, 3UL ] ) Matrix.fromCoordinateList clist |> Ok - checkResult (Graph.Boruvka.mst graph) expected - - -[] -let ``Boruvka MST complex line.`` () = + graph, expected +let private ``test complex line`` () = let graph = let clist = Matrix.CoordinateList( @@ -964,16 +784,15 @@ let ``Boruvka MST complex line.`` () = 8UL, 7UL, 1UL 8UL, 9UL, 1UL - 9UL, 8UL, 1UL - - - ] + 9UL, 8UL, 1UL ] ) Matrix.fromCoordinateList clist + graph, Ok graph - let expected = +let private ``test complex line 2`` () = + let graph = let clist = Matrix.CoordinateList( 10UL, @@ -987,110 +806,237 @@ let ``Boruvka MST complex line.`` () = 2UL, 3UL, 1UL 3UL, 2UL, 1UL - 3UL, 4UL, 3UL - 4UL, 3UL, 3UL + 3UL, 9UL, 3UL + 9UL, 3UL, 3UL - 4UL, 5UL, 1UL - 5UL, 4UL, 1UL + 9UL, 8UL, 1UL + 8UL, 9UL, 1UL - 5UL, 6UL, 1UL - 6UL, 5UL, 1UL + 8UL, 7UL, 1UL + 7UL, 8UL, 1UL 6UL, 7UL, 2UL 7UL, 6UL, 2UL - 7UL, 8UL, 1UL - 8UL, 7UL, 1UL + 5UL, 6UL, 1UL + 6UL, 5UL, 1UL - 8UL, 9UL, 1UL - 9UL, 8UL, 1UL + 5UL, 4UL, 1UL + 4UL, 5UL, 1UL ] + ) + Matrix.fromCoordinateList clist - ] - ) + graph, Ok graph - Matrix.fromCoordinateList clist |> Ok +// ============== Tests ============== + +[] +let ``Boruvka MST 2 nodes.`` () = + let graph, expected = ``test 2 nodes`` () checkResult (Graph.Boruvka.mst graph) expected +[] +let ``Maggs-Plotkin MST 2 nodes.`` () = + let graph, expected = ``test 2 nodes`` () + checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + [] -let ``Boruvka MST complex line 2.`` () = +let ``Boruvka MST 3 nodes line.`` () = + let graph, expected = ``test 3 nodes line`` () + checkResult (Graph.Boruvka.mst graph) expected - let graph = - let clist = - Matrix.CoordinateList( - 10UL, - 10UL, - [ 0UL, 1UL, 1UL - 1UL, 0UL, 1UL +[] +let ``Maggs-Plotkin MST 3 nodes line.`` () = + let graph, expected = ``test 3 nodes line`` () + checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected - 1UL, 2UL, 2UL - 2UL, 1UL, 2UL - 2UL, 3UL, 1UL - 3UL, 2UL, 1UL +[] +let ``Boruvka MST 4 nodes line.`` () = + let graph, expected = ``test 4 nodes line`` () + checkResult (Graph.Boruvka.mst graph) expected - 3UL, 9UL, 3UL - 9UL, 3UL, 3UL +[] +let ``Maggs-Plotkin MST 4 nodes line.`` () = + let graph, expected = ``test 4 nodes line`` () + checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected - 9UL, 8UL, 1UL - 8UL, 9UL, 1UL - 8UL, 7UL, 1UL - 7UL, 8UL, 1UL - 6UL, 7UL, 2UL - 7UL, 6UL, 2UL +[] +let ``Boruvka MST 5 nodes line.`` () = + let graph, expected = ``test 5 nodes line`` () + checkResult (Graph.Boruvka.mst graph) expected - 5UL, 6UL, 1UL - 6UL, 5UL, 1UL +[] +let ``Maggs-Plotkin MST 5 nodes line.`` () = + let graph, expected = ``test 5 nodes line`` () + checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected - 5UL, 4UL, 1UL - 4UL, 5UL, 1UL +[] +let ``Boruvka MST 5 nodes star.`` () = + let graph, expected = ``test 5 nodes star`` () + checkResult (Graph.Boruvka.mst graph) expected - ] - ) +[] +let ``Maggs-Plotkin MST 5 nodes star.`` () = + let graph, expected = ``test 5 nodes star`` () + checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected - Matrix.fromCoordinateList clist +[] +let ``Boruvka MST 5 nodes complete.`` () = + let graph, expected = ``test 5 nodes complete`` () + checkResult (Graph.Boruvka.mst graph) expected - let expected = - let clist = - Matrix.CoordinateList( - 10UL, - 10UL, - [ 0UL, 1UL, 1UL - 1UL, 0UL, 1UL +[] +let ``Maggs-Plotkin MST 5 nodes complete.`` () = + let graph, expected = ``test 5 nodes complete`` () + checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected - 1UL, 2UL, 2UL - 2UL, 1UL, 2UL - 2UL, 3UL, 1UL - 3UL, 2UL, 1UL +[] +let ``Boruvka MST two components.`` () = + let graph, expected = ``test two components`` () + checkResult (Graph.Boruvka.mst graph) expected - 3UL, 9UL, 3UL - 9UL, 3UL, 3UL +[] +let ``Maggs-Plotkin MST two components.`` () = + let graph, expected = ``test two components`` () + checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected - 9UL, 8UL, 1UL - 8UL, 9UL, 1UL - 8UL, 7UL, 1UL - 7UL, 8UL, 1UL +[] +let ``Boruvka MST cycle graph 6 nodes.`` () = + let graph, expected = ``test cycle graph 6 nodes`` () + checkResult (Graph.Boruvka.mst graph) expected - 6UL, 7UL, 2UL - 7UL, 6UL, 2UL +[] +let ``Maggs-Plotkin MST cycle graph 6 nodes.`` () = + let graph, expected = ``test cycle graph 6 nodes`` () + checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected - 5UL, 6UL, 1UL - 6UL, 5UL, 1UL - 5UL, 4UL, 1UL - 4UL, 5UL, 1UL +[] +let ``Boruvka MST complete bipartite K3,3.`` () = + let graph, expected = ``test complete bipartite K3,3`` () + checkResult (Graph.Boruvka.mst graph) expected - ] - ) +[] +let ``Maggs-Plotkin MST complete bipartite K3,3.`` () = + let graph, expected = ``test complete bipartite K3,3`` () + checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected - Matrix.fromCoordinateList clist |> Ok +[] +let ``Boruvka MST random weights.`` () = + let graph, expected = ``test random weights`` () checkResult (Graph.Boruvka.mst graph) expected + +[] +let ``Maggs-Plotkin MST random weights.`` () = + let graph, expected = ``test random weights`` () + checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + + +[] +let ``Boruvka MST 8 nodes grid.`` () = + let graph, expected = ``test 8 nodes grid`` () + checkResult (Graph.Boruvka.mst graph) expected + +[] +let ``Maggs-Plotkin MST 8 nodes grid.`` () = + let graph, expected = ``test 8 nodes grid`` () + checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + + +[] +let ``Boruvka MST 10 nodes random.`` () = + let graph, expected = ``test 10 nodes random`` () + checkResult (Graph.Boruvka.mst graph) expected + +[] +let ``Maggs-Plotkin MST 10 nodes random.`` () = + let graph, expected = ``test 10 nodes random`` () + checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + + +[] +let ``Boruvka MST simple triangle.`` () = + let graph, expected = ``test simple triangle`` () + checkResult (Graph.Boruvka.mst graph) expected + +[] +let ``Maggs-Plotkin MST simple triangle.`` () = + let graph, expected = ``test simple triangle`` () + checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + + +[] +let ``Boruvka MST simple square.`` () = + let graph, expected = ``test simple square`` () + checkResult (Graph.Boruvka.mst graph) expected + +[] +let ``Maggs-Plotkin MST simple square.`` () = + let graph, expected = ``test simple square`` () + checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + + +[] +let ``Boruvka MST simple square in two steps.`` () = + let graph, expected = ``test simple square in two steps`` () + checkResult (Graph.Boruvka.mst graph) expected + +[] +let ``Maggs-Plotkin MST simple square in two steps.`` () = + let graph, expected = ``test simple square in two steps`` () + checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + + +[] +let ``Boruvka MST.`` () = + let graph, expected = ``test 7 nodes`` () + checkResult (Graph.Boruvka.mst graph) expected + +[] +let ``Maggs-Plotkin MST.`` () = + let graph, expected = ``test 7 nodes`` () + checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + + +[] +let ``Boruvka MST big.`` () = + let graph, expected = ``test big`` () + checkResult (Graph.Boruvka.mst graph) expected + +[] +let ``Maggs-Plotkin MST big.`` () = + let graph, expected = ``test big`` () + checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + + +[] +let ``Boruvka MST complex line.`` () = + let graph, expected = ``test complex line`` () + checkResult (Graph.Boruvka.mst graph) expected + +[] +let ``Maggs-Plotkin MST complex line.`` () = + let graph, expected = ``test complex line`` () + checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + + +[] +let ``Boruvka MST complex line 2.`` () = + let graph, expected = ``test complex line 2`` () + checkResult (Graph.Boruvka.mst graph) expected + +[] +let ``Maggs-Plotkin MST complex line 2.`` () = + let graph, expected = ``test complex line 2`` () + checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected From 588f40738f2369ece103131c37ee32a8d4591c16 Mon Sep 17 00:00:00 2001 From: gsv Date: Fri, 29 May 2026 12:45:43 +0300 Subject: [PATCH 03/13] Formatted --- QuadTree/Maggs_Plotkin_MST.fs | 55 +++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/QuadTree/Maggs_Plotkin_MST.fs b/QuadTree/Maggs_Plotkin_MST.fs index fd82552..ce5bef3 100644 --- a/QuadTree/Maggs_Plotkin_MST.fs +++ b/QuadTree/Maggs_Plotkin_MST.fs @@ -12,48 +12,59 @@ type Error = let mst (graph: Matrix.SparseMatrix<'a>) = - let diag = + let diag = let zero = Unchecked.defaultof<'a> + Matrix.fromCoordinateList ( Matrix.CoordinateList( graph.nrows, graph.ncols, - [ for i in 0UL .. uint64 graph.nrows -> (i * 1UL, i * 1UL, zero)] + [ for i in 0UL .. uint64 graph.nrows -> (i * 1UL, i * 1UL, zero) ] ) ) - let _max x y = - match (x,y) with + + let _max x y = + match (x, y) with | Some x, Some y -> max x y |> Some | _ -> None - let _min x y = - match (x,y) with + let _min x y = + match (x, y) with | Some x, Some y -> min x y |> Some - | Some x , None + | Some x, None | None, Some x -> Some x | _ -> None resultM { - let! graph = - Matrix.map2 graph diag (fun x y -> match y with None -> x | _ -> y) + let! graph = + Matrix.map2 graph diag (fun x y -> + match y with + | None -> x + | _ -> y) |> Result.mapError DiagAdditionProblem - - let! closure = - let rec compute (matrix:SparseMatrix<_>) = + + let! closure = + let rec compute (matrix: SparseMatrix<_>) = let nnz = matrix.nvals - resultM{ - let! step = LinearAlgebra.mxm _min _max matrix matrix - if nnz = step.nvals && matrix.storage = step.storage - then return step - else return! compute step + resultM { + + let! step = LinearAlgebra.mxm _min _max matrix matrix + + if nnz = step.nvals && matrix.storage = step.storage then + return step + else + return! compute step } - compute graph - |> Result.mapError ClosureComputationProblem - let! mst = - Matrix.map2i graph closure (fun i j x y -> if uint64 i = uint64 j then None else if x = y then x else None) + compute graph |> Result.mapError ClosureComputationProblem + + let! mst = + Matrix.map2i graph closure (fun i j x y -> + if uint64 i = uint64 j then None + elif x = y then x + else None) |> Result.mapError MSTComputationProblem + return mst } - From ac44fe0c1959b4fbdf7cd044f2a104d6973c9f9c Mon Sep 17 00:00:00 2001 From: gsv Date: Sun, 31 May 2026 10:33:04 +0300 Subject: [PATCH 04/13] Maggs-Plotkin: handle edges with identical weights correctly. --- QuadTree/Maggs_Plotkin_MST.fs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/QuadTree/Maggs_Plotkin_MST.fs b/QuadTree/Maggs_Plotkin_MST.fs index ce5bef3..c88c42d 100644 --- a/QuadTree/Maggs_Plotkin_MST.fs +++ b/QuadTree/Maggs_Plotkin_MST.fs @@ -19,7 +19,7 @@ let mst (graph: Matrix.SparseMatrix<'a>) = Matrix.CoordinateList( graph.nrows, graph.ncols, - [ for i in 0UL .. uint64 graph.nrows -> (i * 1UL, i * 1UL, zero) ] + [ for i in 0UL .. uint64 graph.nrows - 1UL -> (i * 1UL, i * 1UL, zero) ] ) ) @@ -43,6 +43,9 @@ let mst (graph: Matrix.SparseMatrix<'a>) = | _ -> y) |> Result.mapError DiagAdditionProblem + let graph = + Matrix.mapi graph (fun i j v -> Option.map (fun x -> x, min (uint64 i) (uint64 j), max (uint64 i) (uint64 j)) v) + let! closure = let rec compute (matrix: SparseMatrix<_>) = let nnz = matrix.nvals @@ -62,7 +65,9 @@ let mst (graph: Matrix.SparseMatrix<'a>) = let! mst = Matrix.map2i graph closure (fun i j x y -> if uint64 i = uint64 j then None - elif x = y then x + elif x = y + then + match x with | Some(w,_,_) -> Some(w) | _ -> None else None) |> Result.mapError MSTComputationProblem From 8bcd91ab1eb7a0bc2c0b92144174b9439e8f287c Mon Sep 17 00:00:00 2001 From: gsv Date: Sun, 31 May 2026 10:33:29 +0300 Subject: [PATCH 05/13] MST tests fixed. In progress. --- QuadTree.Tests/Tests.MST.fs | 176 +++++++++++++++++++++++++++--------- 1 file changed, 132 insertions(+), 44 deletions(-) diff --git a/QuadTree.Tests/Tests.MST.fs b/QuadTree.Tests/Tests.MST.fs index 258fc46..f8b3d7b 100644 --- a/QuadTree.Tests/Tests.MST.fs +++ b/QuadTree.Tests/Tests.MST.fs @@ -16,7 +16,7 @@ let checkResult name actual expected = | _ -> None) Assert.Equal(expected, actual) - | x -> Assert.Fail(sprintf "MST failed: %A" x) + | x -> Assert.Fail(sprintf $"MST {name} failed: {x}") // ============== Shared test data ============== @@ -310,28 +310,40 @@ let private ``test random weights`` () = 8UL, [ 0UL, 1UL, 7UL 1UL, 0UL, 7UL + 0UL, 2UL, 5UL 2UL, 0UL, 5UL + 0UL, 3UL, 9UL 3UL, 0UL, 9UL + 1UL, 2UL, 3UL 2UL, 1UL, 3UL + 1UL, 3UL, 4UL 3UL, 1UL, 4UL + 2UL, 3UL, 2UL 3UL, 2UL, 2UL + 4UL, 5UL, 1UL 5UL, 4UL, 1UL + 4UL, 6UL, 6UL 6UL, 4UL, 6UL + 4UL, 7UL, 8UL 7UL, 4UL, 8UL + 5UL, 6UL, 3UL 6UL, 5UL, 3UL + 5UL, 7UL, 5UL 7UL, 5UL, 5UL + 6UL, 7UL, 2UL 7UL, 6UL, 2UL + // Connect two components 3UL, 4UL, 10UL 4UL, 3UL, 10UL ] @@ -346,20 +358,25 @@ let private ``test random weights`` () = 8UL, [ 0UL, 2UL, 5UL 2UL, 0UL, 5UL + 1UL, 2UL, 3UL 2UL, 1UL, 3UL + 2UL, 3UL, 2UL 3UL, 2UL, 2UL - 1UL, 3UL, 4UL - 3UL, 1UL, 4UL + + 4UL, 3UL, 10UL + 3UL, 4UL, 10UL + 4UL, 5UL, 1UL 5UL, 4UL, 1UL + 5UL, 6UL, 3UL 6UL, 5UL, 3UL + 6UL, 7UL, 2UL 7UL, 6UL, 2UL - 3UL, 4UL, 10UL - 4UL, 3UL, 10UL ] + ] ) Matrix.fromCoordinateList clist |> Ok @@ -433,35 +450,82 @@ let private ``test 10 nodes random`` () = 10UL, [ 0UL, 1UL, 4UL 1UL, 0UL, 4UL + 0UL, 5UL, 2UL 5UL, 0UL, 2UL + 1UL, 2UL, 3UL 2UL, 1UL, 3UL + 1UL, 6UL, 5UL 6UL, 1UL, 5UL + 2UL, 3UL, 1UL 3UL, 2UL, 1UL + 2UL, 7UL, 4UL 7UL, 2UL, 4UL + 3UL, 4UL, 2UL 4UL, 3UL, 2UL + 3UL, 8UL, 6UL 8UL, 3UL, 6UL + 4UL, 9UL, 3UL 9UL, 4UL, 3UL + 5UL, 6UL, 1UL 6UL, 5UL, 1UL + 6UL, 7UL, 2UL 7UL, 6UL, 2UL + 7UL, 8UL, 1UL 8UL, 7UL, 1UL + 8UL, 9UL, 4UL 9UL, 8UL, 4UL ] ) Matrix.fromCoordinateList clist - graph, Ok graph + let expected = + let clist = + Matrix.CoordinateList( + 10UL, + 10UL, + [ 0UL, 1UL, 4UL + 1UL, 0UL, 4UL + + 1UL, 2UL, 3UL + 2UL, 1UL, 3UL + + 3UL, 2UL, 1UL + 2UL, 3UL, 1UL + + 3UL, 4UL, 2UL + 4UL, 3UL, 2UL + + 9UL, 4UL, 3UL + 4UL, 9UL, 3UL + + 0UL, 5UL, 2UL + 5UL, 0UL, 2UL + + 6UL, 5UL, 1UL + 5UL, 6UL, 1UL + + 7UL, 6UL, 2UL + 6UL, 7UL, 2UL + + 7UL, 8UL, 1UL + 8UL, 7UL, 1UL] + ) + + Matrix.fromCoordinateList clist |> Ok + + graph, expected let private ``test simple triangle`` () = let graph = @@ -835,208 +899,232 @@ let private ``test complex line 2`` () = [] let ``Boruvka MST 2 nodes.`` () = let graph, expected = ``test 2 nodes`` () - checkResult (Graph.Boruvka.mst graph) expected + checkResult "Boruvka 2 nodes" (Graph.Boruvka.mst graph) expected [] let ``Maggs-Plotkin MST 2 nodes.`` () = let graph, expected = ``test 2 nodes`` () - checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + checkResult "Maggs-Plotkin 2 nodes" (Graph.Maggs_Plotkin_MST.mst graph) expected [] let ``Boruvka MST 3 nodes line.`` () = let graph, expected = ``test 3 nodes line`` () - checkResult (Graph.Boruvka.mst graph) expected + checkResult "Boruvka 3 nodes line" (Graph.Boruvka.mst graph) expected [] let ``Maggs-Plotkin MST 3 nodes line.`` () = let graph, expected = ``test 3 nodes line`` () - checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + let result = Graph.Maggs_Plotkin_MST.mst graph + //match result with + //| Ok (result) -> Matrix.Tests.printMatrixCoordinate result + //| Error e -> printfn $"!!! {e}" + checkResult "Maggs-Plotkin 3 nodes line" result expected [] let ``Boruvka MST 4 nodes line.`` () = let graph, expected = ``test 4 nodes line`` () - checkResult (Graph.Boruvka.mst graph) expected + checkResult "Boruvka 4 nodes line" (Graph.Boruvka.mst graph) expected [] let ``Maggs-Plotkin MST 4 nodes line.`` () = let graph, expected = ``test 4 nodes line`` () - checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + checkResult "Maggs-Plotkin 4 nodes line" (Graph.Maggs_Plotkin_MST.mst graph) expected [] let ``Boruvka MST 5 nodes line.`` () = let graph, expected = ``test 5 nodes line`` () - checkResult (Graph.Boruvka.mst graph) expected + checkResult "Boruvka 5 nodes line" (Graph.Boruvka.mst graph) expected [] let ``Maggs-Plotkin MST 5 nodes line.`` () = let graph, expected = ``test 5 nodes line`` () - checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + checkResult "Maggs-Plotkin 5 nodes line" (Graph.Maggs_Plotkin_MST.mst graph) expected [] let ``Boruvka MST 5 nodes star.`` () = let graph, expected = ``test 5 nodes star`` () - checkResult (Graph.Boruvka.mst graph) expected + checkResult "Boruvka 5 nodes star" (Graph.Boruvka.mst graph) expected [] let ``Maggs-Plotkin MST 5 nodes star.`` () = let graph, expected = ``test 5 nodes star`` () - checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + checkResult "Maggs-Plotkin 5 nodes star" (Graph.Maggs_Plotkin_MST.mst graph) expected [] let ``Boruvka MST 5 nodes complete.`` () = let graph, expected = ``test 5 nodes complete`` () - checkResult (Graph.Boruvka.mst graph) expected + checkResult "Boruvka 5 nodes complete" (Graph.Boruvka.mst graph) expected [] let ``Maggs-Plotkin MST 5 nodes complete.`` () = let graph, expected = ``test 5 nodes complete`` () - checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + checkResult "Maggs-Plotkin 5 nodes complete" (Graph.Maggs_Plotkin_MST.mst graph) expected [] let ``Boruvka MST two components.`` () = let graph, expected = ``test two components`` () - checkResult (Graph.Boruvka.mst graph) expected + checkResult "Boruvka two components" (Graph.Boruvka.mst graph) expected [] let ``Maggs-Plotkin MST two components.`` () = let graph, expected = ``test two components`` () - checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + checkResult "Maggs-Plotkin two components" (Graph.Maggs_Plotkin_MST.mst graph) expected [] let ``Boruvka MST cycle graph 6 nodes.`` () = let graph, expected = ``test cycle graph 6 nodes`` () - checkResult (Graph.Boruvka.mst graph) expected + checkResult "Boruvka cycle graph 6 nodes" (Graph.Boruvka.mst graph) expected [] let ``Maggs-Plotkin MST cycle graph 6 nodes.`` () = let graph, expected = ``test cycle graph 6 nodes`` () - checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + checkResult "Maggs-Plotkin cycle graph 6 nodes" (Graph.Maggs_Plotkin_MST.mst graph) expected [] let ``Boruvka MST complete bipartite K3,3.`` () = let graph, expected = ``test complete bipartite K3,3`` () - checkResult (Graph.Boruvka.mst graph) expected + checkResult "Boruvka complete bipartite K3,3" (Graph.Boruvka.mst graph) expected [] let ``Maggs-Plotkin MST complete bipartite K3,3.`` () = let graph, expected = ``test complete bipartite K3,3`` () - checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + checkResult "Maggs-Plotkin complete bipartite K3,3" (Graph.Maggs_Plotkin_MST.mst graph) expected [] let ``Boruvka MST random weights.`` () = let graph, expected = ``test random weights`` () - checkResult (Graph.Boruvka.mst graph) expected + let result = (Graph.Boruvka.mst graph) + //match result with + //| Ok (result) -> Matrix.Tests.printMatrixCoordinate result + //| Error e -> printfn $"!!! {e}" + checkResult "Boruvka random weights" result expected [] let ``Maggs-Plotkin MST random weights.`` () = let graph, expected = ``test random weights`` () - checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + let result = Graph.Maggs_Plotkin_MST.mst graph + //match result with + //| Ok (result) -> Matrix.Tests.printMatrixCoordinate result + //| Error e -> printfn $"!!! {e}" + checkResult "Maggs-Plotkin random weights" result expected [] let ``Boruvka MST 8 nodes grid.`` () = let graph, expected = ``test 8 nodes grid`` () - checkResult (Graph.Boruvka.mst graph) expected + checkResult "Boruvka 8 nodes grid" (Graph.Boruvka.mst graph) expected [] let ``Maggs-Plotkin MST 8 nodes grid.`` () = let graph, expected = ``test 8 nodes grid`` () - checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + checkResult "Maggs-Plotkin 8 nodes grid" (Graph.Maggs_Plotkin_MST.mst graph) expected [] let ``Boruvka MST 10 nodes random.`` () = let graph, expected = ``test 10 nodes random`` () - checkResult (Graph.Boruvka.mst graph) expected + checkResult "Boruvka 10 nodes random" (Graph.Boruvka.mst graph) expected [] let ``Maggs-Plotkin MST 10 nodes random.`` () = let graph, expected = ``test 10 nodes random`` () - checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + let result = Graph.Maggs_Plotkin_MST.mst graph + //match result with + //| Ok (result) -> Matrix.Tests.printMatrixCoordinate result + //| Error e -> printfn $"!!! {e}" + checkResult "Maggs-Plotkin 10 nodes random" result expected [] let ``Boruvka MST simple triangle.`` () = let graph, expected = ``test simple triangle`` () - checkResult (Graph.Boruvka.mst graph) expected + checkResult "Boruvka simple triangle" (Graph.Boruvka.mst graph) expected [] let ``Maggs-Plotkin MST simple triangle.`` () = let graph, expected = ``test simple triangle`` () - checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + checkResult "Maggs-Plotkin simple triangle" (Graph.Maggs_Plotkin_MST.mst graph) expected [] let ``Boruvka MST simple square.`` () = let graph, expected = ``test simple square`` () - checkResult (Graph.Boruvka.mst graph) expected + checkResult "Boruvka simple square" (Graph.Boruvka.mst graph) expected [] let ``Maggs-Plotkin MST simple square.`` () = let graph, expected = ``test simple square`` () - checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + checkResult "Maggs-Plotkin simple square" (Graph.Maggs_Plotkin_MST.mst graph) expected [] let ``Boruvka MST simple square in two steps.`` () = let graph, expected = ``test simple square in two steps`` () - checkResult (Graph.Boruvka.mst graph) expected + checkResult "Boruvka simple square in two steps" (Graph.Boruvka.mst graph) expected [] let ``Maggs-Plotkin MST simple square in two steps.`` () = let graph, expected = ``test simple square in two steps`` () - checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + let result = Graph.Maggs_Plotkin_MST.mst graph + //match result with + //| Ok (result) -> Matrix.Tests.printMatrixCoordinate result + //| Error e -> printfn $"!!! {e}" + checkResult "Maggs-Plotkin simple square in two steps" result expected [] let ``Boruvka MST.`` () = let graph, expected = ``test 7 nodes`` () - checkResult (Graph.Boruvka.mst graph) expected + checkResult "Boruvka" (Graph.Boruvka.mst graph) expected [] let ``Maggs-Plotkin MST.`` () = let graph, expected = ``test 7 nodes`` () - checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + checkResult "Maggs-Plotkin" (Graph.Maggs_Plotkin_MST.mst graph) expected [] let ``Boruvka MST big.`` () = let graph, expected = ``test big`` () - checkResult (Graph.Boruvka.mst graph) expected + let result = (Graph.Boruvka.mst graph) + match result with + | Ok (result) -> Matrix.Tests.printMatrixCoordinate result + | Error e -> printfn $"!!! {e}" + checkResult "Boruvka big" result expected [] let ``Maggs-Plotkin MST big.`` () = let graph, expected = ``test big`` () - checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + checkResult "Maggs-Plotkin big" (Graph.Maggs_Plotkin_MST.mst graph) expected [] let ``Boruvka MST complex line.`` () = let graph, expected = ``test complex line`` () - checkResult (Graph.Boruvka.mst graph) expected + checkResult "Boruvka complex line" (Graph.Boruvka.mst graph) expected [] let ``Maggs-Plotkin MST complex line.`` () = let graph, expected = ``test complex line`` () - checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + checkResult "Maggs-Plotkin complex line" (Graph.Maggs_Plotkin_MST.mst graph) expected [] let ``Boruvka MST complex line 2.`` () = let graph, expected = ``test complex line 2`` () - checkResult (Graph.Boruvka.mst graph) expected + checkResult "Boruvka complex line 2" (Graph.Boruvka.mst graph) expected [] let ``Maggs-Plotkin MST complex line 2.`` () = let graph, expected = ``test complex line 2`` () - checkResult (Graph.Maggs_Plotkin_MST.mst graph) expected + checkResult "Maggs-Plotkin complex line 2" (Graph.Maggs_Plotkin_MST.mst graph) expected From 86b2e89d78f3809f6509d4faf8f4729f9ad6b7e9 Mon Sep 17 00:00:00 2001 From: gsv Date: Sun, 31 May 2026 11:38:29 +0300 Subject: [PATCH 06/13] Simple test on Boruvka to investigate what goes wrong. --- QuadTree.Tests/Tests.MST.fs | 73 ++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/QuadTree.Tests/Tests.MST.fs b/QuadTree.Tests/Tests.MST.fs index f8b3d7b..33d710b 100644 --- a/QuadTree.Tests/Tests.MST.fs +++ b/QuadTree.Tests/Tests.MST.fs @@ -107,6 +107,51 @@ let private ``test 5 nodes star`` () = graph, Ok graph +let private ``test square`` () = + let graph = + let clist = + Matrix.CoordinateList( + 4UL, + 4UL, + [ 0UL, 1UL, 1UL + 1UL, 0UL, 1UL + + 1UL, 2UL, 2UL + 2UL, 1UL, 2UL + + 2UL, 3UL, 1UL + 3UL, 2UL, 1UL + + 3UL, 0UL, 2UL + 0UL, 3UL, 2UL + ] + ) + + Matrix.fromCoordinateList clist + + let expected = + let clist = + Matrix.CoordinateList( + 4UL, + 4UL, + [ 0UL, 1UL, 1UL + 1UL, 0UL, 1UL + + 2UL, 3UL, 1UL + 3UL, 2UL, 1UL + + 3UL, 0UL, 2UL + 0UL, 3UL, 2UL + ] + ) + + Matrix.fromCoordinateList clist + |> Ok + + + graph, expected + + let private ``test 5 nodes complete`` () = let graph = let clist = @@ -933,6 +978,16 @@ let ``Maggs-Plotkin MST 4 nodes line.`` () = checkResult "Maggs-Plotkin 4 nodes line" (Graph.Maggs_Plotkin_MST.mst graph) expected +[] +let ``Boruvka MST square.`` () = + let graph, expected = ``test square`` () + checkResult "Boruvka 4 nodes line" (Graph.Boruvka.mst graph) expected + +[] +let ``Maggs-Plotkin MST square.`` () = + let graph, expected = ``test square`` () + checkResult "Maggs-Plotkin 4 nodes line" (Graph.Maggs_Plotkin_MST.mst graph) expected + [] let ``Boruvka MST 5 nodes line.`` () = @@ -1004,18 +1059,18 @@ let ``Maggs-Plotkin MST complete bipartite K3,3.`` () = let ``Boruvka MST random weights.`` () = let graph, expected = ``test random weights`` () let result = (Graph.Boruvka.mst graph) - //match result with - //| Ok (result) -> Matrix.Tests.printMatrixCoordinate result - //| Error e -> printfn $"!!! {e}" + match result with + | Ok (result) -> Matrix.Tests.printMatrixCoordinate result + | Error e -> printfn $"!!! {e}" checkResult "Boruvka random weights" result expected [] let ``Maggs-Plotkin MST random weights.`` () = let graph, expected = ``test random weights`` () let result = Graph.Maggs_Plotkin_MST.mst graph - //match result with - //| Ok (result) -> Matrix.Tests.printMatrixCoordinate result - //| Error e -> printfn $"!!! {e}" + match result with + | Ok (result) -> Matrix.Tests.printMatrixCoordinate result + | Error e -> printfn $"!!! {e}" checkResult "Maggs-Plotkin random weights" result expected @@ -1097,9 +1152,9 @@ let ``Maggs-Plotkin MST.`` () = let ``Boruvka MST big.`` () = let graph, expected = ``test big`` () let result = (Graph.Boruvka.mst graph) - match result with - | Ok (result) -> Matrix.Tests.printMatrixCoordinate result - | Error e -> printfn $"!!! {e}" + //match result with + //| Ok (result) -> Matrix.Tests.printMatrixCoordinate result + //| Error e -> printfn $"!!! {e}" checkResult "Boruvka big" result expected [] From 1937a67ac7fafd33447e2da4ccdb8152f4ac3596 Mon Sep 17 00:00:00 2001 From: gsv Date: Sun, 31 May 2026 16:58:02 +0300 Subject: [PATCH 07/13] Fixed cycles in Boruvka MST --- QuadTree.Tests/Tests.MST.fs | 113 ++++++++++++++-------------------- QuadTree/Boruvka.fs | 25 ++++++++ QuadTree/Maggs_Plotkin_MST.fs | 18 +++--- 3 files changed, 82 insertions(+), 74 deletions(-) diff --git a/QuadTree.Tests/Tests.MST.fs b/QuadTree.Tests/Tests.MST.fs index 33d710b..4d7052f 100644 --- a/QuadTree.Tests/Tests.MST.fs +++ b/QuadTree.Tests/Tests.MST.fs @@ -120,11 +120,10 @@ let private ``test square`` () = 2UL, 1UL, 2UL 2UL, 3UL, 1UL - 3UL, 2UL, 1UL + 3UL, 2UL, 1UL 3UL, 0UL, 2UL - 0UL, 3UL, 2UL - ] + 0UL, 3UL, 2UL ] ) Matrix.fromCoordinateList clist @@ -138,15 +137,13 @@ let private ``test square`` () = 1UL, 0UL, 1UL 2UL, 3UL, 1UL - 3UL, 2UL, 1UL + 3UL, 2UL, 1UL 3UL, 0UL, 2UL - 0UL, 3UL, 2UL - ] + 0UL, 3UL, 2UL ] ) - Matrix.fromCoordinateList clist - |> Ok + Matrix.fromCoordinateList clist |> Ok graph, expected @@ -358,37 +355,37 @@ let private ``test random weights`` () = 0UL, 2UL, 5UL 2UL, 0UL, 5UL - + 0UL, 3UL, 9UL 3UL, 0UL, 9UL - + 1UL, 2UL, 3UL 2UL, 1UL, 3UL - + 1UL, 3UL, 4UL 3UL, 1UL, 4UL - + 2UL, 3UL, 2UL 3UL, 2UL, 2UL - + 4UL, 5UL, 1UL 5UL, 4UL, 1UL - + 4UL, 6UL, 6UL 6UL, 4UL, 6UL - + 4UL, 7UL, 8UL 7UL, 4UL, 8UL - + 5UL, 6UL, 3UL 6UL, 5UL, 3UL - + 5UL, 7UL, 5UL 7UL, 5UL, 5UL - + 6UL, 7UL, 2UL 7UL, 6UL, 2UL - + // Connect two components 3UL, 4UL, 10UL 4UL, 3UL, 10UL ] @@ -403,25 +400,24 @@ let private ``test random weights`` () = 8UL, [ 0UL, 2UL, 5UL 2UL, 0UL, 5UL - + 1UL, 2UL, 3UL 2UL, 1UL, 3UL - + 2UL, 3UL, 2UL 3UL, 2UL, 2UL - + 4UL, 3UL, 10UL 3UL, 4UL, 10UL - + 4UL, 5UL, 1UL 5UL, 4UL, 1UL - + 5UL, 6UL, 3UL 6UL, 5UL, 3UL - + 6UL, 7UL, 2UL - 7UL, 6UL, 2UL - ] + 7UL, 6UL, 2UL ] ) Matrix.fromCoordinateList clist |> Ok @@ -498,37 +494,37 @@ let private ``test 10 nodes random`` () = 0UL, 5UL, 2UL 5UL, 0UL, 2UL - + 1UL, 2UL, 3UL 2UL, 1UL, 3UL - + 1UL, 6UL, 5UL 6UL, 1UL, 5UL - + 2UL, 3UL, 1UL 3UL, 2UL, 1UL - + 2UL, 7UL, 4UL 7UL, 2UL, 4UL - + 3UL, 4UL, 2UL 4UL, 3UL, 2UL - + 3UL, 8UL, 6UL 8UL, 3UL, 6UL - + 4UL, 9UL, 3UL 9UL, 4UL, 3UL - + 5UL, 6UL, 1UL 6UL, 5UL, 1UL - + 6UL, 7UL, 2UL 7UL, 6UL, 2UL - + 7UL, 8UL, 1UL 8UL, 7UL, 1UL - + 8UL, 9UL, 4UL 9UL, 8UL, 4UL ] ) @@ -542,30 +538,30 @@ let private ``test 10 nodes random`` () = 10UL, [ 0UL, 1UL, 4UL 1UL, 0UL, 4UL - + 1UL, 2UL, 3UL 2UL, 1UL, 3UL - + 3UL, 2UL, 1UL 2UL, 3UL, 1UL - + 3UL, 4UL, 2UL 4UL, 3UL, 2UL - + 9UL, 4UL, 3UL 4UL, 9UL, 3UL - + 0UL, 5UL, 2UL 5UL, 0UL, 2UL - + 6UL, 5UL, 1UL - 5UL, 6UL, 1UL - + 5UL, 6UL, 1UL + 7UL, 6UL, 2UL 6UL, 7UL, 2UL - + 7UL, 8UL, 1UL - 8UL, 7UL, 1UL] + 8UL, 7UL, 1UL ] ) Matrix.fromCoordinateList clist |> Ok @@ -961,9 +957,6 @@ let ``Boruvka MST 3 nodes line.`` () = let ``Maggs-Plotkin MST 3 nodes line.`` () = let graph, expected = ``test 3 nodes line`` () let result = Graph.Maggs_Plotkin_MST.mst graph - //match result with - //| Ok (result) -> Matrix.Tests.printMatrixCoordinate result - //| Error e -> printfn $"!!! {e}" checkResult "Maggs-Plotkin 3 nodes line" result expected @@ -986,7 +979,8 @@ let ``Boruvka MST square.`` () = [] let ``Maggs-Plotkin MST square.`` () = let graph, expected = ``test square`` () - checkResult "Maggs-Plotkin 4 nodes line" (Graph.Maggs_Plotkin_MST.mst graph) expected + let result = Graph.Maggs_Plotkin_MST.mst graph + checkResult "Maggs-Plotkin 4 nodes line" result expected [] @@ -1059,18 +1053,12 @@ let ``Maggs-Plotkin MST complete bipartite K3,3.`` () = let ``Boruvka MST random weights.`` () = let graph, expected = ``test random weights`` () let result = (Graph.Boruvka.mst graph) - match result with - | Ok (result) -> Matrix.Tests.printMatrixCoordinate result - | Error e -> printfn $"!!! {e}" checkResult "Boruvka random weights" result expected [] let ``Maggs-Plotkin MST random weights.`` () = let graph, expected = ``test random weights`` () let result = Graph.Maggs_Plotkin_MST.mst graph - match result with - | Ok (result) -> Matrix.Tests.printMatrixCoordinate result - | Error e -> printfn $"!!! {e}" checkResult "Maggs-Plotkin random weights" result expected @@ -1094,9 +1082,6 @@ let ``Boruvka MST 10 nodes random.`` () = let ``Maggs-Plotkin MST 10 nodes random.`` () = let graph, expected = ``test 10 nodes random`` () let result = Graph.Maggs_Plotkin_MST.mst graph - //match result with - //| Ok (result) -> Matrix.Tests.printMatrixCoordinate result - //| Error e -> printfn $"!!! {e}" checkResult "Maggs-Plotkin 10 nodes random" result expected @@ -1131,9 +1116,6 @@ let ``Boruvka MST simple square in two steps.`` () = let ``Maggs-Plotkin MST simple square in two steps.`` () = let graph, expected = ``test simple square in two steps`` () let result = Graph.Maggs_Plotkin_MST.mst graph - //match result with - //| Ok (result) -> Matrix.Tests.printMatrixCoordinate result - //| Error e -> printfn $"!!! {e}" checkResult "Maggs-Plotkin simple square in two steps" result expected @@ -1152,9 +1134,6 @@ let ``Maggs-Plotkin MST.`` () = let ``Boruvka MST big.`` () = let graph, expected = ``test big`` () let result = (Graph.Boruvka.mst graph) - //match result with - //| Ok (result) -> Matrix.Tests.printMatrixCoordinate result - //| Error e -> printfn $"!!! {e}" checkResult "Boruvka big" result expected [] diff --git a/QuadTree/Boruvka.fs b/QuadTree/Boruvka.fs index c0ed119..b3bf95c 100644 --- a/QuadTree/Boruvka.fs +++ b/QuadTree/Boruvka.fs @@ -82,6 +82,31 @@ let mst (graph: Matrix.SparseMatrix<_>) = Vector.scatter (Vector.empty length) edges parent op_min |> Result.mapError CEdgesCalculationProblem + // Suppress mutual 2-cycles between components (LAGraph approach). + // When components p and q select each other, keep only the larger root's edge. + let! cedges_dst = + Vector.map2i cedges cedges (fun _ cv _ -> + match cv with + | Some(w, dst) -> Some(uint64 dst * 1UL) + | None -> None) + |> Result.mapError IndexInnerCalculationProblem + + let dst_comp = Vector.gather parent cedges_dst + let back_check = Vector.gather dst_comp dst_comp + + let! cedges = + Vector.map2i cedges back_check (fun i cv bc -> + match cv with + | Some(w, dst) -> + match bc with + | Some bc_val -> + match Vector.unsafeGet parent i, Vector.unsafeGet dst_comp i with + | Some p, Some cd when cd <> p && bc_val = p && p < cd -> None + | _ -> Some(w, dst) + | None -> Some(w, dst) + | None -> None) + |> Result.mapError IndexInnerCalculationProblem + // Propagate component's cheapest edge to all its vertices // Each vertex gets its component's edge let t = Vector.gather cedges parent diff --git a/QuadTree/Maggs_Plotkin_MST.fs b/QuadTree/Maggs_Plotkin_MST.fs index c88c42d..97f311c 100644 --- a/QuadTree/Maggs_Plotkin_MST.fs +++ b/QuadTree/Maggs_Plotkin_MST.fs @@ -43,8 +43,9 @@ let mst (graph: Matrix.SparseMatrix<'a>) = | _ -> y) |> Result.mapError DiagAdditionProblem - let graph = - Matrix.mapi graph (fun i j v -> Option.map (fun x -> x, min (uint64 i) (uint64 j), max (uint64 i) (uint64 j)) v) + let graph = + Matrix.mapi graph (fun i j v -> + Option.map (fun x -> x, min (uint64 i) (uint64 j), max (uint64 i) (uint64 j)) v) let! closure = let rec compute (matrix: SparseMatrix<_>) = @@ -64,11 +65,14 @@ let mst (graph: Matrix.SparseMatrix<'a>) = let! mst = Matrix.map2i graph closure (fun i j x y -> - if uint64 i = uint64 j then None - elif x = y - then - match x with | Some(w,_,_) -> Some(w) | _ -> None - else None) + if uint64 i = uint64 j then + None + elif x = y then + match x with + | Some(w, _, _) -> Some(w) + | _ -> None + else + None) |> Result.mapError MSTComputationProblem return mst From 0243914d0549af7c9bc05dbc3257d01ac0d42214 Mon Sep 17 00:00:00 2001 From: gsv Date: Sun, 31 May 2026 17:34:42 +0300 Subject: [PATCH 08/13] Added information about Maggs-Plotkin MSF. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8084adb..16532d8 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ Infrastructure for benchmarking the implemented algorithms is available in the [ * Single-source shortest path (SSSP) * Triangles counting * Boruvka MSF +* Maggs-Plotkin MSF ## TODO * [ ] Single-source parent BFS From 069d6b98f1956fb04d92add21e960382ab1d0160 Mon Sep 17 00:00:00 2001 From: gsv Date: Sun, 31 May 2026 21:47:46 +0300 Subject: [PATCH 09/13] First vrsion of parent BFS. --- QuadTree.Tests/Tests.BFS.fs | 298 ++++++++++++++++++++++++++++++++++-- QuadTree/BFS.fs | 67 +++++--- 2 files changed, 333 insertions(+), 32 deletions(-) diff --git a/QuadTree.Tests/Tests.BFS.fs b/QuadTree.Tests/Tests.BFS.fs index df5d0f3..bbfbdef 100644 --- a/QuadTree.Tests/Tests.BFS.fs +++ b/QuadTree.Tests/Tests.BFS.fs @@ -7,16 +7,25 @@ open Matrix open Vector open Common -(* -1,N,N,N -, -N,1,1,N -3,N,2,3 -N,N,N,2 -N,N,3,N -=> -0,1,1,2 -*) +let singleStart (n: uint64) (s: uint64) = + Vector.CoordinateList( + n * 1UL, + [s * 1UL, 1UL] + ) + |> Vector.fromCoordinateList + +let vec (n: uint64) pairs = + Vector.CoordinateList( + n * 1UL, + pairs |> List.map (fun (i: uint64, v: uint64) -> i * 1UL, v) + ) + |> Vector.fromCoordinateList + +let unsafes (n: uint64) (v: Vector.SparseVector<_>) = + List.init (int n) (fun i -> Vector.unsafeGet v (uint64 i * 1UL)) + +// ============== Existing test (unchanged) ============== + [] let ``Simple level bfs.`` () = let graph = @@ -69,3 +78,272 @@ let ``Simple level bfs.`` () = let actual = Graph.BFS.bfs_level graph startVertices Assert.Equal(expected, actual) + +// ============== Parent BFS on same graph ============== + +[] +let ``Simple parent bfs.`` () = + let graph = + let tree = + Matrix.qtree.Node( + Matrix.qtree.Node( + Matrix.qtree.Leaf(UserValue(None)), + Matrix.qtree.Leaf(UserValue(Some(1))), + Matrix.qtree.Leaf(UserValue(Some(3))), + Matrix.qtree.Leaf(UserValue(None)) + ), + Matrix.qtree.Node( + Matrix.qtree.Leaf(UserValue(Some(1))), + Matrix.qtree.Leaf(UserValue(None)), + Matrix.qtree.Leaf(UserValue(Some(2))), + Matrix.qtree.Leaf(UserValue(Some(3))) + ), + Matrix.qtree.Leaf(UserValue(None)), + Matrix.qtree.Node( + Matrix.qtree.Leaf(UserValue(None)), + Matrix.qtree.Leaf(UserValue(Some(2))), + Matrix.qtree.Leaf(UserValue(Some(3))), + Matrix.qtree.Leaf(UserValue(None)) + ) + ) + + let store = Matrix.Storage(4UL, tree) + SparseMatrix(4UL, 4UL, 9UL, store) + + let startVertices = + let tree = + Vector.btree.Node( + Vector.btree.Node(Vector.btree.Leaf(UserValue(Some(1UL))), Vector.btree.Leaf(UserValue(None))), + Vector.btree.Leaf(UserValue(None)) + ) + + let store = Vector.Storage(4UL, tree) + SparseVector(4UL, 1UL, store) + + let expected = + let tree = + Vector.btree.Node( + Vector.btree.Leaf(UserValue(Some(0UL))), + Vector.btree.Node( + Vector.btree.Leaf(UserValue(Some(0UL))), + Vector.btree.Leaf(UserValue(Some(1UL))) + ) + ) + + let store = Vector.Storage(4UL, tree) + Ok(SparseVector(4UL, 4UL, store)) + + let actual = Graph.BFS.bfs_parent graph startVertices + + Assert.Equal(expected, actual) + +// ============== 3-node line ============== + +let private line3graph = + Matrix.fromCoordinateList ( + Matrix.CoordinateList( + 3UL, + 3UL, + [0UL, 1UL, 1UL + 1UL, 0UL, 1UL + 1UL, 2UL, 1UL + 2UL, 1UL, 1UL] + ) + ) + +[] +let ``Level bfs 3 node line start 0`` () = + let n = uint64 line3graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_level line3graph start + let expected = [ Some 0UL; Some 1UL; Some 2UL ] + Assert.Equal(Ok expected, Result.map (unsafes n) result) + +[] +let ``Parent bfs 3 node line start 0`` () = + let n = uint64 line3graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_parent line3graph start + let expected = [ Some 0UL; Some 0UL; Some 1UL ] + Assert.Equal(Ok expected, Result.map (unsafes n) result) + +[] +let ``Level bfs 3 node line start 1`` () = + let n = uint64 line3graph.ncols + let start = singleStart n 1UL + let result = Graph.BFS.bfs_level line3graph start + let expected = [ Some 1UL; Some 0UL; Some 1UL ] + Assert.Equal(Ok expected, Result.map (unsafes n) result) + +[] +let ``Parent bfs 3 node line start 1`` () = + let n = uint64 line3graph.ncols + let start = singleStart n 1UL + let result = Graph.BFS.bfs_parent line3graph start + let expected = [ Some 1UL; Some 1UL; Some 1UL ] + Assert.Equal(Ok expected, Result.map (unsafes n) result) + +// ============== 5-node star (center 0) ============== + +let private star5graph = + Matrix.fromCoordinateList ( + Matrix.CoordinateList( + 5UL, + 5UL, + [0UL, 1UL, 1UL + 1UL, 0UL, 1UL + 0UL, 2UL, 1UL + 2UL, 0UL, 1UL + 0UL, 3UL, 1UL + 3UL, 0UL, 1UL + 0UL, 4UL, 1UL + 4UL, 0UL, 1UL] + ) + ) + +[] +let ``Level bfs 5 node star start center`` () = + let n = uint64 star5graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_level star5graph start + let expected = [ Some 0UL; Some 1UL; Some 1UL; Some 1UL; Some 1UL ] + Assert.Equal(Ok expected, Result.map (unsafes n) result) + +[] +let ``Parent bfs 5 node star start center`` () = + let n = uint64 star5graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_parent star5graph start + let expected = [ Some 0UL; Some 0UL; Some 0UL; Some 0UL; Some 0UL ] + Assert.Equal(Ok expected, Result.map (unsafes n) result) + +[] +let ``Level bfs 5 node star start leaf`` () = + let n = uint64 star5graph.ncols + let start = singleStart n 1UL + let result = Graph.BFS.bfs_level star5graph start + let expected = [ Some 1UL; Some 0UL; Some 2UL; Some 2UL; Some 2UL ] + Assert.Equal(Ok expected, Result.map (unsafes n) result) + +[] +let ``Parent bfs 5 node star start leaf`` () = + let n = uint64 star5graph.ncols + let start = singleStart n 1UL + let result = Graph.BFS.bfs_parent star5graph start + let expected = [ Some 1UL; Some 1UL; Some 0UL; Some 0UL; Some 0UL ] + Assert.Equal(Ok expected, Result.map (unsafes n) result) + +// ============== Two components ============== + +let private twoCompGraph = + Matrix.fromCoordinateList ( + Matrix.CoordinateList( + 6UL, + 6UL, + [0UL, 1UL, 1UL + 1UL, 0UL, 1UL + 1UL, 2UL, 1UL + 2UL, 1UL, 1UL + 0UL, 2UL, 1UL + 2UL, 0UL, 1UL + + 3UL, 4UL, 1UL + 4UL, 3UL, 1UL + 4UL, 5UL, 1UL + 5UL, 4UL, 1UL + 3UL, 5UL, 1UL + 5UL, 3UL, 1UL] + ) + ) + +[] +let ``Level bfs two components start 0`` () = + let n = uint64 twoCompGraph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_level twoCompGraph start + let expected = + [ Some 0UL; Some 1UL; Some 1UL + None; None; None ] + Assert.Equal(Ok expected, Result.map (unsafes n) result) + +[] +let ``Parent bfs two components start 0`` () = + let n = uint64 twoCompGraph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_parent twoCompGraph start + let expected = + [ Some 0UL; Some 0UL; Some 0UL + None; None; None ] + Assert.Equal(Ok expected, Result.map (unsafes n) result) + +// ============== Square (4-cycle) ============== + +let private squareGraph = + Matrix.fromCoordinateList ( + Matrix.CoordinateList( + 4UL, + 4UL, + [0UL, 1UL, 1UL + 1UL, 0UL, 1UL + 1UL, 2UL, 2UL + 2UL, 1UL, 2UL + 2UL, 3UL, 1UL + 3UL, 2UL, 1UL + 3UL, 0UL, 2UL + 0UL, 3UL, 2UL] + ) + ) + +[] +let ``Level bfs square start 0`` () = + let n = uint64 squareGraph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_level squareGraph start + let expected = [ Some 0UL; Some 1UL; Some 2UL; Some 1UL ] + Assert.Equal(Ok expected, Result.map (unsafes n) result) + +[] +let ``Parent bfs square start 0`` () = + let n = uint64 squareGraph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_parent squareGraph start + let expected = [ Some 0UL; Some 0UL; Some 1UL; Some 0UL ] + Assert.Equal(Ok expected, Result.map (unsafes n) result) + +// ============== 6-cycle ============== + +let private cycle6graph = + Matrix.fromCoordinateList ( + Matrix.CoordinateList( + 6UL, + 6UL, + [0UL, 1UL, 1UL + 1UL, 0UL, 1UL + 1UL, 2UL, 2UL + 2UL, 1UL, 2UL + 2UL, 3UL, 3UL + 3UL, 2UL, 3UL + 3UL, 4UL, 4UL + 4UL, 3UL, 4UL + 4UL, 5UL, 5UL + 5UL, 4UL, 5UL + 5UL, 0UL, 6UL + 0UL, 5UL, 6UL] + ) + ) + +[] +let ``Level bfs 6 cycle start 0`` () = + let n = uint64 cycle6graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_level cycle6graph start + let expected = [ Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 2UL; Some 1UL ] + Assert.Equal(Ok expected, Result.map (unsafes n) result) + +[] +let ``Parent bfs 6 cycle start 0`` () = + let n = uint64 cycle6graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_parent cycle6graph start + let expected = [ Some 0UL; Some 0UL; Some 1UL; Some 2UL; Some 5UL; Some 0UL ] + Assert.Equal(Ok expected, Result.map (unsafes n) result) diff --git a/QuadTree/BFS.fs b/QuadTree/BFS.fs index 0ba2fc5..c240ed2 100644 --- a/QuadTree/BFS.fs +++ b/QuadTree/BFS.fs @@ -8,23 +8,20 @@ type Error = | FrontierCalculationProblem of Vector.Error | VisitedCalculationProblem of Vector.Error -let bfs_level graph startVertices = - let rec inner level (frontier: Vector.SparseVector<_>) (visited: Vector.SparseVector<_>) = +let bfs + (op_add: 'c option -> 'c option -> 'c option) + (op_mult: uint64 * 'c -> uint64 * uint64 * 'b -> Option<'c>) + (initVisited: uint64 -> Option<'c> -> Option<'c>) + (graph: Matrix.SparseMatrix<'b>) + (startVertices: Vector.SparseVector<'c>) + = + let initialVisited = Vector.mapi startVertices initVisited + + let rec inner (frontier: Vector.SparseVector<'c>) (visited: Vector.SparseVector<'c>) = if frontier.nvals > 0UL then resultM { let! new_frontier = - LinearAlgebra.vxm - (fun x y -> - match (x, y) with - | Some(v), _ - | _, Some(v) -> Some(v) - | _ -> None) - (fun x y -> - match (x, y) with - | Some(v), Some(_) -> Some(v) - | _ -> None) - frontier - graph + LinearAlgebra.vxmi_values op_add op_mult frontier graph |> Result.mapError NewFrontierCalculationProblem let! frontier = @@ -32,17 +29,43 @@ let bfs_level graph startVertices = |> Result.mapError FrontierCalculationProblem let! visited = - Vector.map2 visited new_frontier (fun x y -> - match (x, y) with - | Some(_), _ -> x - | None, Some(_) -> Some(level) - | _ -> None) + Vector.map2 visited frontier (fun oldVal newVal -> + match oldVal with + | Some _ -> oldVal + | None -> newVal) |> Result.mapError VisitedCalculationProblem - return! inner (level + 1UL) frontier visited + return! inner frontier visited } else Ok visited - let initialVisited = Vector.map startVertices (Option.map (fun x -> 0UL)) - inner 1UL startVertices initialVisited + inner startVertices initialVisited + +let bfs_level graph startVertices = + let op_add x y = + match (x, y) with + | Some(v), _ + | _, Some(v) -> Some(v) + | _ -> None + + let op_mult (_, vp) (_, _, _) = Some(vp + 1UL) + + let initVisited _ v = v |> Option.map (fun _ -> 0UL) + + let frontier0 = Vector.mapi startVertices (fun _ v -> v |> Option.map (fun _ -> 0UL)) + + bfs op_add op_mult initVisited graph frontier0 + +let bfs_parent graph startVertices = + let op_add x y = + match (x, y) with + | Some(v), _ + | _, Some(v) -> Some(v) + | _ -> None + + let op_mult (vi, _) (_, _, _) = Some(uint64 vi) + + let initVisited i v = v |> Option.map (fun _ -> uint64 i) + + bfs op_add op_mult initVisited graph startVertices From a8f2a7ab1622bae44ede3ebf427c93928325e232 Mon Sep 17 00:00:00 2001 From: gsv Date: Mon, 1 Jun 2026 16:33:12 +0300 Subject: [PATCH 10/13] Fixed vxmi. --- QuadTree.Tests/Tests.BFS.fs | 2 + QuadTree.Tests/Tests.LinearAlgebra.fs | 55 +++++++++++++++++++++++++++ QuadTree/LinearAlgebra.fs | 20 +++++----- 3 files changed, 68 insertions(+), 9 deletions(-) diff --git a/QuadTree.Tests/Tests.BFS.fs b/QuadTree.Tests/Tests.BFS.fs index bbfbdef..d0b958b 100644 --- a/QuadTree.Tests/Tests.BFS.fs +++ b/QuadTree.Tests/Tests.BFS.fs @@ -347,3 +347,5 @@ let ``Parent bfs 6 cycle start 0`` () = let result = Graph.BFS.bfs_parent cycle6graph start let expected = [ Some 0UL; Some 0UL; Some 1UL; Some 2UL; Some 5UL; Some 0UL ] Assert.Equal(Ok expected, Result.map (unsafes n) result) + + diff --git a/QuadTree.Tests/Tests.LinearAlgebra.fs b/QuadTree.Tests/Tests.LinearAlgebra.fs index 3bde7b3..2a891dc 100644 --- a/QuadTree.Tests/Tests.LinearAlgebra.fs +++ b/QuadTree.Tests/Tests.LinearAlgebra.fs @@ -346,6 +346,61 @@ let ``Simple vxmi_values. 4 * (4x3).`` () = Assert.Equal(expected, actual) +[] +let ``vxmi_values 3x3 line graph start 0. BFS semantics`` () = + // 3-node line graph (3x3 stored as 4x4): + // N 1 N D + // 1 N 1 D + // N 1 N D + // D D D D + let m = + let tree = + Matrix.qtree.Node( + Matrix.qtree.Node(leaf_n (), leaf_v 1UL, leaf_v 1UL, leaf_n ()), + Matrix.qtree.Node(leaf_n (), leaf_d (), leaf_v 1UL, leaf_d ()), + Matrix.qtree.Node(leaf_n (), leaf_v 1UL, leaf_d (), leaf_d ()), + Matrix.qtree.Node(leaf_n (), leaf_d (), leaf_d (), leaf_d ()) + ) + + let store = Matrix.Storage(4UL, tree) + SparseMatrix(3UL, 3UL, 4UL, store) + + // frontier = start 0 mapped to level 0: + // [0, N, N, D] = Node(Node(0, N), Node(N, D)) + let f = + let tree = + Vector.btree.Node( + Vector.btree.Node(vleaf_v 0UL, vleaf_n ()), + Vector.btree.Node(vleaf_n (), vleaf_d ()) + ) + + let store = Vector.Storage(4UL, tree) + SparseVector(3UL, 1UL, store) + + let op_add x y = + match (x, y) with + | Some(v), _ + | _, Some(v) -> Some(v) + | _ -> None + + let op_mult (_, vp) (_, _, _) = Some(vp + 1UL) + + let expected = + // result = [N, 1, N, D] = Node(Node(N, 1), Node(N, D)) + let tree = + Vector.btree.Node( + Vector.btree.Node(vleaf_n (), vleaf_v 1UL), + Vector.btree.Node(vleaf_n (), vleaf_d ()) + ) + + let store = Vector.Storage(4UL, tree) + Ok(SparseVector(3UL, 1UL, store)) + + let actual = LinearAlgebra.vxmi_values op_add op_mult f m + + Assert.Equal(expected, actual) + + [] let ``Simple mxm`` () = // 222D diff --git a/QuadTree/LinearAlgebra.fs b/QuadTree/LinearAlgebra.fs index 7405e02..a57daca 100644 --- a/QuadTree/LinearAlgebra.fs +++ b/QuadTree/LinearAlgebra.fs @@ -36,9 +36,9 @@ let vxm op_add op_mult (vector: Vector.SparseVector<'a>) (matrix: Matrix.SparseM let v3 = Vector.SparseVector(data_length, nvals3, (Vector.Storage(new_size, t3))) let v4 = Vector.SparseVector(data_length, nvals4, (Vector.Storage(new_size, t4))) - let vAdd v1 (v2: Vector.SparseVector<_>) = - match v2.storage.data with - | Vector.Leaf(Dummy) -> Ok(v1) + let vAdd (v1: Vector.SparseVector<_>) (v2: Vector.SparseVector<_>) = + match v1.storage.data, v2.storage.data with + | _, Vector.Leaf(Dummy) -> Ok(v1) | _ -> Vector.map2 v1 v2 op_add let z1 = vAdd v1 v3 @@ -144,9 +144,9 @@ let vxmi_values let v3 = Vector.SparseVector(data_length, nvals3, (Vector.Storage(new_size, t3))) let v4 = Vector.SparseVector(data_length, nvals4, (Vector.Storage(new_size, t4))) - let vAdd v1 (v2: Vector.SparseVector<_>) = - match v2.storage.data with - | Vector.Leaf(Dummy) -> Ok(v1) + let vAdd (v1: Vector.SparseVector<_>) (v2: Vector.SparseVector<_>) = + match v1.storage.data, v2.storage.data with + | _, Vector.Leaf(Dummy) -> Ok(v1) | _ -> Vector.map2 v1 v2 op_add let z1 = vAdd v1 v3 @@ -183,14 +183,16 @@ let vxmi_values colIdx | Vector.btree.Leaf(UserValue(Some(_))), Matrix.qtree.Node(y1, y2, y3, y4) -> _do vector vector y1 y2 y3 y4 + | Vector.btree.Leaf(UserValue(None)), Matrix.qtree.Node(y1, y2, y3, y4) -> _do vector vector y1 y2 y3 y4 | Vector.btree.Node(x1, x2), Matrix.qtree.Leaf(UserValue(Some(_))) -> _do x1 x2 matrix matrix matrix matrix + | Vector.btree.Node(x1, x2), Matrix.qtree.Leaf(UserValue(None)) -> _do x1 x2 matrix matrix matrix matrix | Vector.btree.Node(x1, x2), Matrix.qtree.Node(y1, y2, y3, y4) -> _do x1 x2 y1 y2 y3 y4 - | Vector.btree.Leaf(UserValue(None)), _ - | _, Matrix.qtree.Leaf(UserValue(None)) -> Ok(Vector.btree.Leaf(UserValue(None)), 0UL) - | Vector.btree.Leaf(Dummy), _ | _, Matrix.qtree.Leaf(Dummy) -> Ok(Vector.btree.Leaf(Dummy), 0UL) + | Vector.btree.Leaf(UserValue(None)), _ + | _, Matrix.qtree.Leaf(UserValue(None)) -> Ok(Vector.btree.Leaf(UserValue(None)), 0UL) + if uint64 vector.length = uint64 matrix.nrows then let vector_storage = if uint64 vector.storage.size < uint64 matrix.storage.size then From 98aa4b2e5d3989dce46f893356807dcd1ac9beed Mon Sep 17 00:00:00 2001 From: gsv Date: Mon, 1 Jun 2026 18:29:12 +0300 Subject: [PATCH 11/13] More tests on BFS. --- QuadTree.Tests/Tests.BFS.fs | 627 +++++++++++++++++++++++++++++++++++- 1 file changed, 623 insertions(+), 4 deletions(-) diff --git a/QuadTree.Tests/Tests.BFS.fs b/QuadTree.Tests/Tests.BFS.fs index d0b958b..e18997a 100644 --- a/QuadTree.Tests/Tests.BFS.fs +++ b/QuadTree.Tests/Tests.BFS.fs @@ -24,8 +24,6 @@ let vec (n: uint64) pairs = let unsafes (n: uint64) (v: Vector.SparseVector<_>) = List.init (int n) (fun i -> Vector.unsafeGet v (uint64 i * 1UL)) -// ============== Existing test (unchanged) ============== - [] let ``Simple level bfs.`` () = let graph = @@ -79,8 +77,6 @@ let ``Simple level bfs.`` () = Assert.Equal(expected, actual) -// ============== Parent BFS on same graph ============== - [] let ``Simple parent bfs.`` () = let graph = @@ -348,4 +344,627 @@ let ``Parent bfs 6 cycle start 0`` () = let expected = [ Some 0UL; Some 0UL; Some 1UL; Some 2UL; Some 5UL; Some 0UL ] Assert.Equal(Ok expected, Result.map (unsafes n) result) +// ============== 2 nodes ============== + +let private graph2 = + Matrix.fromCoordinateList ( + Matrix.CoordinateList( + 2UL, + 2UL, + [0UL, 1UL, 5UL; 1UL, 0UL, 5UL] + ) + ) + +[] +let ``Level bfs 2 nodes start 0`` () = + let n = uint64 graph2.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_level graph2 start + Assert.Equal(Ok [ Some 0UL; Some 1UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 2 nodes start 0`` () = + let n = uint64 graph2.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_parent graph2 start + Assert.Equal(Ok [ Some 0UL; Some 0UL ], Result.map (unsafes n) result) + +[] +let ``Level bfs 2 nodes start 1`` () = + let n = uint64 graph2.ncols + let start = singleStart n 1UL + let result = Graph.BFS.bfs_level graph2 start + Assert.Equal(Ok [ Some 1UL; Some 0UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 2 nodes start 1`` () = + let n = uint64 graph2.ncols + let start = singleStart n 1UL + let result = Graph.BFS.bfs_parent graph2 start + Assert.Equal(Ok [ Some 1UL; Some 1UL ], Result.map (unsafes n) result) + +// ============== 4-node line ============== + +let private line4graph = + Matrix.fromCoordinateList ( + Matrix.CoordinateList( + 4UL, + 4UL, + [0UL, 1UL, 1UL; 1UL, 0UL, 1UL + 1UL, 2UL, 2UL; 2UL, 1UL, 2UL + 2UL, 3UL, 3UL; 3UL, 2UL, 3UL] + ) + ) + +[] +let ``Level bfs 4 node line start 0`` () = + let n = uint64 line4graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_level line4graph start + Assert.Equal(Ok [ Some 0UL; Some 1UL; Some 2UL; Some 3UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 4 node line start 0`` () = + let n = uint64 line4graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_parent line4graph start + Assert.Equal(Ok [ Some 0UL; Some 0UL; Some 1UL; Some 2UL ], Result.map (unsafes n) result) + +[] +let ``Level bfs 4 node line start 3`` () = + let n = uint64 line4graph.ncols + let start = singleStart n 3UL + let result = Graph.BFS.bfs_level line4graph start + Assert.Equal(Ok [ Some 3UL; Some 2UL; Some 1UL; Some 0UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 4 node line start 3`` () = + let n = uint64 line4graph.ncols + let start = singleStart n 3UL + let result = Graph.BFS.bfs_parent line4graph start + Assert.Equal(Ok [ Some 1UL; Some 2UL; Some 3UL; Some 3UL ], Result.map (unsafes n) result) + +// ============== 5-node line ============== + +let private line5graph = + Matrix.fromCoordinateList ( + Matrix.CoordinateList( + 5UL, + 5UL, + [0UL, 1UL, 1UL; 1UL, 0UL, 1UL + 1UL, 2UL, 2UL; 2UL, 1UL, 2UL + 2UL, 3UL, 3UL; 3UL, 2UL, 3UL + 3UL, 4UL, 4UL; 4UL, 3UL, 4UL] + ) + ) + +[] +let ``Level bfs 5 node line start 0`` () = + let n = uint64 line5graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_level line5graph start + Assert.Equal(Ok [ Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 4UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 5 node line start 0`` () = + let n = uint64 line5graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_parent line5graph start + Assert.Equal(Ok [ Some 0UL; Some 0UL; Some 1UL; Some 2UL; Some 3UL ], Result.map (unsafes n) result) + +[] +let ``Level bfs 5 node line start 4`` () = + let n = uint64 line5graph.ncols + let start = singleStart n 4UL + let result = Graph.BFS.bfs_level line5graph start + Assert.Equal(Ok [ Some 4UL; Some 3UL; Some 2UL; Some 1UL; Some 0UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 5 node line start 4`` () = + let n = uint64 line5graph.ncols + let start = singleStart n 4UL + let result = Graph.BFS.bfs_parent line5graph start + Assert.Equal(Ok [ Some 1UL; Some 2UL; Some 3UL; Some 4UL; Some 4UL ], Result.map (unsafes n) result) + +[] +let ``Level bfs 5 node line start 2`` () = + let n = uint64 line5graph.ncols + let start = singleStart n 2UL + let result = Graph.BFS.bfs_level line5graph start + Assert.Equal(Ok [ Some 2UL; Some 1UL; Some 0UL; Some 1UL; Some 2UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 5 node line start 2`` () = + let n = uint64 line5graph.ncols + let start = singleStart n 2UL + let result = Graph.BFS.bfs_parent line5graph start + Assert.Equal(Ok [ Some 1UL; Some 2UL; Some 2UL; Some 2UL; Some 3UL ], Result.map (unsafes n) result) + +// ============== Simple triangle ============== + +let private triangleGraph = + Matrix.fromCoordinateList ( + Matrix.CoordinateList( + 3UL, + 3UL, + [0UL, 1UL, 1UL; 1UL, 0UL, 1UL + 0UL, 2UL, 1UL; 2UL, 0UL, 1UL + 1UL, 2UL, 1UL; 2UL, 1UL, 1UL] + ) + ) + +[] +let ``Level bfs triangle start 0`` () = + let n = uint64 triangleGraph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_level triangleGraph start + Assert.Equal(Ok [ Some 0UL; Some 1UL; Some 1UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs triangle start 0`` () = + let n = uint64 triangleGraph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_parent triangleGraph start + Assert.Equal(Ok [ Some 0UL; Some 0UL; Some 0UL ], Result.map (unsafes n) result) + +[] +let ``Level bfs triangle start 2`` () = + let n = uint64 triangleGraph.ncols + let start = singleStart n 2UL + let result = Graph.BFS.bfs_level triangleGraph start + Assert.Equal(Ok [ Some 1UL; Some 1UL; Some 0UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs triangle start 2`` () = + let n = uint64 triangleGraph.ncols + let start = singleStart n 2UL + let result = Graph.BFS.bfs_parent triangleGraph start + Assert.Equal(Ok [ Some 2UL; Some 2UL; Some 2UL ], Result.map (unsafes n) result) + +// ============== 5-node complete graph ============== + +let private complete5graph = + Matrix.fromCoordinateList ( + Matrix.CoordinateList( + 5UL, + 5UL, + [0UL, 1UL, 1UL; 1UL, 0UL, 1UL + 0UL, 2UL, 2UL; 2UL, 0UL, 2UL + 0UL, 3UL, 3UL; 3UL, 0UL, 3UL + 0UL, 4UL, 4UL; 4UL, 0UL, 4UL + 1UL, 2UL, 5UL; 2UL, 1UL, 5UL + 1UL, 3UL, 6UL; 3UL, 1UL, 6UL + 1UL, 4UL, 7UL; 4UL, 1UL, 7UL + 2UL, 3UL, 8UL; 3UL, 2UL, 8UL + 2UL, 4UL, 9UL; 4UL, 2UL, 9UL + 3UL, 4UL,10UL; 4UL, 3UL,10UL] + ) + ) + +[] +let ``Level bfs 5 node complete start 0`` () = + let n = uint64 complete5graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_level complete5graph start + Assert.Equal(Ok [ Some 0UL; Some 1UL; Some 1UL; Some 1UL; Some 1UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 5 node complete start 0`` () = + let n = uint64 complete5graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_parent complete5graph start + Assert.Equal(Ok [ Some 0UL; Some 0UL; Some 0UL; Some 0UL; Some 0UL ], Result.map (unsafes n) result) + +[] +let ``Level bfs 5 node complete start 4`` () = + let n = uint64 complete5graph.ncols + let start = singleStart n 4UL + let result = Graph.BFS.bfs_level complete5graph start + Assert.Equal(Ok [ Some 1UL; Some 1UL; Some 1UL; Some 1UL; Some 0UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 5 node complete start 4`` () = + let n = uint64 complete5graph.ncols + let start = singleStart n 4UL + let result = Graph.BFS.bfs_parent complete5graph start + Assert.Equal(Ok [ Some 4UL; Some 4UL; Some 4UL; Some 4UL; Some 4UL ], Result.map (unsafes n) result) + +[] +let ``Level bfs 5 node complete start 2`` () = + let n = uint64 complete5graph.ncols + let start = singleStart n 2UL + let result = Graph.BFS.bfs_level complete5graph start + Assert.Equal(Ok [ Some 1UL; Some 1UL; Some 0UL; Some 1UL; Some 1UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 5 node complete start 2`` () = + let n = uint64 complete5graph.ncols + let start = singleStart n 2UL + let result = Graph.BFS.bfs_parent complete5graph start + Assert.Equal(Ok [ Some 2UL; Some 2UL; Some 2UL; Some 2UL; Some 2UL ], Result.map (unsafes n) result) + +// ============== K3,3 bipartite ============== + +let private k33graph = + Matrix.fromCoordinateList ( + Matrix.CoordinateList( + 6UL, + 6UL, + [0UL, 3UL, 1UL; 3UL, 0UL, 1UL + 0UL, 4UL, 2UL; 4UL, 0UL, 2UL + 0UL, 5UL, 3UL; 5UL, 0UL, 3UL + 1UL, 3UL, 4UL; 3UL, 1UL, 4UL + 1UL, 4UL, 5UL; 4UL, 1UL, 5UL + 1UL, 5UL, 6UL; 5UL, 1UL, 6UL + 2UL, 3UL, 7UL; 3UL, 2UL, 7UL + 2UL, 4UL, 8UL; 4UL, 2UL, 8UL + 2UL, 5UL, 9UL; 5UL, 2UL, 9UL] + ) + ) + +[] +let ``Level bfs K3 3 start 0`` () = + let n = uint64 k33graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_level k33graph start + Assert.Equal(Ok [ Some 0UL; Some 2UL; Some 2UL; Some 1UL; Some 1UL; Some 1UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs K3 3 start 0`` () = + let n = uint64 k33graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_parent k33graph start + Assert.Equal(Ok [ Some 0UL; Some 3UL; Some 3UL; Some 0UL; Some 0UL; Some 0UL ], Result.map (unsafes n) result) + +[] +let ``Level bfs K3 3 start 5`` () = + let n = uint64 k33graph.ncols + let start = singleStart n 5UL + let result = Graph.BFS.bfs_level k33graph start + Assert.Equal(Ok [ Some 1UL; Some 1UL; Some 1UL; Some 2UL; Some 2UL; Some 0UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs K3 3 start 5`` () = + let n = uint64 k33graph.ncols + let start = singleStart n 5UL + let result = Graph.BFS.bfs_parent k33graph start + Assert.Equal(Ok [ Some 5UL; Some 5UL; Some 5UL; Some 0UL; Some 0UL; Some 5UL ], Result.map (unsafes n) result) + +[] +let ``Level bfs K3 3 start 3`` () = + let n = uint64 k33graph.ncols + let start = singleStart n 3UL + let result = Graph.BFS.bfs_level k33graph start + Assert.Equal(Ok [ Some 1UL; Some 1UL; Some 1UL; Some 0UL; Some 2UL; Some 2UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs K3 3 start 3`` () = + let n = uint64 k33graph.ncols + let start = singleStart n 3UL + let result = Graph.BFS.bfs_parent k33graph start + Assert.Equal(Ok [ Some 3UL; Some 3UL; Some 3UL; Some 3UL; Some 0UL; Some 0UL ], Result.map (unsafes n) result) + +// ============== 8 nodes random weights ============== + +let private random8graph = + Matrix.fromCoordinateList ( + Matrix.CoordinateList( + 8UL, + 8UL, + [0UL, 1UL, 7UL; 1UL, 0UL, 7UL + 0UL, 2UL, 5UL; 2UL, 0UL, 5UL + 0UL, 3UL, 9UL; 3UL, 0UL, 9UL + 1UL, 2UL, 3UL; 2UL, 1UL, 3UL + 1UL, 3UL, 4UL; 3UL, 1UL, 4UL + 2UL, 3UL, 2UL; 3UL, 2UL, 2UL + 4UL, 5UL, 1UL; 5UL, 4UL, 1UL + 4UL, 6UL, 6UL; 6UL, 4UL, 6UL + 4UL, 7UL, 8UL; 7UL, 4UL, 8UL + 5UL, 6UL, 3UL; 6UL, 5UL, 3UL + 5UL, 7UL, 5UL; 7UL, 5UL, 5UL + 6UL, 7UL, 2UL; 7UL, 6UL, 2UL + 3UL, 4UL,10UL; 4UL, 3UL,10UL] + ) + ) + +[] +let ``Level bfs 8 node random start 0`` () = + let n = uint64 random8graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_level random8graph start + Assert.Equal(Ok [ Some 0UL; Some 1UL; Some 1UL; Some 1UL; Some 2UL; Some 3UL; Some 3UL; Some 3UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 8 node random start 0`` () = + let n = uint64 random8graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_parent random8graph start + Assert.Equal(Ok [ Some 0UL; Some 0UL; Some 0UL; Some 0UL; Some 3UL; Some 4UL; Some 4UL; Some 4UL ], Result.map (unsafes n) result) + +[] +let ``Level bfs 8 node random start 7`` () = + let n = uint64 random8graph.ncols + let start = singleStart n 7UL + let result = Graph.BFS.bfs_level random8graph start + Assert.Equal(Ok [ Some 3UL; Some 3UL; Some 3UL; Some 2UL; Some 1UL; Some 1UL; Some 1UL; Some 0UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 8 node random start 7`` () = + let n = uint64 random8graph.ncols + let start = singleStart n 7UL + let result = Graph.BFS.bfs_parent random8graph start + Assert.Equal(Ok [ Some 3UL; Some 3UL; Some 3UL; Some 4UL; Some 7UL; Some 7UL; Some 7UL; Some 7UL ], Result.map (unsafes n) result) + +[] +let ``Level bfs 8 node random start 4`` () = + let n = uint64 random8graph.ncols + let start = singleStart n 4UL + let result = Graph.BFS.bfs_level random8graph start + Assert.Equal(Ok [ Some 2UL; Some 2UL; Some 2UL; Some 1UL; Some 0UL; Some 1UL; Some 1UL; Some 1UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 8 node random start 4`` () = + let n = uint64 random8graph.ncols + let start = singleStart n 4UL + let result = Graph.BFS.bfs_parent random8graph start + Assert.Equal(Ok [ Some 3UL; Some 3UL; Some 3UL; Some 4UL; Some 4UL; Some 4UL; Some 4UL; Some 4UL ], Result.map (unsafes n) result) + +// ============== 8 nodes grid ============== + +let private grid8graph = + Matrix.fromCoordinateList ( + Matrix.CoordinateList( + 8UL, + 8UL, + [0UL, 1UL, 1UL; 1UL, 0UL, 1UL + 1UL, 2UL, 2UL; 2UL, 1UL, 2UL + 2UL, 3UL, 1UL; 3UL, 2UL, 1UL + 0UL, 4UL, 3UL; 4UL, 0UL, 3UL + 1UL, 5UL, 4UL; 5UL, 1UL, 4UL + 2UL, 6UL, 5UL; 6UL, 2UL, 5UL + 3UL, 7UL, 6UL; 7UL, 3UL, 6UL + 4UL, 5UL, 2UL; 5UL, 4UL, 2UL + 5UL, 6UL, 1UL; 6UL, 5UL, 1UL + 6UL, 7UL, 3UL; 7UL, 6UL, 3UL] + ) + ) + +[] +let ``Level bfs 8 node grid start 0`` () = + let n = uint64 grid8graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_level grid8graph start + Assert.Equal(Ok [ Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 1UL; Some 2UL; Some 3UL; Some 4UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 8 node grid start 0`` () = + let n = uint64 grid8graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_parent grid8graph start + Assert.Equal(Ok [ Some 0UL; Some 0UL; Some 1UL; Some 2UL; Some 0UL; Some 1UL; Some 2UL; Some 3UL ], Result.map (unsafes n) result) + +[] +let ``Level bfs 8 node grid start 7`` () = + let n = uint64 grid8graph.ncols + let start = singleStart n 7UL + let result = Graph.BFS.bfs_level grid8graph start + Assert.Equal(Ok [ Some 4UL; Some 3UL; Some 2UL; Some 1UL; Some 3UL; Some 2UL; Some 1UL; Some 0UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 8 node grid start 7`` () = + let n = uint64 grid8graph.ncols + let start = singleStart n 7UL + let result = Graph.BFS.bfs_parent grid8graph start + Assert.Equal(Ok [ Some 1UL; Some 2UL; Some 3UL; Some 7UL; Some 5UL; Some 6UL; Some 7UL; Some 7UL ], Result.map (unsafes n) result) + +[] +let ``Level bfs 8 node grid start 4`` () = + let n = uint64 grid8graph.ncols + let start = singleStart n 4UL + let result = Graph.BFS.bfs_level grid8graph start + Assert.Equal(Ok [ Some 1UL; Some 2UL; Some 3UL; Some 4UL; Some 0UL; Some 1UL; Some 2UL; Some 3UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 8 node grid start 4`` () = + let n = uint64 grid8graph.ncols + let start = singleStart n 4UL + let result = Graph.BFS.bfs_parent grid8graph start + Assert.Equal(Ok [ Some 4UL; Some 0UL; Some 1UL; Some 2UL; Some 4UL; Some 4UL; Some 5UL; Some 6UL ], Result.map (unsafes n) result) + +// ============== 10 nodes random ============== + +let private random10graph = + Matrix.fromCoordinateList ( + Matrix.CoordinateList( + 10UL, + 10UL, + [0UL, 1UL, 4UL; 1UL, 0UL, 4UL + 0UL, 5UL, 2UL; 5UL, 0UL, 2UL + 1UL, 2UL, 3UL; 2UL, 1UL, 3UL + 1UL, 6UL, 5UL; 6UL, 1UL, 5UL + 2UL, 3UL, 1UL; 3UL, 2UL, 1UL + 2UL, 7UL, 4UL; 7UL, 2UL, 4UL + 3UL, 4UL, 2UL; 4UL, 3UL, 2UL + 3UL, 8UL, 6UL; 8UL, 3UL, 6UL + 4UL, 9UL, 3UL; 9UL, 4UL, 3UL + 5UL, 6UL, 1UL; 6UL, 5UL, 1UL + 6UL, 7UL, 2UL; 7UL, 6UL, 2UL + 7UL, 8UL, 1UL; 8UL, 7UL, 1UL + 8UL, 9UL, 4UL; 9UL, 8UL, 4UL] + ) + ) + +[] +let ``Level bfs 10 node random start 0`` () = + let n = uint64 random10graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_level random10graph start + Assert.Equal(Ok [ Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 4UL; Some 1UL; Some 2UL; Some 3UL; Some 4UL; Some 5UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 10 node random start 0`` () = + let n = uint64 random10graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_parent random10graph start + Assert.Equal(Ok [ Some 0UL; Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 4UL ], Result.map (unsafes n) result) + +[] +let ``Level bfs 10 node random start 9`` () = + let n = uint64 random10graph.ncols + let start = singleStart n 9UL + let result = Graph.BFS.bfs_level random10graph start + Assert.Equal(Ok [ Some 5UL; Some 4UL; Some 3UL; Some 2UL; Some 1UL; Some 4UL; Some 3UL; Some 2UL; Some 1UL; Some 0UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 10 node random start 9`` () = + let n = uint64 random10graph.ncols + let start = singleStart n 9UL + let result = Graph.BFS.bfs_parent random10graph start + Assert.Equal(Ok [ Some 1UL; Some 2UL; Some 3UL; Some 4UL; Some 9UL; Some 6UL; Some 7UL; Some 8UL; Some 9UL; Some 9UL ], Result.map (unsafes n) result) + +[] +let ``Level bfs 10 node random start 5`` () = + let n = uint64 random10graph.ncols + let start = singleStart n 5UL + let result = Graph.BFS.bfs_level random10graph start + Assert.Equal(Ok [ Some 1UL; Some 2UL; Some 3UL; Some 4UL; Some 5UL; Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 4UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 10 node random start 5`` () = + let n = uint64 random10graph.ncols + let start = singleStart n 5UL + let result = Graph.BFS.bfs_parent random10graph start + Assert.Equal(Ok [ Some 5UL; Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 5UL; Some 5UL; Some 6UL; Some 7UL; Some 8UL ], Result.map (unsafes n) result) + +// ============== 12 nodes big ============== + +let private big12graph = + Matrix.fromCoordinateList ( + Matrix.CoordinateList( + 12UL, + 12UL, + [0UL, 1UL, 1UL; 1UL, 0UL, 1UL + 1UL, 11UL, 1UL; 11UL, 1UL, 1UL + 0UL, 11UL, 1UL; 11UL, 0UL, 1UL + 2UL, 3UL, 1UL; 3UL, 2UL, 1UL + 3UL, 4UL, 1UL; 4UL, 3UL, 1UL + 2UL, 4UL, 1UL; 4UL, 2UL, 1UL + 5UL, 6UL, 1UL; 6UL, 5UL, 1UL + 6UL, 7UL, 1UL; 7UL, 6UL, 1UL + 5UL, 7UL, 1UL; 7UL, 5UL, 1UL + 8UL, 9UL, 1UL; 9UL, 8UL, 1UL + 9UL, 10UL, 1UL; 10UL, 9UL, 1UL + 8UL, 10UL, 1UL; 10UL, 8UL, 1UL + 1UL, 2UL, 2UL; 2UL, 1UL, 2UL + 11UL, 4UL, 2UL; 4UL, 11UL, 2UL + 10UL, 5UL, 2UL; 5UL, 10UL, 2UL + 8UL, 7UL, 2UL; 7UL, 8UL, 2UL + 10UL, 11UL, 3UL; 11UL, 10UL, 3UL + 5UL, 4UL, 3UL; 4UL, 5UL, 3UL] + ) + ) + +[] +let ``Level bfs 12 node big start 0`` () = + let n = uint64 big12graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_level big12graph start + Assert.Equal(Ok [ Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 2UL; Some 3UL; Some 4UL; Some 4UL; Some 3UL; Some 3UL; Some 2UL; Some 1UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 12 node big start 0`` () = + let n = uint64 big12graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_parent big12graph start + Assert.Equal(Ok [ Some 0UL; Some 0UL; Some 1UL; Some 2UL; Some 11UL; Some 4UL; Some 5UL; Some 5UL; Some 10UL; Some 10UL; Some 11UL; Some 0UL ], Result.map (unsafes n) result) + +[] +let ``Level bfs 12 node big start 11`` () = + let n = uint64 big12graph.ncols + let start = singleStart n 11UL + let result = Graph.BFS.bfs_level big12graph start + Assert.Equal(Ok [ Some 1UL; Some 1UL; Some 2UL; Some 2UL; Some 1UL; Some 2UL; Some 3UL; Some 3UL; Some 2UL; Some 2UL; Some 1UL; Some 0UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 12 node big start 11`` () = + let n = uint64 big12graph.ncols + let start = singleStart n 11UL + let result = Graph.BFS.bfs_parent big12graph start + Assert.Equal(Ok [ Some 11UL; Some 11UL; Some 1UL; Some 4UL; Some 11UL; Some 4UL; Some 5UL; Some 5UL; Some 10UL; Some 10UL; Some 11UL; Some 11UL ], Result.map (unsafes n) result) + +[] +let ``Level bfs 12 node big start 6`` () = + let n = uint64 big12graph.ncols + let start = singleStart n 6UL + let result = Graph.BFS.bfs_level big12graph start + Assert.Equal(Ok [ Some 4UL; Some 4UL; Some 3UL; Some 3UL; Some 2UL; Some 1UL; Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 2UL; Some 3UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 12 node big start 6`` () = + let n = uint64 big12graph.ncols + let start = singleStart n 6UL + let result = Graph.BFS.bfs_parent big12graph start + Assert.Equal(Ok [ Some 11UL; Some 2UL; Some 4UL; Some 4UL; Some 5UL; Some 6UL; Some 6UL; Some 6UL; Some 7UL; Some 8UL; Some 5UL; Some 4UL ], Result.map (unsafes n) result) + +// ============== 10 nodes complex line ============== + +let private complexLine10graph = + Matrix.fromCoordinateList ( + Matrix.CoordinateList( + 10UL, + 10UL, + [0UL, 1UL, 1UL; 1UL, 0UL, 1UL + 1UL, 2UL, 2UL; 2UL, 1UL, 2UL + 2UL, 3UL, 1UL; 3UL, 2UL, 1UL + 3UL, 4UL, 3UL; 4UL, 3UL, 3UL + 4UL, 5UL, 1UL; 5UL, 4UL, 1UL + 5UL, 6UL, 1UL; 6UL, 5UL, 1UL + 6UL, 7UL, 2UL; 7UL, 6UL, 2UL + 7UL, 8UL, 1UL; 8UL, 7UL, 1UL + 8UL, 9UL, 1UL; 9UL, 8UL, 1UL] + ) + ) + +[] +let ``Level bfs 10 node complex line start 0`` () = + let n = uint64 complexLine10graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_level complexLine10graph start + Assert.Equal(Ok [ Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 4UL; Some 5UL; Some 6UL; Some 7UL; Some 8UL; Some 9UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 10 node complex line start 0`` () = + let n = uint64 complexLine10graph.ncols + let start = singleStart n 0UL + let result = Graph.BFS.bfs_parent complexLine10graph start + Assert.Equal(Ok [ Some 0UL; Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 4UL; Some 5UL; Some 6UL; Some 7UL; Some 8UL ], Result.map (unsafes n) result) + +[] +let ``Level bfs 10 node complex line start 9`` () = + let n = uint64 complexLine10graph.ncols + let start = singleStart n 9UL + let result = Graph.BFS.bfs_level complexLine10graph start + Assert.Equal(Ok [ Some 9UL; Some 8UL; Some 7UL; Some 6UL; Some 5UL; Some 4UL; Some 3UL; Some 2UL; Some 1UL; Some 0UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 10 node complex line start 9`` () = + let n = uint64 complexLine10graph.ncols + let start = singleStart n 9UL + let result = Graph.BFS.bfs_parent complexLine10graph start + Assert.Equal(Ok [ Some 1UL; Some 2UL; Some 3UL; Some 4UL; Some 5UL; Some 6UL; Some 7UL; Some 8UL; Some 9UL; Some 9UL ], Result.map (unsafes n) result) + +[] +let ``Level bfs 10 node complex line start 5`` () = + let n = uint64 complexLine10graph.ncols + let start = singleStart n 5UL + let result = Graph.BFS.bfs_level complexLine10graph start + Assert.Equal(Ok [ Some 5UL; Some 4UL; Some 3UL; Some 2UL; Some 1UL; Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 4UL ], Result.map (unsafes n) result) + +[] +let ``Parent bfs 10 node complex line start 5`` () = + let n = uint64 complexLine10graph.ncols + let start = singleStart n 5UL + let result = Graph.BFS.bfs_parent complexLine10graph start + Assert.Equal(Ok [ Some 1UL; Some 2UL; Some 3UL; Some 4UL; Some 5UL; Some 5UL; Some 5UL; Some 6UL; Some 7UL; Some 8UL ], Result.map (unsafes n) result) + From 1b6479ee7afbe66312cb7433d3a9010b7c0ff30d Mon Sep 17 00:00:00 2001 From: gsv Date: Mon, 1 Jun 2026 18:29:45 +0300 Subject: [PATCH 12/13] Added Parent-BFS --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 16532d8..bd6ec23 100644 --- a/README.md +++ b/README.md @@ -9,13 +9,13 @@ Infrastructure for benchmarking the implemented algorithms is available in the [ ## Implemented Algorithms * Single-source level BFS +* Single-source parent BFS * Single-source shortest path (SSSP) * Triangles counting * Boruvka MSF * Maggs-Plotkin MSF ## TODO -* [ ] Single-source parent BFS * [ ] Multiple-source level BFS * [ ] Multiple-source parent BFS * [ ] PageRank From a09b299b53bc4f881ebf6328907c1928c97cff67 Mon Sep 17 00:00:00 2001 From: gsv Date: Mon, 1 Jun 2026 18:49:56 +0300 Subject: [PATCH 13/13] Formatted. --- QuadTree.Tests/Tests.BFS.fs | 854 ++++++++++++++++++++------ QuadTree.Tests/Tests.LinearAlgebra.fs | 10 +- QuadTree/BFS.fs | 3 +- 3 files changed, 675 insertions(+), 192 deletions(-) diff --git a/QuadTree.Tests/Tests.BFS.fs b/QuadTree.Tests/Tests.BFS.fs index e18997a..49bc80b 100644 --- a/QuadTree.Tests/Tests.BFS.fs +++ b/QuadTree.Tests/Tests.BFS.fs @@ -8,10 +8,7 @@ open Vector open Common let singleStart (n: uint64) (s: uint64) = - Vector.CoordinateList( - n * 1UL, - [s * 1UL, 1UL] - ) + Vector.CoordinateList(n * 1UL, [ s * 1UL, 1UL ]) |> Vector.fromCoordinateList let vec (n: uint64) pairs = @@ -120,10 +117,7 @@ let ``Simple parent bfs.`` () = let tree = Vector.btree.Node( Vector.btree.Leaf(UserValue(Some(0UL))), - Vector.btree.Node( - Vector.btree.Leaf(UserValue(Some(0UL))), - Vector.btree.Leaf(UserValue(Some(1UL))) - ) + Vector.btree.Node(Vector.btree.Leaf(UserValue(Some(0UL))), Vector.btree.Leaf(UserValue(Some(1UL)))) ) let store = Vector.Storage(4UL, tree) @@ -140,10 +134,10 @@ let private line3graph = Matrix.CoordinateList( 3UL, 3UL, - [0UL, 1UL, 1UL - 1UL, 0UL, 1UL - 1UL, 2UL, 1UL - 2UL, 1UL, 1UL] + [ 0UL, 1UL, 1UL + 1UL, 0UL, 1UL + 1UL, 2UL, 1UL + 2UL, 1UL, 1UL ] ) ) @@ -186,14 +180,14 @@ let private star5graph = Matrix.CoordinateList( 5UL, 5UL, - [0UL, 1UL, 1UL - 1UL, 0UL, 1UL - 0UL, 2UL, 1UL - 2UL, 0UL, 1UL - 0UL, 3UL, 1UL - 3UL, 0UL, 1UL - 0UL, 4UL, 1UL - 4UL, 0UL, 1UL] + [ 0UL, 1UL, 1UL + 1UL, 0UL, 1UL + 0UL, 2UL, 1UL + 2UL, 0UL, 1UL + 0UL, 3UL, 1UL + 3UL, 0UL, 1UL + 0UL, 4UL, 1UL + 4UL, 0UL, 1UL ] ) ) @@ -236,19 +230,19 @@ let private twoCompGraph = Matrix.CoordinateList( 6UL, 6UL, - [0UL, 1UL, 1UL - 1UL, 0UL, 1UL - 1UL, 2UL, 1UL - 2UL, 1UL, 1UL - 0UL, 2UL, 1UL - 2UL, 0UL, 1UL - - 3UL, 4UL, 1UL - 4UL, 3UL, 1UL - 4UL, 5UL, 1UL - 5UL, 4UL, 1UL - 3UL, 5UL, 1UL - 5UL, 3UL, 1UL] + [ 0UL, 1UL, 1UL + 1UL, 0UL, 1UL + 1UL, 2UL, 1UL + 2UL, 1UL, 1UL + 0UL, 2UL, 1UL + 2UL, 0UL, 1UL + + 3UL, 4UL, 1UL + 4UL, 3UL, 1UL + 4UL, 5UL, 1UL + 5UL, 4UL, 1UL + 3UL, 5UL, 1UL + 5UL, 3UL, 1UL ] ) ) @@ -257,9 +251,7 @@ let ``Level bfs two components start 0`` () = let n = uint64 twoCompGraph.ncols let start = singleStart n 0UL let result = Graph.BFS.bfs_level twoCompGraph start - let expected = - [ Some 0UL; Some 1UL; Some 1UL - None; None; None ] + let expected = [ Some 0UL; Some 1UL; Some 1UL; None; None; None ] Assert.Equal(Ok expected, Result.map (unsafes n) result) [] @@ -267,9 +259,7 @@ let ``Parent bfs two components start 0`` () = let n = uint64 twoCompGraph.ncols let start = singleStart n 0UL let result = Graph.BFS.bfs_parent twoCompGraph start - let expected = - [ Some 0UL; Some 0UL; Some 0UL - None; None; None ] + let expected = [ Some 0UL; Some 0UL; Some 0UL; None; None; None ] Assert.Equal(Ok expected, Result.map (unsafes n) result) // ============== Square (4-cycle) ============== @@ -279,14 +269,14 @@ let private squareGraph = Matrix.CoordinateList( 4UL, 4UL, - [0UL, 1UL, 1UL - 1UL, 0UL, 1UL - 1UL, 2UL, 2UL - 2UL, 1UL, 2UL - 2UL, 3UL, 1UL - 3UL, 2UL, 1UL - 3UL, 0UL, 2UL - 0UL, 3UL, 2UL] + [ 0UL, 1UL, 1UL + 1UL, 0UL, 1UL + 1UL, 2UL, 2UL + 2UL, 1UL, 2UL + 2UL, 3UL, 1UL + 3UL, 2UL, 1UL + 3UL, 0UL, 2UL + 0UL, 3UL, 2UL ] ) ) @@ -313,18 +303,18 @@ let private cycle6graph = Matrix.CoordinateList( 6UL, 6UL, - [0UL, 1UL, 1UL - 1UL, 0UL, 1UL - 1UL, 2UL, 2UL - 2UL, 1UL, 2UL - 2UL, 3UL, 3UL - 3UL, 2UL, 3UL - 3UL, 4UL, 4UL - 4UL, 3UL, 4UL - 4UL, 5UL, 5UL - 5UL, 4UL, 5UL - 5UL, 0UL, 6UL - 0UL, 5UL, 6UL] + [ 0UL, 1UL, 1UL + 1UL, 0UL, 1UL + 1UL, 2UL, 2UL + 2UL, 1UL, 2UL + 2UL, 3UL, 3UL + 3UL, 2UL, 3UL + 3UL, 4UL, 4UL + 4UL, 3UL, 4UL + 4UL, 5UL, 5UL + 5UL, 4UL, 5UL + 5UL, 0UL, 6UL + 0UL, 5UL, 6UL ] ) ) @@ -351,7 +341,7 @@ let private graph2 = Matrix.CoordinateList( 2UL, 2UL, - [0UL, 1UL, 5UL; 1UL, 0UL, 5UL] + [ 0UL, 1UL, 5UL; 1UL, 0UL, 5UL ] ) ) @@ -390,9 +380,12 @@ let private line4graph = Matrix.CoordinateList( 4UL, 4UL, - [0UL, 1UL, 1UL; 1UL, 0UL, 1UL - 1UL, 2UL, 2UL; 2UL, 1UL, 2UL - 2UL, 3UL, 3UL; 3UL, 2UL, 3UL] + [ 0UL, 1UL, 1UL + 1UL, 0UL, 1UL + 1UL, 2UL, 2UL + 2UL, 1UL, 2UL + 2UL, 3UL, 3UL + 3UL, 2UL, 3UL ] ) ) @@ -431,10 +424,14 @@ let private line5graph = Matrix.CoordinateList( 5UL, 5UL, - [0UL, 1UL, 1UL; 1UL, 0UL, 1UL - 1UL, 2UL, 2UL; 2UL, 1UL, 2UL - 2UL, 3UL, 3UL; 3UL, 2UL, 3UL - 3UL, 4UL, 4UL; 4UL, 3UL, 4UL] + [ 0UL, 1UL, 1UL + 1UL, 0UL, 1UL + 1UL, 2UL, 2UL + 2UL, 1UL, 2UL + 2UL, 3UL, 3UL + 3UL, 2UL, 3UL + 3UL, 4UL, 4UL + 4UL, 3UL, 4UL ] ) ) @@ -487,9 +484,12 @@ let private triangleGraph = Matrix.CoordinateList( 3UL, 3UL, - [0UL, 1UL, 1UL; 1UL, 0UL, 1UL - 0UL, 2UL, 1UL; 2UL, 0UL, 1UL - 1UL, 2UL, 1UL; 2UL, 1UL, 1UL] + [ 0UL, 1UL, 1UL + 1UL, 0UL, 1UL + 0UL, 2UL, 1UL + 2UL, 0UL, 1UL + 1UL, 2UL, 1UL + 2UL, 1UL, 1UL ] ) ) @@ -528,16 +528,26 @@ let private complete5graph = Matrix.CoordinateList( 5UL, 5UL, - [0UL, 1UL, 1UL; 1UL, 0UL, 1UL - 0UL, 2UL, 2UL; 2UL, 0UL, 2UL - 0UL, 3UL, 3UL; 3UL, 0UL, 3UL - 0UL, 4UL, 4UL; 4UL, 0UL, 4UL - 1UL, 2UL, 5UL; 2UL, 1UL, 5UL - 1UL, 3UL, 6UL; 3UL, 1UL, 6UL - 1UL, 4UL, 7UL; 4UL, 1UL, 7UL - 2UL, 3UL, 8UL; 3UL, 2UL, 8UL - 2UL, 4UL, 9UL; 4UL, 2UL, 9UL - 3UL, 4UL,10UL; 4UL, 3UL,10UL] + [ 0UL, 1UL, 1UL + 1UL, 0UL, 1UL + 0UL, 2UL, 2UL + 2UL, 0UL, 2UL + 0UL, 3UL, 3UL + 3UL, 0UL, 3UL + 0UL, 4UL, 4UL + 4UL, 0UL, 4UL + 1UL, 2UL, 5UL + 2UL, 1UL, 5UL + 1UL, 3UL, 6UL + 3UL, 1UL, 6UL + 1UL, 4UL, 7UL + 4UL, 1UL, 7UL + 2UL, 3UL, 8UL + 3UL, 2UL, 8UL + 2UL, 4UL, 9UL + 4UL, 2UL, 9UL + 3UL, 4UL, 10UL + 4UL, 3UL, 10UL ] ) ) @@ -590,15 +600,24 @@ let private k33graph = Matrix.CoordinateList( 6UL, 6UL, - [0UL, 3UL, 1UL; 3UL, 0UL, 1UL - 0UL, 4UL, 2UL; 4UL, 0UL, 2UL - 0UL, 5UL, 3UL; 5UL, 0UL, 3UL - 1UL, 3UL, 4UL; 3UL, 1UL, 4UL - 1UL, 4UL, 5UL; 4UL, 1UL, 5UL - 1UL, 5UL, 6UL; 5UL, 1UL, 6UL - 2UL, 3UL, 7UL; 3UL, 2UL, 7UL - 2UL, 4UL, 8UL; 4UL, 2UL, 8UL - 2UL, 5UL, 9UL; 5UL, 2UL, 9UL] + [ 0UL, 3UL, 1UL + 3UL, 0UL, 1UL + 0UL, 4UL, 2UL + 4UL, 0UL, 2UL + 0UL, 5UL, 3UL + 5UL, 0UL, 3UL + 1UL, 3UL, 4UL + 3UL, 1UL, 4UL + 1UL, 4UL, 5UL + 4UL, 1UL, 5UL + 1UL, 5UL, 6UL + 5UL, 1UL, 6UL + 2UL, 3UL, 7UL + 3UL, 2UL, 7UL + 2UL, 4UL, 8UL + 4UL, 2UL, 8UL + 2UL, 5UL, 9UL + 5UL, 2UL, 9UL ] ) ) @@ -651,19 +670,32 @@ let private random8graph = Matrix.CoordinateList( 8UL, 8UL, - [0UL, 1UL, 7UL; 1UL, 0UL, 7UL - 0UL, 2UL, 5UL; 2UL, 0UL, 5UL - 0UL, 3UL, 9UL; 3UL, 0UL, 9UL - 1UL, 2UL, 3UL; 2UL, 1UL, 3UL - 1UL, 3UL, 4UL; 3UL, 1UL, 4UL - 2UL, 3UL, 2UL; 3UL, 2UL, 2UL - 4UL, 5UL, 1UL; 5UL, 4UL, 1UL - 4UL, 6UL, 6UL; 6UL, 4UL, 6UL - 4UL, 7UL, 8UL; 7UL, 4UL, 8UL - 5UL, 6UL, 3UL; 6UL, 5UL, 3UL - 5UL, 7UL, 5UL; 7UL, 5UL, 5UL - 6UL, 7UL, 2UL; 7UL, 6UL, 2UL - 3UL, 4UL,10UL; 4UL, 3UL,10UL] + [ 0UL, 1UL, 7UL + 1UL, 0UL, 7UL + 0UL, 2UL, 5UL + 2UL, 0UL, 5UL + 0UL, 3UL, 9UL + 3UL, 0UL, 9UL + 1UL, 2UL, 3UL + 2UL, 1UL, 3UL + 1UL, 3UL, 4UL + 3UL, 1UL, 4UL + 2UL, 3UL, 2UL + 3UL, 2UL, 2UL + 4UL, 5UL, 1UL + 5UL, 4UL, 1UL + 4UL, 6UL, 6UL + 6UL, 4UL, 6UL + 4UL, 7UL, 8UL + 7UL, 4UL, 8UL + 5UL, 6UL, 3UL + 6UL, 5UL, 3UL + 5UL, 7UL, 5UL + 7UL, 5UL, 5UL + 6UL, 7UL, 2UL + 7UL, 6UL, 2UL + 3UL, 4UL, 10UL + 4UL, 3UL, 10UL ] ) ) @@ -672,42 +704,114 @@ let ``Level bfs 8 node random start 0`` () = let n = uint64 random8graph.ncols let start = singleStart n 0UL let result = Graph.BFS.bfs_level random8graph start - Assert.Equal(Ok [ Some 0UL; Some 1UL; Some 1UL; Some 1UL; Some 2UL; Some 3UL; Some 3UL; Some 3UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 0UL + Some 1UL + Some 1UL + Some 1UL + Some 2UL + Some 3UL + Some 3UL + Some 3UL ], + Result.map (unsafes n) result + ) [] let ``Parent bfs 8 node random start 0`` () = let n = uint64 random8graph.ncols let start = singleStart n 0UL let result = Graph.BFS.bfs_parent random8graph start - Assert.Equal(Ok [ Some 0UL; Some 0UL; Some 0UL; Some 0UL; Some 3UL; Some 4UL; Some 4UL; Some 4UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 0UL + Some 0UL + Some 0UL + Some 0UL + Some 3UL + Some 4UL + Some 4UL + Some 4UL ], + Result.map (unsafes n) result + ) [] let ``Level bfs 8 node random start 7`` () = let n = uint64 random8graph.ncols let start = singleStart n 7UL let result = Graph.BFS.bfs_level random8graph start - Assert.Equal(Ok [ Some 3UL; Some 3UL; Some 3UL; Some 2UL; Some 1UL; Some 1UL; Some 1UL; Some 0UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 3UL + Some 3UL + Some 3UL + Some 2UL + Some 1UL + Some 1UL + Some 1UL + Some 0UL ], + Result.map (unsafes n) result + ) [] let ``Parent bfs 8 node random start 7`` () = let n = uint64 random8graph.ncols let start = singleStart n 7UL let result = Graph.BFS.bfs_parent random8graph start - Assert.Equal(Ok [ Some 3UL; Some 3UL; Some 3UL; Some 4UL; Some 7UL; Some 7UL; Some 7UL; Some 7UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 3UL + Some 3UL + Some 3UL + Some 4UL + Some 7UL + Some 7UL + Some 7UL + Some 7UL ], + Result.map (unsafes n) result + ) [] let ``Level bfs 8 node random start 4`` () = let n = uint64 random8graph.ncols let start = singleStart n 4UL let result = Graph.BFS.bfs_level random8graph start - Assert.Equal(Ok [ Some 2UL; Some 2UL; Some 2UL; Some 1UL; Some 0UL; Some 1UL; Some 1UL; Some 1UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 2UL + Some 2UL + Some 2UL + Some 1UL + Some 0UL + Some 1UL + Some 1UL + Some 1UL ], + Result.map (unsafes n) result + ) [] let ``Parent bfs 8 node random start 4`` () = let n = uint64 random8graph.ncols let start = singleStart n 4UL let result = Graph.BFS.bfs_parent random8graph start - Assert.Equal(Ok [ Some 3UL; Some 3UL; Some 3UL; Some 4UL; Some 4UL; Some 4UL; Some 4UL; Some 4UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 3UL + Some 3UL + Some 3UL + Some 4UL + Some 4UL + Some 4UL + Some 4UL + Some 4UL ], + Result.map (unsafes n) result + ) // ============== 8 nodes grid ============== @@ -716,16 +820,26 @@ let private grid8graph = Matrix.CoordinateList( 8UL, 8UL, - [0UL, 1UL, 1UL; 1UL, 0UL, 1UL - 1UL, 2UL, 2UL; 2UL, 1UL, 2UL - 2UL, 3UL, 1UL; 3UL, 2UL, 1UL - 0UL, 4UL, 3UL; 4UL, 0UL, 3UL - 1UL, 5UL, 4UL; 5UL, 1UL, 4UL - 2UL, 6UL, 5UL; 6UL, 2UL, 5UL - 3UL, 7UL, 6UL; 7UL, 3UL, 6UL - 4UL, 5UL, 2UL; 5UL, 4UL, 2UL - 5UL, 6UL, 1UL; 6UL, 5UL, 1UL - 6UL, 7UL, 3UL; 7UL, 6UL, 3UL] + [ 0UL, 1UL, 1UL + 1UL, 0UL, 1UL + 1UL, 2UL, 2UL + 2UL, 1UL, 2UL + 2UL, 3UL, 1UL + 3UL, 2UL, 1UL + 0UL, 4UL, 3UL + 4UL, 0UL, 3UL + 1UL, 5UL, 4UL + 5UL, 1UL, 4UL + 2UL, 6UL, 5UL + 6UL, 2UL, 5UL + 3UL, 7UL, 6UL + 7UL, 3UL, 6UL + 4UL, 5UL, 2UL + 5UL, 4UL, 2UL + 5UL, 6UL, 1UL + 6UL, 5UL, 1UL + 6UL, 7UL, 3UL + 7UL, 6UL, 3UL ] ) ) @@ -734,42 +848,114 @@ let ``Level bfs 8 node grid start 0`` () = let n = uint64 grid8graph.ncols let start = singleStart n 0UL let result = Graph.BFS.bfs_level grid8graph start - Assert.Equal(Ok [ Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 1UL; Some 2UL; Some 3UL; Some 4UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 0UL + Some 1UL + Some 2UL + Some 3UL + Some 1UL + Some 2UL + Some 3UL + Some 4UL ], + Result.map (unsafes n) result + ) [] let ``Parent bfs 8 node grid start 0`` () = let n = uint64 grid8graph.ncols let start = singleStart n 0UL let result = Graph.BFS.bfs_parent grid8graph start - Assert.Equal(Ok [ Some 0UL; Some 0UL; Some 1UL; Some 2UL; Some 0UL; Some 1UL; Some 2UL; Some 3UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 0UL + Some 0UL + Some 1UL + Some 2UL + Some 0UL + Some 1UL + Some 2UL + Some 3UL ], + Result.map (unsafes n) result + ) [] let ``Level bfs 8 node grid start 7`` () = let n = uint64 grid8graph.ncols let start = singleStart n 7UL let result = Graph.BFS.bfs_level grid8graph start - Assert.Equal(Ok [ Some 4UL; Some 3UL; Some 2UL; Some 1UL; Some 3UL; Some 2UL; Some 1UL; Some 0UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 4UL + Some 3UL + Some 2UL + Some 1UL + Some 3UL + Some 2UL + Some 1UL + Some 0UL ], + Result.map (unsafes n) result + ) [] let ``Parent bfs 8 node grid start 7`` () = let n = uint64 grid8graph.ncols let start = singleStart n 7UL let result = Graph.BFS.bfs_parent grid8graph start - Assert.Equal(Ok [ Some 1UL; Some 2UL; Some 3UL; Some 7UL; Some 5UL; Some 6UL; Some 7UL; Some 7UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 1UL + Some 2UL + Some 3UL + Some 7UL + Some 5UL + Some 6UL + Some 7UL + Some 7UL ], + Result.map (unsafes n) result + ) [] let ``Level bfs 8 node grid start 4`` () = let n = uint64 grid8graph.ncols let start = singleStart n 4UL let result = Graph.BFS.bfs_level grid8graph start - Assert.Equal(Ok [ Some 1UL; Some 2UL; Some 3UL; Some 4UL; Some 0UL; Some 1UL; Some 2UL; Some 3UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 1UL + Some 2UL + Some 3UL + Some 4UL + Some 0UL + Some 1UL + Some 2UL + Some 3UL ], + Result.map (unsafes n) result + ) [] let ``Parent bfs 8 node grid start 4`` () = let n = uint64 grid8graph.ncols let start = singleStart n 4UL let result = Graph.BFS.bfs_parent grid8graph start - Assert.Equal(Ok [ Some 4UL; Some 0UL; Some 1UL; Some 2UL; Some 4UL; Some 4UL; Some 5UL; Some 6UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 4UL + Some 0UL + Some 1UL + Some 2UL + Some 4UL + Some 4UL + Some 5UL + Some 6UL ], + Result.map (unsafes n) result + ) // ============== 10 nodes random ============== @@ -778,19 +964,32 @@ let private random10graph = Matrix.CoordinateList( 10UL, 10UL, - [0UL, 1UL, 4UL; 1UL, 0UL, 4UL - 0UL, 5UL, 2UL; 5UL, 0UL, 2UL - 1UL, 2UL, 3UL; 2UL, 1UL, 3UL - 1UL, 6UL, 5UL; 6UL, 1UL, 5UL - 2UL, 3UL, 1UL; 3UL, 2UL, 1UL - 2UL, 7UL, 4UL; 7UL, 2UL, 4UL - 3UL, 4UL, 2UL; 4UL, 3UL, 2UL - 3UL, 8UL, 6UL; 8UL, 3UL, 6UL - 4UL, 9UL, 3UL; 9UL, 4UL, 3UL - 5UL, 6UL, 1UL; 6UL, 5UL, 1UL - 6UL, 7UL, 2UL; 7UL, 6UL, 2UL - 7UL, 8UL, 1UL; 8UL, 7UL, 1UL - 8UL, 9UL, 4UL; 9UL, 8UL, 4UL] + [ 0UL, 1UL, 4UL + 1UL, 0UL, 4UL + 0UL, 5UL, 2UL + 5UL, 0UL, 2UL + 1UL, 2UL, 3UL + 2UL, 1UL, 3UL + 1UL, 6UL, 5UL + 6UL, 1UL, 5UL + 2UL, 3UL, 1UL + 3UL, 2UL, 1UL + 2UL, 7UL, 4UL + 7UL, 2UL, 4UL + 3UL, 4UL, 2UL + 4UL, 3UL, 2UL + 3UL, 8UL, 6UL + 8UL, 3UL, 6UL + 4UL, 9UL, 3UL + 9UL, 4UL, 3UL + 5UL, 6UL, 1UL + 6UL, 5UL, 1UL + 6UL, 7UL, 2UL + 7UL, 6UL, 2UL + 7UL, 8UL, 1UL + 8UL, 7UL, 1UL + 8UL, 9UL, 4UL + 9UL, 8UL, 4UL ] ) ) @@ -799,42 +998,126 @@ let ``Level bfs 10 node random start 0`` () = let n = uint64 random10graph.ncols let start = singleStart n 0UL let result = Graph.BFS.bfs_level random10graph start - Assert.Equal(Ok [ Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 4UL; Some 1UL; Some 2UL; Some 3UL; Some 4UL; Some 5UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 0UL + Some 1UL + Some 2UL + Some 3UL + Some 4UL + Some 1UL + Some 2UL + Some 3UL + Some 4UL + Some 5UL ], + Result.map (unsafes n) result + ) [] let ``Parent bfs 10 node random start 0`` () = let n = uint64 random10graph.ncols let start = singleStart n 0UL let result = Graph.BFS.bfs_parent random10graph start - Assert.Equal(Ok [ Some 0UL; Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 4UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 0UL + Some 0UL + Some 1UL + Some 2UL + Some 3UL + Some 0UL + Some 1UL + Some 2UL + Some 3UL + Some 4UL ], + Result.map (unsafes n) result + ) [] let ``Level bfs 10 node random start 9`` () = let n = uint64 random10graph.ncols let start = singleStart n 9UL let result = Graph.BFS.bfs_level random10graph start - Assert.Equal(Ok [ Some 5UL; Some 4UL; Some 3UL; Some 2UL; Some 1UL; Some 4UL; Some 3UL; Some 2UL; Some 1UL; Some 0UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 5UL + Some 4UL + Some 3UL + Some 2UL + Some 1UL + Some 4UL + Some 3UL + Some 2UL + Some 1UL + Some 0UL ], + Result.map (unsafes n) result + ) [] let ``Parent bfs 10 node random start 9`` () = let n = uint64 random10graph.ncols let start = singleStart n 9UL let result = Graph.BFS.bfs_parent random10graph start - Assert.Equal(Ok [ Some 1UL; Some 2UL; Some 3UL; Some 4UL; Some 9UL; Some 6UL; Some 7UL; Some 8UL; Some 9UL; Some 9UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 1UL + Some 2UL + Some 3UL + Some 4UL + Some 9UL + Some 6UL + Some 7UL + Some 8UL + Some 9UL + Some 9UL ], + Result.map (unsafes n) result + ) [] let ``Level bfs 10 node random start 5`` () = let n = uint64 random10graph.ncols let start = singleStart n 5UL let result = Graph.BFS.bfs_level random10graph start - Assert.Equal(Ok [ Some 1UL; Some 2UL; Some 3UL; Some 4UL; Some 5UL; Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 4UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 1UL + Some 2UL + Some 3UL + Some 4UL + Some 5UL + Some 0UL + Some 1UL + Some 2UL + Some 3UL + Some 4UL ], + Result.map (unsafes n) result + ) [] let ``Parent bfs 10 node random start 5`` () = let n = uint64 random10graph.ncols let start = singleStart n 5UL let result = Graph.BFS.bfs_parent random10graph start - Assert.Equal(Ok [ Some 5UL; Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 5UL; Some 5UL; Some 6UL; Some 7UL; Some 8UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 5UL + Some 0UL + Some 1UL + Some 2UL + Some 3UL + Some 5UL + Some 5UL + Some 6UL + Some 7UL + Some 8UL ], + Result.map (unsafes n) result + ) // ============== 12 nodes big ============== @@ -843,24 +1126,42 @@ let private big12graph = Matrix.CoordinateList( 12UL, 12UL, - [0UL, 1UL, 1UL; 1UL, 0UL, 1UL - 1UL, 11UL, 1UL; 11UL, 1UL, 1UL - 0UL, 11UL, 1UL; 11UL, 0UL, 1UL - 2UL, 3UL, 1UL; 3UL, 2UL, 1UL - 3UL, 4UL, 1UL; 4UL, 3UL, 1UL - 2UL, 4UL, 1UL; 4UL, 2UL, 1UL - 5UL, 6UL, 1UL; 6UL, 5UL, 1UL - 6UL, 7UL, 1UL; 7UL, 6UL, 1UL - 5UL, 7UL, 1UL; 7UL, 5UL, 1UL - 8UL, 9UL, 1UL; 9UL, 8UL, 1UL - 9UL, 10UL, 1UL; 10UL, 9UL, 1UL - 8UL, 10UL, 1UL; 10UL, 8UL, 1UL - 1UL, 2UL, 2UL; 2UL, 1UL, 2UL - 11UL, 4UL, 2UL; 4UL, 11UL, 2UL - 10UL, 5UL, 2UL; 5UL, 10UL, 2UL - 8UL, 7UL, 2UL; 7UL, 8UL, 2UL - 10UL, 11UL, 3UL; 11UL, 10UL, 3UL - 5UL, 4UL, 3UL; 4UL, 5UL, 3UL] + [ 0UL, 1UL, 1UL + 1UL, 0UL, 1UL + 1UL, 11UL, 1UL + 11UL, 1UL, 1UL + 0UL, 11UL, 1UL + 11UL, 0UL, 1UL + 2UL, 3UL, 1UL + 3UL, 2UL, 1UL + 3UL, 4UL, 1UL + 4UL, 3UL, 1UL + 2UL, 4UL, 1UL + 4UL, 2UL, 1UL + 5UL, 6UL, 1UL + 6UL, 5UL, 1UL + 6UL, 7UL, 1UL + 7UL, 6UL, 1UL + 5UL, 7UL, 1UL + 7UL, 5UL, 1UL + 8UL, 9UL, 1UL + 9UL, 8UL, 1UL + 9UL, 10UL, 1UL + 10UL, 9UL, 1UL + 8UL, 10UL, 1UL + 10UL, 8UL, 1UL + 1UL, 2UL, 2UL + 2UL, 1UL, 2UL + 11UL, 4UL, 2UL + 4UL, 11UL, 2UL + 10UL, 5UL, 2UL + 5UL, 10UL, 2UL + 8UL, 7UL, 2UL + 7UL, 8UL, 2UL + 10UL, 11UL, 3UL + 11UL, 10UL, 3UL + 5UL, 4UL, 3UL + 4UL, 5UL, 3UL ] ) ) @@ -869,42 +1170,138 @@ let ``Level bfs 12 node big start 0`` () = let n = uint64 big12graph.ncols let start = singleStart n 0UL let result = Graph.BFS.bfs_level big12graph start - Assert.Equal(Ok [ Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 2UL; Some 3UL; Some 4UL; Some 4UL; Some 3UL; Some 3UL; Some 2UL; Some 1UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 0UL + Some 1UL + Some 2UL + Some 3UL + Some 2UL + Some 3UL + Some 4UL + Some 4UL + Some 3UL + Some 3UL + Some 2UL + Some 1UL ], + Result.map (unsafes n) result + ) [] let ``Parent bfs 12 node big start 0`` () = let n = uint64 big12graph.ncols let start = singleStart n 0UL let result = Graph.BFS.bfs_parent big12graph start - Assert.Equal(Ok [ Some 0UL; Some 0UL; Some 1UL; Some 2UL; Some 11UL; Some 4UL; Some 5UL; Some 5UL; Some 10UL; Some 10UL; Some 11UL; Some 0UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 0UL + Some 0UL + Some 1UL + Some 2UL + Some 11UL + Some 4UL + Some 5UL + Some 5UL + Some 10UL + Some 10UL + Some 11UL + Some 0UL ], + Result.map (unsafes n) result + ) [] let ``Level bfs 12 node big start 11`` () = let n = uint64 big12graph.ncols let start = singleStart n 11UL let result = Graph.BFS.bfs_level big12graph start - Assert.Equal(Ok [ Some 1UL; Some 1UL; Some 2UL; Some 2UL; Some 1UL; Some 2UL; Some 3UL; Some 3UL; Some 2UL; Some 2UL; Some 1UL; Some 0UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 1UL + Some 1UL + Some 2UL + Some 2UL + Some 1UL + Some 2UL + Some 3UL + Some 3UL + Some 2UL + Some 2UL + Some 1UL + Some 0UL ], + Result.map (unsafes n) result + ) [] let ``Parent bfs 12 node big start 11`` () = let n = uint64 big12graph.ncols let start = singleStart n 11UL let result = Graph.BFS.bfs_parent big12graph start - Assert.Equal(Ok [ Some 11UL; Some 11UL; Some 1UL; Some 4UL; Some 11UL; Some 4UL; Some 5UL; Some 5UL; Some 10UL; Some 10UL; Some 11UL; Some 11UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 11UL + Some 11UL + Some 1UL + Some 4UL + Some 11UL + Some 4UL + Some 5UL + Some 5UL + Some 10UL + Some 10UL + Some 11UL + Some 11UL ], + Result.map (unsafes n) result + ) [] let ``Level bfs 12 node big start 6`` () = let n = uint64 big12graph.ncols let start = singleStart n 6UL let result = Graph.BFS.bfs_level big12graph start - Assert.Equal(Ok [ Some 4UL; Some 4UL; Some 3UL; Some 3UL; Some 2UL; Some 1UL; Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 2UL; Some 3UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 4UL + Some 4UL + Some 3UL + Some 3UL + Some 2UL + Some 1UL + Some 0UL + Some 1UL + Some 2UL + Some 3UL + Some 2UL + Some 3UL ], + Result.map (unsafes n) result + ) [] let ``Parent bfs 12 node big start 6`` () = let n = uint64 big12graph.ncols let start = singleStart n 6UL let result = Graph.BFS.bfs_parent big12graph start - Assert.Equal(Ok [ Some 11UL; Some 2UL; Some 4UL; Some 4UL; Some 5UL; Some 6UL; Some 6UL; Some 6UL; Some 7UL; Some 8UL; Some 5UL; Some 4UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 11UL + Some 2UL + Some 4UL + Some 4UL + Some 5UL + Some 6UL + Some 6UL + Some 6UL + Some 7UL + Some 8UL + Some 5UL + Some 4UL ], + Result.map (unsafes n) result + ) // ============== 10 nodes complex line ============== @@ -913,15 +1310,24 @@ let private complexLine10graph = Matrix.CoordinateList( 10UL, 10UL, - [0UL, 1UL, 1UL; 1UL, 0UL, 1UL - 1UL, 2UL, 2UL; 2UL, 1UL, 2UL - 2UL, 3UL, 1UL; 3UL, 2UL, 1UL - 3UL, 4UL, 3UL; 4UL, 3UL, 3UL - 4UL, 5UL, 1UL; 5UL, 4UL, 1UL - 5UL, 6UL, 1UL; 6UL, 5UL, 1UL - 6UL, 7UL, 2UL; 7UL, 6UL, 2UL - 7UL, 8UL, 1UL; 8UL, 7UL, 1UL - 8UL, 9UL, 1UL; 9UL, 8UL, 1UL] + [ 0UL, 1UL, 1UL + 1UL, 0UL, 1UL + 1UL, 2UL, 2UL + 2UL, 1UL, 2UL + 2UL, 3UL, 1UL + 3UL, 2UL, 1UL + 3UL, 4UL, 3UL + 4UL, 3UL, 3UL + 4UL, 5UL, 1UL + 5UL, 4UL, 1UL + 5UL, 6UL, 1UL + 6UL, 5UL, 1UL + 6UL, 7UL, 2UL + 7UL, 6UL, 2UL + 7UL, 8UL, 1UL + 8UL, 7UL, 1UL + 8UL, 9UL, 1UL + 9UL, 8UL, 1UL ] ) ) @@ -930,41 +1336,123 @@ let ``Level bfs 10 node complex line start 0`` () = let n = uint64 complexLine10graph.ncols let start = singleStart n 0UL let result = Graph.BFS.bfs_level complexLine10graph start - Assert.Equal(Ok [ Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 4UL; Some 5UL; Some 6UL; Some 7UL; Some 8UL; Some 9UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 0UL + Some 1UL + Some 2UL + Some 3UL + Some 4UL + Some 5UL + Some 6UL + Some 7UL + Some 8UL + Some 9UL ], + Result.map (unsafes n) result + ) [] let ``Parent bfs 10 node complex line start 0`` () = let n = uint64 complexLine10graph.ncols let start = singleStart n 0UL let result = Graph.BFS.bfs_parent complexLine10graph start - Assert.Equal(Ok [ Some 0UL; Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 4UL; Some 5UL; Some 6UL; Some 7UL; Some 8UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 0UL + Some 0UL + Some 1UL + Some 2UL + Some 3UL + Some 4UL + Some 5UL + Some 6UL + Some 7UL + Some 8UL ], + Result.map (unsafes n) result + ) [] let ``Level bfs 10 node complex line start 9`` () = let n = uint64 complexLine10graph.ncols let start = singleStart n 9UL let result = Graph.BFS.bfs_level complexLine10graph start - Assert.Equal(Ok [ Some 9UL; Some 8UL; Some 7UL; Some 6UL; Some 5UL; Some 4UL; Some 3UL; Some 2UL; Some 1UL; Some 0UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 9UL + Some 8UL + Some 7UL + Some 6UL + Some 5UL + Some 4UL + Some 3UL + Some 2UL + Some 1UL + Some 0UL ], + Result.map (unsafes n) result + ) [] let ``Parent bfs 10 node complex line start 9`` () = let n = uint64 complexLine10graph.ncols let start = singleStart n 9UL let result = Graph.BFS.bfs_parent complexLine10graph start - Assert.Equal(Ok [ Some 1UL; Some 2UL; Some 3UL; Some 4UL; Some 5UL; Some 6UL; Some 7UL; Some 8UL; Some 9UL; Some 9UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 1UL + Some 2UL + Some 3UL + Some 4UL + Some 5UL + Some 6UL + Some 7UL + Some 8UL + Some 9UL + Some 9UL ], + Result.map (unsafes n) result + ) [] let ``Level bfs 10 node complex line start 5`` () = let n = uint64 complexLine10graph.ncols let start = singleStart n 5UL let result = Graph.BFS.bfs_level complexLine10graph start - Assert.Equal(Ok [ Some 5UL; Some 4UL; Some 3UL; Some 2UL; Some 1UL; Some 0UL; Some 1UL; Some 2UL; Some 3UL; Some 4UL ], Result.map (unsafes n) result) + + Assert.Equal( + Ok + [ Some 5UL + Some 4UL + Some 3UL + Some 2UL + Some 1UL + Some 0UL + Some 1UL + Some 2UL + Some 3UL + Some 4UL ], + Result.map (unsafes n) result + ) [] let ``Parent bfs 10 node complex line start 5`` () = let n = uint64 complexLine10graph.ncols let start = singleStart n 5UL let result = Graph.BFS.bfs_parent complexLine10graph start - Assert.Equal(Ok [ Some 1UL; Some 2UL; Some 3UL; Some 4UL; Some 5UL; Some 5UL; Some 5UL; Some 6UL; Some 7UL; Some 8UL ], Result.map (unsafes n) result) - + Assert.Equal( + Ok + [ Some 1UL + Some 2UL + Some 3UL + Some 4UL + Some 5UL + Some 5UL + Some 5UL + Some 6UL + Some 7UL + Some 8UL ], + Result.map (unsafes n) result + ) diff --git a/QuadTree.Tests/Tests.LinearAlgebra.fs b/QuadTree.Tests/Tests.LinearAlgebra.fs index 2a891dc..c114e8d 100644 --- a/QuadTree.Tests/Tests.LinearAlgebra.fs +++ b/QuadTree.Tests/Tests.LinearAlgebra.fs @@ -369,10 +369,7 @@ let ``vxmi_values 3x3 line graph start 0. BFS semantics`` () = // [0, N, N, D] = Node(Node(0, N), Node(N, D)) let f = let tree = - Vector.btree.Node( - Vector.btree.Node(vleaf_v 0UL, vleaf_n ()), - Vector.btree.Node(vleaf_n (), vleaf_d ()) - ) + Vector.btree.Node(Vector.btree.Node(vleaf_v 0UL, vleaf_n ()), Vector.btree.Node(vleaf_n (), vleaf_d ())) let store = Vector.Storage(4UL, tree) SparseVector(3UL, 1UL, store) @@ -388,10 +385,7 @@ let ``vxmi_values 3x3 line graph start 0. BFS semantics`` () = let expected = // result = [N, 1, N, D] = Node(Node(N, 1), Node(N, D)) let tree = - Vector.btree.Node( - Vector.btree.Node(vleaf_n (), vleaf_v 1UL), - Vector.btree.Node(vleaf_n (), vleaf_d ()) - ) + Vector.btree.Node(Vector.btree.Node(vleaf_n (), vleaf_v 1UL), Vector.btree.Node(vleaf_n (), vleaf_d ())) let store = Vector.Storage(4UL, tree) Ok(SparseVector(3UL, 1UL, store)) diff --git a/QuadTree/BFS.fs b/QuadTree/BFS.fs index c240ed2..4cda183 100644 --- a/QuadTree/BFS.fs +++ b/QuadTree/BFS.fs @@ -53,7 +53,8 @@ let bfs_level graph startVertices = let initVisited _ v = v |> Option.map (fun _ -> 0UL) - let frontier0 = Vector.mapi startVertices (fun _ v -> v |> Option.map (fun _ -> 0UL)) + let frontier0 = + Vector.mapi startVertices (fun _ v -> v |> Option.map (fun _ -> 0UL)) bfs op_add op_mult initVisited graph frontier0