public void TestDijkstra()
        {
            // 0 -- 1 -- 2 -- 3
            //  \        |   /
            //    \      | /
            //      4 -- 5
            bool[,] graph1 = {
                                 { false, true,  false, false, true,  false },
                                 { true,  false, true,  false, false, false },
                                 { false, true,  false, true,  false, true  },
                                 { false, false, true,  false, false, true  },
                                 { true,  false, false, false, false, true  },
                                 { false, false, true,  true,  true,  false },
                             };

            SearchGraph searchGraph1 = SearchGraphFromData(graph1);

            Dictionary<int, GraphNode> graphNodes = GetGraphNodesIdIndex(searchGraph1);


            DistanceLookup distanceLookup = new DistanceLookup(graphNodes.Values.ToList());
            Assert.AreEqual((uint)0, distanceLookup[graphNodes[0].DistancesIndex, graphNodes[0].DistancesIndex], "Failed 0 distance test");
            Assert.AreEqual((uint)2, distanceLookup[graphNodes[0].DistancesIndex, graphNodes[5].DistancesIndex], "Wrong distance");
            Assert.AreEqual((uint)3, distanceLookup[graphNodes[0].DistancesIndex, graphNodes[3].DistancesIndex], "Wrong distance");
        }
        /// <summary>
        ///  Instantiates a new MinimalSpanningTree.
        /// </summary>
        /// <param name="mstNodes">The GraphNodes that should be spanned. (not null)</param>
        /// <param name="distances">The DistanceLookup used as cache.
        /// <see cref="DistanceLookup.CalculateFully"/> must have been called. (not null</param>
        public MinimalSpanningTree(List <GraphNode> mstNodes, DistanceLookup distances)
        {
            if (mstNodes == null)
            {
                throw new ArgumentNullException("mstNodes");
            }
            if (distances == null)
            {
                throw new ArgumentNullException("distances");
            }
            if (!distances.FullyCached)
            {
                throw new ArgumentException("CalculateFully must have been called.", "distances");
            }

            // Copy might be preferable, doesn't really matter atm though.
            _mstNodes  = mstNodes;
            _distances = distances;
            IsSpanned  = false;
        }
        public void DijkstraUnconnected()
        {
            // 0 -- 1    2 -- 3
            //           |   /
            //           | /
            //      4 -- 5
            bool[,] graph2 =
            {
                {false, true, false, false, false, false},
                {true, false, false, false, false, false},
                {false, false, false, true, false, true},
                {false, false, true, false, false, true},
                {false, false, false, false, false, true},
                {false, false, true, true, true, false},
            };
            SearchGraph searchGraph2 = SearchGraphFromData(graph2);
            Dictionary<int, GraphNode> graphNodes2 = GetGraphNodesIdIndex(searchGraph2);
            var mstNodes2 = new List<GraphNode> { graphNodes2[0], graphNodes2[2], graphNodes2[4], graphNodes2[3] };

            var distances = new DistanceLookup(graphNodes2.Values.ToArray());
            Assert.IsNull(distances.GetShortestPath(mstNodes2[0].DistancesIndex, mstNodes2[3].DistancesIndex));
        }
        public void TestMST()
        {
            // 0 -- 1 -- 2 -- 3
            //  \        |   /
            //    \      | /
            //      4 -- 5 -- 6 -- 7
            bool[,] graph1 = {
                                 { false, true,  false, false, true,  false, false, false },
                                 { true,  false, true,  false, false, false, false, false },
                                 { false, true,  false, true,  false, true,  false, false },
                                 { false, false, true,  false, false, true,  false, false },
                                 { true,  false, false, false, false, true,  false, false },
                                 { false, false, true,  true,  true,  false, true,  false },
                                 { false, false, false, false, false, true,  false, true  },
                                 { false, false, false, false, false, false, true,  false },
                             };

            SearchGraph searchGraph1 = SearchGraphFromData(graph1);

            Dictionary<int, GraphNode> graphNodes1 = GetGraphNodesIdIndex(searchGraph1);

            var mstNodes1 = new List<GraphNode>
                { graphNodes1[3], graphNodes1[5], graphNodes1[7], graphNodes1[0] };
            var distances = new DistanceLookup(mstNodes1);
            var mst1 = new MinimalSpanningTree(mstNodes1.Select(n => n.DistancesIndex).ToList(), distances);
            mst1.Span(graphNodes1[0].DistancesIndex);

            Assert.AreEqual(3, mst1.SpanningEdges.Count, "Wrong amount of spanning edges");
            var goalEdges = new[]
            {
                new []{0, 5}, new []{5, 3}, new []{5, 7}
            };
            foreach (var edge in goalEdges)
            {
                Assert.AreEqual(1,
                    mst1.SpanningEdges.Select(e => new Tuple<ushort, ushort>(distances.IndexToNode(e.Inside).Id, distances.IndexToNode(e.Outside).Id)).Count(
                        t =>
                            (t.Item1 == edge[0] && t.Item2 == edge[1]) ||
                            (t.Item1 == edge[1] && t.Item2 == edge[0])),
                    "Edge " + edge + " not contained exactly once.");
            }
        }