@@ -1361,34 +1361,42 @@ class EvenRegularGraphBuilder {
13611361 */
13621362void remove_non_mrng_edges (deglib::graph::MutableGraph& graph) {
13631363
1364- const auto vertex_count = graph.size ();
1365- const auto edge_per_vertex = graph.getEdgesPerVertex ();
1364+ const auto vertex_count = graph.size ();
1365+ const auto edge_per_vertex = graph.getEdgesPerVertex ();
13661366
1367- const auto start = std::chrono::steady_clock::now ();
1367+ const auto start = std::chrono::steady_clock::now ();
1368+ const auto thread_count = std::thread::hardware_concurrency ();
1369+ auto removed_rng_edges_per_thread = std::vector<uint32_t >(thread_count);
1370+ deglib::concurrent::parallel_for (0 , vertex_count, thread_count, [&] (size_t vertex_index, size_t thread_id) {
13681371 uint32_t removed_rng_edges = 0 ;
1369- for (uint32_t i = 0 ; i < vertex_count; i++) {
1370- const auto vertex_index = i;
13711372
1372- const auto neighbor_indices = graph.getNeighborIndices (vertex_index);
1373- const auto neighbor_weights = graph.getNeighborWeights (vertex_index);
1373+ const auto neighbor_indices = graph.getNeighborIndices (vertex_index);
1374+ const auto neighbor_weights = graph.getNeighborWeights (vertex_index);
13741375
1375- // find all none rng conform neighbors
1376- std::vector<uint32_t > remove_neighbor_ids;
1377- for (uint32_t n = 0 ; n < edge_per_vertex; n++) {
1378- const auto neighbor_index = neighbor_indices[n];
1379- const auto neighbor_weight = neighbor_weights[n];
1376+ // find all none rng conform neighbors
1377+ std::vector<uint32_t > remove_neighbor_ids;
1378+ for (uint32_t n = 0 ; n < edge_per_vertex; n++) {
1379+ const auto neighbor_index = neighbor_indices[n];
1380+ const auto neighbor_weight = neighbor_weights[n];
13801381
1381- if (deglib::analysis::checkRNG (graph, edge_per_vertex, vertex_index, neighbor_index, neighbor_weight) == false ) {
1382- remove_neighbor_ids.emplace_back (neighbor_index);
1383- }
1384- }
1382+ if (deglib::analysis::checkRNG (graph, edge_per_vertex, vertex_index, neighbor_index, neighbor_weight) == false ) {
1383+ remove_neighbor_ids.emplace_back (neighbor_index);
1384+ }
1385+ }
13851386
1386- for (uint32_t n = 0 ; n < remove_neighbor_ids.size (); n++) {
1387- graph.changeEdge (vertex_index, remove_neighbor_ids[n], vertex_index, 0 );
1388- removed_rng_edges++;
1389- }
1387+ for (uint32_t n = 0 ; n < remove_neighbor_ids.size (); n++) {
1388+ graph.changeEdge (vertex_index, remove_neighbor_ids[n], vertex_index, 0 );
1389+ removed_rng_edges++;
13901390 }
1391- const auto duration_ms = uint32_t (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now () - start).count ());
1391+ removed_rng_edges_per_thread[thread_id] += removed_rng_edges;
1392+ });
1393+
1394+ // aggregate
1395+ uint32_t removed_rng_edges = 0 ;
1396+ for (uint32_t i = 0 ; i < thread_count; i++)
1397+ removed_rng_edges += removed_rng_edges_per_thread[i];
1398+
1399+ const auto duration_ms = uint32_t (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now () - start).count ());
13921400
13931401 std::cout << " Removed " << removed_rng_edges << " edges in " << duration_ms << " ms. Final graph contains " << deglib::analysis::calc_non_rng_edges (graph) << " non-RNG edges\n " ;
13941402}
@@ -1399,35 +1407,35 @@ void remove_non_mrng_edges(deglib::graph::MutableGraph& graph) {
13991407 */
14001408void optimze_edges (deglib::graph::MutableGraph& graph, const uint8_t k_opt, const float eps_opt, const uint8_t i_opt, const uint32_t iterations) {
14011409
1402- auto rnd = std::mt19937 (7 ); // default 7
1410+ auto rnd = std::mt19937 (7 ); // default 7
14031411
1404- // create a graph builder to add vertices to the new graph and improve its edges
1412+ // create a graph builder to add vertices to the new graph and improve its edges
14051413 std::cout << " Start graph builder\n " ;
1406- auto builder = deglib::builder::EvenRegularGraphBuilder (graph, rnd, deglib::builder::Unknown, 0 , 0 .0f , k_opt, eps_opt, i_opt, 1 , 0 );
1407-
1408- // check the integrity of the graph during the graph build process
1409- auto start = std::chrono::steady_clock::now ();
1410- uint64_t duration_ms = 0 ;
1411- const auto improvement_callback = [&](deglib::builder::BuilderStatus& status) {
1412- const auto size = graph.size ();
1413-
1414- if (status.step % (iterations/10 ) == 0 ) {
1415- duration_ms += uint32_t (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now () - start).count ());
1416- auto avg_edge_weight = deglib::analysis::calc_avg_edge_weight (graph, 100 );
1417- auto valid_weights = deglib::analysis::check_graph_weights (graph) && deglib::analysis::check_graph_regularity (graph, uint32_t (size), true );
1418- auto connected = deglib::analysis::check_graph_connectivity (graph);
1419-
1420- auto duration = duration_ms / 1000 ;
1421- std::cout << std::setw (7 ) << status.step << " step, " << std::setw (5 ) << duration << " s, AEW: " << std::fixed << std::setprecision (2 ) << std::setw (4 ) << avg_edge_weight << " , " << (connected ? " " : " not" ) << " connected, " << (valid_weights ? " valid" : " invalid" ) << " \n " ;
1422- start = std::chrono::steady_clock::now ();
1423- }
1414+ auto builder = deglib::builder::EvenRegularGraphBuilder (graph, rnd, deglib::builder::Unknown, 0 , 0 .0f , k_opt, eps_opt, i_opt, 1 , 0 );
1415+
1416+ // check the integrity of the graph during the graph build process
1417+ auto start = std::chrono::steady_clock::now ();
1418+ uint64_t duration_ms = 0 ;
1419+ const auto improvement_callback = [&](deglib::builder::BuilderStatus& status) {
1420+ const auto size = graph.size ();
1421+
1422+ if (status.step % (iterations/10 ) == 0 ) {
1423+ duration_ms += uint32_t (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now () - start).count ());
1424+ auto avg_edge_weight = deglib::analysis::calc_avg_edge_weight (graph, 100 );
1425+ auto valid_weights = deglib::analysis::check_graph_weights (graph) && deglib::analysis::check_graph_regularity (graph, uint32_t (size), true );
1426+ auto connected = deglib::analysis::check_graph_connectivity (graph);
1427+
1428+ auto duration = duration_ms / 1000 ;
1429+ std::cout << std::setw (7 ) << status.step << " step, " << std::setw (5 ) << duration << " s, AEW: " << std::fixed << std::setprecision (2 ) << std::setw (4 ) << avg_edge_weight << " , " << (connected ? " " : " not" ) << " connected, " << (valid_weights ? " valid" : " invalid" ) << " \n " ;
1430+ start = std::chrono::steady_clock::now ();
1431+ }
14241432
1425- if (status.step > iterations)
1426- builder.stop ();
1427- };
1433+ if (status.step > iterations)
1434+ builder.stop ();
1435+ };
14281436
1429- // start the build process
1430- builder.build (improvement_callback, true );
1437+ // start the build process
1438+ builder.build (improvement_callback, true );
14311439}
14321440
14331441} // end namespace deglib::builder
0 commit comments