Beispiel #1
0
    // This uses Prim's algorithm: "https://en.wikipedia.org/wiki/Prim's_algorithm. We don't actually need
    // to build the MST, just need the total cost of the streets that compose it. The heap itself can be
    // used to keep track of which vertices are in the MST. Arbitrarily choose the building/vertex with ID 0
    // to begin creating the MST from. Using int.MaxValue as a sentinel value to represent the street cost
    // for a building into the growing MST when that building actually has no street into the MST. Hopefully
    // that doesn't lead to problems, otherwise would need nullable ints w/ a custom comparer, or something.
    public static long Solve(int buildingCount, int[,] streets)
    {
        var  buildingGraph   = WeightedSimpleGraph.CreateFromOneBasedEdges(buildingCount, streets);
        var  connectionCosts = new BinaryHeap(buildingGraph, buildingGraph.Vertices[0]);
        long totalStreetCost = 0;

        while (!connectionCosts.IsEmpty)
        {
            var cheapestConnection    = connectionCosts.Extract();
            var building              = cheapestConnection.Key;
            int costToConnectBuilding = cheapestConnection.Value;
            totalStreetCost += costToConnectBuilding;

            foreach (var neighbor in building.Neighbors)
            {
                int costToConnectNeighborFromBuilding = building.GetEdgeWeight(neighbor);
                int currentCostToConnectNeighbor;

                // The neighboring building may still be in the heap, or it might already be in the MST. If
                // it's still in the heap, check to see if we can improve its cost to get into the MST by
                // utilizing its street to the building just added.
                if (connectionCosts.TryGetValue(neighbor, out currentCostToConnectNeighbor))
                {
                    if (costToConnectNeighborFromBuilding < currentCostToConnectNeighbor)
                    {
                        connectionCosts.Update(neighbor, costToConnectNeighborFromBuilding);
                    }
                }
            }
        }

        return(totalStreetCost);
    }
Beispiel #2
0
        public void ValidatesAGraph2()
        {
            // This graph is two lines and a point.
            var graph = WeightedSimpleGraph <int> .CreateFromOneBasedEdges(5, new[, ]
            {
                { 1, 2, 10 }, { 3, 4, 11 }
            });

            Assert.AreEqual(1, graph.Vertices[0].Degree);
            Assert.AreEqual(1, graph.Vertices[1].Degree);
            Assert.AreEqual(1, graph.Vertices[2].Degree);
            Assert.AreEqual(1, graph.Vertices[3].Degree);
            Assert.AreEqual(0, graph.Vertices[4].Degree);

            Assert.IsTrue(graph.HasEdge(0, 1));
            Assert.IsTrue(graph.HasEdge(2, 3));
            Assert.IsFalse(graph.HasEdge(2, 0));
            Assert.IsFalse(graph.HasEdge(0, 3));
            Assert.IsFalse(graph.HasEdge(1, 2));
            Assert.IsFalse(graph.HasEdge(3, 1));

            for (int i = 0; i <= 4; ++i)
            {
                Assert.IsFalse(graph.HasEdge(4, i));
            }

            Assert.IsFalse(graph.Vertices[0].HasNeighbor(0));
            Assert.IsTrue(graph.Vertices[0].HasNeighbor(1));
            Assert.IsFalse(graph.Vertices[0].HasNeighbor(2));
            Assert.IsFalse(graph.Vertices[0].HasNeighbor(3));
            Assert.IsFalse(graph.Vertices[0].HasNeighbor(4));

            Assert.IsTrue(graph.Vertices[1].HasNeighbor(0));
            Assert.IsFalse(graph.Vertices[1].HasNeighbor(1));
            Assert.IsFalse(graph.Vertices[1].HasNeighbor(2));
            Assert.IsFalse(graph.Vertices[1].HasNeighbor(3));
            Assert.IsFalse(graph.Vertices[1].HasNeighbor(4));

            Assert.IsFalse(graph.Vertices[2].HasNeighbor(0));
            Assert.IsFalse(graph.Vertices[2].HasNeighbor(1));
            Assert.IsFalse(graph.Vertices[2].HasNeighbor(2));
            Assert.IsTrue(graph.Vertices[2].HasNeighbor(3));
            Assert.IsFalse(graph.Vertices[2].HasNeighbor(4));

            Assert.IsFalse(graph.Vertices[3].HasNeighbor(0));
            Assert.IsFalse(graph.Vertices[3].HasNeighbor(1));
            Assert.IsTrue(graph.Vertices[3].HasNeighbor(2));
            Assert.IsFalse(graph.Vertices[3].HasNeighbor(3));
            Assert.IsFalse(graph.Vertices[3].HasNeighbor(4));

            Assert.IsFalse(graph.Vertices[4].HasNeighbor(0));
            Assert.IsFalse(graph.Vertices[4].HasNeighbor(1));
            Assert.IsFalse(graph.Vertices[4].HasNeighbor(2));
            Assert.IsFalse(graph.Vertices[4].HasNeighbor(3));
            Assert.IsFalse(graph.Vertices[4].HasNeighbor(4));

            Assert.AreEqual(10, graph.Vertices[0].GetEdgeWeight(1));
            Assert.AreEqual(11, graph.Vertices[2].GetEdgeWeight(3));
        }