source: src/Graph/BreadthFirstSearchGatherer.cpp@ fba720

Candidate_v1.6.1 ChemicalSpaceEvaluator TremoloParser_IncreasedPrecision
Last change on this file since fba720 was 966ce7, checked in by Frederik Heber <frederik.heber@…>, 8 years ago

BreadthFirstSearchGatherer::getDistances() added.

  • Property mode set to 100644
File size: 4.0 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2017 Frederik Heber. All rights reserved.
5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * BreadthFirstSearchGatherer.cpp
25 *
26 * Created on: May 17, 2017
27 * Author: heber
28 */
29
30
31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36//#include "CodePatterns/MemDebug.hpp"
37
38#include "BreadthFirstSearchGatherer.hpp"
39
40#include "CodePatterns/Log.hpp"
41
42#include "Graph/BoostGraphCreator.hpp"
43
44#include <boost/graph/breadth_first_search.hpp>
45
46struct found_max_distance {}; // exception when doing limited BFS
47
48/**
49 * I have no idea why this is so complicated with BGL ...
50 *
51 * This is taken from the book "The Boost Graph Library: User Guide and Reference Manual, Portable Documents",
52 * chapter "Basic Graph Algorithms", example on calculating the bacon number.
53 */
54template <typename DistanceMap>
55class distance_recorder : public boost::default_bfs_visitor
56{
57public:
58 distance_recorder(
59 DistanceMap dist,
60 const int _max_distance) : d(dist), max_distance(_max_distance) {}
61
62 template <typename Edge, typename Graph>
63 void tree_edge(Edge e, const Graph &g) const {
64 typename boost::graph_traits<Graph>::vertex_descriptor u = source(e,g), v = target(e,g);
65 d[v] = d[u] + 1;
66 }
67
68 template <typename Vertex, typename Graph>
69 void discover_vertex(Vertex u, const Graph &g) const {
70 if ((max_distance >= 0) && (d[u] >= max_distance))
71 throw found_max_distance();
72 }
73
74private:
75 DistanceMap d;
76 const int max_distance;
77};
78
79template <typename DistanceMap>
80distance_recorder<DistanceMap> record_distance(DistanceMap d, const size_t _max_distance)
81{
82 return distance_recorder<DistanceMap>(d, _max_distance);
83}
84
85BreadthFirstSearchGatherer::BreadthFirstSearchGatherer(BoostGraphCreator &_BGcreator) :
86 BGcreator(_BGcreator)
87{}
88
89std::vector<atomId_t> BreadthFirstSearchGatherer::operator()(
90 const atomId_t &_discoverfrom,
91 const int &_max_distance)
92{
93 std::vector<atomId_t> returnids;
94
95 // Do BFS through graph from given vertex
96 const size_t num_vertices = BGcreator.getNumVertices();
97 distances_t distances(num_vertices, num_vertices+1); // set distance to num+1
98 const BoostGraphCreator::UndirectedGraph &BGgraph = BGcreator.get();
99 const BoostGraphCreator::nodeId_t discoverfrom_nodeid = BGcreator.getNodeId(_discoverfrom);
100 distances[ boost::vertex(discoverfrom_nodeid, BGgraph) ] = 0;
101 try {
102 boost::breadth_first_search(
103 BGgraph,
104 boost::vertex(discoverfrom_nodeid, BGgraph),
105 boost::visitor(record_distance(&distances[0], _max_distance)));
106 } catch (found_max_distance &e) {
107 // where are at discovery horizon
108 }
109 LOG(3, "DEBUG: From atom #" << _discoverfrom
110 << " BFS discovered the following distances " << distances);
111
112 // any node was discovered whose distances is less than num_vertices+1
113 distance_map.clear();
114 const BoostGraphCreator::const_name_map_t name_map = boost::get(boost::vertex_name, BGgraph);
115 BoostGraphCreator::vertex_iter vp, vpend;
116 for (boost::tie(vp, vpend) = vertices(BGgraph); vp != vpend; ++vp) {
117 BoostGraphCreator::Vertex v = *vp;
118 if (distances[v] != (num_vertices+1)) {
119 returnids.push_back( boost::get(name_map, v) );
120 distance_map.insert( std::make_pair(boost::get(name_map, v), distances[v]) );
121 }
122 }
123
124 return returnids;
125}
Note: See TracBrowser for help on using the repository browser.