Skip to content

Commit 0b886eb

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 0b886eb

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

src/util/graph.h

Lines changed: 43 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,46 @@ 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+
PRECONDITION(i <= reachable[reachable_idx]);
495+
if(i > reachable[reachable_idx])
496+
throw "error disconnecting unreachable nodes";
497+
498+
if(i == reachable[reachable_idx])
499+
{
500+
reachable_idx++;
501+
}
502+
else
503+
remove_edges(i);
504+
}
505+
}
506+
464507
/// Add to `set`, nodes that are reachable from `set`.
465508
///
466509
/// This implements a depth first search using a stack: at each step we pop a

0 commit comments

Comments
 (0)