Skip to content

Commit eca3366

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 eca3366

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

src/util/graph.h

Lines changed: 40 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(const std::vector<node_indext> &src);
257+
255258
void make_chordal();
256259

257260
// return value: number of connected subgraphs
@@ -461,6 +464,43 @@ 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+
const std::vector<node_indext> source_nodes(1, src);
479+
disconnect_unreachable(source_nodes);
480+
}
481+
482+
/// Removes any edges between nodes in a graph that are unreachable
483+
/// from a vector of start nodes.
484+
/// \param src: vector of indices of start nodes
485+
template <class N>
486+
void grapht<N>::disconnect_unreachable(const std::vector<node_indext> &src)
487+
{
488+
std::vector<node_indext> reachable = get_reachable(src, true);
489+
std::sort(reachable.begin(), reachable.end());
490+
std::size_t reachable_idx = 0;
491+
for(std::size_t i = 0; i < nodes.size(); i++)
492+
{
493+
if(reachable_idx >= reachable.size())
494+
remove_edges(i);
495+
else if(i == reachable[reachable_idx])
496+
reachable_idx++;
497+
else if(i > reachable[reachable_idx])
498+
throw "error disconnecting unreachable nodes";
499+
else
500+
remove_edges(i);
501+
}
502+
}
503+
464504
/// Add to `set`, nodes that are reachable from `set`.
465505
///
466506
/// This implements a depth first search using a stack: at each step we pop a

0 commit comments

Comments
 (0)