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.BFS.fs b/QuadTree.Tests/Tests.BFS.fs
index df5d0f3..49bc80b 100644
--- a/QuadTree.Tests/Tests.BFS.fs
+++ b/QuadTree.Tests/Tests.BFS.fs
@@ -7,16 +7,20 @@ 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))
+
[]
let ``Simple level bfs.`` () =
let graph =
@@ -69,3 +73,1386 @@ let ``Simple level bfs.`` () =
let actual = Graph.BFS.bfs_level graph startVertices
Assert.Equal(expected, actual)
+
+[]
+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)
+
+// ============== 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