/// <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); }
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)); }
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)); }
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)); }
/// <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); }
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)); }
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)); }
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)); }
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); } }
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); }
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); } }
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); }
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)); }
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()); }
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)); }