Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/graph/test/astar_search_test.cpp @ 47

Last change on this file since 47 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 6.1 KB
Line 
1
2
3//
4//=======================================================================
5// Copyright (c) 2004 Kristopher Beevers
6//
7// Distributed under the Boost Software License, Version 1.0. (See
8// accompanying file LICENSE_1_0.txt or copy at
9// http://www.boost.org/LICENSE_1_0.txt)
10//=======================================================================
11//
12
13
14#include <boost/graph/astar_search.hpp>
15#include <boost/graph/adjacency_list.hpp>
16#include <boost/graph/random.hpp>
17#include <boost/random.hpp>
18#include <vector>
19#include <list>
20#include <iostream>
21#include <math.h>    // for sqrt
22#include <time.h>
23
24using namespace boost;
25using namespace std;
26
27
28// auxiliary types
29struct location
30{
31  float y, x; // lat, long
32};
33typedef float cost;
34
35template <class Name, class LocMap>
36class city_writer {
37public:
38  city_writer(Name n, LocMap l, float _minx, float _maxx,
39              float _miny, float _maxy,
40              unsigned int _ptx, unsigned int _pty)
41    : name(n), loc(l), minx(_minx), maxx(_maxx), miny(_miny),
42      maxy(_maxy), ptx(_ptx), pty(_pty) {}
43  template <class Vertex>
44  void operator()(ostream& out, const Vertex& v) const {
45    float px = 1 - (loc[v].x - minx) / (maxx - minx);
46    float py = (loc[v].y - miny) / (maxy - miny);
47    out << "[label=\"" << name[v] << "\", pos=\""
48        << static_cast<unsigned int>(ptx * px) << ","
49        << static_cast<unsigned int>(pty * py)
50        << "\", fontsize=\"11\"]";
51  }
52private:
53  Name name;
54  LocMap loc;
55  float minx, maxx, miny, maxy;
56  unsigned int ptx, pty;
57};
58
59template <class WeightMap>
60class time_writer {
61public:
62  time_writer(WeightMap w) : wm(w) {}
63  template <class Edge>
64  void operator()(ostream &out, const Edge& e) const {
65    out << "[label=\"" << wm[e] << "\", fontsize=\"11\"]";
66  }
67private:
68  WeightMap wm;
69};
70
71
72// euclidean distance heuristic
73template <class Graph, class CostType, class LocMap>
74class distance_heuristic : public astar_heuristic<Graph, CostType>
75{
76public:
77  typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
78  distance_heuristic(LocMap l, Vertex goal)
79    : m_location(l), m_goal(goal) {}
80  CostType operator()(Vertex u)
81  {
82    CostType dx = m_location[m_goal].x - m_location[u].x;
83    CostType dy = m_location[m_goal].y - m_location[u].y;
84    return ::sqrt(dx * dx + dy * dy);
85  }
86private:
87  LocMap m_location;
88  Vertex m_goal;
89};
90
91
92struct found_goal {}; // exception for termination
93
94// visitor that terminates when we find the goal
95template <class Vertex>
96class astar_goal_visitor : public boost::default_astar_visitor
97{
98public:
99  astar_goal_visitor(Vertex goal) : m_goal(goal) {}
100  template <class Graph>
101  void examine_vertex(Vertex u, Graph& g) {
102    if(u == m_goal)
103      throw found_goal();
104  }
105private:
106  Vertex m_goal;
107};
108
109
110int main(int argc, char **argv)
111{
112 
113  // specify some types
114  typedef adjacency_list<listS, vecS, undirectedS, no_property,
115    property<edge_weight_t, cost> > mygraph_t;
116  typedef property_map<mygraph_t, edge_weight_t>::type WeightMap;
117  typedef mygraph_t::vertex_descriptor vertex;
118  typedef mygraph_t::edge_descriptor edge_descriptor;
119  typedef mygraph_t::vertex_iterator vertex_iterator;
120  typedef std::pair<int, int> edge;
121 
122  // specify data
123  enum nodes {
124    Troy, LakePlacid, Plattsburgh, Massena, Watertown, Utica,
125    Syracuse, Rochester, Buffalo, Ithaca, Binghamton, Woodstock,
126    NewYork, N
127  };
128  const char *name[] = {
129    "Troy", "Lake Placid", "Plattsburgh", "Massena",
130    "Watertown", "Utica", "Syracuse", "Rochester", "Buffalo",
131    "Ithaca", "Binghamton", "Woodstock", "New York"
132  };
133  location locations[] = { // lat/long
134    {42.73, 73.68}, {44.28, 73.99}, {44.70, 73.46},
135    {44.93, 74.89}, {43.97, 75.91}, {43.10, 75.23},
136    {43.04, 76.14}, {43.17, 77.61}, {42.89, 78.86},
137    {42.44, 76.50}, {42.10, 75.91}, {42.04, 74.11},
138    {40.67, 73.94}
139  };
140  edge edge_array[] = {
141    edge(Troy,Utica), edge(Troy,LakePlacid),
142    edge(Troy,Plattsburgh), edge(LakePlacid,Plattsburgh),
143    edge(Plattsburgh,Massena), edge(LakePlacid,Massena),
144    edge(Massena,Watertown), edge(Watertown,Utica),
145    edge(Watertown,Syracuse), edge(Utica,Syracuse),
146    edge(Syracuse,Rochester), edge(Rochester,Buffalo),
147    edge(Syracuse,Ithaca), edge(Ithaca,Binghamton),
148    edge(Ithaca,Rochester), edge(Binghamton,Troy),
149    edge(Binghamton,Woodstock), edge(Binghamton,NewYork),
150    edge(Syracuse,Binghamton), edge(Woodstock,Troy),
151    edge(Woodstock,NewYork)
152  };
153  unsigned int num_edges = sizeof(edge_array) / sizeof(edge);
154  cost weights[] = { // estimated travel time (mins)
155    96, 134, 143, 65, 115, 133, 117, 116, 74, 56,
156    84, 73, 69, 70, 116, 147, 173, 183, 74, 71, 124
157  };
158 
159 
160  // create graph
161  mygraph_t g(N);
162  WeightMap weightmap = get(edge_weight, g);
163  for(std::size_t j = 0; j < num_edges; ++j) {
164    edge_descriptor e; bool inserted;
165    tie(e, inserted) = add_edge(edge_array[j].first,
166                                edge_array[j].second, g);
167    weightmap[e] = weights[j];
168  }
169 
170 
171  // pick random start/goal
172  minstd_rand gen(time(0));
173  vertex start = gen() % num_vertices(g);
174  vertex goal = gen() % num_vertices(g);
175 
176 
177  cout << "Start vertex: " << name[start] << endl;
178  cout << "Goal vertex: " << name[goal] << endl;
179 
180  vector<mygraph_t::vertex_descriptor> p(num_vertices(g));
181  vector<cost> d(num_vertices(g));
182  try {
183    // call astar named parameter interface
184    astar_search
185      (g, start,
186       distance_heuristic<mygraph_t, cost, location*>
187        (locations, goal),
188       predecessor_map(&p[0]).distance_map(&d[0]).
189       visitor(astar_goal_visitor<vertex>(goal)));
190 
191 
192  } catch(found_goal fg) { // found a path to the goal
193    list<vertex> shortest_path;
194    for(vertex v = goal;; v = p[v]) {
195      shortest_path.push_front(v);
196      if(p[v] == v)
197        break;
198    }
199    cout << "Shortest path from " << name[start] << " to "
200         << name[goal] << ": ";
201    list<vertex>::iterator spi = shortest_path.begin();
202    cout << name[start];
203    for(++spi; spi != shortest_path.end(); ++spi)
204      cout << " -> " << name[*spi];
205    cout << endl << "Total travel time: " << d[goal] << endl;
206    return 0;
207  }
208 
209  cout << "Didn't find a path from " << name[start] << "to"
210       << name[goal] << "!" << endl;
211  return 0;
212 
213}
Note: See TracBrowser for help on using the repository browser.