Example #1
0
        public static Graph LabelCorrecting(Graph g, int vert)
        {
            Output.WriteLine("[Label Correcting Output]");
            //Not working, I think because of the two loops for in and out edges

            //Change this to assume g is an undirected graph

            //Keep a heap of vertices, based on their distance label
            //Each one is initially infinity, except the intial vertex, which is 0

            Graph copy = new Graph();
            Graph tree = new Graph();
            //Create a copy to preserve g's state
            g.CopyTo(copy);

            List<Vertex> vertices = copy.GetVertices();
            List<Edge> edges = copy.GetEdges();

            DijkstraData v = new DijkstraData();
            v.Predecessor = null;
            v.InQ = false;
            v.V = vertices[vert];
            v.D = 0;
            v.InTree = false;
            v.EdgeLength = float.PositiveInfinity;
            vertices[vert].Tag = v;

            Heap<DijkstraData> q = new Heap<DijkstraData>(true);
            q.Add(vertices[vert].Tag as DijkstraData);
            (vertices[vert].Tag as DijkstraData).InQ = true;

            foreach (Vertex u in vertices)
            {
                if (!v.V.Equals(u))
                {
                    DijkstraData dd = new DijkstraData();
                    dd.D = float.PositiveInfinity;
                    dd.V = u;
                    dd.InTree = false;
                    dd.InQ = false;
                    u.Tag = dd;
                }
            }

            float maxEdgeWeight = float.NegativeInfinity;
            foreach (Edge e in edges)
            {
                if (Math.Abs(e.Weight) > maxEdgeWeight)
                {
                    maxEdgeWeight = Math.Abs(e.Weight);
                }
            }
            int n = vertices.Count;
            float negativeCycleCheck = n * -maxEdgeWeight;

            while (q.HasNext())
            {
                DijkstraData dd = q.Next();
                dd.InQ = false;
                /*if (dd.Predecessor == null)
                {
                    tree.AddVertex(dd.V);
                }
                else
                {
                    tree.AddEdge(new Edge(dd.Predecessor, dd.V, dd.EdgeLength));
                    dd.InTree = true;
                }*/

                foreach (Edge e in dd.V.GetOutEdges())
                {
                    Vertex connectedVertex = e.GetToVertex();
                    DijkstraData data = connectedVertex.Tag as DijkstraData;

                    if (data.D > dd.D + e.Weight)
                    {
                        data.D = dd.D + e.Weight;
                        if (data.D < negativeCycleCheck)
                        {
                            throw new Exception("Negative cycle detected!");
                        }
                        data.Predecessor = dd.V;
                        if (!q.Contains(data))
                        {
                            q.Add(data);
                            data.InQ = true;
                        }
                    }
                }

                if (g.Directed)
                {
                    continue;
                }

                foreach (Edge e in dd.V.GetInEdges())
                {
                    Vertex connectedVertex = e.GetFromVertex();
                    DijkstraData data = connectedVertex.Tag as DijkstraData;

                    if (data.D > dd.D + e.Weight)
                    {
                        data.D = dd.D + e.Weight;
                        if (data.D < negativeCycleCheck)
                        {
                            throw new Exception("Negative cycle detected!");
                        }
                        data.Predecessor = dd.V;
                        if (!q.Contains(data))
                        {
                            q.Add(data);
                            data.InQ = true;
                        }
                    }
                }
            }

            Output.WriteLine("Distance from selected vertex to:");

            foreach (Vertex vertex in vertices)
            {
                Output.WriteLine(vertex.ToString() + " = " + (vertex.Tag as DijkstraData).D);
            }

            Output.WriteLine("[End Label Correcting Output]");
            return tree;
        }
Example #2
0
        public static Graph PrimMST(Graph g)
        {
            if (g.Directed)
            {
                Output.WriteLine("Can't run Prim's algorithm on a directed graph");
                return null;
            }

            Graph copy = new Graph();
            Graph mst = new Graph();
            //Create a copy to preserve g's state
            g.CopyTo(copy);

            List<Vertex> vertices = copy.GetVertices();
            foreach (Vertex vert in vertices)
            {
                mst.AddVertex(vert);
            }

            PrimData v = new PrimData();
            v.Predecessor = null;
            v.Seen = true;
            v.V = vertices[0];
            v.D = 0;
            v.InMST = true;
            v.EdgeLength = float.PositiveInfinity;
            vertices[0].Tag = v;

            foreach (Vertex u in vertices)
            {
                if (!v.V.Equals(u))
                {
                    PrimData pd = new PrimData();
                    pd.D = float.PositiveInfinity;
                    pd.V = u;
                    pd.InMST = false;
                    pd.Seen = false;
                    u.Tag = pd;
                }
            }

            Heap<PrimData> q = new Heap<PrimData>(true);
            q.Add(vertices[0].Tag as PrimData);

            while (q.HasNext())
            {
                PrimData pd = q.Next();
                if (pd.Predecessor == null)
                {
                    //mst.AddVertex(pd.V);
                }
                else
                {
                    string label = pd.V.Label;
                    mst.AddEdge(new Edge(pd.Predecessor, pd.V, pd.EdgeLength));
                    pd.V.Label = label;
                    pd.InMST = true;
                }

                foreach (Edge e in pd.V.GetOutEdges())
                {
                    Vertex connectedVertex = e.GetToVertex();
                    PrimData data = connectedVertex.Tag as PrimData;
                    if (!data.Seen)
                    {
                        q.Add(data);
                        data.Predecessor = pd.V;
                        data.EdgeLength = e.Weight;
                        data.Seen = true;
                    }

                    if (data.D > e.Weight && !data.InMST)
                    {
                        data.D = e.Weight;
                        data.Predecessor = pd.V;
                        data.EdgeLength = e.Weight;
                        q.Update(data);
                    }
                }
                /*foreach (Edge e in pd.V.GetInEdges())
                {
                    Vertex connectedVertex = e.GetFromVertex();
                    PrimData data = connectedVertex.Tag as PrimData;
                    if (!data.Seen)
                    {
                        q.Add(data);
                        data.Predecessor = pd.V;
                        data.EdgeLength = e.Weight;
                        data.Seen = true;
                    }

                    if (data.D > e.Weight && !data.InMST)
                    {
                        data.D = e.Weight;
                        data.Predecessor = pd.V;
                        data.EdgeLength = e.Weight;
                        q.Update(data);
                    }
                }*/
            }

            return mst;
        }
Example #3
0
        public static Graph Dijkstra(Graph g, int vert, bool directed)
        {
            Output.WriteLine("[Dijkstra Output]");

            //If I get a negative edge weight, tell user to use label correcting instead of dijkstra's

            //Change this to assume g is an undirected graph

            //Keep a heap of vertices, based on their distance label
            //Each one is initially infinity, except the intial vertex, which is 0

            Graph copy = new Graph();
            Graph tree = new Graph();
            //Create a copy to preserve g's state
            g.CopyTo(copy);

            List<Vertex> vertices = copy.GetVertices();
            List<Edge> edges = copy.GetEdges();

            DijkstraData v = new DijkstraData();
            v.Predecessor = null;
            v.InQ = false;
            v.V = vertices[vert];
            v.D = 0;
            v.InTree = false;
            v.EdgeLength = float.PositiveInfinity;
            vertices[vert].Tag = v;

            Heap<DijkstraData> q = new Heap<DijkstraData>(true);
            q.Add(vertices[vert].Tag as DijkstraData);
            (vertices[vert].Tag as DijkstraData).InQ = true;

            foreach (Vertex u in vertices)
            {
                if (!v.V.Equals(u))
                {
                    DijkstraData dd = new DijkstraData();
                    dd.D = float.PositiveInfinity;
                    dd.V = u;
                    dd.InTree = false;
                    u.Tag = dd;
                    q.Add(dd);
                    dd.InQ = true;
                }
            }

            foreach (Edge e in edges)
            {
                if (e.Weight < 0)
                {
                    Output.WriteLine("Negative edge weight detected. Use Label Correcting instead of Dijkstra");
                    return null;
                }
            }

            while (q.HasNext())
            {
                DijkstraData dd = q.Next();
                dd.InQ = false;
                /*if (dd.Predecessor == null)
                {
                    tree.AddVertex(dd.V);
                    dd.InTree = true;
                }
                else
                {
                    tree.AddEdge(new Edge(dd.Predecessor, dd.V, dd.EdgeLength));
                    dd.InTree = true;
                }*/

                foreach (Edge e in dd.V.GetOutEdges())
                {
                    Vertex connectedVertex = e.GetToVertex();
                    DijkstraData data = connectedVertex.Tag as DijkstraData;

                    if (data.InQ)
                    {
                        if (dd.D + e.Weight < data.D)
                        {
                            if (dd.D + e.Weight < data.D)
                            {
                                data.D = dd.D + e.Weight;
                                q.Update(data);
                            }
                        }
                    }
                }

                //If this is a directed graph, don't consider in edges
                if (directed)
                {
                    continue;
                }
                foreach (Edge e in dd.V.GetInEdges())
                {
                    Vertex connectedVertex = e.GetFromVertex();
                    DijkstraData data = connectedVertex.Tag as DijkstraData;

                    if (data.InQ)
                    {
                        if (dd.D + e.Weight < data.D)
                        {
                            data.D = dd.D + e.Weight;
                            q.Update(data);
                        }
                    }
                }
            }

            Output.WriteLine("Distance from selected vertex to:");

            foreach (Vertex vertex in vertices)
            {
                Output.WriteLine(vertex.ToString() +  " = " + (vertex.Tag as DijkstraData).D);
            }

            Output.WriteLine("[End Dijkstra Output]");
            return tree;
        }
Example #4
0
        public static Graph KruskalMST(Graph g)
        {
            Graph copy = new Graph();
            Graph mst = new Graph();
            //Create a copy to preserve g's state
            g.CopyTo(copy);

            List<Edge> edges = copy.GetEdges();
            List<Vertex> vertices = copy.GetVertices();

            for (int i = 0; i < vertices.Count; i++)
            {
                //Associate each vertex with a set of vertices
                //Initially, each vertex belongs to its own set
                List<Vertex> vertexSet = new List<Vertex>();
                vertexSet.Add(vertices[i]);
                vertices[i].Tag = vertexSet;
                mst.AddVertex(vertices[i]);
            }

            //We don't want to consider edges going in the opposite direction
            List<Edge> filteredEdges = new List<Edge>();
            for (int i = 0; i < edges.Count; i += 2)
            {
                filteredEdges.Add(edges[i]);
            }

            filteredEdges.Sort(delegate(Edge e1, Edge e2)
                        {
                            return e1.Weight.CompareTo(e2.Weight);
                        });

            //Have counter that counts number of edges used.
            //If it equals the total number of edges then the original graph was disconnected

            int edgeIndex = 0;
            //Loop through all the edges
            while (edgeIndex < filteredEdges.Count/* && mst.GetEdges().Count < g.GetVertices().Count - 1*/)
            {
                //Walk up the array instead of removing the vertex
                Edge minEdge = filteredEdges[edgeIndex];

                //Get the sets associated with the vertices on the minEdge
                List<Vertex> fromSet = minEdge.GetFromVertex().Tag as List<Vertex>;
                List<Vertex> toSet = minEdge.GetToVertex().Tag as List<Vertex>;

                //If these two sets are not the same set...
                if (!fromSet.Equals(toSet))
                {
                    //...then add the edge to the MST
                    string fromLabel = minEdge.GetFromVertex().Label;
                    string toLabel = minEdge.GetToVertex().Label;
                    mst.AddEdge(minEdge);
                    minEdge.GetFromVertex().Label = fromLabel;
                    minEdge.GetToVertex().Label = toLabel;

                    //Merge the two vertices' sets together
                    List<Vertex> newList = fromSet.Union(toSet).ToList<Vertex>();
                    foreach (Vertex v in newList)
                    {
                        v.Tag = newList;
                    }
                    minEdge.GetFromVertex().Tag = newList;
                    minEdge.GetToVertex().Tag = newList;
                }

                //Offset by 2 because we're ignoring edges that go in the opposite direction
                edgeIndex++;
            }

            return mst;
        }
Example #5
0
        private static void TestMatrixStuff()
        {
            Graph g = new Graph();
            g.Directed = true;
            Vertex v1 = new Vertex();
            Vertex v2 = new Vertex();
            Vertex v3 = new Vertex();
            Vertex v4 = new Vertex();

            g.AddVertex(v1);
            g.AddVertex(v2);
            g.AddVertex(v3);
            g.AddVertex(v4);

            g.AddEdge(new Edge(v2, v1, 25f));
            g.AddEdge(new Edge(v1, v3, 10f));

            g.RemoveEdge(g.GetEdges()[1]);

            g.AddEdge(new Edge(v4, v2, 7f));

            g.RemoveVertex(v1);
            g.RemoveVertex(v2);

            g.AddEdge(new Edge(v3, v4, 30f));
            g.AddEdge(new Edge(v4, v3, 27f));

            Console.WriteLine("Testing graph insertion and deletion");

            g.PrintMatrix();

            Console.WriteLine();
            Graph g2 = new Graph();
            g.CopyTo(g2);
            g2.PrintMatrix();
        }
Example #6
0
        public static Graph PrimMST(Graph g)
        {
            if (g.Directed)
            {
                Output.WriteLine("Can't run Prim's algorithm on a directed graph");
                return(null);
            }

            Graph copy = new Graph();
            Graph mst  = new Graph();

            //Create a copy to preserve g's state
            g.CopyTo(copy);

            List <Vertex> vertices = copy.GetVertices();

            foreach (Vertex vert in vertices)
            {
                mst.AddVertex(vert);
            }

            PrimData v = new PrimData();

            v.Predecessor   = null;
            v.Seen          = true;
            v.V             = vertices[0];
            v.D             = 0;
            v.InMST         = true;
            v.EdgeLength    = float.PositiveInfinity;
            vertices[0].Tag = v;

            foreach (Vertex u in vertices)
            {
                if (!v.V.Equals(u))
                {
                    PrimData pd = new PrimData();
                    pd.D     = float.PositiveInfinity;
                    pd.V     = u;
                    pd.InMST = false;
                    pd.Seen  = false;
                    u.Tag    = pd;
                }
            }

            Heap <PrimData> q = new Heap <PrimData>(true);

            q.Add(vertices[0].Tag as PrimData);

            while (q.HasNext())
            {
                PrimData pd = q.Next();
                if (pd.Predecessor == null)
                {
                    //mst.AddVertex(pd.V);
                }
                else
                {
                    string label = pd.V.Label;
                    mst.AddEdge(new Edge(pd.Predecessor, pd.V, pd.EdgeLength));
                    pd.V.Label = label;
                    pd.InMST   = true;
                }

                foreach (Edge e in pd.V.GetOutEdges())
                {
                    Vertex   connectedVertex = e.GetToVertex();
                    PrimData data            = connectedVertex.Tag as PrimData;
                    if (!data.Seen)
                    {
                        q.Add(data);
                        data.Predecessor = pd.V;
                        data.EdgeLength  = e.Weight;
                        data.Seen        = true;
                    }

                    if (data.D > e.Weight && !data.InMST)
                    {
                        data.D           = e.Weight;
                        data.Predecessor = pd.V;
                        data.EdgeLength  = e.Weight;
                        q.Update(data);
                    }
                }

                /*foreach (Edge e in pd.V.GetInEdges())
                 * {
                 *  Vertex connectedVertex = e.GetFromVertex();
                 *  PrimData data = connectedVertex.Tag as PrimData;
                 *  if (!data.Seen)
                 *  {
                 *      q.Add(data);
                 *      data.Predecessor = pd.V;
                 *      data.EdgeLength = e.Weight;
                 *      data.Seen = true;
                 *  }
                 *
                 *  if (data.D > e.Weight && !data.InMST)
                 *  {
                 *      data.D = e.Weight;
                 *      data.Predecessor = pd.V;
                 *      data.EdgeLength = e.Weight;
                 *      q.Update(data);
                 *  }
                 * }*/
            }

            return(mst);
        }
Example #7
0
        public static Graph LabelCorrecting(Graph g, int vert)
        {
            Output.WriteLine("[Label Correcting Output]");
            //Not working, I think because of the two loops for in and out edges

            //Change this to assume g is an undirected graph

            //Keep a heap of vertices, based on their distance label
            //Each one is initially infinity, except the intial vertex, which is 0

            Graph copy = new Graph();
            Graph tree = new Graph();

            //Create a copy to preserve g's state
            g.CopyTo(copy);

            List <Vertex> vertices = copy.GetVertices();
            List <Edge>   edges    = copy.GetEdges();

            DijkstraData v = new DijkstraData();

            v.Predecessor      = null;
            v.InQ              = false;
            v.V                = vertices[vert];
            v.D                = 0;
            v.InTree           = false;
            v.EdgeLength       = float.PositiveInfinity;
            vertices[vert].Tag = v;

            Heap <DijkstraData> q = new Heap <DijkstraData>(true);

            q.Add(vertices[vert].Tag as DijkstraData);
            (vertices[vert].Tag as DijkstraData).InQ = true;

            foreach (Vertex u in vertices)
            {
                if (!v.V.Equals(u))
                {
                    DijkstraData dd = new DijkstraData();
                    dd.D      = float.PositiveInfinity;
                    dd.V      = u;
                    dd.InTree = false;
                    dd.InQ    = false;
                    u.Tag     = dd;
                }
            }

            float maxEdgeWeight = float.NegativeInfinity;

            foreach (Edge e in edges)
            {
                if (Math.Abs(e.Weight) > maxEdgeWeight)
                {
                    maxEdgeWeight = Math.Abs(e.Weight);
                }
            }
            int   n = vertices.Count;
            float negativeCycleCheck = n * -maxEdgeWeight;

            while (q.HasNext())
            {
                DijkstraData dd = q.Next();
                dd.InQ = false;

                /*if (dd.Predecessor == null)
                 * {
                 *  tree.AddVertex(dd.V);
                 * }
                 * else
                 * {
                 *  tree.AddEdge(new Edge(dd.Predecessor, dd.V, dd.EdgeLength));
                 *  dd.InTree = true;
                 * }*/

                foreach (Edge e in dd.V.GetOutEdges())
                {
                    Vertex       connectedVertex = e.GetToVertex();
                    DijkstraData data            = connectedVertex.Tag as DijkstraData;

                    if (data.D > dd.D + e.Weight)
                    {
                        data.D = dd.D + e.Weight;
                        if (data.D < negativeCycleCheck)
                        {
                            throw new Exception("Negative cycle detected!");
                        }
                        data.Predecessor = dd.V;
                        if (!q.Contains(data))
                        {
                            q.Add(data);
                            data.InQ = true;
                        }
                    }
                }

                if (g.Directed)
                {
                    continue;
                }

                foreach (Edge e in dd.V.GetInEdges())
                {
                    Vertex       connectedVertex = e.GetFromVertex();
                    DijkstraData data            = connectedVertex.Tag as DijkstraData;

                    if (data.D > dd.D + e.Weight)
                    {
                        data.D = dd.D + e.Weight;
                        if (data.D < negativeCycleCheck)
                        {
                            throw new Exception("Negative cycle detected!");
                        }
                        data.Predecessor = dd.V;
                        if (!q.Contains(data))
                        {
                            q.Add(data);
                            data.InQ = true;
                        }
                    }
                }
            }

            Output.WriteLine("Distance from selected vertex to:");

            foreach (Vertex vertex in vertices)
            {
                Output.WriteLine(vertex.ToString() + " = " + (vertex.Tag as DijkstraData).D);
            }


            Output.WriteLine("[End Label Correcting Output]");
            return(tree);
        }
Example #8
0
        public static Graph Dijkstra(Graph g, int vert, bool directed)
        {
            Output.WriteLine("[Dijkstra Output]");

            //If I get a negative edge weight, tell user to use label correcting instead of dijkstra's

            //Change this to assume g is an undirected graph

            //Keep a heap of vertices, based on their distance label
            //Each one is initially infinity, except the intial vertex, which is 0

            Graph copy = new Graph();
            Graph tree = new Graph();

            //Create a copy to preserve g's state
            g.CopyTo(copy);

            List <Vertex> vertices = copy.GetVertices();
            List <Edge>   edges    = copy.GetEdges();

            DijkstraData v = new DijkstraData();

            v.Predecessor      = null;
            v.InQ              = false;
            v.V                = vertices[vert];
            v.D                = 0;
            v.InTree           = false;
            v.EdgeLength       = float.PositiveInfinity;
            vertices[vert].Tag = v;

            Heap <DijkstraData> q = new Heap <DijkstraData>(true);

            q.Add(vertices[vert].Tag as DijkstraData);
            (vertices[vert].Tag as DijkstraData).InQ = true;

            foreach (Vertex u in vertices)
            {
                if (!v.V.Equals(u))
                {
                    DijkstraData dd = new DijkstraData();
                    dd.D      = float.PositiveInfinity;
                    dd.V      = u;
                    dd.InTree = false;
                    u.Tag     = dd;
                    q.Add(dd);
                    dd.InQ = true;
                }
            }

            foreach (Edge e in edges)
            {
                if (e.Weight < 0)
                {
                    Output.WriteLine("Negative edge weight detected. Use Label Correcting instead of Dijkstra");
                    return(null);
                }
            }

            while (q.HasNext())
            {
                DijkstraData dd = q.Next();
                dd.InQ = false;

                /*if (dd.Predecessor == null)
                 * {
                 *  tree.AddVertex(dd.V);
                 *  dd.InTree = true;
                 * }
                 * else
                 * {
                 *  tree.AddEdge(new Edge(dd.Predecessor, dd.V, dd.EdgeLength));
                 *  dd.InTree = true;
                 * }*/

                foreach (Edge e in dd.V.GetOutEdges())
                {
                    Vertex       connectedVertex = e.GetToVertex();
                    DijkstraData data            = connectedVertex.Tag as DijkstraData;

                    if (data.InQ)
                    {
                        if (dd.D + e.Weight < data.D)
                        {
                            if (dd.D + e.Weight < data.D)
                            {
                                data.D = dd.D + e.Weight;
                                q.Update(data);
                            }
                        }
                    }
                }

                //If this is a directed graph, don't consider in edges
                if (directed)
                {
                    continue;
                }
                foreach (Edge e in dd.V.GetInEdges())
                {
                    Vertex       connectedVertex = e.GetFromVertex();
                    DijkstraData data            = connectedVertex.Tag as DijkstraData;

                    if (data.InQ)
                    {
                        if (dd.D + e.Weight < data.D)
                        {
                            data.D = dd.D + e.Weight;
                            q.Update(data);
                        }
                    }
                }
            }

            Output.WriteLine("Distance from selected vertex to:");

            foreach (Vertex vertex in vertices)
            {
                Output.WriteLine(vertex.ToString() + " = " + (vertex.Tag as DijkstraData).D);
            }

            Output.WriteLine("[End Dijkstra Output]");
            return(tree);
        }
Example #9
0
        public static Graph KruskalMST(Graph g)
        {
            Graph copy = new Graph();
            Graph mst  = new Graph();

            //Create a copy to preserve g's state
            g.CopyTo(copy);

            List <Edge>   edges    = copy.GetEdges();
            List <Vertex> vertices = copy.GetVertices();

            for (int i = 0; i < vertices.Count; i++)
            {
                //Associate each vertex with a set of vertices
                //Initially, each vertex belongs to its own set
                List <Vertex> vertexSet = new List <Vertex>();
                vertexSet.Add(vertices[i]);
                vertices[i].Tag = vertexSet;
                mst.AddVertex(vertices[i]);
            }

            //We don't want to consider edges going in the opposite direction
            List <Edge> filteredEdges = new List <Edge>();

            for (int i = 0; i < edges.Count; i += 2)
            {
                filteredEdges.Add(edges[i]);
            }

            filteredEdges.Sort(delegate(Edge e1, Edge e2)
            {
                return(e1.Weight.CompareTo(e2.Weight));
            });


            //Have counter that counts number of edges used.
            //If it equals the total number of edges then the original graph was disconnected

            int edgeIndex = 0;

            //Loop through all the edges
            while (edgeIndex < filteredEdges.Count /* && mst.GetEdges().Count < g.GetVertices().Count - 1*/)
            {
                //Walk up the array instead of removing the vertex
                Edge minEdge = filteredEdges[edgeIndex];

                //Get the sets associated with the vertices on the minEdge
                List <Vertex> fromSet = minEdge.GetFromVertex().Tag as List <Vertex>;
                List <Vertex> toSet   = minEdge.GetToVertex().Tag as List <Vertex>;

                //If these two sets are not the same set...
                if (!fromSet.Equals(toSet))
                {
                    //...then add the edge to the MST
                    string fromLabel = minEdge.GetFromVertex().Label;
                    string toLabel   = minEdge.GetToVertex().Label;
                    mst.AddEdge(minEdge);
                    minEdge.GetFromVertex().Label = fromLabel;
                    minEdge.GetToVertex().Label   = toLabel;

                    //Merge the two vertices' sets together
                    List <Vertex> newList = fromSet.Union(toSet).ToList <Vertex>();
                    foreach (Vertex v in newList)
                    {
                        v.Tag = newList;
                    }
                    minEdge.GetFromVertex().Tag = newList;
                    minEdge.GetToVertex().Tag   = newList;
                }

                //Offset by 2 because we're ignoring edges that go in the opposite direction
                edgeIndex++;
            }

            return(mst);
        }