123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- #ifndef BOOST_GRAPH_METRIC_TSP_APPROX_HPP
- #define BOOST_GRAPH_METRIC_TSP_APPROX_HPP
- #include <vector>
- #include <boost/shared_ptr.hpp>
- #include <boost/concept_check.hpp>
- #include <boost/graph/graph_traits.hpp>
- #include <boost/graph/graph_as_tree.hpp>
- #include <boost/graph/adjacency_list.hpp>
- #include <boost/graph/prim_minimum_spanning_tree.hpp>
- #include <boost/graph/lookup_edge.hpp>
- #include <boost/throw_exception.hpp>
- namespace boost
- {
- template < typename Visitor, typename Graph > struct TSPVertexVisitorConcept
- {
- private:
- Visitor vis_;
- public:
- typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
- BOOST_CONCEPT_USAGE(TSPVertexVisitorConcept)
- {
- Visitor vis(vis_);
- Graph g(1);
- Vertex v(*vertices(g).first);
- vis.visit_vertex(v, g);
- }
- };
- template < typename Node, typename Tree > class PreorderTraverser
- {
- private:
- std::vector< Node >& path_;
- public:
- typedef typename std::vector< Node >::const_iterator const_iterator;
- PreorderTraverser(std::vector< Node >& p) : path_(p) {}
- void preorder(Node n, const Tree&) { path_.push_back(n); }
- void inorder(Node, const Tree&) const {}
- void postorder(Node, const Tree&) const {}
- const_iterator begin() const { return path_.begin(); }
- const_iterator end() const { return path_.end(); }
- };
- template < typename > class tsp_tour_visitor;
- template < typename, typename, typename, typename > class tsp_tour_len_visitor;
- template < typename VertexListGraph, typename OutputIterator >
- void metric_tsp_approx_tour(VertexListGraph& g, OutputIterator o)
- {
- metric_tsp_approx_from_vertex(g, *vertices(g).first, get(edge_weight, g),
- get(vertex_index, g), tsp_tour_visitor< OutputIterator >(o));
- }
- template < typename VertexListGraph, typename WeightMap,
- typename OutputIterator >
- void metric_tsp_approx_tour(VertexListGraph& g, WeightMap w, OutputIterator o)
- {
- metric_tsp_approx_from_vertex(
- g, *vertices(g).first, w, tsp_tour_visitor< OutputIterator >(o));
- }
- template < typename VertexListGraph, typename OutputIterator >
- void metric_tsp_approx_tour_from_vertex(VertexListGraph& g,
- typename graph_traits< VertexListGraph >::vertex_descriptor start,
- OutputIterator o)
- {
- metric_tsp_approx_from_vertex(g, start, get(edge_weight, g),
- get(vertex_index, g), tsp_tour_visitor< OutputIterator >(o));
- }
- template < typename VertexListGraph, typename WeightMap,
- typename OutputIterator >
- void metric_tsp_approx_tour_from_vertex(VertexListGraph& g,
- typename graph_traits< VertexListGraph >::vertex_descriptor start,
- WeightMap w, OutputIterator o)
- {
- metric_tsp_approx_from_vertex(g, start, w, get(vertex_index, g),
- tsp_tour_visitor< OutputIterator >(o));
- }
- template < typename VertexListGraph, typename TSPVertexVisitor >
- void metric_tsp_approx(VertexListGraph& g, TSPVertexVisitor vis)
- {
- metric_tsp_approx_from_vertex(
- g, *vertices(g).first, get(edge_weight, g), get(vertex_index, g), vis);
- }
- template < typename VertexListGraph, typename Weightmap,
- typename VertexIndexMap, typename TSPVertexVisitor >
- void metric_tsp_approx(VertexListGraph& g, Weightmap w, TSPVertexVisitor vis)
- {
- metric_tsp_approx_from_vertex(
- g, *vertices(g).first, w, get(vertex_index, g), vis);
- }
- template < typename VertexListGraph, typename WeightMap,
- typename VertexIndexMap, typename TSPVertexVisitor >
- void metric_tsp_approx(
- VertexListGraph& g, WeightMap w, VertexIndexMap id, TSPVertexVisitor vis)
- {
- metric_tsp_approx_from_vertex(g, *vertices(g).first, w, id, vis);
- }
- template < typename VertexListGraph, typename WeightMap,
- typename TSPVertexVisitor >
- void metric_tsp_approx_from_vertex(VertexListGraph& g,
- typename graph_traits< VertexListGraph >::vertex_descriptor start,
- WeightMap w, TSPVertexVisitor vis)
- {
- metric_tsp_approx_from_vertex(g, start, w, get(vertex_index, g), vis);
- }
- template < typename VertexListGraph, typename WeightMap,
- typename VertexIndexMap, typename TSPVertexVisitor >
- void metric_tsp_approx_from_vertex(const VertexListGraph& g,
- typename graph_traits< VertexListGraph >::vertex_descriptor start,
- WeightMap weightmap, VertexIndexMap indexmap, TSPVertexVisitor vis)
- {
- using namespace boost;
- using namespace std;
- BOOST_CONCEPT_ASSERT((VertexListGraphConcept< VertexListGraph >));
- BOOST_CONCEPT_ASSERT(
- (TSPVertexVisitorConcept< TSPVertexVisitor, VertexListGraph >));
-
- typedef typename graph_traits< VertexListGraph >::vertex_descriptor GVertex;
- typedef typename graph_traits< VertexListGraph >::vertex_iterator GVItr;
-
- typedef adjacency_list< vecS, vecS, directedS, no_property, no_property >
- MSTImpl;
- typedef graph_traits< MSTImpl >::vertex_descriptor Vertex;
- typedef graph_traits< MSTImpl >::vertex_iterator VItr;
-
- typedef iterator_property_map< vector< Vertex >::iterator,
- property_map< MSTImpl, vertex_index_t >::type >
- ParentMap;
- typedef graph_as_tree< MSTImpl, ParentMap > Tree;
- typedef tree_traits< Tree >::node_descriptor Node;
-
- typedef vector< GVertex > PredMap;
- typedef iterator_property_map< typename PredMap::iterator, VertexIndexMap >
- PredPMap;
- PredMap preds(num_vertices(g));
- PredPMap pred_pmap(preds.begin(), indexmap);
-
- prim_minimum_spanning_tree(g, pred_pmap,
- root_vertex(start).vertex_index_map(indexmap).weight_map(weightmap));
-
- MSTImpl mst(num_vertices(g));
- std::size_t cnt = 0;
- pair< VItr, VItr > mst_verts(vertices(mst));
- for (typename PredMap::iterator vi(preds.begin()); vi != preds.end();
- ++vi, ++cnt)
- {
- if (indexmap[*vi] != cnt)
- {
- add_edge(*next(mst_verts.first, indexmap[*vi]),
- *next(mst_verts.first, cnt), mst);
- }
- }
-
- vector< Vertex > parent(num_vertices(mst));
- Tree t(mst, *vertices(mst).first,
- make_iterator_property_map(parent.begin(), get(vertex_index, mst)));
-
- vector< Node > tour;
- PreorderTraverser< Node, Tree > tvis(tour);
- traverse_tree(indexmap[start], t, tvis);
- pair< GVItr, GVItr > g_verts(vertices(g));
- for (PreorderTraverser< Node, Tree >::const_iterator curr(tvis.begin());
- curr != tvis.end(); ++curr)
- {
-
- GVertex v = *next(g_verts.first, get(vertex_index, mst)[*curr]);
- vis.visit_vertex(v, g);
- }
-
- vis.visit_vertex(start, g);
- }
- template < typename OutItr > class tsp_tour_visitor
- {
- OutItr itr_;
- public:
- tsp_tour_visitor(OutItr itr) : itr_(itr) {}
- template < typename Vertex, typename Graph >
- void visit_vertex(Vertex v, const Graph&)
- {
- BOOST_CONCEPT_ASSERT((OutputIterator< OutItr, Vertex >));
- *itr_++ = v;
- }
- };
- template < typename Graph, typename WeightMap, typename OutIter,
- typename Length >
- class tsp_tour_len_visitor
- {
- typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
- BOOST_CONCEPT_ASSERT((OutputIterator< OutIter, Vertex >));
- OutIter iter_;
- Length& tourlen_;
- WeightMap& wmap_;
- Vertex previous_;
-
- Vertex null() { return graph_traits< Graph >::null_vertex(); }
- public:
- tsp_tour_len_visitor(Graph const&, OutIter iter, Length& l, WeightMap& map)
- : iter_(iter), tourlen_(l), wmap_(map), previous_(null())
- {
- }
- void visit_vertex(Vertex v, const Graph& g)
- {
- typedef typename graph_traits< Graph >::edge_descriptor Edge;
-
-
- if (previous_ != null())
- {
-
-
-
-
- Edge e;
- bool found;
- boost::tie(e, found) = lookup_edge(previous_, v, g);
- if (!found)
- {
- BOOST_THROW_EXCEPTION(not_complete());
- }
- tourlen_ += wmap_[e];
- }
- previous_ = v;
- *iter_++ = v;
- }
- };
- template < typename OutIter >
- inline tsp_tour_visitor< OutIter > make_tsp_tour_visitor(OutIter iter)
- {
- return tsp_tour_visitor< OutIter >(iter);
- }
- template < typename Graph, typename WeightMap, typename OutIter,
- typename Length >
- inline tsp_tour_len_visitor< Graph, WeightMap, OutIter, Length >
- make_tsp_tour_len_visitor(
- Graph const& g, OutIter iter, Length& l, WeightMap map)
- {
- return tsp_tour_len_visitor< Graph, WeightMap, OutIter, Length >(
- g, iter, l, map);
- }
- }
- #endif
|