Esempio n. 1
0
        public string RunPart2(IEnumerable <string> testData)
        {
            var graph = new UndirectedWeightedGraph <string>();

            // Populate graph
            foreach (var line in testData)
            {
                var parts = line.Split(' ');
                var from  = parts[0];
                var to    = parts[2];
                var cost  = int.Parse(parts[4]);

                var fromV = graph.GetVertex(from) ?? graph.AddVertex(from);
                var toV   = graph.GetVertex(to) ?? graph.AddVertex(to);

                graph.AddEdge(fromV, toV, cost);
            }

            return(graph.CalculateLongestPath().ToString());
        }
        public void TestBreadthFirstSearch()
        {
            // Item1 - the vertices to add to the graph
            // Item2 - the edges to add to the graph
            // Item3 - the list of vertex indices, BFS search is run from
            //         each of these vertices
            // Item4 - the expected result of the BFS 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",   "F", "G",   "I", "A", "B", "D", "H", "J" },
                    new string[] { "J",                       "F",   "D", "E",   "H", "B", "C", "G", "I", "A" },
                    new string[] { "C",                       "A",   "B", "D",   "E", "F", "G", "I", "H", "J" },
                    new string[] { "H",                       "F",   "D", "E",   "J", "B", "C", "G", "I", "A" },
                    new string[] { "D",                       "B",   "C", "F",   "A", "E", "H", "J", "G", "I" },
                    new string[] { "A",                       "B",   "C", "D",   "E", "F", "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",   "D", "A" },
                    new string[] { "E",                       "F" },
                    new string[] { "F",                       "E" },
                    new string[] { "G" },
                    new string[] { "I",                       "H",   "J", "M",   "K", "L" },
                    new string[] { "M",                       "H",   "L", "I",   "J", "K" },
                    new string[] { "L",                       "J",   "K", "M",   "I", "H" }
                })
            };

            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, 0.5f);
                        }
                    }
                }

                // Run BFS 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.BreadthFirstSearch(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 BFS visited expected number of vertices
                    Assert.AreEqual(test_vector.Item4[i++].Length, count);
                }
            }
        }