private void TestMstAlgorithm(IWeightedGraph <int, double> graph, double expectedMstWeight, double precision, ALGORITHM algorithm) { // Build minimum spanning tree with algorithm to test IWeightedGraph <int, double> msp; switch (algorithm) { case ALGORITHM.KRUSKAL: msp = Kruskal.FindMinimumSpanningTree(graph); break; case ALGORITHM.PRIM: msp = Prim.FindMinimumSpanningTree(graph, 0, double.MaxValue); break; default: throw new NotImplementedException($"No minimum spanning tree test implemented for algorithm {algorithm.ToString()}."); } // Check that all verteces are included Assert.AreEqual(graph.VertexCount, msp.VertexCount); // Count edges and compute total weight IEnumerable <IWeightedEdge <int, double> > edges = msp.GetAllEdges(); int edgeCount = edges.Count(); double mspWeight = edges.Sum(e => e.Weight); // Check edge count Assert.AreEqual(graph.VertexCount - 1, edgeCount); // Check that the total weight is as expected AssertDoublesNearlyEqual(expectedMstWeight, mspWeight, precision); }
public static IWeightedGraph <TV, TW> FindTour <TV, TW>(IWeightedGraph <TV, TW> graph) where TV : IEquatable <TV> { GraphBuilder <TV, TW> builder = new GraphBuilder <TV, TW>(); builder.AddVerteces(graph.GetAllVerteces().Select(v => v.Value)); // Find minimum spanning tree IWeightedGraph <TV, TW> msp = Kruskal.FindMinimumSpanningTree(graph); // Connect verteces in the order of the MSP IVertex <TV> lastVertex = null; DepthFirstSearch.Traverse(msp, currentVertex => { if (lastVertex != null) { try { builder.AddEdge(lastVertex.Value, currentVertex.Value, graph.GetEdgeBetweenVerteces(lastVertex.Value, currentVertex.Value).Weight); } catch (VertecesNotConnectedException <TV> exception) { throw new GraphNotCompleteException("The graph is not complete.", exception); } } lastVertex = currentVertex; }); // Add closing edge IVertex <TV> firstVertex = msp.GetFirstVertex(); IWeightedEdge <TV, TW> closingEdge = graph.GetEdgeBetweenVerteces(lastVertex.Value, firstVertex.Value); builder.AddEdge(lastVertex.Value, firstVertex.Value, closingEdge.Weight); // Done! return(builder.Build()); }