/// <summary>
    /// Create a directed graph based on the provided connections (between node IDs) and a predefined set of input/output
    /// node IDs defined as being in a contiguous sequence starting at ID zero.
    /// </summary>
    /// <param name="connections">The connections that define the structure and weights of the weighted directed graph.</param>
    /// <param name="inputCount">Input node count.</param>
    /// <param name="outputCount">Output node count.</param>
    /// <returns>A new instance of <see cref="DirectedGraph"/>.</returns>
    /// <remarks>
    /// <paramref name="connections"/> is required to be sorted by sourceId, TargetId.
    /// </remarks>
    public static DirectedGraph Create(
        Span <DirectedConnection> connections,
        int inputCount, int outputCount)
    {
        // Debug assert that the connections are sorted.
        Debug.Assert(SortUtils.IsSortedAscending <DirectedConnection>(connections));

        // Determine the full set of hidden node IDs.
        int inputOutputCount = inputCount + outputCount;
        var hiddenNodeIdArr  = GetHiddenNodeIdArray(connections, inputOutputCount);

        // Compile a mapping from current nodeIDs to new IDs (i.e. removing gaps in the ID space).
        INodeIdMap nodeIdMap = DirectedGraphBuilderUtils.CompileNodeIdMap(
            inputOutputCount, hiddenNodeIdArr);

        // Extract/copy the neat genome connectivity graph into an array of DirectedConnection.
        // Notes.
        // The array contents will be manipulated, so copying this avoids modification of the genome's
        // connection gene list.
        // The IDs are substituted for node indexes here.
        ConnectionIds connIds = CopyAndMapIds(connections, nodeIdMap);

        // Construct and return a new DirectedGraph.
        int totalNodeCount = inputOutputCount + hiddenNodeIdArr.Length;

        return(new DirectedGraph(inputCount, outputCount, totalNodeCount, connIds));
    }
        /// <summary>
        /// Create a NeatGenome with the given meta data, connection genes and supplementary data.
        /// </summary>
        /// <param name="id">Genome ID.</param>
        /// <param name="birthGeneration">Birth generation.</param>
        /// <param name="connGenes">Connection genes.</param>
        /// <param name="hiddenNodeIdArr">An array of the hidden node IDs in the genome, in ascending order.</param>
        /// <returns>A new NeatGenome instance.</returns>
        public NeatGenome <T> Create(
            int id, int birthGeneration,
            ConnectionGenes <T> connGenes,
            int[] hiddenNodeIdArr)
        {
            // Create a mapping from node IDs to node indexes.
            INodeIdMap nodeIndexByIdMap = DirectedGraphBuilderUtils.CompileNodeIdMap(
                _metaNeatGenome.InputOutputNodeCount, hiddenNodeIdArr);

            return(Create(id, birthGeneration, connGenes, hiddenNodeIdArr, nodeIndexByIdMap));
        }