single source longest path
parent
27c5a9e73e
commit
fd43036b2b
|
@ -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>();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue