-
Notifications
You must be signed in to change notification settings - Fork 294
/
Copy pathBiDirectional.cs
77 lines (61 loc) · 2.3 KB
/
BiDirectional.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using System.Collections.Generic;
using Advanced.Algorithms.DataStructures.Graph;
namespace Advanced.Algorithms.Graph;
/// <summary>
/// A BiDirectional Path Search on DiGraph.
/// </summary>
public class BiDirectional<T>
{
/// <summary>
/// Returns true if Path exists from source to destination.
/// </summary>
public bool PathExists(IGraph<T> graph, T source, T destination)
{
return Bfs(graph, source, destination);
}
/// <summary>
/// Use breadth First Search from Source and Target until they meet.
/// If they could'nt find the element before they meet return false.
/// </summary>
private bool Bfs(IGraph<T> graph, T source, T destination)
{
var visitedA = new HashSet<T>();
var visitedB = new HashSet<T>();
var bfsQueueA = new Queue<IGraphVertex<T>>();
var bfsQueueB = new Queue<IGraphVertex<T>>();
bfsQueueA.Enqueue(graph.GetVertex(source));
bfsQueueB.Enqueue(graph.GetVertex(destination));
visitedA.Add(graph.GetVertex(source).Key);
visitedB.Add(graph.GetVertex(destination).Key);
//search from both ends for a Path
while (true)
{
if (bfsQueueA.Count > 0)
{
var current = bfsQueueA.Dequeue();
//intersects with search from other end
if (visitedB.Contains(current.Key)) return true;
foreach (var edge in current.Edges)
{
if (visitedA.Contains(edge.TargetVertexKey)) continue;
visitedA.Add(edge.TargetVertexKey);
bfsQueueA.Enqueue(edge.TargetVertex);
}
}
if (bfsQueueB.Count > 0)
{
var current = bfsQueueB.Dequeue();
//intersects with search from other end
if (visitedA.Contains(current.Key)) return true;
foreach (var edge in current.Edges)
{
if (visitedB.Contains(edge.TargetVertexKey)) continue;
visitedB.Add(edge.TargetVertexKey);
bfsQueueB.Enqueue(edge.TargetVertex);
}
}
if (bfsQueueA.Count == 0 && bfsQueueB.Count == 0) break;
}
return false;
}
}