root/tags/release-1.0-beta/boost_drivedist.cpp

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

1.0.0b tag 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#include <iostream>
24#include <fstream>
25
26#include <boost/graph/graph_traits.hpp>
27#include <boost/graph/adjacency_list.hpp>
28#include <boost/graph/dijkstra_shortest_paths.hpp>
29
30#include "drivedist.h"
31
32using namespace std;
33using namespace boost;
34
35
36// Maximal number of nodes in the path (to avoid infinite loops)
37#define MAX_NODES 1000000
38
39struct Edge
40{
41  int id;
42  float8 cost;
43};
44
45struct Vertex
46{
47  int id;
48  int edge_id;
49};
50
51template <class G, class E>
52static void
53graph_add_edge(G &graph, int id, int source, int target, float8 cost)
54{
55  E e;
56  bool inserted;
57 
58  if (cost < 0) // edges are not inserted in the graph if cost is negative
59    return;
60 
61  tie(e, inserted) = add_edge(source, target, graph);
62 
63  graph[e].cost = cost;
64  graph[e].id = id;
65
66  typedef typename graph_traits<G>::vertex_descriptor Vertex;
67  Vertex s = vertex(source, graph);
68  Vertex t = vertex(target, graph);
69  graph[s].id = source;
70  graph[t].id = target;
71  graph[s].edge_id = id;
72  graph[t].edge_id = id;
73
74}
75
76int
77boost_dijkstra_dist(edge_t *edges, unsigned int count, int source_vertex_id,
78                    double rdistance, bool directed, bool has_reverse_cost,
79                    path_element_t **path, int *path_count, char **err_msg)
80{
81  typedef adjacency_list < listS, vecS, undirectedS, Vertex, Edge > graph_t;
82  typedef graph_traits < graph_t >::vertex_descriptor vertex_descriptor;
83  typedef graph_traits < graph_t >::edge_descriptor edge_descriptor;
84
85  const unsigned int num_nodes = 1;
86 
87  graph_t graph( num_nodes );
88 
89  property_map<graph_t, edge_weight_t>::type weightmap =
90    get(edge_weight, graph);
91 
92  for (std::size_t j = 0; j < count; ++j)
93    {
94      graph_add_edge<graph_t, edge_descriptor>
95        (graph, edges[j].id, edges[j].source,
96         edges[j].target, edges[j].cost);     
97                                       
98      if (!directed || (directed && has_reverse_cost))
99        {
100          if (has_reverse_cost)
101            {
102              graph_add_edge<graph_t, edge_descriptor>
103                (graph, edges[j].id, edges[j].target,
104                 edges[j].source, edges[j].reverse_cost);     
105            }
106          else
107            {
108              graph_add_edge<graph_t, edge_descriptor>
109                (graph, edges[j].id, edges[j].target,
110                 edges[j].source, edges[j].cost);     
111            }
112        }
113    }
114
115  vertex_descriptor source_vertex = vertex( source_vertex_id, graph );
116 
117  std::vector<vertex_descriptor> predecessors(num_vertices(graph));
118  std::vector<float8> distances(num_vertices(graph));
119 
120  dijkstra_shortest_paths(graph, source_vertex,
121                          predecessor_map(&predecessors[0])
122                          .weight_map(get(&Edge::cost, graph))
123                          .distance_map(&distances[0]));
124
125 
126  graph_traits < graph_t >::vertex_iterator vi, vend;
127  vector<path_element> path_vector;
128  int j=0;
129 
130  for(tie(vi, vend) = vertices(graph); vi != vend; vi++) {
131               
132    if( (double)distances[*vi] <= rdistance ) {
133     
134      path_element pe;
135
136      graph_traits<graph_t>::vertex_descriptor s;
137
138      s = vertex(*vi, graph);
139
140      pe.vertex_id = graph[s].id;
141      pe.edge_id   = graph[s].edge_id;
142      pe.cost      = distances[*vi];
143       
144      path_vector.push_back( pe );
145    }   
146  }
147 
148  if( path_vector.size() == 0 ) {
149    *err_msg = "No path found";
150    return 0;         
151  }
152 
153  vector<path_element>::iterator itr;
154  *path = (path_element_t *) malloc( sizeof(path_element_t) *
155                                     (path_vector.size() + 1) );
156  *path_count = path_vector.size();
157 
158  for(j=0,itr=path_vector.begin();itr != path_vector.end();itr++,j++) {
159    path_element pe = *itr;
160    (*path)[j].vertex_id = pe.vertex_id;
161    (*path)[j].edge_id   = pe.edge_id;
162    (*path)[j].cost      = pe.cost;
163  }
164 
165  return EXIT_SUCCESS;
166}
167
Note: See TracBrowser for help on using the browser.