public void SimpleAcyclic_A1() { // Simple acyclic graph. var connList = new LightweightList <DirectedConnection> { new DirectedConnection(0, 3), new DirectedConnection(1, 3), new DirectedConnection(2, 3), new DirectedConnection(2, 4), new DirectedConnection(4, 3) }; // Create graph. var connSpan = connList.AsSpan(); connSpan.Sort(); var digraph = DirectedGraphBuilder.Create(connSpan, 3, 2); // Perform depth analysis. GraphDepthInfo depthInfo = new CyclicGraphDepthAnalysis().CalculateNodeDepths(digraph); // Assertions. Assert.Equal(3, depthInfo._graphDepth); Assert.Equal(5, depthInfo._nodeDepthArr.Length); // Node depths. Assert.Equal(0, depthInfo._nodeDepthArr[0]); Assert.Equal(0, depthInfo._nodeDepthArr[1]); Assert.Equal(0, depthInfo._nodeDepthArr[2]); Assert.Equal(2, depthInfo._nodeDepthArr[3]); Assert.Equal(1, depthInfo._nodeDepthArr[4]); }
/// <summary> /// Create an array that gives the node layer for each node, keyed by node index. /// </summary> /// <param name="digraph">The directed cyclic graph.</param> /// <returns>A new integer array.</returns> private static int[] BuildNodeLayerByIdx_Cyclic(DirectedGraph digraph) { // Perform an analysis on the cyclic graph to assign a depth to each node. // TODO: Re-use these instances, by maintaining a pool of them that can be 'rented from' and 'returned to' the pool. CyclicGraphDepthAnalysis cyclicDepthAnalysis = new CyclicGraphDepthAnalysis(); GraphDepthInfo depthInfo = cyclicDepthAnalysis.CalculateNodeDepths(digraph); int[] nodeLayerByIdx = depthInfo._nodeDepthArr; // Move all nodes up one layer, such that layer 1 is the first/top layer; layer zero will be // used later to represent input nodes only. for (int i = digraph.InputCount; i < nodeLayerByIdx.Length; i++) { nodeLayerByIdx[i]++; } // Assign input nodes to their own layer (layer zero). for (int i = 0; i < digraph.InputCount; i++) { nodeLayerByIdx[i] = 0; } // Assign output nodes to their own layer. int outputLayerIdx = depthInfo._graphDepth + 1; for (int i = 0; i < digraph.OutputCount; i++) { // Note. For cyclic networks the output node indexes occur in a contiguous segment following the input nodes. int outputNodeIdx = digraph.InputCount + i; nodeLayerByIdx[outputNodeIdx] = outputLayerIdx; } // Remove empty layers (if any), by adjusting the depth values in nodeLayerByIdx. RemoveEmptyLayers(nodeLayerByIdx, outputLayerIdx + 1); // Return the constructed node layer lookup table. return(nodeLayerByIdx); }