Skip to content

Commit 4772929

Browse files
committed
Disconnect unreachable nodes in a graph
This function removes all edges between unreachable nodes in a graph. This can then be used to compute the cone of influence between 2 points, A and B: 1 - disconnect all nodes unreachable from A 2 - do backwards reachability from B.
1 parent c4aadab commit 4772929

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

src/util/graph.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,9 @@ class grapht
252252
std::vector<node_indext>
253253
get_reachable(const std::vector<node_indext> &src, bool forwards) const;
254254

255+
void disconnect_unreachable(node_indext src);
256+
void disconnect_unreachable(std::vector<node_indext> src);
257+
255258
void make_chordal();
256259

257260
// return value: number of connected subgraphs
@@ -461,6 +464,48 @@ void grapht<N>::visit_reachable(node_indext src)
461464
nodes[index].visited = true;
462465
}
463466

467+
/// Removes any edges between nodes in a graph that are unreachable from
468+
/// a given start node. Used for computing cone of influence,
469+
/// by disconnecting unreachable nodes and then performing backwards
470+
/// reachability.
471+
/// Note nodes are not actually removed from the vector nodes, because
472+
/// this requires renumbering node indices. This copies the way nodes
473+
/// are "removed" in make_chordal.
474+
/// \param src: start node
475+
template <class N>
476+
void grapht<N>::disconnect_unreachable(node_indext src)
477+
{
478+
std::vector<node_indext> source_nodes;
479+
source_nodes.push_back(src);
480+
disconnect_unreachable(source_nodes);
481+
}
482+
483+
/// Removes any edges between nodes in a graph that are unreachable
484+
/// from a vector of start nodes.
485+
/// \param src: vector of indices of start nodes
486+
template <class N>
487+
void grapht<N>::disconnect_unreachable(std::vector<node_indext> src)
488+
{
489+
std::vector<node_indext> reachable = get_reachable(src, true);
490+
std::sort(reachable.begin(), reachable.end());
491+
std::size_t reachable_idx = 0;
492+
for(std::size_t i = 0; i < nodes.size(); i++)
493+
{
494+
if(reachable_idx >= reachable.size())
495+
return;
496+
PRECONDITION(i <= reachable[reachable_idx]);
497+
if(i > reachable[reachable_idx])
498+
throw "error disconnecting unreachable nodes";
499+
500+
if(i == reachable[reachable_idx])
501+
{
502+
reachable_idx++;
503+
}
504+
else
505+
remove_edges(i);
506+
}
507+
}
508+
464509
/// Add to `set`, nodes that are reachable from `set`.
465510
///
466511
/// This implements a depth first search using a stack: at each step we pop a

0 commit comments

Comments
 (0)