single source longest path

pull/5/head
Evan Hemsley 2019-07-25 20:01:21 -07:00
parent 27c5a9e73e
commit fd43036b2b
2 changed files with 141 additions and 88 deletions

View File

@ -89,7 +89,7 @@ namespace Encompass
} }
} }
public void AddEdges(params Tuple<T, T>[] edges) public void AddEdges(params ValueTuple<T, T>[] edges)
{ {
foreach (var edge in edges) foreach (var edge in edges)
{ {
@ -174,6 +174,34 @@ namespace Encompass
return priority.Values.Reverse(); return priority.Values.Reverse();
} }
public IEnumerable<ValueTuple<T, int>> LongestPaths(T source)
{
var topoSort = TopologicalSort();
var distances = new Dictionary<T, int>();
foreach (var node in Vertices)
{
distances[node] = int.MaxValue;
}
distances[source] = 0;
foreach (var node in topoSort)
{
if (distances[node] != int.MaxValue)
{
foreach (var neighbor in Neighbors(node))
{
if (distances[neighbor] > distances[node] + 1)
{
distances[neighbor] = distances[node] + 1;
}
}
}
}
return distances.Select((pair) => (pair.Key, pair.Value));
}
public IEnumerable<IEnumerable<T>> StronglyConnectedComponents() public IEnumerable<IEnumerable<T>> StronglyConnectedComponents()
{ {
var preorder = new Dictionary<T, uint>(); var preorder = new Dictionary<T, uint>();

View File

@ -47,10 +47,10 @@ namespace Tests
var myGraph = new DirectedGraph<int>(); var myGraph = new DirectedGraph<int>();
myGraph.AddVertices(1, 2, 3, 4); myGraph.AddVertices(1, 2, 3, 4);
myGraph.AddEdges( myGraph.AddEdges(
Tuple.Create(1, 2), (1, 2),
Tuple.Create(2, 3), (2, 3),
Tuple.Create(2, 4), (2, 4),
Tuple.Create(3, 4) (3, 4)
); );
Assert.That(myGraph.Neighbors(1), Does.Contain(2)); Assert.That(myGraph.Neighbors(1), Does.Contain(2));
@ -66,10 +66,10 @@ namespace Tests
var myGraph = new DirectedGraph<int>(); var myGraph = new DirectedGraph<int>();
myGraph.AddVertices(1, 2, 3, 4); myGraph.AddVertices(1, 2, 3, 4);
myGraph.AddEdges( myGraph.AddEdges(
Tuple.Create(1, 2), (1, 2),
Tuple.Create(2, 3), (2, 3),
Tuple.Create(2, 4), (2, 4),
Tuple.Create(3, 4) (3, 4)
); );
myGraph.RemoveEdge(2, 3); myGraph.RemoveEdge(2, 3);
@ -84,10 +84,10 @@ namespace Tests
var myGraph = new DirectedGraph<int>(); var myGraph = new DirectedGraph<int>();
myGraph.AddVertices(1, 2, 3, 4); myGraph.AddVertices(1, 2, 3, 4);
myGraph.AddEdges( myGraph.AddEdges(
Tuple.Create(1, 2), (1, 2),
Tuple.Create(2, 3), (2, 3),
Tuple.Create(2, 4), (2, 4),
Tuple.Create(3, 4) (3, 4)
); );
myGraph.RemoveVertex(2); myGraph.RemoveVertex(2);
@ -103,9 +103,9 @@ namespace Tests
var myGraph = new DirectedGraph<char>(); var myGraph = new DirectedGraph<char>();
myGraph.AddVertices('a', 'b', 'c', 'd'); myGraph.AddVertices('a', 'b', 'c', 'd');
myGraph.AddEdges( myGraph.AddEdges(
Tuple.Create('a', 'b'), ('a', 'b'),
Tuple.Create('a', 'c'), ('a', 'c'),
Tuple.Create('b', 'd') ('b', 'd')
); );
var result = myGraph.NodeDFS(); var result = myGraph.NodeDFS();
@ -129,10 +129,10 @@ namespace Tests
var simpleGraph = new DirectedGraph<char>(); var simpleGraph = new DirectedGraph<char>();
simpleGraph.AddVertices('a', 'b', 'c', 'd'); simpleGraph.AddVertices('a', 'b', 'c', 'd');
simpleGraph.AddEdges( simpleGraph.AddEdges(
Tuple.Create('a', 'b'), ('a', 'b'),
Tuple.Create('a', 'c'), ('a', 'c'),
Tuple.Create('b', 'a'), ('b', 'a'),
Tuple.Create('b', 'd') ('b', 'd')
); );
Assert.That(simpleGraph.TopologicalSort(), Is.EqualTo(new char[] { 'a', 'c', 'b', 'd' })); Assert.That(simpleGraph.TopologicalSort(), Is.EqualTo(new char[] { 'a', 'c', 'b', 'd' }));
@ -144,14 +144,14 @@ namespace Tests
var complexGraph = new DirectedGraph<char>(); var complexGraph = new DirectedGraph<char>();
complexGraph.AddVertices('a', 'b', 'c', 'd', 'e', 'f', 'g', 't', 'm'); complexGraph.AddVertices('a', 'b', 'c', 'd', 'e', 'f', 'g', 't', 'm');
complexGraph.AddEdges( complexGraph.AddEdges(
Tuple.Create('a', 'b'), ('a', 'b'),
Tuple.Create('a', 'c'), ('a', 'c'),
Tuple.Create('a', 'd'), ('a', 'd'),
Tuple.Create('b', 'f'), ('b', 'f'),
Tuple.Create('b', 'g'), ('b', 'g'),
Tuple.Create('c', 'g'), ('c', 'g'),
Tuple.Create('e', 't'), ('e', 't'),
Tuple.Create('t', 'm') ('t', 'm')
); );
Assert.That( Assert.That(
@ -160,16 +160,41 @@ namespace Tests
); );
} }
[Test]
public void LongestPaths()
{
var graph = new DirectedGraph<char>();
graph.AddVertices('r', 's', 't', 'x', 'y', 'z');
graph.AddEdges(
('r', 's'),
('r', 't'),
('s', 'x'),
('s', 't'),
('t', 'y'),
('t', 'x'),
('x', 'y'),
('y', 'z')
);
var result = graph.LongestPaths('r');
result.Should().Contain(('r', 0));
result.Should().Contain(('s', 1));
result.Should().Contain(('t', 1));
result.Should().Contain(('x', 2));
result.Should().Contain(('y', 2));
result.Should().Contain(('z', 3));
}
[Test] [Test]
public void StronglyConnectedComponentsSimple() public void StronglyConnectedComponentsSimple()
{ {
var simpleGraph = new DirectedGraph<int>(); var simpleGraph = new DirectedGraph<int>();
simpleGraph.AddVertices(1, 2, 3); simpleGraph.AddVertices(1, 2, 3);
simpleGraph.AddEdges( simpleGraph.AddEdges(
Tuple.Create(1, 2), (1, 2),
Tuple.Create(2, 3), (2, 3),
Tuple.Create(3, 2), (3, 2),
Tuple.Create(2, 1) (2, 1)
); );
var result = simpleGraph.StronglyConnectedComponents(); var result = simpleGraph.StronglyConnectedComponents();
@ -185,12 +210,12 @@ namespace Tests
var mediumGraph = new DirectedGraph<int>(); var mediumGraph = new DirectedGraph<int>();
mediumGraph.AddVertices(1, 2, 3, 4); mediumGraph.AddVertices(1, 2, 3, 4);
mediumGraph.AddEdges( mediumGraph.AddEdges(
Tuple.Create(1, 2), (1, 2),
Tuple.Create(1, 3), (1, 3),
Tuple.Create(1, 4), (1, 4),
Tuple.Create(4, 2), (4, 2),
Tuple.Create(3, 4), (3, 4),
Tuple.Create(2, 3) (2, 3)
); );
var result = mediumGraph.StronglyConnectedComponents(); var result = mediumGraph.StronglyConnectedComponents();
@ -208,18 +233,18 @@ namespace Tests
var complexGraph = new DirectedGraph<int>(); var complexGraph = new DirectedGraph<int>();
complexGraph.AddVertices(1, 2, 3, 4, 5, 6, 7, 8); complexGraph.AddVertices(1, 2, 3, 4, 5, 6, 7, 8);
complexGraph.AddEdges( complexGraph.AddEdges(
Tuple.Create(1, 2), (1, 2),
Tuple.Create(2, 3), (2, 3),
Tuple.Create(2, 8), (2, 8),
Tuple.Create(3, 4), (3, 4),
Tuple.Create(3, 7), (3, 7),
Tuple.Create(4, 5), (4, 5),
Tuple.Create(5, 3), (5, 3),
Tuple.Create(5, 6), (5, 6),
Tuple.Create(7, 4), (7, 4),
Tuple.Create(7, 6), (7, 6),
Tuple.Create(8, 1), (8, 1),
Tuple.Create(8, 7) (8, 7)
); );
var result = complexGraph.StronglyConnectedComponents(); var result = complexGraph.StronglyConnectedComponents();
@ -239,11 +264,11 @@ namespace Tests
var myGraph = new DirectedGraph<int>(); var myGraph = new DirectedGraph<int>();
myGraph.AddVertices(1, 2, 3, 4); myGraph.AddVertices(1, 2, 3, 4);
myGraph.AddEdges( myGraph.AddEdges(
Tuple.Create(1, 1), (1, 1),
Tuple.Create(1, 2), (1, 2),
Tuple.Create(2, 3), (2, 3),
Tuple.Create(2, 1), (2, 1),
Tuple.Create(3, 4) (3, 4)
); );
var clone = myGraph.Clone(); var clone = myGraph.Clone();
@ -260,11 +285,11 @@ namespace Tests
var myGraph = new DirectedGraph<int>(); var myGraph = new DirectedGraph<int>();
myGraph.AddVertices(1, 2, 3, 4); myGraph.AddVertices(1, 2, 3, 4);
myGraph.AddEdges( myGraph.AddEdges(
Tuple.Create(1, 1), (1, 1),
Tuple.Create(1, 2), (1, 2),
Tuple.Create(2, 3), (2, 3),
Tuple.Create(2, 1), (2, 1),
Tuple.Create(3, 4) (3, 4)
); );
var subGraph = myGraph.SubGraph(1, 2, 3); var subGraph = myGraph.SubGraph(1, 2, 3);
@ -280,13 +305,13 @@ namespace Tests
var myGraph = new DirectedGraph<int>(); var myGraph = new DirectedGraph<int>();
myGraph.AddVertices(0, 1, 2); myGraph.AddVertices(0, 1, 2);
myGraph.AddEdges( myGraph.AddEdges(
Tuple.Create(0, 0), (0, 0),
Tuple.Create(0, 1), (0, 1),
Tuple.Create(0, 2), (0, 2),
Tuple.Create(1, 2), (1, 2),
Tuple.Create(2, 0), (2, 0),
Tuple.Create(2, 1), (2, 1),
Tuple.Create(2, 2) (2, 2)
); );
var result = myGraph.SimpleCycles(); var result = myGraph.SimpleCycles();
@ -311,20 +336,20 @@ namespace Tests
var myGraph = new DirectedGraph<int>(); var myGraph = new DirectedGraph<int>();
myGraph.AddVertices(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); myGraph.AddVertices(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
myGraph.AddEdges( myGraph.AddEdges(
Tuple.Create(0, 1), (0, 1),
Tuple.Create(1, 2), (1, 2),
Tuple.Create(2, 3), (2, 3),
Tuple.Create(3, 0), (3, 0),
Tuple.Create(0, 3), (0, 3),
Tuple.Create(3, 4), (3, 4),
Tuple.Create(4, 5), (4, 5),
Tuple.Create(5, 0), (5, 0),
Tuple.Create(0, 1), (0, 1),
Tuple.Create(1, 6), (1, 6),
Tuple.Create(6, 7), (6, 7),
Tuple.Create(7, 8), (7, 8),
Tuple.Create(8, 0), (8, 0),
Tuple.Create(8, 9) (8, 9)
); );
var result = myGraph.SimpleCycles(); var result = myGraph.SimpleCycles();
@ -348,10 +373,10 @@ namespace Tests
var myGraph = new DirectedGraph<int>(); var myGraph = new DirectedGraph<int>();
myGraph.AddVertices(1, 2, 3, 4); myGraph.AddVertices(1, 2, 3, 4);
myGraph.AddEdges( myGraph.AddEdges(
Tuple.Create(1, 2), (1, 2),
Tuple.Create(2, 3), (2, 3),
Tuple.Create(3, 1), (3, 1),
Tuple.Create(3, 4) (3, 4)
); );
Assert.That(myGraph.Cyclic(), Is.True); Assert.That(myGraph.Cyclic(), Is.True);
@ -363,9 +388,9 @@ namespace Tests
var myGraph = new DirectedGraph<int>(); var myGraph = new DirectedGraph<int>();
myGraph.AddVertices(1, 2, 3, 4); myGraph.AddVertices(1, 2, 3, 4);
myGraph.AddEdges( myGraph.AddEdges(
Tuple.Create(1, 2), (1, 2),
Tuple.Create(2, 3), (2, 3),
Tuple.Create(3, 4) (3, 4)
); );
Assert.That(myGraph.Cyclic(), Is.False); Assert.That(myGraph.Cyclic(), Is.False);