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);
 }