#include "c_Test.h" #include "c_EdgeWeightedGraph.h" #include "c_LazyPrimMST.h" #include "c_VertexIdList.h" TEST_CASE(test_realigned_lazy_prim_mst) { c_EdgeWeightedGraph_t g; /* 1. Initialize an undirected edge-weighted graph with 4 vertices */ c_err_t err = c_EdgeWeightedGraph_Init(&g, 4, NULL); ASSERT_INT_EQ(C_SUCCESS, err); ASSERT_LL_EQ(4, c_EdgeWeightedGraph_GetV(&g)); /* * 2. Build a classic cyclical cycle graph topology to verify tree minimization: * 0 - 1 (Weight: 1.0) -> Expected in MST * 1 - 2 (Weight: 2.0) -> Expected in MST * 2 - 3 (Weight: 3.0) -> Expected in MST * 3 - 0 (Weight: 4.0) -> Redundant (heavier cycle closer edge) * 0 - 2 (Weight: 5.0) -> Heavy redundant cross-diagonal edge */ err = c_EdgeWeightedGraph_AddEdge(&g, 0, 1, 1.0); ASSERT_INT_EQ(C_SUCCESS, err); err = c_EdgeWeightedGraph_AddEdge(&g, 1, 2, 2.0); ASSERT_INT_EQ(C_SUCCESS, err); err = c_EdgeWeightedGraph_AddEdge(&g, 2, 3, 3.0); ASSERT_INT_EQ(C_SUCCESS, err); err = c_EdgeWeightedGraph_AddEdge(&g, 3, 0, 4.0); ASSERT_INT_EQ(C_SUCCESS, err); err = c_EdgeWeightedGraph_AddEdge(&g, 0, 2, 5.0); ASSERT_INT_EQ(C_SUCCESS, err); ASSERT_LL_EQ(5, c_EdgeWeightedGraph_GetE(&g)); /* 3. Compute the Minimum Spanning Tree using our normalized Lazy Prim component */ c_LazyPrimMST_t prim; err = c_LazyPrimMST_Init(&prim, &g, 0); ASSERT_INT_EQ(C_SUCCESS, err); /* 4. Total minimal spanning tree weight must sum exactly to 1.0 + 2.0 + 3.0 = 6.0 */ ASSERT_DOUBLE_EQ_MSG(6.0, c_LazyPrimMST_Weight(&prim), "Lazy Prim failed to compute correct total MST weight"); /* 5. Extract tree edge selections and parse structural contents */ c_VertexIdList_t selected_edges; c_VertexIdList_Init(&selected_edges, 0, 0); err = c_LazyPrimMST_GetEdges(&prim, &selected_edges); ASSERT_INT_EQ(C_SUCCESS, err); /* A graph with V vertices must span exactly V - 1 edges in its minimal spanning layout */ c_size_t mst_size = (c_size_t)c_VertexIdList_GetSize(&selected_edges); ASSERT_LL_EQ(3, mst_size); /* 6. Verify that our heavier redundant edges (4.0 and 5.0) were skipped */ double computed_weight_check = 0.0; for (c_size_t i = 0; i < mst_size; ++i) { c_uint_t generic_edge_id = 0; err = c_VertexIdList_Get(&selected_edges, i, &generic_edge_id); ASSERT_INT_EQ(C_SUCCESS, err); /* Resolve back via the graph's continuous edge pool layout mapping */ c_Edge_t* edge = &g.edges_pool[(c_size_t)generic_edge_id]; double w = c_Edge_Weight(edge); computed_weight_check += w; /* Ensure neither of the heavy loop closures was mistakenly collected */ ASSERT_TRUE(w < 3.9); } ASSERT_DOUBLE_EQ_MSG(6.0, computed_weight_check, "Sum of extracted edges does not equal total logged weight"); /* 7. Reclaim and safely recycle structural resources */ c_VertexIdList_Destroy(&selected_edges); c_LazyPrimMST_Destroy(&prim); c_EdgeWeightedGraph_Destroy(&g); } int main(void) { /* Fire up the core testing wrapper suite */ TEST_START(LazyPrimMST_GenericPQ_Integration_Suite); /* Run specified structural plumbing edge cases */ RUN_TEST(test_realigned_lazy_prim_mst); /* Output summary metrics logs to console */ TEST_REPORT(); /* Unwind system back with proper testing suite status signals */ RETURN_TEST_STATUS; }