Example #1
0
    /// <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>
    /// <param name="nodeIndexByIdMap">Provides a mapping from node ID to node index.</param>
    /// <returns>A new NeatGenome instance.</returns>
    public NeatGenome <T> Create(
        int id, int birthGeneration,
        ConnectionGenes <T> connGenes,
        int[] hiddenNodeIdArr,
        INodeIdMap nodeIndexByIdMap)
    {
        // Create a digraph from the genome.
        DirectedGraph digraph = NeatGenomeBuilderUtils.CreateDirectedGraph(
            _metaNeatGenome, connGenes, nodeIndexByIdMap);

        return(new NeatGenome <T>(_metaNeatGenome, id, birthGeneration, connGenes, hiddenNodeIdArr, nodeIndexByIdMap, digraph, null));
    }
Example #2
0
    /// <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)
    {
        int inputCount = _metaNeatGenome.InputNodeCount;

        // Create a mapping from node IDs to node indexes.
        Dictionary <int, int> nodeIdxById = BuildNodeIndexById(hiddenNodeIdArr);

        // Create a DictionaryNodeIdMap.
        DictionaryNodeIdMap nodeIndexByIdMap = new(inputCount, nodeIdxById);

        // Create a digraph from the genome.
        DirectedGraph digraph = NeatGenomeBuilderUtils.CreateDirectedGraph(
            _metaNeatGenome, connGenes, nodeIndexByIdMap);

        // Calc the depth of each node in the digraph.
        GraphDepthInfo depthInfo = _graphDepthAnalysis.CalculateNodeDepths(digraph);

        // Create a weighted acyclic digraph.
        // Note. This also outputs connectionIndexMap. For each connection in the acyclic graph this gives
        // the index of the same connection in the genome; this is because connections are re-ordered based
        // on node depth in the acyclic graph.
        DirectedGraphAcyclic acyclicDigraph = DirectedGraphAcyclicBuilderUtils.CreateDirectedGraphAcyclic(
            digraph,
            depthInfo,
            out int[] newIdByOldId,
            out int[] connectionIndexMap,
            ref _timesortWorkArr,
            ref _timesortWorkVArr);

        // TODO: Write unit tests to cover this!
        // Update nodeIdxById with the new depth based node index allocations.
        // Notes.
        // The current nodeIndexByIdMap maps node IDs (also know as innovation IDs in NEAT) to a compact
        // ID space in which any gaps have been removed, i.e. a compacted set of IDs that can be used as indexes,
        // i.e. if there are N nodes in total then the highest node ID will be N-1.
        //
        // Here we map the new compact IDs to an alternative ID space that is also compact, but ensures that nodeIDs
        // reflect the depth of a node in the acyclic graph.
        UpdateNodeIndexById(nodeIdxById, hiddenNodeIdArr, newIdByOldId);

        // Create the neat genome.
        return(new NeatGenome <T>(
                   _metaNeatGenome, id, birthGeneration,
                   connGenes,
                   hiddenNodeIdArr,
                   nodeIndexByIdMap,
                   acyclicDigraph,
                   connectionIndexMap));
    }