Пример #1
0
        public void ForestCyclesCheck()
        {
            var vertices = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };

            var graph = new WeightedALGraph <int, int>();

            graph.AddVertices(vertices);

            // Graph is:
            // first component
            // 1 <-> 2, 3, 4
            // 2 <-> 1, 3, 5, 6
            // 3 <-> 1, 2, 6
            // 4 <-> 1, 6, 7
            // 5 <-> 2, 7, 8
            // 6 <-> 2, 3, 4
            // 7 <-> 4, 8
            // 8 <-> 7, 5
            // second component
            // 9 <-> 10, 12
            // 10 <-> 9, 11, 12
            // 11 <-> 10, 12, 13
            // 12 <-> 9, 10, 11
            // 13 <-> 11
            // third component
            // 14 <-> 15, 16
            // 15 <-> 14, 16
            // 16 <-> 14, 15
            // With each edge having a weight of the absolute value of the difference of the vertices
            graph.AddEdge(1, 2, 1);
            graph.AddEdge(1, 3, 2);
            graph.AddEdge(1, 4, 3);
            graph.AddEdge(2, 3, 1);
            graph.AddEdge(2, 5, 3);
            graph.AddEdge(2, 6, 4);
            graph.AddEdge(3, 6, 3);
            graph.AddEdge(4, 6, 2);
            graph.AddEdge(4, 7, 3);
            graph.AddEdge(5, 7, 2);
            graph.AddEdge(5, 8, 3);
            graph.AddEdge(7, 8, 1);
            graph.AddEdge(9, 10, 1);
            graph.AddEdge(9, 12, 3);
            graph.AddEdge(10, 11, 1);
            graph.AddEdge(10, 12, 2);
            graph.AddEdge(11, 12, 1);
            graph.AddEdge(11, 13, 2);
            graph.AddEdge(14, 15, 1);
            graph.AddEdge(14, 16, 2);
            graph.AddEdge(15, 16, 1);

            // Graph has to be cyclic
            Assert.IsTrue(graph.IsCyclic());

            // Compute MST of the graph
            var mst = graph.KruskalMST();

            // The MST is acyclic
            Assert.IsFalse(mst.IsCyclic());
        }
Пример #2
0
        public void BipartiteColoringWeightedGraphCheck()
        {
            var vertices = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            var graph = new WeightedALGraph <int, int>();

            graph.AddVertices(vertices);

            // Graph is:
            // 1 <-> 2, 3, 4
            // 2 <-> 1, 5, 6
            // 3 <-> 1, 6
            // 4 <-> 1, 5, 6, 7
            // 5 <-> 2, 4, 8
            // 6 <-> 2, 3, 4
            // 7 <-> 4, 8
            // 8 <-> 7, 5
            // 9 <->
            // With each edge having a weight of the sum of its vertices
            graph.AddEdge(1, 2, 3);
            graph.AddEdge(1, 3, 4);
            graph.AddEdge(1, 4, 5);
            graph.AddEdge(2, 5, 7);
            graph.AddEdge(2, 6, 8);
            graph.AddEdge(3, 6, 9);
            graph.AddEdge(4, 5, 9);
            graph.AddEdge(4, 6, 10);
            graph.AddEdge(4, 7, 11);
            graph.AddEdge(5, 8, 13);
            graph.AddEdge(7, 8, 15);

            Dictionary <int, BipartiteColor> verticesColors;

            Assert.IsTrue(graph.TryGetBipartiteColoring(out verticesColors));

            foreach (var edge in graph.Edges)
            {
                Assert.IsTrue(verticesColors[edge.Source] != verticesColors[edge.Destination]);
            }

            // Check with not bipartite graph

            graph = new WeightedALGraph <int, int>();

            graph.AddVertices(vertices);

            // Graph is:
            // 1 <-> 2, 3, 4
            // 2 <-> 1, 3, 5, 6
            // 3 <-> 1, 2, 6
            // 4 <-> 1, 6, 7
            // 5 <-> 2, 7, 8
            // 6 <-> 2, 3, 4
            // 7 <-> 4, 8
            // 8 <-> 7, 5
            // 9 <->
            // With each edge having a weight of the sum of its vertices
            graph.AddEdge(1, 2, 3);
            graph.AddEdge(1, 3, 4);
            graph.AddEdge(1, 4, 5);
            graph.AddEdge(2, 3, 5);
            graph.AddEdge(2, 5, 7);
            graph.AddEdge(2, 6, 8);
            graph.AddEdge(3, 6, 9);
            graph.AddEdge(4, 6, 10);
            graph.AddEdge(4, 7, 11);
            graph.AddEdge(5, 7, 12);
            graph.AddEdge(5, 8, 13);
            graph.AddEdge(7, 8, 15);

            Assert.IsFalse(graph.TryGetBipartiteColoring(out verticesColors));
        }
Пример #3
0
        /// <summary>
        /// Uses Kruskal's algorithm to find the minimum spanning tree of the undirected weighted graph. Returns a <see cref="WeightedALGraph{TVertex, TWeight}"/> representing the MST.
        /// </summary>
        /// <typeparam name="TVertex">The data type of the vertices. TVertex implements <see cref="IComparable{T}"/>.</typeparam>
        /// <typeparam name="TWeight">The data type of weight of the edges. TWeight implements <see cref="IComparable{T}"/>.</typeparam>
        /// <param name="graph">The graph structure that implements <see cref="IWeightedGraph{TVertex, TWeight}"/>.</param>
        /// <returns>Returns a <see cref="WeightedALGraph{TVertex, TWeight}"/> representing the MST.</returns>
        public static WeightedALGraph <TVertex, TWeight> KruskalMST <TVertex, TWeight>(this IWeightedGraph <TVertex, TWeight> graph)
            where TVertex : IComparable <TVertex>
            where TWeight : IComparable <TWeight>
        {
            if (graph.IsDirected)
            {
                throw new ArgumentException("Graph is directed!");
            }

            var mst = new WeightedALGraph <TVertex, TWeight>();

            // A dictionary of the added vertices to the MST and their tree identifiers (first vertex from the tree)
            var addedVertices = new Dictionary <TVertex, TVertex>();
            // Edge comparer for the edge sorting
            var edgeComparer = Comparer <IWeightedEdge <TVertex, TWeight> > .Create((x, y) =>
            {
                int cmp = 0;
                // null checking because TWeight can be null
                if (x.Weight == null)
                {
                    if (y.Weight == null)
                    {
                        cmp = -1;                   // change cmp to skip next comparisons
                    }
                    else
                    {
                        return(int.MinValue);
                    }
                }

                if (cmp == 0)// if Weights are not both null
                {
                    if (y.Weight == null)
                    {
                        return(int.MaxValue);
                    }
                    // normal check if both weights are not null
                    cmp = x.Weight.CompareTo(y.Weight);
                }
                else
                {
                    cmp = 0; // if both Weights were null, compare the kvp value
                }
                if (cmp == 0)
                {
                    cmp = x.Source.CompareTo(y.Source);
                }
                if (cmp == 0)
                {
                    cmp = x.Destination.CompareTo(y.Destination);
                }
                return(cmp);
            });

            var vertices = graph.Vertices.ToList();

            if (vertices.Count == 0)
            {
                return(mst);
            }

            mst.AddVertices(vertices);

            // Get edges
            var edges = graph.Edges.ToList();

            if (edges.Count == 0)
            {
                return(mst);
            }
            // Sort them
            edges.QuickSort(edgeComparer);

            for (int i = 0; i < edges.Count; i++)
            {
                var curEdge = edges[i];

                if (addedVertices.ContainsKey(curEdge.Source))
                {
                    if (addedVertices.ContainsKey(curEdge.Destination))// if both vertices are added to the MST
                    {
                        // Find tree roots
                        var srcRoot = FindTreeRoot(addedVertices, curEdge.Source);
                        var dstRoot = FindTreeRoot(addedVertices, curEdge.Destination);

                        // If vertices belong to the same tree we continue. Edge will create a cycle.
                        if (object.Equals(srcRoot, dstRoot))
                        {
                            continue;
                        }
                        else // if not add edge and connect the trees
                        {
                            // Add edge to MST
                            mst.AddEdge(curEdge.Source, curEdge.Destination, curEdge.Weight);
                            // Connect destination vertex tree with the source
                            addedVertices[curEdge.Destination] = srcRoot;
                            addedVertices[dstRoot]             = srcRoot;
                        }
                    }
                    else // if the source is added to the MST but not the destination
                    {
                        // Add edge to MST
                        mst.AddEdge(curEdge.Source, curEdge.Destination, curEdge.Weight);
                        // Find tree root
                        var srcRoot = FindTreeRoot(addedVertices, curEdge.Source);
                        // Add to the tree
                        addedVertices.Add(curEdge.Destination, srcRoot);
                    }
                }
                else // if the source is not added to the MST
                {
                    if (addedVertices.ContainsKey(curEdge.Destination))// if the destination is added
                    {
                        // Add edge to MST
                        mst.AddEdge(curEdge.Source, curEdge.Destination, curEdge.Weight);
                        // Find tree root
                        var dstRoot = FindTreeRoot(addedVertices, curEdge.Destination);
                        // Add to the tree
                        addedVertices.Add(curEdge.Source, dstRoot);
                    }
                    else// if both vertices are not added to the MST
                    {
                        // Add edge to MST
                        mst.AddEdge(curEdge.Source, curEdge.Destination, curEdge.Weight);
                        // Connect the vertices in a tree
                        addedVertices.Add(curEdge.Source, curEdge.Source);
                        addedVertices.Add(curEdge.Destination, curEdge.Source);
                    }
                }
            }

            // Return MST
            return(mst);
        }
Пример #4
0
        public void MinimumSpanningForest()
        {
            var vertices = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };

            var graph = new WeightedALGraph <int, int>();

            graph.AddVertices(vertices);

            // Graph is:
            // first component
            // 1 <-> 2, 3, 4
            // 2 <-> 1, 3, 5, 6
            // 3 <-> 1, 2, 6
            // 4 <-> 1, 6, 7
            // 5 <-> 2, 7, 8
            // 6 <-> 2, 3, 4
            // 7 <-> 4, 8
            // 8 <-> 7, 5
            // second component
            // 9 <-> 10, 12
            // 10 <-> 9, 11, 12
            // 11 <-> 10, 12, 13
            // 12 <-> 9, 10, 11
            // 13 <-> 11
            // third component
            // 14 <-> 15, 16
            // 15 <-> 14, 16
            // 16 <-> 14, 15
            // With each edge having a weight of the absolute value of the difference of the vertices
            graph.AddEdge(1, 2, 1);
            graph.AddEdge(1, 3, 2);
            graph.AddEdge(1, 4, 3);
            graph.AddEdge(2, 3, 1);
            graph.AddEdge(2, 5, 3);
            graph.AddEdge(2, 6, 4);
            graph.AddEdge(3, 6, 3);
            graph.AddEdge(4, 6, 2);
            graph.AddEdge(4, 7, 3);
            graph.AddEdge(5, 7, 2);
            graph.AddEdge(5, 8, 3);
            graph.AddEdge(7, 8, 1);
            graph.AddEdge(9, 10, 1);
            graph.AddEdge(9, 12, 3);
            graph.AddEdge(10, 11, 1);
            graph.AddEdge(10, 12, 2);
            graph.AddEdge(11, 12, 1);
            graph.AddEdge(11, 13, 2);
            graph.AddEdge(14, 15, 1);
            graph.AddEdge(14, 16, 2);
            graph.AddEdge(15, 16, 1);

            // Expected MST
            // first component
            // 1 <-> 2, 4
            // 2 <-> 1, 3, 5
            // 3 <-> 2
            // 4 <-> 1, 6
            // 5 <-> 2, 7
            // 6 <-> 4
            // 7 <-> 5, 8
            // 8 <-> 7
            // second component
            // 9 <-> 10
            // 10 <-> 9, 11
            // 11 <-> 10, 12, 13
            // 12 <-> 11
            // 13 <-> 11
            // third component
            // 14 <-> 15
            // 15 <-> 14, 16
            // 16 <-> 15

            var mst = graph.PrimMST();

            int weight = 0;

            // first component
            Assert.IsTrue(mst.TryGetEdgeWeight(1, 2, out weight));
            Assert.IsTrue(weight == 1);
            Assert.IsTrue(mst.TryGetEdgeWeight(2, 1, out weight));
            Assert.IsTrue(weight == 1);
            Assert.IsTrue(mst.TryGetEdgeWeight(1, 4, out weight));
            Assert.IsTrue(weight == 3);
            Assert.IsTrue(mst.TryGetEdgeWeight(4, 1, out weight));
            Assert.IsTrue(weight == 3);
            Assert.IsTrue(mst.TryGetEdgeWeight(2, 3, out weight));
            Assert.IsTrue(weight == 1);
            Assert.IsTrue(mst.TryGetEdgeWeight(3, 2, out weight));
            Assert.IsTrue(weight == 1);
            Assert.IsTrue(mst.TryGetEdgeWeight(2, 5, out weight));
            Assert.IsTrue(weight == 3);
            Assert.IsTrue(mst.TryGetEdgeWeight(5, 2, out weight));
            Assert.IsTrue(weight == 3);
            Assert.IsTrue(mst.TryGetEdgeWeight(4, 6, out weight));
            Assert.IsTrue(weight == 2);
            Assert.IsTrue(mst.TryGetEdgeWeight(6, 4, out weight));
            Assert.IsTrue(weight == 2);
            Assert.IsTrue(mst.TryGetEdgeWeight(5, 7, out weight));
            Assert.IsTrue(weight == 2);
            Assert.IsTrue(mst.TryGetEdgeWeight(7, 5, out weight));
            Assert.IsTrue(weight == 2);
            Assert.IsTrue(mst.TryGetEdgeWeight(7, 8, out weight));
            Assert.IsTrue(weight == 1);
            Assert.IsTrue(mst.TryGetEdgeWeight(8, 7, out weight));
            Assert.IsTrue(weight == 1);
            // second component
            Assert.IsTrue(mst.TryGetEdgeWeight(9, 10, out weight));
            Assert.IsTrue(weight == 1);
            Assert.IsTrue(mst.TryGetEdgeWeight(10, 9, out weight));
            Assert.IsTrue(weight == 1);
            Assert.IsTrue(mst.TryGetEdgeWeight(10, 11, out weight));
            Assert.IsTrue(weight == 1);
            Assert.IsTrue(mst.TryGetEdgeWeight(11, 10, out weight));
            Assert.IsTrue(weight == 1);
            Assert.IsTrue(mst.TryGetEdgeWeight(11, 12, out weight));
            Assert.IsTrue(weight == 1);
            Assert.IsTrue(mst.TryGetEdgeWeight(12, 11, out weight));
            Assert.IsTrue(weight == 1);
            Assert.IsTrue(mst.TryGetEdgeWeight(11, 13, out weight));
            Assert.IsTrue(weight == 2);
            Assert.IsTrue(mst.TryGetEdgeWeight(13, 11, out weight));
            Assert.IsTrue(weight == 2);
            // third component
            Assert.IsTrue(mst.TryGetEdgeWeight(14, 15, out weight));
            Assert.IsTrue(weight == 1);
            Assert.IsTrue(mst.TryGetEdgeWeight(15, 14, out weight));
            Assert.IsTrue(weight == 1);
            Assert.IsTrue(mst.TryGetEdgeWeight(15, 16, out weight));
            Assert.IsTrue(weight == 1);
            Assert.IsTrue(mst.TryGetEdgeWeight(16, 15, out weight));
            Assert.IsTrue(weight == 1);

            // first component
            Assert.IsFalse(mst.ContainsEdge(1, 3));
            Assert.IsFalse(mst.ContainsEdge(3, 1));
            Assert.IsFalse(mst.ContainsEdge(2, 6));
            Assert.IsFalse(mst.ContainsEdge(6, 2));
            Assert.IsFalse(mst.ContainsEdge(3, 6));
            Assert.IsFalse(mst.ContainsEdge(6, 3));
            Assert.IsFalse(mst.ContainsEdge(4, 7));
            Assert.IsFalse(mst.ContainsEdge(7, 4));
            Assert.IsFalse(mst.ContainsEdge(5, 8));
            Assert.IsFalse(mst.ContainsEdge(8, 5));
            // second component
            Assert.IsFalse(mst.ContainsEdge(9, 12));
            Assert.IsFalse(mst.ContainsEdge(12, 9));
            Assert.IsFalse(mst.ContainsEdge(10, 12));
            Assert.IsFalse(mst.ContainsEdge(12, 10));
            // third component
            Assert.IsFalse(mst.ContainsEdge(14, 16));
            Assert.IsFalse(mst.ContainsEdge(16, 14));
        }
Пример #5
0
        public void StringWeightsMST()
        {
            var vertices = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            var graph = new WeightedALGraph <int, string>();

            graph.AddVertices(vertices);

            // Graph is:
            // 1 <-> 2, 3, 4
            // 2 <-> 1, 3, 5, 6
            // 3 <-> 1, 2, 6
            // 4 <-> 1, 6, 7
            // 5 <-> 2, 7, 8
            // 6 <-> 2, 3, 4
            // 7 <-> 4, 8
            // 8 <-> 7, 5
            // 9 <->
            graph.AddEdge(1, 2, "a");
            graph.AddEdge(1, 3, "b");
            graph.AddEdge(1, 4, "b");
            graph.AddEdge(2, 3, "a");
            graph.AddEdge(2, 5, "c");
            graph.AddEdge(2, 6, "c");
            graph.AddEdge(3, 6, "c");
            graph.AddEdge(4, 6, "b");
            graph.AddEdge(4, 7, "b");
            graph.AddEdge(5, 7, "b");
            graph.AddEdge(5, 8, "c");
            graph.AddEdge(7, 8, "a");

            // Expected MST
            // 1 <-> 2, 4
            // 2 <-> 3
            // 3 <-> 2
            // 4 <-> 1, 6, 7
            // 5 <-> 7
            // 6 <-> 4
            // 7 <-> 4, 5, 8
            // 8 <-> 7
            // 9 <->
            var mst = graph.PrimMST();

            string weight = string.Empty;

            Assert.IsTrue(mst.TryGetEdgeWeight(1, 2, out weight));
            Assert.IsTrue(object.Equals(weight, "a"));
            Assert.IsTrue(mst.TryGetEdgeWeight(2, 1, out weight));
            Assert.IsTrue(object.Equals(weight, "a"));
            Assert.IsTrue(mst.TryGetEdgeWeight(1, 4, out weight));
            Assert.IsTrue(object.Equals(weight, "b"));
            Assert.IsTrue(mst.TryGetEdgeWeight(4, 1, out weight));
            Assert.IsTrue(object.Equals(weight, "b"));
            Assert.IsTrue(mst.TryGetEdgeWeight(2, 3, out weight));
            Assert.IsTrue(object.Equals(weight, "a"));
            Assert.IsTrue(mst.TryGetEdgeWeight(3, 2, out weight));
            Assert.IsTrue(object.Equals(weight, "a"));
            Assert.IsTrue(mst.TryGetEdgeWeight(4, 6, out weight));
            Assert.IsTrue(object.Equals(weight, "b"));
            Assert.IsTrue(mst.TryGetEdgeWeight(6, 4, out weight));
            Assert.IsTrue(object.Equals(weight, "b"));
            Assert.IsTrue(mst.TryGetEdgeWeight(4, 7, out weight));
            Assert.IsTrue(object.Equals(weight, "b"));
            Assert.IsTrue(mst.TryGetEdgeWeight(7, 4, out weight));
            Assert.IsTrue(object.Equals(weight, "b"));
            Assert.IsTrue(mst.TryGetEdgeWeight(5, 7, out weight));
            Assert.IsTrue(object.Equals(weight, "b"));
            Assert.IsTrue(mst.TryGetEdgeWeight(7, 5, out weight));
            Assert.IsTrue(object.Equals(weight, "b"));
            Assert.IsTrue(mst.TryGetEdgeWeight(7, 8, out weight));
            Assert.IsTrue(object.Equals(weight, "a"));
            Assert.IsTrue(mst.TryGetEdgeWeight(8, 7, out weight));
            Assert.IsTrue(object.Equals(weight, "a"));

            Assert.IsFalse(mst.ContainsEdge(1, 3));
            Assert.IsFalse(mst.ContainsEdge(3, 1));
            Assert.IsFalse(mst.ContainsEdge(2, 5));
            Assert.IsFalse(mst.ContainsEdge(5, 2));
            Assert.IsFalse(mst.ContainsEdge(2, 6));
            Assert.IsFalse(mst.ContainsEdge(6, 2));
            Assert.IsFalse(mst.ContainsEdge(3, 6));
            Assert.IsFalse(mst.ContainsEdge(6, 3));
            Assert.IsFalse(mst.ContainsEdge(5, 8));
            Assert.IsFalse(mst.ContainsEdge(8, 5));
        }
Пример #6
0
        public void NegativeEdgesWeightsAsVertexDifference()
        {
            var vertices = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            var graph = new WeightedALGraph <int, int>();

            graph.AddVertices(vertices);

            // Graph is:
            // 1 <-> 2, 3, 4
            // 2 <-> 1, 3, 5, 6
            // 3 <-> 1, 2, 6
            // 4 <-> 1, 6, 7
            // 5 <-> 2, 7, 8
            // 6 <-> 2, 3, 4
            // 7 <-> 4, 8
            // 8 <-> 7, 5
            // 9 <->
            // With each edge having a weight of the absolute value of the difference of the vertices
            graph.AddEdge(1, 2, -1);
            graph.AddEdge(1, 3, -2);
            graph.AddEdge(1, 4, -3);
            graph.AddEdge(2, 3, -1);
            graph.AddEdge(2, 5, -3);
            graph.AddEdge(2, 6, -4);
            graph.AddEdge(3, 6, -3);
            graph.AddEdge(4, 6, -2);
            graph.AddEdge(4, 7, -3);
            graph.AddEdge(5, 7, -2);
            graph.AddEdge(5, 8, -3);
            graph.AddEdge(7, 8, -1);

            // Expected MST
            // 1 <-> 3, 4
            // 2 <-> 5, 6
            // 3 <-> 1, 6
            // 4 <-> 1, 7
            // 5 <-> 2, 8
            // 6 <-> 2, 3
            // 7 <-> 4
            // 8 <-> 5
            // 9 <->

            var mst = graph.PrimMST();

            int weight = 0;

            Assert.IsTrue(mst.TryGetEdgeWeight(1, 3, out weight));
            Assert.IsTrue(weight == -2);
            Assert.IsTrue(mst.TryGetEdgeWeight(3, 1, out weight));
            Assert.IsTrue(weight == -2);
            Assert.IsTrue(mst.TryGetEdgeWeight(1, 4, out weight));
            Assert.IsTrue(weight == -3);
            Assert.IsTrue(mst.TryGetEdgeWeight(4, 1, out weight));
            Assert.IsTrue(weight == -3);
            Assert.IsTrue(mst.TryGetEdgeWeight(2, 5, out weight));
            Assert.IsTrue(weight == -3);
            Assert.IsTrue(mst.TryGetEdgeWeight(5, 2, out weight));
            Assert.IsTrue(weight == -3);
            Assert.IsTrue(mst.TryGetEdgeWeight(2, 6, out weight));
            Assert.IsTrue(weight == -4);
            Assert.IsTrue(mst.TryGetEdgeWeight(6, 2, out weight));
            Assert.IsTrue(weight == -4);
            Assert.IsTrue(mst.TryGetEdgeWeight(3, 6, out weight));
            Assert.IsTrue(weight == -3);
            Assert.IsTrue(mst.TryGetEdgeWeight(6, 3, out weight));
            Assert.IsTrue(weight == -3);
            Assert.IsTrue(mst.TryGetEdgeWeight(4, 7, out weight));
            Assert.IsTrue(weight == -3);
            Assert.IsTrue(mst.TryGetEdgeWeight(7, 4, out weight));
            Assert.IsTrue(weight == -3);
            Assert.IsTrue(mst.TryGetEdgeWeight(5, 8, out weight));
            Assert.IsTrue(weight == -3);
            Assert.IsTrue(mst.TryGetEdgeWeight(8, 5, out weight));
            Assert.IsTrue(weight == -3);

            Assert.IsFalse(mst.ContainsEdge(1, 2));
            Assert.IsFalse(mst.ContainsEdge(2, 1));
            Assert.IsFalse(mst.ContainsEdge(2, 3));
            Assert.IsFalse(mst.ContainsEdge(3, 2));
            Assert.IsFalse(mst.ContainsEdge(4, 6));
            Assert.IsFalse(mst.ContainsEdge(6, 4));
            Assert.IsFalse(mst.ContainsEdge(5, 7));
            Assert.IsFalse(mst.ContainsEdge(7, 5));
            Assert.IsFalse(mst.ContainsEdge(7, 8));
            Assert.IsFalse(mst.ContainsEdge(8, 7));
        }
Пример #7
0
        /// <summary>
        /// Uses Prim's algorithm to find the minimum spanning tree of the undirected weighted graph. Returns a <see cref="WeightedALGraph{TVertex, TWeight}"/> representing the MST.
        /// </summary>
        /// <typeparam name="TVertex">The data type of the vertices. TVertex implements <see cref="IComparable{T}"/>.</typeparam>
        /// <typeparam name="TWeight">The data type of weight of the edges. TWeight implements <see cref="IComparable{T}"/>.</typeparam>
        /// <param name="graph">The graph structure that implements <see cref="IWeightedGraph{TVertex, TWeight}"/>.</param>
        /// <returns>Returns a <see cref="WeightedALGraph{TVertex, TWeight}"/> representing the MST.</returns>
        public static WeightedALGraph <TVertex, TWeight> PrimMST <TVertex, TWeight>(this IWeightedGraph <TVertex, TWeight> graph)
            where TVertex : IComparable <TVertex>
            where TWeight : IComparable <TWeight>
        {
            if (graph.IsDirected)
            {
                throw new ArgumentException("Graph is directed!");
            }

            var mst = new WeightedALGraph <TVertex, TWeight>();

            // A hash set of the added vertices to the MST
            var addedVertices = new HashSet <TVertex>();
            // Comparer for the kvp in the priority queue
            var kvpComparer = Comparer <KeyValuePair <TWeight, KeyValuePair <TVertex, TVertex> > > .Create((x, y) =>
            {
                int cmp = 0;
                // null checking because TWeight can be null
                if (x.Key == null)
                {
                    if (y.Key == null)
                    {
                        cmp = -1;                // change cmp to skip next comparisons
                    }
                    else
                    {
                        return(int.MinValue);
                    }
                }

                if (cmp == 0)// if x.Key and y.Key are not null
                {
                    if (y.Key == null)
                    {
                        return(int.MaxValue);
                    }
                    // normal check if both weights are not null
                    cmp = x.Key.CompareTo(y.Key);
                }
                else
                {
                    cmp = 0; // if x.Key and y.Key were both null, compare the kvp value
                }
                if (cmp == 0)
                {
                    cmp = x.Value.Key.CompareTo(y.Value.Key);
                }
                if (cmp == 0)
                {
                    cmp = x.Value.Value.CompareTo(y.Value.Value);
                }
                return(cmp);
            });

            // Priority queue of the edges for computing. Having the weight as key and as value - another kvp with source vertex as key and destination vertex as value.
            var priorityQueue = new MinPriorityQueue <TWeight, KeyValuePair <TVertex, TVertex> >(kvpComparer);

            var vertices = graph.Vertices.ToList();

            if (vertices.Count == 0)
            {
                return(mst);
            }
            int verticesIndex = 0;

            mst.AddVertices(vertices);

            // Add dummy edge to the priority queue
            priorityQueue.Enqueue(default(TWeight), new KeyValuePair <TVertex, TVertex>(vertices[verticesIndex], vertices[verticesIndex]));
            addedVertices.Add(vertices[verticesIndex]);

            while (priorityQueue.Count > 0)
            {
                var     curKVP               = priorityQueue.Dequeue();
                TVertex curSourceVertex      = curKVP.Value.Key;
                TVertex curDestinationVertex = curKVP.Value.Value;

                // If the destination verex of the edge is not added we add the edge
                if (!addedVertices.Contains(curDestinationVertex))
                {
                    mst.AddEdge(curSourceVertex, curDestinationVertex, curKVP.Key);
                    addedVertices.Add(curDestinationVertex);
                }

                foreach (var edge in graph.OutgoingEdgesSorted(curDestinationVertex))
                {
                    var edgeDestination = edge.Destination;
                    var edgeWeight      = edge.Weight;

                    // If the destination vertex is added to the MST we skip it
                    if (addedVertices.Contains(edgeDestination))
                    {
                        continue;
                    }

                    // Add the edge for computing
                    priorityQueue.Enqueue(edgeWeight, new KeyValuePair <TVertex, TVertex>(curDestinationVertex, edgeDestination));
                }

                // If priority queue is empty
                if (priorityQueue.Count == 0)
                {
                    // Check if all vertices of the graph were added to the MST
                    if (addedVertices.Count != vertices.Count)
                    {
                        // If not we have a forest.
                        // Add the next non added vertex
                        while (verticesIndex < vertices.Count)
                        {
                            if (!addedVertices.Contains(vertices[verticesIndex]))
                            {
                                // Add dummy edge to the priority queue
                                priorityQueue.Enqueue(default(TWeight), new KeyValuePair <TVertex, TVertex>(vertices[verticesIndex], vertices[verticesIndex]));
                                addedVertices.Add(vertices[verticesIndex]);

                                break;
                            }
                            verticesIndex++;
                        }
                    }
                }
            }

            // Return MST
            return(mst);
        }
Пример #8
0
        public void StringWeightsShortestPathsWithAddWeightsDelegateUsageCheck()
        {
            var vertices = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            var graph = new WeightedALGraph <int, string>();

            graph.AddVertices(vertices);

            // Graph is:
            // 1 <-> 2, 3, 4
            // 2 <-> 1, 3, 5, 6
            // 3 <-> 1, 2, 6
            // 4 <-> 1, 6, 7
            // 5 <-> 2, 7, 8
            // 6 <-> 2, 3, 4
            // 7 <-> 4, 8
            // 8 <-> 7, 5
            // 9 <->
            graph.AddEdge(1, 2, "a");
            graph.AddEdge(1, 3, "b");
            graph.AddEdge(1, 4, "b");
            graph.AddEdge(2, 3, "a");
            graph.AddEdge(2, 5, "c");
            graph.AddEdge(2, 6, "c");
            graph.AddEdge(3, 6, "c");
            graph.AddEdge(4, 6, "b");
            graph.AddEdge(4, 7, "b");
            graph.AddEdge(5, 7, "b");
            graph.AddEdge(5, 8, "c");
            graph.AddEdge(7, 8, "a");

            // Expected shortest paths for vertex 1
            // 1 to 2 : 1 -> 2
            // 1 to 3 : 1 -> 2 -> 3
            // 1 to 4 : 1 -> 2 -> 3 -> 6 -> 4
            // 1 to 5 : 1 -> 2 -> 3 -> 6 -> 4 -> 7 -> 8 -> 5
            // 1 to 6 : 1 -> 2 -> 3 -> 6
            // 1 to 7 : 1 -> 2 -> 3 -> 6 -> 4 -> 7
            // 1 to 8 : 1 -> 2 -> 3 -> 6 -> 4 -> 7 -> 8
            // 1 to 9 : no path
            var expectedPaths = new int[7][]
            {
                new int[] { 1, 2 },
                new int[] { 1, 2, 3 },
                new int[] { 1, 2, 3, 6, 4 },
                new int[] { 1, 2, 3, 6, 4, 7, 8, 5 },
                new int[] { 1, 2, 3, 6 },
                new int[] { 1, 2, 3, 6, 4, 7 },
                new int[] { 1, 2, 3, 6, 4, 7, 8 }
            };

            var expectedEdgesWeights = new string[7][]
            {
                new string[] { "a" },
                new string[] { "a", "a" },
                new string[] { "a", "a", "c", "b" },
                new string[] { "a", "a", "c", "b", "b", "a", "c" },
                new string[] { "a", "a", "c" },
                new string[] { "a", "a", "c", "b", "b" },
                new string[] { "a", "a", "c", "b", "b", "a" }
            };

            var paths = graph.DijkstraShortestPaths(1, (x, y) => x + y);

            for (int i = 0; i < 7; i++)
            {
                var curPath = paths.VerticesPathTo(i + 2);

                for (int j = 0; j < curPath.Count; j++)
                {
                    if (expectedPaths[i][j] != curPath[j])
                    {
                        Assert.Fail();
                    }
                }

                var curEdgesPath = paths.EdgesPathTo(i + 2);

                for (int j = 0; j < curEdgesPath.Count; j++)
                {
                    if (expectedEdgesWeights[i][j] != curEdgesPath[j].Weight)
                    {
                        Assert.Fail();
                    }
                }
            }
            Assert.IsFalse(paths.HasPathTo(9));

            // Expected shortest paths for vertex 8
            // 8 to 1 : 8 -> 7 -> 4 -> 1
            // 8 to 2 : 8 -> 7 -> 4 -> 1 -> 2
            // 8 to 3 : 8 -> 7 -> 4 -> 1 -> 2 -> 3
            // 8 to 4 : 8 -> 7 -> 4
            // 8 to 5 : 8 -> 7 -> 5
            // 8 to 6 : 8 -> 7 -> 4 -> 6
            // 8 to 7 : 8 -> 7
            // 8 to 9 : no path
            expectedPaths = new int[7][]
            {
                new int[] { 8, 7, 4, 1 },
                new int[] { 8, 7, 4, 1, 2 },
                new int[] { 8, 7, 4, 1, 2, 3 },
                new int[] { 8, 7, 4 },
                new int[] { 8, 7, 5 },
                new int[] { 8, 7, 4, 6 },
                new int[] { 8, 7 }
            };

            expectedEdgesWeights = new string[7][]
            {
                new string[] { "a", "b", "b" },
                new string[] { "a", "b", "b", "a" },
                new string[] { "a", "b", "b", "a", "a" },
                new string[] { "a", "b" },
                new string[] { "a", "b" },
                new string[] { "a", "b", "b" },
                new string[] { "a" }
            };

            paths = graph.DijkstraShortestPaths(8, (x, y) => x + y);

            for (int i = 0; i < 7; i++)
            {
                var curPath = paths.VerticesPathTo(i + 1);

                for (int j = 0; j < curPath.Count; j++)
                {
                    if (expectedPaths[i][j] != curPath[j])
                    {
                        Assert.Fail();
                    }
                }

                var curEdgesPath = paths.EdgesPathTo(i + 1);

                for (int j = 0; j < curEdgesPath.Count; j++)
                {
                    if (expectedEdgesWeights[i][j] != curEdgesPath[j].Weight)
                    {
                        Assert.Fail();
                    }
                }
            }
            Assert.IsFalse(paths.HasPathTo(9));
        }
Пример #9
0
        public void UndirectedAndWeightedGraphShortestPathsCheck()
        {
            var vertices = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            var graph = new WeightedALGraph <int, int>();

            graph.AddVertices(vertices);

            // Graph is:
            // 1 <-> 2, 3, 4
            // 2 <-> 1, 3, 5, 6
            // 3 <-> 1, 2, 6
            // 4 <-> 1, 6, 7
            // 5 <-> 2, 7, 8
            // 6 <-> 2, 3, 4
            // 7 <-> 4, 8
            // 8 <-> 7, 5
            // 9 <->
            // With each edge having a weight of the absolute value of the difference of the vertices
            graph.AddEdge(1, 2, 1);
            graph.AddEdge(1, 3, 2);
            graph.AddEdge(1, 4, 3);
            graph.AddEdge(2, 3, 1);
            graph.AddEdge(2, 5, 3);
            graph.AddEdge(2, 6, 4);
            graph.AddEdge(3, 6, 3);
            graph.AddEdge(4, 6, 2);
            graph.AddEdge(4, 7, 3);
            graph.AddEdge(5, 7, 2);
            graph.AddEdge(5, 8, 3);
            graph.AddEdge(7, 8, 1);

            // Expected shortest paths for vertex 1
            // 1 to 2 : 1 -> 2
            // 1 to 3 : 1 -> 3
            // 1 to 4 : 1 -> 4
            // 1 to 5 : 1 -> 2 -> 5
            // 1 to 6 : 1 -> 2 -> 6
            // 1 to 7 : 1 -> 4 -> 7
            // 1 to 8 : 1 -> 2 -> 5 -> 8
            // 1 to 9 : no path
            var expectedPaths = new int[7][]
            {
                new int[] { 1, 2 },
                new int[] { 1, 3 },
                new int[] { 1, 4 },
                new int[] { 1, 2, 5 },
                new int[] { 1, 2, 6 },
                new int[] { 1, 4, 7 },
                new int[] { 1, 2, 5, 8 }
            };

            var expectedEdgesWeights = new int[7][]
            {
                new int[] { 1 },
                new int[] { 2 },
                new int[] { 3 },
                new int[] { 1, 3 },
                new int[] { 1, 4 },
                new int[] { 3, 3 },
                new int[] { 1, 3, 3 }
            };

            var paths = graph.DijkstraShortestPaths(1);

            for (int i = 0; i < 7; i++)
            {
                var curPath = paths.VerticesPathTo(i + 2);

                for (int j = 0; j < curPath.Count; j++)
                {
                    if (expectedPaths[i][j] != curPath[j])
                    {
                        Assert.Fail();
                    }
                }

                var curEdgesPath = paths.EdgesPathTo(i + 2);

                for (int j = 0; j < curEdgesPath.Count; j++)
                {
                    if (expectedEdgesWeights[i][j] != curEdgesPath[j].Weight)
                    {
                        Assert.Fail();
                    }
                }
            }
            Assert.IsFalse(paths.HasPathTo(9));

            // Expected shortest paths for vertex 8
            // 8 to 1 : 8 -> 7 -> 4 -> 1
            // 8 to 2 : 8 -> 5 -> 2
            // 8 to 3 : 8 -> 5 -> 2 -> 3
            // 8 to 4 : 8 -> 7 -> 4
            // 8 to 5 : 8 -> 5
            // 8 to 6 : 8 -> 7 -> 4 -> 6
            // 8 to 7 : 8 -> 7
            // 8 to 9 : no path
            expectedPaths = new int[7][]
            {
                new int[] { 8, 7, 4, 1 },
                new int[] { 8, 5, 2 },
                new int[] { 8, 5, 2, 3 },
                new int[] { 8, 7, 4 },
                new int[] { 8, 5 },
                new int[] { 8, 7, 4, 6 },
                new int[] { 8, 7 }
            };

            expectedEdgesWeights = new int[7][]
            {
                new int[] { 1, 3, 3 },
                new int[] { 3, 3 },
                new int[] { 3, 3, 1 },
                new int[] { 1, 3 },
                new int[] { 3 },
                new int[] { 1, 3, 2 },
                new int[] { 1 }
            };

            paths = graph.DijkstraShortestPaths(8);

            for (int i = 0; i < 7; i++)
            {
                var curPath = paths.VerticesPathTo(i + 1);

                for (int j = 0; j < curPath.Count; j++)
                {
                    if (expectedPaths[i][j] != curPath[j])
                    {
                        Assert.Fail();
                    }
                }

                var curEdgesPath = paths.EdgesPathTo(i + 1);

                for (int j = 0; j < curEdgesPath.Count; j++)
                {
                    if (expectedEdgesWeights[i][j] != curEdgesPath[j].Weight)
                    {
                        Assert.Fail();
                    }
                }
            }
            Assert.IsFalse(paths.HasPathTo(9));
        }
Пример #10
0
        public void UpdatingAndGettingEdgeWeight()
        {
            var vertices = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            var graph = new WeightedALGraph <int, int>();

            graph.AddVertices(vertices);

            Assert.IsTrue(graph.VerticesCount == vertices.Length);

            foreach (var vertex in vertices)
            {
                Assert.IsTrue(graph.ContainsVertex(vertex));
            }

            // Graph is:
            // 1 <-> 2, 3, 4
            // 2 <-> 1, 3, 5, 6
            // 3 <-> 1, 2, 6
            // 4 <-> 1, 6, 7
            // 5 <-> 2, 7, 8
            // 6 <-> 2, 3, 4
            // 7 <-> 4, 8
            // 8 <-> 7, 5
            // 9 <->
            // With each edge having a weight of the sum of its vertices
            graph.AddEdge(1, 2, 3);
            graph.AddEdge(1, 3, 4);
            graph.AddEdge(1, 4, 5);
            graph.AddEdge(2, 3, 5);
            graph.AddEdge(2, 5, 7);
            graph.AddEdge(2, 6, 8);
            graph.AddEdge(3, 6, 9);
            graph.AddEdge(4, 6, 10);
            graph.AddEdge(4, 7, 11);
            graph.AddEdge(5, 7, 12);
            graph.AddEdge(5, 8, 13);
            graph.AddEdge(7, 8, 15);

            int weight = 0;

            Assert.IsTrue(graph.TryGetEdgeWeight(1, 2, out weight));
            Assert.IsTrue(weight == 3);
            Assert.IsTrue(graph.UpdateEdgeWeight(1, 2, weight * 2));
            Assert.IsTrue(graph.TryGetEdgeWeight(2, 1, out weight));
            Assert.IsTrue(weight == 6);
            Assert.IsTrue(graph.TryGetEdgeWeight(1, 3, out weight));
            Assert.IsTrue(weight == 4);
            Assert.IsTrue(graph.UpdateEdgeWeight(1, 3, weight * 2));
            Assert.IsTrue(graph.TryGetEdgeWeight(3, 1, out weight));
            Assert.IsTrue(weight == 8);
            Assert.IsTrue(graph.TryGetEdgeWeight(1, 4, out weight));
            Assert.IsTrue(weight == 5);
            Assert.IsTrue(graph.UpdateEdgeWeight(1, 4, weight * 2));
            Assert.IsTrue(graph.TryGetEdgeWeight(4, 1, out weight));
            Assert.IsTrue(weight == 10);
            Assert.IsTrue(graph.TryGetEdgeWeight(2, 3, out weight));
            Assert.IsTrue(weight == 5);
            Assert.IsTrue(graph.UpdateEdgeWeight(2, 3, weight * 2));
            Assert.IsTrue(graph.TryGetEdgeWeight(3, 2, out weight));
            Assert.IsTrue(weight == 10);
            Assert.IsTrue(graph.TryGetEdgeWeight(2, 5, out weight));
            Assert.IsTrue(weight == 7);
            Assert.IsTrue(graph.UpdateEdgeWeight(2, 5, weight * 2));
            Assert.IsTrue(graph.TryGetEdgeWeight(5, 2, out weight));
            Assert.IsTrue(weight == 14);
            Assert.IsTrue(graph.TryGetEdgeWeight(2, 6, out weight));
            Assert.IsTrue(weight == 8);
            Assert.IsTrue(graph.UpdateEdgeWeight(2, 6, weight * 2));
            Assert.IsTrue(graph.TryGetEdgeWeight(6, 2, out weight));
            Assert.IsTrue(weight == 16);
            Assert.IsTrue(graph.TryGetEdgeWeight(3, 6, out weight));
            Assert.IsTrue(weight == 9);
            Assert.IsTrue(graph.UpdateEdgeWeight(3, 6, weight * 2));
            Assert.IsTrue(graph.TryGetEdgeWeight(6, 3, out weight));
            Assert.IsTrue(weight == 18);
            Assert.IsTrue(graph.TryGetEdgeWeight(4, 6, out weight));
            Assert.IsTrue(weight == 10);
            Assert.IsTrue(graph.UpdateEdgeWeight(4, 6, weight * 2));
            Assert.IsTrue(graph.TryGetEdgeWeight(6, 4, out weight));
            Assert.IsTrue(weight == 20);
            Assert.IsTrue(graph.TryGetEdgeWeight(4, 7, out weight));
            Assert.IsTrue(weight == 11);
            Assert.IsTrue(graph.UpdateEdgeWeight(4, 7, weight * 2));
            Assert.IsTrue(graph.TryGetEdgeWeight(7, 4, out weight));
            Assert.IsTrue(weight == 22);
            Assert.IsTrue(graph.TryGetEdgeWeight(5, 7, out weight));
            Assert.IsTrue(weight == 12);
            Assert.IsTrue(graph.UpdateEdgeWeight(5, 7, weight * 2));
            Assert.IsTrue(graph.TryGetEdgeWeight(7, 5, out weight));
            Assert.IsTrue(weight == 24);
            Assert.IsTrue(graph.TryGetEdgeWeight(5, 8, out weight));
            Assert.IsTrue(weight == 13);
            Assert.IsTrue(graph.UpdateEdgeWeight(5, 8, weight * 2));
            Assert.IsTrue(graph.TryGetEdgeWeight(8, 5, out weight));
            Assert.IsTrue(weight == 26);
            Assert.IsTrue(graph.TryGetEdgeWeight(7, 8, out weight));
            Assert.IsTrue(weight == 15);
            Assert.IsTrue(graph.UpdateEdgeWeight(7, 8, weight * 2));
            Assert.IsTrue(graph.TryGetEdgeWeight(8, 7, out weight));
            Assert.IsTrue(weight == 30);
        }
Пример #11
0
        public void CheckIfDFSIsCorrect()
        {
            var vertices = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            var graph = new WeightedALGraph <int, int>();

            graph.AddVertices(vertices);

            // Graph is:
            // 1 <-> 2, 3, 4
            // 2 <-> 1, 3, 5, 6
            // 3 <-> 1, 2, 6
            // 4 <-> 1, 6, 7
            // 5 <-> 2, 7, 8
            // 6 <-> 2, 3, 4
            // 7 <-> 4, 8
            // 8 <-> 7, 5
            // 9 <->
            // With each edge having a weight of the sum of its vertices
            graph.AddEdge(1, 2, 3);
            graph.AddEdge(1, 3, 4);
            graph.AddEdge(1, 4, 5);
            graph.AddEdge(2, 3, 5);
            graph.AddEdge(2, 5, 7);
            graph.AddEdge(2, 6, 8);
            graph.AddEdge(3, 6, 9);
            graph.AddEdge(4, 6, 10);
            graph.AddEdge(4, 7, 11);
            graph.AddEdge(5, 7, 12);
            graph.AddEdge(5, 8, 13);
            graph.AddEdge(7, 8, 15);

            // Expected dfs for vertex 1:
            // 1 | 2 | 3 | 6 | 4 | 7 | 5 | 8
            var dfsExpectedOutput = new int[] { 1, 2, 3, 6, 4, 7, 5, 8 };
            var dfs = graph.DepthFirstSearch(1).ToList();

            Assert.IsTrue(dfs.Count == dfsExpectedOutput.Length);
            for (int i = 0; i < dfs.Count; i++)
            {
                Assert.IsTrue(dfs[i] == dfsExpectedOutput[i]);
            }

            // Expected dfs edges for vertex 1:
            // 1 | 2 | 3 | 6 | 4 | 7 | 5
            // 2 | 3 | 6 | 4 | 7 | 5 | 8
            var dfsExpectedSources      = new int[] { 1, 2, 3, 6, 4, 7, 5 };
            var dfsExpectedDestinations = new int[] { 2, 3, 6, 4, 7, 5, 8 };
            var dfsEdges = graph.DepthFirstSearchEdges(1).ToList();

            Assert.IsTrue(dfsEdges.Count == dfsExpectedSources.Length);
            for (int i = 0; i < dfsEdges.Count; i++)
            {
                Assert.IsTrue(dfsEdges[i].Source == dfsExpectedSources[i]);
                Assert.IsTrue(dfsEdges[i].Destination == dfsExpectedDestinations[i]);
                Assert.IsTrue(dfsEdges[i].Weight == dfsEdges[i].Source + dfsEdges[i].Destination);
            }

            // Expected dfs for vertex 8:
            // 8 | 5 | 2 | 1 | 3 | 6 | 4 | 7
            dfsExpectedOutput = new int[] { 8, 5, 2, 1, 3, 6, 4, 7 };
            dfs = graph.DepthFirstSearch(8).ToList();

            Assert.IsTrue(dfs.Count == dfsExpectedOutput.Length);
            for (int i = 0; i < dfs.Count; i++)
            {
                Assert.IsTrue(dfs[i] == dfsExpectedOutput[i]);
            }

            // Expected dfs edges for vertex 8:
            // 8 | 5 | 2 | 1 | 3 | 6 | 4
            // 5 | 2 | 1 | 3 | 6 | 4 | 7
            dfsExpectedSources      = new int[] { 8, 5, 2, 1, 3, 6, 4 };
            dfsExpectedDestinations = new int[] { 5, 2, 1, 3, 6, 4, 7 };
            dfsEdges = graph.DepthFirstSearchEdges(8).ToList();

            Assert.IsTrue(dfsEdges.Count == dfsExpectedSources.Length);
            for (int i = 0; i < dfsEdges.Count; i++)
            {
                Assert.IsTrue(dfsEdges[i].Source == dfsExpectedSources[i]);
                Assert.IsTrue(dfsEdges[i].Destination == dfsExpectedDestinations[i]);
                Assert.IsTrue(dfsEdges[i].Weight == dfsEdges[i].Source + dfsEdges[i].Destination);
            }
        }
Пример #12
0
        public void CheckIfOutgoingEdgesAreCorrect()
        {
            var vertices = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            var graph = new WeightedALGraph <int, int>();

            graph.AddVertices(vertices);

            // Graph is:
            // 1 <-> 2, 3, 4
            // 2 <-> 1, 3, 5, 6
            // 3 <-> 1, 2, 6
            // 4 <-> 1, 6, 7
            // 5 <-> 2, 7, 8
            // 6 <-> 2, 3, 4
            // 7 <-> 4, 8
            // 8 <-> 7, 5
            // 9 <->
            // With each edge having a weight of the sum of its vertices
            graph.AddEdge(1, 2, 3);
            graph.AddEdge(1, 3, 4);
            graph.AddEdge(1, 4, 5);
            graph.AddEdge(2, 3, 5);
            graph.AddEdge(2, 5, 7);
            graph.AddEdge(2, 6, 8);
            graph.AddEdge(3, 6, 9);
            graph.AddEdge(4, 6, 10);
            graph.AddEdge(4, 7, 11);
            graph.AddEdge(5, 7, 12);
            graph.AddEdge(5, 8, 13);
            graph.AddEdge(7, 8, 15);

            // Vertex 1 expected outgoing edges: 2 3 4
            var expected = new int[] { 2, 3, 4 };
            var edges    = graph.OutgoingEdgesSorted(1).ToList();

            Assert.IsTrue(edges.Count == expected.Length);
            for (int i = 0; i < expected.Length; i++)
            {
                Assert.IsTrue(edges[i].Destination == expected[i]);
                Assert.IsTrue(edges[i].Weight == edges[i].Source + edges[i].Destination);
            }

            // Vertex 2 expected outgoing edges: 1 3 5 6
            expected = new int[] { 1, 3, 5, 6 };
            edges    = graph.OutgoingEdgesSorted(2).ToList();
            Assert.IsTrue(edges.Count == expected.Length);
            for (int i = 0; i < expected.Length; i++)
            {
                Assert.IsTrue(edges[i].Destination == expected[i]);
                Assert.IsTrue(edges[i].Weight == edges[i].Source + edges[i].Destination);
            }

            // Vertex 7 expected outgoing edges: 4 5 8
            expected = new int[] { 4, 5, 8 };
            edges    = graph.OutgoingEdgesSorted(7).ToList();
            Assert.IsTrue(edges.Count == expected.Length);
            for (int i = 0; i < expected.Length; i++)
            {
                Assert.IsTrue(edges[i].Destination == expected[i]);
                Assert.IsTrue(edges[i].Weight == edges[i].Source + edges[i].Destination);
            }
        }
Пример #13
0
        public void RemovingVerticesAndCheckingIfRemovedProperly()
        {
            var vertices = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            var graph = new WeightedALGraph <int, int>();

            graph.AddVertices(vertices);

            // Graph is:
            // 1 <-> 2, 3, 4
            // 2 <-> 1, 3, 5, 6
            // 3 <-> 1, 2, 6
            // 4 <-> 1, 6, 7
            // 5 <-> 2, 7, 8
            // 6 <-> 2, 3, 4
            // 7 <-> 4, 8
            // 8 <-> 7, 5
            // 9 <->
            // With each edge having a weight of the sum of its vertices
            graph.AddEdge(1, 2, 3);
            graph.AddEdge(1, 3, 4);
            graph.AddEdge(1, 4, 5);
            graph.AddEdge(2, 3, 5);
            graph.AddEdge(2, 5, 7);
            graph.AddEdge(2, 6, 8);
            graph.AddEdge(3, 6, 9);
            graph.AddEdge(4, 6, 10);
            graph.AddEdge(4, 7, 11);
            graph.AddEdge(5, 7, 12);
            graph.AddEdge(5, 8, 13);
            graph.AddEdge(7, 8, 15);

            Assert.IsTrue(graph.EdgesCount == 12);

            Assert.IsTrue(graph.ContainsVertex(3));
            Assert.IsTrue(graph.ContainsEdge(3, 1));
            Assert.IsTrue(graph.ContainsEdge(3, 2));
            Assert.IsTrue(graph.ContainsEdge(3, 6));
            Assert.IsTrue(graph.ContainsEdge(1, 3));
            Assert.IsTrue(graph.ContainsEdge(2, 3));
            Assert.IsTrue(graph.ContainsEdge(6, 3));
            graph.RemoveVertex(3);
            Assert.IsFalse(graph.ContainsVertex(3));
            Assert.IsFalse(graph.ContainsEdge(3, 1));
            Assert.IsFalse(graph.ContainsEdge(3, 2));
            Assert.IsFalse(graph.ContainsEdge(3, 6));
            Assert.IsFalse(graph.ContainsEdge(1, 3));
            Assert.IsFalse(graph.ContainsEdge(2, 3));
            Assert.IsFalse(graph.ContainsEdge(6, 3));

            Assert.IsTrue(graph.EdgesCount == 9);

            Assert.IsTrue(graph.ContainsVertex(5));
            Assert.IsTrue(graph.ContainsEdge(5, 2));
            Assert.IsTrue(graph.ContainsEdge(5, 7));
            Assert.IsTrue(graph.ContainsEdge(5, 8));
            Assert.IsTrue(graph.ContainsEdge(2, 5));
            Assert.IsTrue(graph.ContainsEdge(7, 5));
            Assert.IsTrue(graph.ContainsEdge(8, 5));
            graph.RemoveVertex(5);
            Assert.IsFalse(graph.ContainsVertex(5));
            Assert.IsFalse(graph.ContainsEdge(5, 2));
            Assert.IsFalse(graph.ContainsEdge(5, 7));
            Assert.IsFalse(graph.ContainsEdge(5, 8));
            Assert.IsFalse(graph.ContainsEdge(2, 5));
            Assert.IsFalse(graph.ContainsEdge(7, 5));
            Assert.IsFalse(graph.ContainsEdge(8, 5));

            Assert.IsTrue(graph.EdgesCount == 6);
        }
Пример #14
0
        public void CheckingIfVerticesAndEdgesAreAddedProperly()
        {
            var vertices = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            var graph = new WeightedALGraph <int, int>();

            graph.AddVertices(vertices);

            Assert.IsTrue(graph.VerticesCount == vertices.Length);

            foreach (var vertex in vertices)
            {
                Assert.IsTrue(graph.ContainsVertex(vertex));
            }

            // Graph is:
            // 1 <-> 2, 3, 4
            // 2 <-> 1, 3, 5, 6
            // 3 <-> 1, 2, 6
            // 4 <-> 1, 6, 7
            // 5 <-> 2, 7, 8
            // 6 <-> 2, 3, 4
            // 7 <-> 4, 8
            // 8 <-> 7, 5
            // 9 <->
            // With each edge having a weight of the sum of its vertices
            graph.AddEdge(1, 2, 3);
            graph.AddEdge(1, 3, 4);
            graph.AddEdge(1, 4, 5);
            graph.AddEdge(2, 3, 5);
            graph.AddEdge(2, 5, 7);
            graph.AddEdge(2, 6, 8);
            graph.AddEdge(3, 6, 9);
            graph.AddEdge(4, 6, 10);
            graph.AddEdge(4, 7, 11);
            graph.AddEdge(5, 7, 12);
            graph.AddEdge(5, 8, 13);
            graph.AddEdge(7, 8, 15);

            Assert.IsTrue(graph.EdgesCount == 12);

            int weight = 0;

            Assert.IsTrue(graph.TryGetEdgeWeight(1, 2, out weight));
            Assert.IsTrue(weight == 3);
            Assert.IsTrue(graph.TryGetEdgeWeight(2, 1, out weight));
            Assert.IsTrue(weight == 3);
            Assert.IsTrue(graph.TryGetEdgeWeight(1, 3, out weight));
            Assert.IsTrue(weight == 4);
            Assert.IsTrue(graph.TryGetEdgeWeight(3, 1, out weight));
            Assert.IsTrue(weight == 4);
            Assert.IsTrue(graph.TryGetEdgeWeight(1, 4, out weight));
            Assert.IsTrue(weight == 5);
            Assert.IsTrue(graph.TryGetEdgeWeight(4, 1, out weight));
            Assert.IsTrue(weight == 5);
            Assert.IsTrue(graph.TryGetEdgeWeight(2, 3, out weight));
            Assert.IsTrue(weight == 5);
            Assert.IsTrue(graph.TryGetEdgeWeight(3, 2, out weight));
            Assert.IsTrue(weight == 5);
            Assert.IsTrue(graph.TryGetEdgeWeight(2, 5, out weight));
            Assert.IsTrue(weight == 7);
            Assert.IsTrue(graph.TryGetEdgeWeight(5, 2, out weight));
            Assert.IsTrue(weight == 7);
            Assert.IsTrue(graph.TryGetEdgeWeight(2, 6, out weight));
            Assert.IsTrue(weight == 8);
            Assert.IsTrue(graph.TryGetEdgeWeight(6, 2, out weight));
            Assert.IsTrue(weight == 8);
            Assert.IsTrue(graph.TryGetEdgeWeight(3, 6, out weight));
            Assert.IsTrue(weight == 9);
            Assert.IsTrue(graph.TryGetEdgeWeight(6, 3, out weight));
            Assert.IsTrue(weight == 9);
            Assert.IsTrue(graph.TryGetEdgeWeight(4, 6, out weight));
            Assert.IsTrue(weight == 10);
            Assert.IsTrue(graph.TryGetEdgeWeight(6, 4, out weight));
            Assert.IsTrue(weight == 10);
            Assert.IsTrue(graph.TryGetEdgeWeight(4, 7, out weight));
            Assert.IsTrue(weight == 11);
            Assert.IsTrue(graph.TryGetEdgeWeight(7, 4, out weight));
            Assert.IsTrue(weight == 11);
            Assert.IsTrue(graph.TryGetEdgeWeight(5, 7, out weight));
            Assert.IsTrue(weight == 12);
            Assert.IsTrue(graph.TryGetEdgeWeight(7, 5, out weight));
            Assert.IsTrue(weight == 12);
            Assert.IsTrue(graph.TryGetEdgeWeight(5, 8, out weight));
            Assert.IsTrue(weight == 13);
            Assert.IsTrue(graph.TryGetEdgeWeight(8, 5, out weight));
            Assert.IsTrue(weight == 13);
            Assert.IsTrue(graph.TryGetEdgeWeight(7, 8, out weight));
            Assert.IsTrue(weight == 15);
            Assert.IsTrue(graph.TryGetEdgeWeight(8, 7, out weight));
            Assert.IsTrue(weight == 15);

            Assert.IsFalse(graph.ContainsEdge(1, 7));
            Assert.IsFalse(graph.ContainsEdge(1, 5));
            Assert.IsFalse(graph.ContainsEdge(1, 8));
            Assert.IsFalse(graph.ContainsEdge(2, 4));
            Assert.IsFalse(graph.ContainsEdge(2, 7));
            Assert.IsFalse(graph.ContainsEdge(2, 8));
            Assert.IsFalse(graph.ContainsEdge(3, 4));
            Assert.IsFalse(graph.ContainsEdge(3, 5));
            Assert.IsFalse(graph.ContainsEdge(3, 7));
            Assert.IsFalse(graph.ContainsEdge(3, 8));
            Assert.IsFalse(graph.ContainsEdge(4, 2));
            Assert.IsFalse(graph.ContainsEdge(4, 3));
            Assert.IsFalse(graph.ContainsEdge(4, 5));
            Assert.IsFalse(graph.ContainsEdge(4, 8));
            Assert.IsFalse(graph.ContainsEdge(5, 1));
            Assert.IsFalse(graph.ContainsEdge(5, 3));
            Assert.IsFalse(graph.ContainsEdge(5, 4));
            Assert.IsFalse(graph.ContainsEdge(5, 6));
            Assert.IsFalse(graph.ContainsEdge(6, 1));
            Assert.IsFalse(graph.ContainsEdge(6, 5));
            Assert.IsFalse(graph.ContainsEdge(6, 7));
            Assert.IsFalse(graph.ContainsEdge(6, 8));
            Assert.IsFalse(graph.ContainsEdge(7, 1));
            Assert.IsFalse(graph.ContainsEdge(7, 2));
            Assert.IsFalse(graph.ContainsEdge(7, 3));
            Assert.IsFalse(graph.ContainsEdge(7, 6));
            Assert.IsFalse(graph.ContainsEdge(8, 1));
            Assert.IsFalse(graph.ContainsEdge(8, 2));
            Assert.IsFalse(graph.ContainsEdge(8, 3));
            Assert.IsFalse(graph.ContainsEdge(8, 4));
            Assert.IsFalse(graph.ContainsEdge(8, 6));
        }
Пример #15
0
        public void PositiveEdgesWeightsAsVertexSum()
        {
            var vertices = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            var graph = new WeightedALGraph <int, int>();

            graph.AddVertices(vertices);

            // Graph is:
            // 1 <-> 2, 3, 4
            // 2 <-> 1, 3, 5, 6
            // 3 <-> 1, 2, 6
            // 4 <-> 1, 6, 7
            // 5 <-> 2, 7, 8
            // 6 <-> 2, 3, 4
            // 7 <-> 4, 8
            // 8 <-> 7, 5
            // 9 <->
            // With each edge having a weight of the absolute value of the difference of the vertices
            graph.AddEdge(1, 2, 3);
            graph.AddEdge(1, 3, 4);
            graph.AddEdge(1, 4, 5);
            graph.AddEdge(2, 3, 5);
            graph.AddEdge(2, 5, 7);
            graph.AddEdge(2, 6, 8);
            graph.AddEdge(3, 6, 9);
            graph.AddEdge(4, 6, 10);
            graph.AddEdge(4, 7, 11);
            graph.AddEdge(5, 7, 12);
            graph.AddEdge(5, 8, 13);
            graph.AddEdge(7, 8, 15);

            // Expected MST
            // 1 <-> 2, 3, 4
            // 2 <-> 1, 5, 6
            // 3 <-> 1
            // 4 <-> 1
            // 5 <-> 2, 7, 8
            // 6 <-> 2
            // 7 <-> 5
            // 8 <-> 5
            // 9 <->

            var mst = graph.KruskalMST();

            int weight = 0;

            Assert.IsTrue(mst.TryGetEdgeWeight(1, 2, out weight));
            Assert.IsTrue(weight == 3);
            Assert.IsTrue(mst.TryGetEdgeWeight(2, 1, out weight));
            Assert.IsTrue(weight == 3);
            Assert.IsTrue(mst.TryGetEdgeWeight(1, 3, out weight));
            Assert.IsTrue(weight == 4);
            Assert.IsTrue(mst.TryGetEdgeWeight(3, 1, out weight));
            Assert.IsTrue(weight == 4);
            Assert.IsTrue(mst.TryGetEdgeWeight(1, 4, out weight));
            Assert.IsTrue(weight == 5);
            Assert.IsTrue(mst.TryGetEdgeWeight(4, 1, out weight));
            Assert.IsTrue(weight == 5);
            Assert.IsTrue(mst.TryGetEdgeWeight(2, 5, out weight));
            Assert.IsTrue(weight == 7);
            Assert.IsTrue(mst.TryGetEdgeWeight(5, 2, out weight));
            Assert.IsTrue(weight == 7);
            Assert.IsTrue(mst.TryGetEdgeWeight(2, 6, out weight));
            Assert.IsTrue(weight == 8);
            Assert.IsTrue(mst.TryGetEdgeWeight(6, 2, out weight));
            Assert.IsTrue(weight == 8);
            Assert.IsTrue(mst.TryGetEdgeWeight(4, 7, out weight));
            Assert.IsTrue(weight == 11);
            Assert.IsTrue(mst.TryGetEdgeWeight(7, 4, out weight));
            Assert.IsTrue(weight == 11);
            Assert.IsTrue(mst.TryGetEdgeWeight(5, 8, out weight));
            Assert.IsTrue(weight == 13);
            Assert.IsTrue(mst.TryGetEdgeWeight(8, 5, out weight));
            Assert.IsTrue(weight == 13);

            Assert.IsFalse(mst.ContainsEdge(2, 3));
            Assert.IsFalse(mst.ContainsEdge(3, 2));
            Assert.IsFalse(mst.ContainsEdge(3, 6));
            Assert.IsFalse(mst.ContainsEdge(6, 3));
            Assert.IsFalse(mst.ContainsEdge(4, 6));
            Assert.IsFalse(mst.ContainsEdge(6, 4));
            Assert.IsFalse(mst.ContainsEdge(5, 7));
            Assert.IsFalse(mst.ContainsEdge(7, 5));
            Assert.IsFalse(mst.ContainsEdge(7, 8));
            Assert.IsFalse(mst.ContainsEdge(8, 7));
        }