root/branches/debug/extra/driving_distance/src/boost_drivedist.cpp

Revision 128, 4.6 KB (checked in by anton, 3 years ago)

Debugging branch added

Line 
1/*
2 * Drivedist algorithm for PostgreSQL
3 *
4 * Copyright (c) 2006 Mario H. Basa, Orkney, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 */
21
22#include <boost/config.hpp>
23
24#include <boost/graph/graph_traits.hpp>
25#include <boost/graph/adjacency_list.hpp>
26#include <boost/graph/dijkstra_shortest_paths.hpp>
27
28#include "drivedist.h"
29
30using namespace std;
31using namespace boost;
32
33
34// Maximal number of nodes in the path (to avoid infinite loops)
35#define MAX_NODES 1000000
36
37struct Edge
38{
39  int id;
40  float8 cost;
41};
42
43struct Vertex
44{
45  int id;
46  int edge_id;
47};
48
49template <class G, class E>
50static void
51graph_add_edge(G &graph, int id, int source, int target, float8 cost)
52{
53  E e;
54  bool inserted;
55 
56  if (cost < 0) // edges are not inserted in the graph if cost is negative
57    return;
58 
59  tie(e, inserted) = add_edge(source, target, graph);
60 
61  graph[e].cost = cost;
62  graph[e].id = id;
63
64  typedef typename graph_traits<G>::vertex_descriptor Vertex;
65  Vertex s = vertex(source, graph);
66  Vertex t = vertex(target, graph);
67  graph[s].id = source;
68  graph[t].id = target;
69  graph[s].edge_id = id;
70  graph[t].edge_id = id;
71
72}
73
74int
75boost_dijkstra_dist(edge_t *edges, unsigned int count, int source_vertex_id,
76                    double rdistance, bool directed, bool has_reverse_cost,
77                    path_element_t **path, int *path_count, char **err_msg)
78{
79  typedef adjacency_list < listS, vecS, undirectedS, Vertex, Edge > graph_t;
80  typedef graph_traits < graph_t >::vertex_descriptor vertex_descriptor;
81  typedef graph_traits < graph_t >::edge_descriptor edge_descriptor;
82
83  const unsigned int num_nodes = 1;
84 
85  graph_t graph( num_nodes );
86 
87  property_map<graph_t, edge_weight_t>::type weightmap =
88    get(edge_weight, graph);
89 
90  for (std::size_t j = 0; j < count; ++j)
91    {
92      graph_add_edge<graph_t, edge_descriptor>
93        (graph, edges[j].id, edges[j].source,
94         edges[j].target, edges[j].cost);     
95                                       
96      if (!directed || (directed && has_reverse_cost))
97        {
98          if (has_reverse_cost)
99            {
100              graph_add_edge<graph_t, edge_descriptor>
101                (graph, edges[j].id, edges[j].target,
102                 edges[j].source, edges[j].reverse_cost);     
103            }
104          else
105            {
106              graph_add_edge<graph_t, edge_descriptor>
107                (graph, edges[j].id, edges[j].target,
108                 edges[j].source, edges[j].cost);     
109            }
110        }
111    }
112
113  vertex_descriptor source_vertex = vertex( source_vertex_id, graph );
114 
115  std::vector<vertex_descriptor> predecessors(num_vertices(graph));
116  std::vector<float8> distances(num_vertices(graph));
117 
118  dijkstra_shortest_paths(graph, source_vertex,
119                          predecessor_map(&predecessors[0])
120                          .weight_map(get(&Edge::cost, graph))
121                          .distance_map(&distances[0]));
122
123 
124  graph_traits < graph_t >::vertex_iterator vi, vend;
125  vector<path_element> path_vector;
126  int j=0;
127 
128  for(tie(vi, vend) = vertices(graph); vi != vend; vi++) {
129               
130    if( (double)distances[*vi] <= rdistance ) {
131     
132      path_element pe;
133
134      graph_traits<graph_t>::vertex_descriptor s;
135
136      s = vertex(*vi, graph);
137
138      pe.vertex_id = graph[s].id;
139      pe.edge_id   = graph[s].edge_id;
140      pe.cost      = distances[*vi];
141       
142      path_vector.push_back( pe );
143    }   
144  }
145 
146  if( path_vector.size() == 0 ) {
147    *err_msg = "No path found";
148    return 0;         
149  }
150 
151  vector<path_element>::iterator itr;
152  *path = (path_element_t *) malloc( sizeof(path_element_t) *
153                                     (path_vector.size() + 1) );
154  *path_count = path_vector.size();
155 
156  for(j=0,itr=path_vector.begin();itr != path_vector.end();itr++,j++) {
157    path_element pe = *itr;
158    (*path)[j].vertex_id = pe.vertex_id;
159    (*path)[j].edge_id   = pe.edge_id;
160    (*path)[j].cost      = pe.cost;
161  }
162 
163  return EXIT_SUCCESS;
164}
165
Note: See TracBrowser for help on using the browser.