26 #if defined(__MinGW32__) || defined(_MSC_VER)
38 #include <boost/graph/iteration_macros.hpp>
39 #include <boost/config.hpp>
40 #include <boost/graph/adjacency_list.hpp>
41 #include <boost/graph/graph_utility.hpp>
219 namespace pgrouting {
222 template <
class G,
typename Vertex,
typename Edge>
238 boost::adjacency_list < boost::vecS, boost::vecS,
244 boost::adjacency_list < boost::vecS, boost::vecS,
245 boost::bidirectionalS,
250 boost::adjacency_list < boost::listS, boost::vecS,
256 boost::adjacency_list < boost::listS, boost::vecS,
257 boost::bidirectionalS,
264 boost::adjacency_list < boost::listS, boost::vecS,
270 boost::adjacency_list < boost::listS, boost::vecS,
271 boost::bidirectionalS,
280 template <
class G,
typename T_V,
typename T_E>
281 class Pgr_base_graph {
296 typedef typename boost::graph_traits < G >::vertex_descriptor
V;
297 typedef typename boost::graph_traits < G >::edge_descriptor
E;
298 typedef typename boost::graph_traits < G >::vertex_iterator
V_i;
299 typedef typename boost::graph_traits < G >::edge_iterator
E_i;
300 typedef typename boost::graph_traits < G >::out_edge_iterator
EO_i;
301 typedef typename boost::graph_traits < G >::in_edge_iterator
EI_i;
303 typedef typename boost::graph_traits < G >::vertices_size_type
305 typedef typename boost::graph_traits < G >::edges_size_type
307 typedef typename boost::graph_traits < G >::degree_size_type
320 typedef typename std::map< int64_t, V >
id_to_V;
321 typedef typename id_to_V::const_iterator
LI;
358 const std::vector< T_V > &vertices,
graphType gtype)
359 :
graph(vertices.size()),
369 for (
auto vi = boost::vertices(
graph).first;
370 vi != boost::vertices(
graph).second; ++vi) {
372 graph[(*vi)].cp_members(vertices[i++]);
396 template <
typename T >
418 template <
typename T >
428 for (
const auto edge : edges) {
481 auto v = add_vertex(
graph);
482 graph[v].cp_members(vertex);
507 return boost::in_degree(v,
graph);
512 return boost::out_degree(v,
graph);
581 for (
auto vi = vertices(g.
graph).first;
582 vi != vertices(g.
graph).second; ++vi) {
584 log << (*vi) <<
": " <<
" out_edges_of(" << g.
graph[(*vi)] <<
"):";
585 for (boost::tie(out, out_end) = out_edges(*vi, g.
graph);
586 out != out_end; ++out) {
588 << g.
graph[*out].id <<
"=("
590 << g.
graph[target(*out, g.
graph)].id <<
") = "
591 << g.
graph[*out].cost <<
"@t";
612 template <
typename T >
619 template <
class G,
typename T_V,
typename T_E >
625 if (!has_vertex(p_from) || !has_vertex(p_to))
return;
628 V g_from(get_V(p_from));
632 for (boost::tie(out, out_end) = out_edges(g_from, graph);
633 out != out_end; ++out) {
634 if (target(*out, graph) == g_to) {
635 d_edge.id = graph[*out].id;
636 d_edge.source = graph[source(*out, graph)].id;
637 d_edge.target = graph[target(*out, graph)].id;
638 d_edge.cost = graph[*out].cost;
639 removed_edges.push_back(d_edge);
643 boost::remove_edge(g_from, g_to, graph);
648 template <
class G,
typename T_V,
typename T_E >
651 int64_t vertex_id, int64_t edge_id) {
655 if (!has_vertex(vertex_id))
return;
656 auto v_from(get_V(vertex_id));
663 for (boost::tie(out, out_end) = out_edges(v_from, graph);
664 out != out_end; ++out) {
665 if (graph[*out].
id == edge_id) {
666 d_edge.id = graph[*out].id;
667 d_edge.source = graph[source(*out, graph)].id;
668 d_edge.target = graph[target(*out, graph)].id;
669 d_edge.cost = graph[*out].cost;
670 removed_edges.push_back(d_edge);
671 boost::remove_edge((*out), graph);
680 template <
class G,
typename T_V,
typename T_E >
683 if (!has_vertex(vertex))
return;
684 disconnect_vertex(get_V(vertex));
687 template <
class G,
typename T_V,
typename T_E >
694 for (boost::tie(out, out_end) = out_edges(vertex, graph);
695 out != out_end; ++out) {
696 d_edge.id = graph[*out].id;
697 d_edge.source = graph[source(*out, graph)].id;
698 d_edge.target = graph[target(*out, graph)].id;
699 d_edge.cost = graph[*out].cost;
700 removed_edges.push_back(d_edge);
706 for (boost::tie(in, in_end) = in_edges(vertex, graph);
707 in != in_end; ++in) {
708 d_edge.id = graph[*in].id;
709 d_edge.source = graph[source(*in, graph)].id;
710 d_edge.target = graph[target(*in, graph)].id;
711 d_edge.cost = graph[*in].cost;
712 removed_edges.push_back(d_edge);
717 boost::clear_vertex(vertex, graph);
720 template <
class G,
typename T_V,
typename T_E >
723 while (removed_edges.size() != 0) {
724 graph_add_edge(removed_edges[0]);
725 removed_edges.pop_front();
730 template <
class G,
typename T_V,
typename T_E >
735 double &distance)
const {
738 V v_source, v_target;
739 double minCost = std::numeric_limits<double>::max();
740 int64_t minEdge = -1;
741 for (boost::tie(out_i, out_end) = boost::out_edges(from, graph);
742 out_i != out_end; ++out_i) {
744 v_target = target(e, graph);
745 v_source = source(e, graph);
746 if ((from == v_source) && (to == v_target)
747 && (distance == graph[e].cost))
749 if ((from == v_source) && (to == v_target)
750 && (minCost > graph[e].cost)) {
751 minCost = graph[e].cost;
752 minEdge = graph[e].id;
755 distance = minEdge == -1? 0: minCost;
760 template <
class G,
typename T_V,
typename T_E >
767 vm_s = vertices_map.find(edge.source);
768 if (vm_s == vertices_map.end()) {
769 vertices_map[edge.source]= m_num_vertices;
770 vm_s = vertices_map.find(edge.source);
773 vm_t = vertices_map.find(edge.target);
774 if (vm_t == vertices_map.end()) {
775 vertices_map[edge.target]= m_num_vertices;
776 vm_t = vertices_map.find(edge.target);
779 if (edge.cost >= 0) {
780 boost::tie(e, inserted) =
781 boost::add_edge(vm_s->second, vm_t->second, graph);
782 graph[e].cp_members(edge);
787 template <
class G,
typename T_V,
typename T_E >
788 template <
typename T>
793 if ((edge.cost < 0) && (edge.reverse_cost < 0))
800 auto vm_s = get_V(T_V(edge,
true));
801 auto vm_t = get_V(T_V(edge,
false));
803 pgassert(vertices_map.find(edge.source) != vertices_map.end());
804 pgassert(vertices_map.find(edge.target) != vertices_map.end());
805 if (edge.cost >= 0) {
806 boost::tie(e, inserted) =
807 boost::add_edge(vm_s, vm_t, graph);
808 graph[e].cost = edge.cost;
809 graph[e].id = edge.id;
810 graph[e].first =
true;
813 if (edge.reverse_cost >= 0) {
814 boost::tie(e, inserted) =
815 boost::add_edge(vm_t, vm_s, graph);
817 graph[e].cost = edge.reverse_cost;
818 graph[e].id = edge.id;
819 graph[e].first =
false;
825 template <
class G,
typename T_V,
typename T_E >
828 std::vector< T_V > vertices) {
830 for (
const auto vertex : vertices) {
833 auto v = add_vertex(graph);
834 vertices_map[
vertex.id] = m_num_vertices++;
835 graph[v].cp_members(
vertex);
837 pgassert(boost::num_vertices(graph) == num_vertices());
void graph_insert_data(const std::vector< T > &edges)
Inserts count edges of type pgr_edge_t into the graph.
boost::graph_traits< G >::edges_size_type edges_size_type
size_t num_vertices() const
boost::graph_traits< G >::edge_descriptor E
void disconnect_vertex(int64_t p_vertex)
Disconnects all incoming and outgoing edges from the vertex.
void disconnect_out_going_edge(int64_t vertex_id, int64_t edge_id)
Disconnects the outgoing edges of a vertex.
graphType m_gType
type (DIRECTED or UNDIRECTED)
int64_t get_edge_id(V from, V to, double &distance) const
bool has_vertex(int64_t vid) const
True when vid is in the graph.
std::map< int64_t, V > id_to_V
boost::graph_traits< G >::vertex_descriptor V
size_t m_num_vertices
local count.
V get_V(const T_V &vertex)
get the vertex descriptor of the vertex
boost::graph_traits< G >::out_edge_iterator EO_i
boost::graph_traits< G >::vertices_size_type vertices_size_type
V get_V(int64_t vid) const
get the vertex descriptor of the vid
id_to_V::const_iterator LI
graph::Pgr_base_graph< boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS, Basic_vertex, Basic_edge >, Basic_vertex, Basic_edge > DirectedGraph
void graph_add_edge(const T_E &edge)
#define pgassert(expr)
Uses the standard assert syntax.
boost::graph_traits< G >::vertex_iterator V_i
boost::graph_traits< G >::edge_iterator E_i
std::vector< Basic_vertex > extract_vertices(std::vector< Basic_vertex > vertices, const std::vector< pgr_edge_t > data_edges)
friend std::ostream & operator<<(std::ostream &log, const Pgr_base_graph< G, T_V, T_E > &g)
id_to_V vertices_map
id -> graph id
T_V operator[](V v) const
degree_size_type out_degree(int64_t vertex_id) const
get the out-degree of a vertex
void disconnect_edge(int64_t p_from, int64_t p_to)
Disconnects all edges from p_from to p_to.
void add_vertices(std::vector< T_V > vertices)
adds the vertices into the graph
graph::Pgr_base_graph< boost::adjacency_list< boost::vecS, boost::vecS, boost::undirectedS, Basic_vertex, Basic_edge >, Basic_vertex, Basic_edge > UndirectedGraph
std::deque< T_E > removed_edges
Used for storing the removed_edges.
boost::graph_traits< G >::degree_size_type degree_size_type
graph::Pgr_base_graph< boost::adjacency_list< boost::listS, boost::vecS, boost::bidirectionalS, XY_vertex, Basic_edge >, XY_vertex, Basic_edge > xyDirectedGraph
degree_size_type in_degree(V &v) const
True when vid is in the graph.
void restore_graph()
Reconnects all edges that were removed.
size_t check_vertices(std::vector< Basic_vertex > vertices)
graph::Pgr_base_graph< boost::adjacency_list< boost::listS, boost::vecS, boost::undirectedS, XY_vertex, Basic_edge >, XY_vertex, Basic_edge > xyUndirectedGraph
degree_size_type out_degree(V &v) const
True when vid is in the graph.
boost::graph_traits< G >::in_edge_iterator EI_i
void graph_insert_data(const T *edges, int64_t count)
Inserts count edges of type T into the graph.