public void ThreeNodeTest() { var vertices = new KosarajuVertex[] { new KosarajuVertex(1, new int[]{2}, new int[]{3} ), new KosarajuVertex(2, new int[]{3}, new int[]{1} ), new KosarajuVertex(3, new int[]{1}, new int[]{2} ), }; var alg = new KosarajuAlgorithm(); var result = alg.CountStronglyConnectedComponentes(vertices); Assert.AreEqual(1, result.Length); Assert.AreEqual(3, result[0]); }
public int[] CountStronglyConnectedComponentes(KosarajuVertex[] vertices) { _vertices = vertices; Func<int, KosarajuVertex> selectByIndex = index => _vertices[index]; Func<int, KosarajuVertex> selectByFinishingTime = index => _vertices[index].FinishTimeVertex; Func<KosarajuVertex, IEnumerable<int>> reversedNodeSelector = v => v.ReversedAdjacentVertices; Func<KosarajuVertex, IEnumerable<int>> nodeSelector = v => v.AdjacentVertices; _exploredVerticesCount = 0; DepthFirstSearchLoop(selectByIndex, reversedNodeSelector); _exploredVerticesCount = -1; DepthFirstSearchLoop(selectByFinishingTime, nodeSelector); int[] sccCounter = _vertices.GroupBy(v => v.Parent.Id) .Select(grouping => grouping.Count()) .OrderByDescending(count => count) .Take(5) .ToArray(); return sccCounter; }
public void TestCaseFromLecture() { var vertices = new KosarajuVertex[] { new KosarajuVertex(1, new int[]{4}, new int[]{7} ), new KosarajuVertex(2, new int[]{8}, new int[]{5} ), new KosarajuVertex(3, new int[]{6}, new int[]{9} ), new KosarajuVertex(4, new int[]{7}, new int[]{1} ), new KosarajuVertex(5, new int[]{2}, new int[]{8} ), new KosarajuVertex(6, new int[]{9}, new int[]{3,8} ), new KosarajuVertex(7, new int[]{1}, new int[]{4,9} ), new KosarajuVertex(8, new int[]{5,6}, new int[]{2} ), new KosarajuVertex(9, new int[]{3,7}, new int[]{6} ), }; var alg = new KosarajuAlgorithm(); var result = alg.CountStronglyConnectedComponentes(vertices); Assert.AreEqual(3, result.Length); Assert.AreEqual(3, result[0]); Assert.AreEqual(3, result[1]); Assert.AreEqual(3, result[2]); }
private void DepthFirstSearchLoop(Func<int, KosarajuVertex> nodeSelector, Func<KosarajuVertex, IEnumerable<int>> adjacentNodesSelector) { Array.ForEach(_vertices, v => { v.Explored = false; v.Parent = v; }); for (int nodeIndex = _vertices.Length - 1; nodeIndex >= 0; nodeIndex--) { var node = nodeSelector(nodeIndex); if (!node.Explored) { _currentSource = node; _searchStack.Push(node); DepthFirstSearch(adjacentNodesSelector); } } }
private void AddEdge(KosarajuVertex[] vertices, int firstVertexId, int secondVertexId) { vertices[GetIndexById(firstVertexId)].AdjacentVertices.Add(GetIndexById(secondVertexId) + 1); vertices[GetIndexById(secondVertexId)].ReversedAdjacentVertices.Add(GetIndexById(firstVertexId) + 1); }