Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 83 additions & 92 deletions include/components/pgr_components.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

#include <boost/config.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/graph/connected_components.hpp>

#include <deque>
#include <set>
#include <vector>
#include <map>
#include <utility>
#include <algorithm>

#include "cpp_common/basePath_SSEC.hpp"
Expand All @@ -55,114 +55,105 @@ class Pgr_components {
public:
typedef typename G::V V;

//! @name Components
//@{
//! one to one
Path components(
//! Connected Components Vertex Version
std::vector<pgr_componentV_t> connectedComponentsV(
G &graph);

private:
//! Call to Dijkstra 1 source to 1 target
bool dijkstra_1_to_1(
G &graph,
V source,
V target);

void clear() {
predecessors.clear();
distances.clear();
nodesInDistance.clear();
}

//! @name members;
//@{
struct found_goals{}; //!< exception for termination
std::vector< V > predecessors;
std::vector< double > distances;
std::deque< V > nodesInDistance;
//@}

//! @name Stopping classes
//@{
//! class for stopping when 1 target is found
class dijkstra_one_goal_visitor : public boost::default_dijkstra_visitor {
public:
explicit dijkstra_one_goal_visitor(V goal) : m_goal(goal) {}
template <class B_G>
void examine_vertex(V &u, B_G &g) {
#if 0
REG_SIGINT;
THROW_ON_SIGINT;
#endif
if (u == m_goal) throw found_goals();
num_edges(g);
}
private:
V m_goal;
};

//@}
//! Call to Connected Components Vertex Version
std::vector<pgr_componentV_t> do_connectedComponentsV(
G &graph);

//! Generate Map V_to_id
std::map< V, int64_t > V_to_id;
void generate_map(
std::map< int64_t, V > id_to_V);
};


/******************** IMPLEMENTTION ******************/

//! Compare two pgr_componentV_t structs
bool
sort_cmp(
pgr_componentV_t a,
pgr_componentV_t b) {
if (a.component == b.component)
return a.node < b.node;
return a.component < b.component;
}

//! Components
//! Generate map V_to_id
template < class G >
Path
Pgr_components< G >::components(
G &graph) {
int64_t end_vertex = 0;
int64_t start_vertex = 0;
bool only_cost = false;
clear();

// adjust predecessors and distances vectors
predecessors.resize(graph.num_vertices());
distances.resize(graph.num_vertices());


if (!graph.has_vertex(start_vertex)
|| !graph.has_vertex(end_vertex)) {
return Path(start_vertex, end_vertex);
void
Pgr_components< G >::generate_map(
std::map< int64_t, V > id_to_V) {
V_to_id.clear();
for (auto iter : id_to_V) {
V_to_id.insert(std::make_pair(iter.second, iter.first));
}
}

// get the graphs source and target
auto v_source(graph.get_V(start_vertex));
auto v_target(graph.get_V(end_vertex));

//! Connected Components Vertex Version
template < class G >
std::vector<pgr_componentV_t>
Pgr_components< G >::connectedComponentsV(
G &graph) {
// perform the algorithm
dijkstra_1_to_1(graph, v_source, v_target);
std::vector<pgr_componentV_t> results = do_connectedComponentsV(graph);

// get the results
return Path(
graph,
v_source, v_target,
predecessors, distances,
only_cost, true);
return results;
}

//! Call to Dijkstra 1 source to 1 target
//! Call Componnets Vertex Version and Generate Results
template < class G >
bool
Pgr_components< G >::dijkstra_1_to_1(
G &graph,
V source,
V target) {
bool found = false;
try {
boost::dijkstra_shortest_paths(graph.graph, source,
boost::predecessor_map(&predecessors[0])
.weight_map(get(&G::G_T_E::cost, graph.graph))
.distance_map(&distances[0])
.visitor(dijkstra_one_goal_visitor(target)));
std::vector<pgr_componentV_t>
Pgr_components< G >::do_connectedComponentsV(
G &graph) {
// call to boost
std::vector< V > components(num_vertices(graph.graph));
boost::connected_components(graph.graph, &components[0]);

// generate V_to_id
generate_map(graph.vertices_map);

// generate results
int totalNodes = num_vertices(graph.graph);

std::vector< pgr_componentV_t > results;
results.resize(totalNodes);

std::vector< int64_t > result_comp;
result_comp.resize(0);
size_t temp_size = 0;
for (int i = 0; i < totalNodes; i++) {
results[i].node = V_to_id.find(i)->second;
if (components[i] >= temp_size) {
result_comp.push_back(results[i].node);
temp_size++;
} else {
result_comp[components[i]] =
std::min(results[i].node, result_comp[components[i]]);
}
results[i].n_seq = -100;
}

// generate component number
for (int i = 0; i < totalNodes; i++) {
results[i].component = result_comp[components[i]];
}
catch(found_goals &) {
found = true; // Target vertex found
} catch (...) {

// sort results and generate n_seq
std::sort(results.begin(), results.end(), sort_cmp);
for (int i = 0; i < totalNodes; i++) {
if (i == 0 || results[i].component != results[i - 1].component) {
results[i].n_seq = 1;
} else {
results[i].n_seq = results[i - 1].n_seq + 1;
}
}
return found;
return results;
}

#endif // INCLUDE_DIJKSTRA_PGR_DIJKSTRA_HPP_
#endif // INCLUDE_COMPONENTS_PGR_COMPONENTS_HPP_
6 changes: 3 additions & 3 deletions include/drivers/components/connectedComponentsV_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

********************************************************************PGR-GNU*/

#ifndef INCLUDE_DRIVERS_CONNECTEDCOMPONENTSV_CONNECTEDCOMPONENTSV_DRIVER_H_
#define INCLUDE_DRIVERS_CONNECTEDCOMPONENTSV_CONNECTEDCOMPONENTSV_DRIVER_H_
#ifndef INCLUDE_DRIVERS_COMPONENTS_CONNECTEDCOMPONENTSV_DRIVER_H_
#define INCLUDE_DRIVERS_COMPONENTS_CONNECTEDCOMPONENTSV_DRIVER_H_
#pragma once

#include "c_types/pgr_edge_t.h"
Expand Down Expand Up @@ -60,4 +60,4 @@ extern "C" {
}
#endif

#endif // INCLUDE_DRIVERS_CONNECTEDCOMPONENTSV_CONNECTEDCOMPONENTSV_DRIVER_H_
#endif // INCLUDE_DRIVERS_COMPONENTS_CONNECTEDCOMPONENTSV_DRIVER_H_
36 changes: 4 additions & 32 deletions src/components/src/connectedComponentsV.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,40 +67,13 @@ static
void
process(
char* edges_sql,
#if 0
/*
* handling arrays example
*/
ArrayType *starts,
ArrayType *ends,
#endif
pgr_componentV_t **result_tuples,
size_t *result_count) {
/*
* https://www.postgresql.org/docs/current/static/spi-spi-connect.html
*/
pgr_SPI_connect();


#if 0
/*
* handling arrays example
*/

PGR_DBG("Initializing arrays");
int64_t* start_vidsArr = NULL;
size_t size_start_vidsArr = 0;
start_vidsArr = (int64_t*)
pgr_get_bigIntArray(&size_start_vidsArr, starts);
PGR_DBG("start_vidsArr size %ld ", size_start_vidsArr);

int64_t* end_vidsArr = NULL;
size_t size_end_vidsArr = 0;
end_vidsArr = (int64_t*)
pgr_get_bigIntArray(&size_end_vidsArr, ends);
PGR_DBG("end_vidsArr size %ld ", size_end_vidsArr);
#endif

(*result_tuples) = NULL;
(*result_count) = 0;

Expand Down Expand Up @@ -207,7 +180,6 @@ PGDLLEXPORT Datum connectedComponentsV(PG_FUNCTION_ARGS) {
&result_tuples,
&result_count);


/* */
/**********************************************************************/

Expand Down Expand Up @@ -258,10 +230,10 @@ PGDLLEXPORT Datum connectedComponentsV(PG_FUNCTION_ARGS) {
}

// postgres starts counting from 1
values[0] = Int32GetDatum(funcctx->call_cntr + 1); // seq
values[2] = Int64GetDatum(result_tuples[funcctx->call_cntr].component); // component
values[3] = Int32GetDatum(result_tuples[funcctx->call_cntr].n_seq); // n_seq
values[4] = Int64GetDatum(result_tuples[funcctx->call_cntr].node); // node
values[0] = Int32GetDatum(funcctx->call_cntr + 1);
values[1] = Int64GetDatum(result_tuples[funcctx->call_cntr].component);
values[2] = Int32GetDatum(result_tuples[funcctx->call_cntr].n_seq);
values[3] = Int64GetDatum(result_tuples[funcctx->call_cntr].node);
/**********************************************************************/

tuple = heap_form_tuple(tuple_desc, values, nulls);
Expand Down
19 changes: 10 additions & 9 deletions src/components/src/connectedComponentsV_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

template < class G >
static
Path
std::vector<pgr_componentV_t>
pgr_connectedComponentsV(
G &graph) {
Path path;
std::vector<pgr_componentV_t> results;
Pgr_components< G > fn_components;
return fn_components.components(graph);
return fn_components.connectedComponentsV(graph);
}


Expand All @@ -81,15 +81,15 @@ do_pgr_connectedComponentsV(

graphType gType = UNDIRECTED;

Path path;
std::vector<pgr_componentV_t> results;

log << "Working with Undirected Graph\n";
pgrouting::UndirectedGraph undigraph(gType);
undigraph.insert_edges(data_edges, total_edges);
path = pgr_connectedComponentsV(
results = pgr_connectedComponentsV(
undigraph);

auto count = path.size();
auto count = results.size();

if (count == 0) {
(*return_tuples) = NULL;
Expand All @@ -100,9 +100,10 @@ do_pgr_connectedComponentsV(
}

(*return_tuples) = pgr_alloc(count, (*return_tuples));
size_t sequence = 0;
// TODO(mg) write a new function that counts the return_tuples
//path.generate_postgres_data(return_tuples, sequence);
for (size_t i = 0; i < count; i++) {
*((*return_tuples) + i) = results[i];
}
size_t sequence = count;
(*return_count) = sequence;

pgassert(*err_msg == NULL);
Expand Down