pub fn bidijkstra<G, N>(edges: &Collection<G, (N,N)>, goals: &Collection<G, (N,N)>) -> Collection<G, ((N,N), u32)>
where
    G: Scope,
    G::Timestamp: Lattice+Ord,
    N: ExchangeData+Hash,
{
    use crate::operators::arrange::arrangement::ArrangeByKey;
    let forward = edges.arrange_by_key();
    let reverse = edges.map(|(x,y)| (y,x)).arrange_by_key();
    bidijkstra_arranged(&forward, &reverse, goals)
}
Returns the subset of `goals` that can reach each other in `edges`, with distance.

This method performs bidirectional search, from both ends of each goal in forward
and reverse direction, for the sources and targets respectively. Each search can
examine a fraction of the graph before meeting, and multiple searches can be managed
concurrently.

Goals that cannot reach from the source to the target are relatively expensive, as
the entire graph must be explored to confirm this. A graph connectivity pre-filter
could be good insurance here.
differential-dataflow/src/algorithms/graphs/bijkstra.rs