public void TestDepthFirstSearch()
        {
            // Item1 - the vertices to add to the graph
            // Item2 - the edges to add to the graph
            // Item3 - the list of vertex indices, DFS search is run from
            //         each of these vertices
            // Item4 - the expected result of the DFS search for each of the
            //         vertex indices in the Item3. Item4.Length must be equal
            //         to Item3.Length
            Tuple <string[], byte[, ], int[], string[][]>[] test_vectors =
            {
                new Tuple <string[],                          byte[, ],   int[], string[][]>(
                    new string[] { "A" },
                    new byte[,                                ] {
                    { 0 }
                },
                    new int[] { 0 },
                    new string[][] { new string[] { "A" } }),

                new Tuple <string[],                          byte[, ],   int[], string[][]>(
                    new string[] { "A",                       "B" },
                    new byte[,                                ]
                {
                    { 0,                                        1 },
                    { 1,                                            0 }
                },
                    new int[] { 0,                              1 },
                    new string[][]
                {
                    new string[] { "A",                       "B" },
                    new string[] { "B",                       "A" }
                }),

                new Tuple <string[],                          byte[, ],   int[], string[][]>(
                    new string[] { "A",                       "B",   "C", "D",   "E", "F", "G", "H", "I", "J" },
                    new byte[,                                ]
                {
                    { 0,                                          1,   1,     0,   0,   0,   0,   0,   0,   0 },
                    { 1,                                          0,   1,     1,   0,   0,   0,   0,   0,   0 },
                    { 1,                                          1,   0,     1,   1,   0,   0,   0,   0,   0 },
                    { 0,                                          1,   1,     0,   0,   1,   0,   0,   0,   0 },
                    { 0,                                          0,   1,     0,   0,   1,   1,   0,   1,   0 },
                    { 0,                                          0,   0,     1,   1,   0,   0,   1,   0,   1 },
                    { 0,                                          0,   0,     0,   1,   0,   0,   0,   1,   0 },
                    { 0,                                          0,   0,     0,   0,   1,   0,   0,   0,   0 },
                    { 0,                                          0,   0,     0,   1,   0,   1,   0,   0,   0 },
                    { 0,                                          0,   0,     0,   0,   1,   0,   0,   0,   0 }
                },
                    new int[] { 4,                                9,   2,     7,   3, 0 },
                    new string[][]
                {
                    new string[] { "E",                       "C",   "A", "B",   "D", "F", "H", "J", "G", "I" },
                    new string[] { "J",                       "F",   "D", "B",   "A", "C", "E", "G", "I", "H" },
                    new string[] { "C",                       "A",   "B", "D",   "F", "E", "G", "I", "H", "J" },
                    new string[] { "H",                       "F",   "D", "B",   "A", "C", "E", "G", "I", "J" },
                    new string[] { "D",                       "B",   "A", "C",   "E", "F", "H", "J", "G", "I" },
                    new string[] { "A",                       "B",   "C", "D",   "F", "E", "G", "I", "H", "J" }
                }),

                // The following defines a disconnected graph with 4 distinct
                // sub-graphs
                new Tuple <string[],                          byte[, ],   int[], string[][]>(
                    new string[] { "A",                       "B",   "C", "D",   "E", "F", "G", "H", "I", "J", "K", "L", "M"},
                    new byte[,                                ]
                {
                    { 0,                                          1,   0,     0,   0,   0,   0,   0,   0,0, 0, 0, 0 },
                    { 1,                                          0,   1,     1,   0,   0,   0,   0,   0,0, 0, 0, 0 },
                    { 0,                                          1,   0,     1,   0,   0,   0,   0,   0,0, 0, 0, 0 },
                    { 0,                                          1,   1,     0,   0,   0,   0,   0,   0,0, 0, 0, 0 },
                    { 0,                                          0,   0,     0,   0,   1,   0,   0,   0,0, 0, 0, 0 },
                    { 0,                                          0,   0,     0,   1,   0,   0,   0,   0,0, 0, 0, 0 },
                    { 0,                                          0,   0,     0,   0,   0,   0,   0,   0,0, 0, 0, 0 },
                    { 0,                                          0,   0,     0,   0,   0,   0,   0,   1,0, 0, 0, 1 },
                    { 0,                                          0,   0,     0,   0,   0,   0,   1,   0,1, 0, 0, 0 },
                    { 0,                                          0,   0,     0,   0,   0,   0,   0,   1,0, 1, 1, 0 },
                    { 0,                                          0,   0,     0,   0,   0,   0,   0,   0,1, 0, 1, 0 },
                    { 0,                                          0,   0,     0,   0,   0,   0,   0,   0,1, 1, 0, 1 },
                    { 0,                                          0,   0,     0,   0,   0,   0,   1,   0,0, 0, 1, 0 }
                },
                    new int[] { 0,                                2,   4,     5,   6,   8,  12,11 },
                    new string[][]
                {
                    new string[] { "A",                       "B",   "C", "D" },
                    new string[] { "C",                       "B",   "A", "D" },
                    new string[] { "E",                       "F" },
                    new string[] { "F",                       "E" },
                    new string[] { "G" },
                    new string[] { "I",                       "H",   "M", "L",   "J", "K" },
                    new string[] { "M",                       "H",   "I", "J",   "K", "L" },
                    new string[] { "L",                       "J",   "I", "H",   "M", "K" }
                })
            };

            foreach (var test_vector in test_vectors)
            {
                IWeightedGraph <String> graph = new UndirectedWeightedGraph <String>(3);

                // Sanity check
                Assert.AreEqual(test_vector.Item1.Length, test_vector.Item2.GetLength(0));
                Assert.AreEqual(test_vector.Item1.Length, test_vector.Item2.GetLength(1));
                Assert.AreEqual(test_vector.Item3.Length, test_vector.Item4.Length);

                // Add vertices
                foreach (var vertex in test_vector.Item1)
                {
                    graph.AddVertex(vertex);
                }

                // Assert that the graph size is as expected
                Assert.AreEqual(test_vector.Item1.Length, graph.Size);

                // Add edges. Iterate over the upper triangular matrix only
                // as the lower triangular matrix (below the diagonal) must
                // be its mirror.
                for (int row = 0; row < test_vector.Item1.Length; ++row)
                {
                    for (int col = row + 1; col < test_vector.Item1.Length; ++col)
                    {
                        // Sanity check
                        Assert.AreEqual(test_vector.Item2[row, col], test_vector.Item2[col, row]);

                        if (Convert.ToBoolean(test_vector.Item2[row, col]))
                        {
                            graph.AddEdge(row, col, 9.0f);
                        }
                    }
                }

                // Run DFS starting from each vertex in the test_vector.Item3
                int i = 0;
                foreach (var start_vertex_index in test_vector.Item3)
                {
                    IEnumerable <int> iter = graph.DepthFirstSearch(start_vertex_index);

                    int count = 0;
                    foreach (var vertex_index in iter)
                    {
                        // Search must not have visited more vertices than expected
                        Assert.Less(count, test_vector.Item4[i].Length);

                        // Assert that the vertex visited at this point in the search
                        // was the expected one
                        Assert.AreEqual(test_vector.Item4[i][count++], graph.GetVertex(vertex_index));
                    }

                    // Assert that DFS visited expected number of vertices
                    Assert.AreEqual(test_vector.Item4[i++].Length, count);
                }
            }
        }
Beispiel #2
0
        public void PrimAlgorithm_ShouldReturnEmptySpanningTreeEdges_WhenTargetGraphHasNoVerticesOrEdges(UndirectedWeightedGraph <int, int> graph)
        {
            var primAlgorithm = PrimTestData.PrimAlgorithm;

            var result = primAlgorithm.Execute(graph);

            Assert.Equal(Enumerable.Empty <Edge <int> >(), result);
        }
        public void TestRemovingEdges()
        {
            IWeightedGraph <int> graph = new UndirectedWeightedGraph <int>(3);

            int[] vertices = { 88, 1, -3, 7, 9, -23, 3, 84, 20, 45 };
            byte[,] edges =
            {
                { 0, 1, 0, 1, 1, 0, 1, 1, 0, 0 },
                { 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 },
                { 0, 1, 0, 1, 1, 0, 0, 0, 1, 1 },
                { 1, 0, 1, 0, 1, 1, 0, 1, 1, 0 },
                { 1, 1, 1, 1, 0, 0, 0, 1, 0, 1 },
                { 0, 0, 0, 1, 0, 0, 1, 1, 0, 0 },
                { 1, 0, 0, 0, 0, 1, 0, 1, 0, 1 },
                { 1, 1, 0, 1, 1, 1, 1, 0, 0, 0 },
                { 0, 0, 1, 1, 0, 0, 0, 0, 0, 1 },
                { 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 }
            };
            Tuple <int, int>[] edges_to_remove =
            {
                new Tuple <int, int>(0, 9),
                new Tuple <int, int>(4, 0),
                new Tuple <int, int>(7, 4),
                new Tuple <int, int>(8, 9),
                new Tuple <int, int>(6, 5),
                new Tuple <int, int>(2, 3),
                new Tuple <int, int>(8, 3),
                new Tuple <int, int>(3, 7),
                new Tuple <int, int>(6, 7),
                new Tuple <int, int>(1, 9)
            };

            // Sanity check
            Assert.AreEqual(vertices.Length, edges.GetLength(0));
            Assert.AreEqual(vertices.Length, edges.GetLength(1));

            // Add vertices
            foreach (var vertex in vertices)
            {
                graph.AddVertex(vertex);
            }

            // Add edges. Iterate over the upper triangular matrix only
            // as the lower triangular matrix (below the diagonal) must
            // be its mirror.
            for (int row = 0; row < vertices.Length; ++row)
            {
                for (int col = row + 1; col < vertices.Length; ++col)
                {
                    // Sanity check
                    Assert.AreEqual(edges[row, col], edges[col, row]);

                    if (Convert.ToBoolean(edges[row, col]))
                    {
                        graph.AddEdge(row, col, 1.0f);
                    }
                }
            }

            // Remove the edges
            foreach (var edge_to_remove in edges_to_remove)
            {
                // Sanity check
                Assert.GreaterOrEqual(edge_to_remove.Item1, 0);
                Assert.GreaterOrEqual(edge_to_remove.Item2, 0);
                Assert.Greater(vertices.Length, edge_to_remove.Item1);
                Assert.Greater(vertices.Length, edge_to_remove.Item2);

                graph.RemoveEdge(edge_to_remove.Item1, edge_to_remove.Item2);

                // Also remove the edge from the 'edges' array used later for verification
                edges[edge_to_remove.Item1, edge_to_remove.Item2]     =
                    edges[edge_to_remove.Item2, edge_to_remove.Item1] = 0;
            }

            // Verify that the edges have been removed from the graph
            for (int row = 0; row < vertices.Length; ++row)
            {
                for (int col = 0; col < vertices.Length; ++col)
                {
                    Assert.AreEqual(Convert.ToBoolean(edges[row, col]), graph.EdgeExists(row, col));
                }
            }
        }
Beispiel #4
0
        public void PrimAlgorithm_ShouldThrowInvalidOperationException_WhenTargetGraphHasMoreThanOneConnectedComponents(UndirectedWeightedGraph <int, int> graph)
        {
            var primAlgorithm = PrimTestData.PrimAlgorithm;

            Assert.Throws <InvalidOperationException>(() =>
            {
                primAlgorithm.Execute(graph);
            });
        }