Skip to content

Commit 9082564

Browse files
committed
depht limited search for grapht
This performs a depth limited depth-first search on a grapht
1 parent ac02bbc commit 9082564

File tree

1 file changed

+102
-0
lines changed

1 file changed

+102
-0
lines changed

src/util/graph.h

+102
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,16 @@ class grapht
252252
std::vector<node_indext>
253253
get_reachable(const std::vector<node_indext> &src, bool forwards) const;
254254

255+
std::vector<node_indext> depth_limited_search(
256+
const node_indext &src,
257+
std::size_t &limit,
258+
bool forwards) const;
259+
260+
std::vector<node_indext> depth_limited_search(
261+
const std::vector<node_indext> &src,
262+
std::size_t &limit,
263+
bool forwards) const;
264+
255265
void make_chordal();
256266

257267
// return value: number of connected subgraphs
@@ -275,6 +285,12 @@ class grapht
275285
std::function<void(const node_indext &)> f) const;
276286

277287
protected:
288+
std::vector<node_indext> depth_limited_search(
289+
const std::vector<node_indext> &src,
290+
std::size_t &limit,
291+
std::vector<bool> &visited,
292+
bool forwards) const;
293+
278294
class tarjant
279295
{
280296
public:
@@ -544,6 +560,92 @@ std::vector<typename N::node_indext> grapht<N>::get_reachable(
544560
return result;
545561
}
546562

563+
/// Run recursive depth-limited search on the graph, starting
564+
/// from multiple source nodes, to find the nodes reachable within n steps.
565+
/// This function initialises the search.
566+
/// \param src The node to start the search from.
567+
/// \param forwards true (false) if the forward (backward) reachability
568+
/// should be performed.
569+
/// \param limit limit on steps
570+
template <class N>
571+
std::vector<typename N::node_indext> grapht<N>::depth_limited_search(
572+
const node_indext &src,
573+
std::size_t &limit,
574+
bool forwards) const
575+
{
576+
std::vector<node_indext> start_vector(1, src);
577+
return depth_limited_search(start_vector, limit, forwards);
578+
}
579+
580+
/// Run recursive depth-limited search on the graph, starting
581+
/// from multiple source nodes, to find the nodes reachable within n steps.
582+
/// This function initialises the search.
583+
/// \param src The nodes to start the search from.
584+
/// \param forwards true (false) if the forward (backward) reachability
585+
/// should be performed.
586+
/// \param limit limit on steps
587+
template <class N>
588+
std::vector<typename N::node_indext> grapht<N>::depth_limited_search(
589+
const std::vector<node_indext> &src,
590+
std::size_t &limit,
591+
bool forwards) const
592+
{
593+
std::vector<bool> visited(nodes.size(), false);
594+
595+
for(const auto &node : src)
596+
visited[node] = true;
597+
598+
return depth_limited_search(src, limit, visited, forwards);
599+
}
600+
601+
/// Run recursive depth-limited search on the graph, starting
602+
// from multiple source nodes, to find the nodes reachable within n steps
603+
/// \param src The nodes to start the search from.
604+
/// \param limit limit on steps
605+
/// \param visited vector of booleans indicating whether a node has been visited
606+
/// \param forwards true (false) if the forward (backward) reachability
607+
/// should be performed.
608+
template <class N>
609+
std::vector<typename N::node_indext> grapht<N>::depth_limited_search(
610+
const std::vector<node_indext> &src,
611+
std::size_t &limit,
612+
std::vector<bool> &visited,
613+
bool forwards) const
614+
{
615+
PRECONDITION(nodes.size() < std::numeric_limits<std::size_t>::max());
616+
617+
if(limit <= 0)
618+
return src;
619+
620+
std::vector<node_indext> result;
621+
std::vector<node_indext> next_ring;
622+
623+
for(const auto &n : src)
624+
{
625+
result.push_back(n);
626+
627+
for(const auto &o : nodes[n].out)
628+
{
629+
if(!visited[o.first])
630+
{
631+
next_ring.push_back(o.first);
632+
visited[o.first] = true;
633+
}
634+
}
635+
}
636+
637+
if(next_ring.empty())
638+
return result;
639+
640+
limit--;
641+
642+
for(const auto &succ :
643+
depth_limited_search(next_ring, limit, visited, forwards))
644+
result.push_back(succ);
645+
646+
return result;
647+
}
648+
547649
template<class N>
548650
std::size_t grapht<N>::connected_subgraphs(
549651
std::vector<node_indext> &subgraph_nr)

0 commit comments

Comments
 (0)