Beispiel #1
0
    private NEAT Crossover(NEAT dominant, NEAT submissive)
    {
        NEAT child = new NEAT(dominant);

        List <Connection> newConnections = new List <Connection>();

        foreach (var connection in child.GetConnetionGenom())
        {
            Connection c = submissive.GetConnetionGenom().Find(x => x.innovation == connection.innovation);

            if (c != null && Random.Range(0f, 1f) > 0.5f)
            {
                Node inNode  = child.GetNodeGenom().Find(n => n.nodeID == c.inNode);
                Node outNode = child.GetNodeGenom().Find(n => n.nodeID == c.outNode);

                if (outNode == null && inNode != null)
                {
                    outNode = new Node(c.outNode, inNode.order + 1, NodeType.Hidden);
                    child.AddNode(outNode);
                }
                else if (outNode == null && inNode == null)
                {
                    outNode = new Node(c.outNode, 1, NodeType.Hidden);
                    child.AddNode(outNode);
                }

                if (inNode == null)
                {
                    inNode = new Node(c.inNode, 0, NodeType.Hidden);
                    child.AddNode(inNode);
                }

                Connection cNew = new Connection(inNode.nodeID, outNode.nodeID, c.weight, c.enabled, c.innovation);

                newConnections.Add(cNew);
            }
        }

        foreach (var connection in newConnections)
        {
            if (!CompareConnection(connection, child))
            {
                if (!LoopSearch(connection, child.GetConnetionGenom()))
                {
                    child.RemoveConnection(child.GetConnetionGenom().Find(n => n.innovation == connection.innovation));
                    child.AddConnection(connection);
                    child.GetNodeGenom().Find(n => n.nodeID == connection.inNode).AddConnection(connection);
                }
            }
        }
        return(child);
    }
Beispiel #2
0
    public void DrawNetwork(NEAT network)
    {
        List <Node>       nodes       = network.GetNodeGenom();
        List <Connection> connections = network.GetConnetionGenom();

        Dictionary <int, List <Node> > table = new Dictionary <int, List <Node> >();

        linePositions = new Dictionary <LineRenderer, Connection>();
        nodeToTrans   = new Dictionary <int, RectTransform>();

        int lastOrder = CalculateLargestOrder(nodes);

        for (int i = 0; i <= lastOrder; i++)
        {
            table.Add(i, new List <Node>());
        }

        table.Add(lastOrder + 1, new List <Node>());

        foreach (var node in nodes)
        {
            if (node.nodeType != NodeType.Output)
            {
                table[node.order].Add(node);
            }
            else
            {
                table[lastOrder + 1].Add(node);
            }
        }

        for (int i = 0; i < table.Count; i++)
        {
            table[i].Sort(delegate(Node a, Node b) {
                return(a.nodeID.CompareTo(b.nodeID));
            });
        }

        for (int i = 0; i <= lastOrder + 1; i++)
        {
            for (int j = 0; j < table[i].Count; j++)
            {
                CreateNode(new Vector2(i * ((panelBounds.x - bounds.x * 2) / (lastOrder + 1)), j * ((panelBounds.y - bounds.y * 1.5f) / table[i].Count)), table[i][j]);
            }
        }

        foreach (var connection in connections)
        {
            Vector3[] poses = new Vector3[2];
            poses[0] = cam.ScreenToWorldPoint(nodeToTrans[connection.inNode].anchoredPosition);
            poses[1] = cam.ScreenToWorldPoint(nodeToTrans[connection.inNode].anchoredPosition);
            CreateConnection(poses, connection);
        }

        draw = true;
    }
Beispiel #3
0
    public SaveBrain(NEAT neat, Vector2Int gridSize, Vector2 bucketSize, Vector2 offset)
    {
        this.gridSize    = new int[2];
        this.gridSize[0] = gridSize.x;
        this.gridSize[1] = gridSize.y;

        this.bucketSize    = new float[2];
        this.bucketSize[0] = bucketSize.x;
        this.bucketSize[1] = bucketSize.y;

        this.offset    = new float[2];
        this.offset[0] = offset.x;
        this.offset[1] = offset.y;

        innovation = neat.GetInnovation();
        inputs     = neat.GetInputSize();
        outputs    = neat.GetOutputsSize();

        List <float> tempFloatsNodes       = new List <float>();
        List <float> tempFloatsConnections = new List <float>();

        foreach (var node in neat.GetNodeGenom())
        {
            //node vars
            tempFloatsNodes.Add(node.order);
            tempFloatsNodes.Add(node.nodeID);
            tempFloatsNodes.Add((int)node.nodeType);
            tempFloatsNodes.Add(node.activation);
            tempFloatsNodes.Add(node.sum);
        }

        foreach (var connection in neat.GetConnetionGenom())
        {
            //connections vars

            tempFloatsConnections.Add(connection.inNode);
            tempFloatsConnections.Add(connection.outNode);
            tempFloatsConnections.Add(connection.weight);

            if (connection.enabled)
            {
                tempFloatsConnections.Add(1);
            }
            else
            {
                tempFloatsConnections.Add(0);
            }

            tempFloatsConnections.Add(connection.innovation);
        }

        floatNodes       = tempFloatsNodes.ToArray();
        floatConnections = tempFloatsConnections.ToArray();
    }
Beispiel #4
0
    private bool CompareConnection(Connection connection, NEAT child)
    {
        int size = child.GetConnetionGenom().Count;

        for (int i = 0; i < size; i++)
        {
            if (child.GetConnectionGene(i).CompareConnection(connection.inNode, connection.outNode))
            {
                return(true);
            }
        }

        return(false);
    }
Beispiel #5
0
    public NEAT LoadBrain()
    {
        NEAT network = new NEAT(0, 0);

        network.SetSize(inputs, outputs);

        //create all nodes
        for (int i = 0; i < floatNodes.Length; i += 5)
        {
            Node current = new Node((int)floatNodes[i + 1], (int)floatNodes[i], (NodeType)(int)floatNodes[i + 2]);
            current.activation = floatNodes[i + 3];
            current.sum        = floatNodes[i + 4];
            network.AddNode(current);
        }

        //create all connections
        for (int i = 0; i < floatConnections.Length; i += 5)
        {
            bool       enable  = floatConnections[i + 3] == 1 ? true : false;
            Connection current = new Connection((int)floatConnections[i], (int)floatConnections[i + 1], floatConnections[i + 2], enable, (int)floatConnections[i + 4]);
            Debug.Log(current.inNode + "Innode id, " + current.outNode + "outnode id, " + current.weight + "weight, " + current.innovation + "innovation");
            network.AddConnection(current);
        }

        //add all connections to nodes
        foreach (var connection in network.GetConnetionGenom())
        {
            Node currentNode = network.GetNodeGenom().Find(x => x.nodeID == connection.inNode);
            if (currentNode != null)
            {
                currentNode.AddConnection(connection);
            }
        }

        network.SetInnovation(innovation);

        return(network);
    }
Beispiel #6
0
    private float CompareGenes(NEAT networkA, NEAT networkB)
    {
        if (networkA.GetConnetionGenom().Count == 0 && networkB.GetConnetionGenom().Count == 0)
        {
            return(0);
        }

        List <Connection> connectionsA = networkA.GetConnetionGenom();
        List <Connection> connectionsB = networkB.GetConnetionGenom();

        connectionsA.Sort(delegate(Connection a, Connection b) {
            return(a.innovation.CompareTo(b.innovation));
        });

        connectionsB.Sort(delegate(Connection a, Connection b) {
            return(a.innovation.CompareTo(b.innovation));
        });

        int diff       = 0;
        int counterMax = 0;

        #region
        if (connectionsA.Count == 0 && connectionsB.Count != 0)
        {
            diff       = connectionsB.Count;
            counterMax = connectionsB[connectionsB.Count - 1].innovation;
        }
        else if (connectionsB.Count == 0 && connectionsA.Count != 0)
        {
            diff       = connectionsA.Count;
            counterMax = connectionsA[connectionsA.Count - 1].innovation;
        }
        else if (connectionsA.Count > 0 && connectionsB.Count > 0)
        {
            diff       = connectionsA[connectionsA.Count - 1].innovation - connectionsB[connectionsB.Count - 1].innovation;
            counterMax = diff < 0 ? connectionsA[connectionsA.Count - 1].innovation : connectionsB[connectionsB.Count - 1].innovation;
        }

        #endregion

        int[] result = new int[counterMax];

        for (int i = 1; i < counterMax; i++)
        {
            Connection A = connectionsA.Find(x => x.innovation == i);
            Connection B = connectionsB.Find(x => x.innovation == i);
            if (A != null && B != null)
            {
                result[i] = 1;
                continue;
            }
            result[i] = 0;
        }

        int disjoints = 0;
        foreach (int i in result)
        {
            if (i == 0)
            {
                disjoints++;
            }
        }

        float weigthSum = 0;
        counterMax = diff > 0 ? connectionsA.Count : connectionsB.Count;
        for (int i = 0; i < counterMax; i++)
        {
            float w1 = 0;
            float w2 = 0;

            if (i < connectionsA.Count)
            {
                w1 = connectionsA[i].weight;
            }

            if (i < connectionsB.Count)
            {
                w2 = connectionsB[i].weight;
            }

            weigthSum += Mathf.Abs(w1 - w1);
        }

        weigthSum /= counterMax;

        diff = Mathf.Abs(diff);

        int genomSumA = connectionsA.Count + networkA.GetNodeGenom().Count;
        int genomSumB = connectionsB.Count + networkB.GetNodeGenom().Count;

        if (genomSumA > genomSumB)
        {
            return(((excessFactor * diff) / genomSumA) + ((disjointFactor * disjoints) / genomSumA) + (weigthFactor * weigthSum));
        }

        return(((excessFactor * diff) / genomSumB) + ((disjointFactor * disjoints) / genomSumB) + (weigthFactor * weigthSum));
    }