3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
8 * Full author contact details are available in file CREDITS.
23 bool Graph::bfs_init(int s, bool clear_visited)
31 vector<Vertex>::iterator it = vertices_.begin();
32 vector<Vertex>::iterator en = vertices_.end();
33 for (; it != en; ++it)
36 if (!vertices_[s].visited) {
38 vertices_[s].visited = true;
45 Graph::getReachableTo(int target, bool clear_visited)
48 if (!bfs_init(target, clear_visited))
51 // Here's the logic, which is shared by the other routines.
52 // Q_ holds a list of nodes we have been able to reach (in this
53 // case, reach backwards). It is initailized to the current node
54 // by bfs_init, and then we recurse, adding the nodes we can reach
55 // from the current node as we go.
57 int const current = Q_.front();
59 if (current != target || formats.get(target).name() != "lyx")
60 result.push_back(current);
62 vector<int>::iterator it = vertices_[current].in_vertices.begin();
63 vector<int>::iterator end = vertices_[current].in_vertices.end();
64 for (; it != end; ++it) {
65 if (!vertices_[*it].visited) {
66 vertices_[*it].visited = true;
77 Graph::getReachable(int from, bool only_viewable,
81 if (!bfs_init(from, clear_visited))
85 int const current = Q_.front();
87 Format const & format = formats.get(current);
88 if (!only_viewable || !format.viewer().empty())
89 result.push_back(current);
90 else if (format.isChildFormat()) {
91 Format const * const parent =
92 formats.getFormat(format.parentFormat());
93 if (parent && !parent->viewer().empty())
94 result.push_back(current);
97 vector<OutEdge>::const_iterator cit =
98 vertices_[current].out_arrows.begin();
99 vector<OutEdge>::const_iterator end =
100 vertices_[current].out_arrows.end();
101 for (; cit != end; ++cit) {
102 int const cv = cit->vertex;
103 if (!vertices_[cv].visited) {
104 vertices_[cv].visited = true;
114 bool Graph::isReachable(int from, int to)
119 if (to < 0 || !bfs_init(from))
122 while (!Q_.empty()) {
123 int const current = Q_.front();
128 vector<OutEdge>::const_iterator cit =
129 vertices_[current].out_arrows.begin();
130 vector<OutEdge>::const_iterator end =
131 vertices_[current].out_arrows.end();
132 for (; cit != end; ++cit) {
133 int const cv = cit->vertex;
134 if (!vertices_[cv].visited) {
135 vertices_[cv].visited = true;
145 Graph::EdgePath const Graph::getPath(int from, int to)
151 if (to < 0 || !bfs_init(from))
154 // pair<vertex, edge>
155 vector<pair<int, int> > prev(vertices_.size());
158 while (!Q_.empty()) {
159 int const current = Q_.front();
162 vector<OutEdge>::const_iterator const beg =
163 vertices_[current].out_arrows.begin();
164 vector<OutEdge>::const_iterator cit = beg;
165 vector<OutEdge>::const_iterator end =
166 vertices_[current].out_arrows.end();
167 for (; cit != end; ++cit) {
168 int const cv = cit->vertex;
169 if (!vertices_[cv].visited) {
170 vertices_[cv].visited = true;
172 // FIXME This will not do for finding multiple paths.
173 // Perhaps we need a vector, or a set. We'll also want
174 // to add this info, even if the node is visited, so
175 // outside this conditional.
176 prev[cv] = pair<int, int>(current, cit->edge);
188 path.push_back(prev[to].second);
191 reverse(path.begin(), path.end());
196 void Graph::init(int size)
198 vertices_ = vector<Vertex>(size);
203 void Graph::addEdge(int from, int to)
205 vertices_[to].in_vertices.push_back(from);
206 vertices_[from].out_arrows.push_back(OutEdge(to, numedges_++));