示例#1
0
        public override NEAT.Person crossover(NEAT.Person person1, NEAT.Person person2)
        {
            NEAT.Person res = ScriptableObject.CreateInstance <NEAT.Person>();

            var dissimilar1 = person1.node_connect.Where(n => !person2.node_connect.Select(n1 => n1.innov).Contains(n.innov));
            var dissimilar2 = person2.node_connect.Where(n => !person1.node_connect.Select(n1 => n1.innov).Contains(n.innov));
            var similar     = person1.node_connect.Where(n => person2.node_connect.Select(n1 => n1.innov).Contains(n.innov));
            var innov       = similar.Select(n => n.innov);

            res.node_gene = new List <NEAT.GENES.Nodes>(person1.node_gene.Union(person2.node_gene).ToList());

            List <int> id = innov.Union(dissimilar1.Union(dissimilar2).Select(n => n.innov)).OrderBy(n => n).ToList();

            for (int i = 0; i < id.Count; ++i)
            {
                NEAT.GENES.Connection conn1 = person1.node_connect.Find(n => n.innov == id[i]);
                NEAT.GENES.Connection conn2 = person2.node_connect.Find(n => n.innov == id[i]);

                var nbNodes = res.node_gene.Select(n => n.nb);
                if (conn1 == null)
                {
                    res.node_connect.Add(conn2);

                    NEAT.GENES.Nodes inN  = person2.node_gene[conn2.inNode];
                    NEAT.GENES.Nodes outN = person2.node_gene[conn2.outNode];
                    if (!nbNodes.Contains(inN.nb))
                    {
                        res.node_gene.Add(inN);
                    }
                    if (!nbNodes.Contains(outN.nb))
                    {
                        res.node_gene.Add(outN);
                    }
                }
                else if (conn2 == null)
                {
                    res.node_connect.Add(conn1);

                    NEAT.GENES.Nodes inN  = person1.node_gene[conn1.inNode];
                    NEAT.GENES.Nodes outN = person1.node_gene[conn1.outNode];
                    if (!nbNodes.Contains(inN.nb))
                    {
                        res.node_gene.Add(inN);
                    }
                    if (!nbNodes.Contains(outN.nb))
                    {
                        res.node_gene.Add(outN);
                    }
                }
                else
                {
                    if (conn1.innov < conn2.innov)
                    {
                        res.node_connect.Add(conn1.Clone());
                    }
                    else
                    {
                        res.node_connect.Add(conn2.Clone());
                    }
                    res.node_connect.Last().w = (conn1.w + conn2.w) / 2.0f;

                    if (!conn1.enabled || !conn2.enabled)
                    {
                        res.node_connect.Last().enabled = false;
                    }

                    NEAT.GENES.Nodes inN  = person1.node_gene[conn1.inNode];
                    NEAT.GENES.Nodes outN = person1.node_gene[conn1.outNode];
                    if (!nbNodes.Contains(inN.nb))
                    {
                        res.node_gene.Add(inN);
                    }
                    if (!nbNodes.Contains(outN.nb))
                    {
                        res.node_gene.Add(outN);
                    }
                }
            }

            res.node_gene.OrderBy(n => n.nb);

            return(res);
        }
示例#2
0
        public override NEAT.Person mutation(NEAT.Person person)
        {
            NEAT.Person res = person.Clone();
            float       r   = UnityEngine.Random.value;

            if (r > 0.2f)
            {
                List <Tuple <int, int> > innout = new List <Tuple <int, int> >();
                for (int i = 0; i < res.node_gene.Count; ++i)
                {
                    if (res.node_gene[i].property != NEAT.GENES.NODE.OUT)
                    {
                        for (int j = i + 1; j < res.node_gene.Count; ++j)
                        {
                            if (res.node_gene[j].property != NEAT.GENES.NODE.IN)
                            {
                                innout.Add(new Tuple <int, int>(res.node_gene[i].nb, res.node_gene[j].nb));
                            }
                        }
                    }
                }
                List <Tuple <int, int> > connectionsPossible = innout.Where(
                    p => !res.node_connect.Select(n => n.inNode).Contains(p.Item1) ||
                    !res.node_connect.Select(n => n.outNode).Contains(p.Item2)).ToList();

                if (connectionsPossible.Count > 0)
                {
                    System.Random random = new System.Random();
                    int           rr     = random.Next(connectionsPossible.Count);
                    int           nb1    = connectionsPossible[rr].Item1;
                    int           nb2    = connectionsPossible[rr].Item2;

                    NEAT.GENES.Connection connection;
                    int indexC = NEAT.GENES.Connection.alreadyExists(nb1, nb2);
                    if (indexC > -1)
                    {
                        connection         = NEAT.GENES.Connection.existing_connections[indexC].Clone();
                        connection.w       = UnityEngine.Random.Range(-1f, 1f);
                        connection.enabled = true;
                    }
                    else
                    {
                        connection = ScriptableObject.CreateInstance <NEAT.GENES.Connection>();
                        connection.init(nb1, nb2, UnityEngine.Random.Range(-1f, 1f), true);
                        NEAT.GENES.Connection.existing_connections.Add(connection);
                    }
                    //NEAT.GENES.Connection connection = new NEAT.GENES.Connection(nb1, nb2, UnityEngine.Random.Range(-1f, 1f), true);

                    res.node_connect.Add(connection);
                }
            }
            else
            {
                System.Random random = new System.Random();
                int           ran    = random.Next(res.node_connect.Count);
                res.node_connect[ran]         = res.node_connect[ran].Clone();
                res.node_connect[ran].enabled = false;

                NEAT.GENES.Nodes newn = ScriptableObject.CreateInstance <NEAT.GENES.Nodes>();
                newn.activation = (NEAT.GENES.ACTIVATION)random.Next(8);
                newn.nb         = res.node_gene.Select(n => n.nb).Max() + 1;
                newn.property   = NEAT.GENES.NODE.HIDDEN;


                NEAT.GENES.Connection con1;
                NEAT.GENES.Connection con2;
                int indexC = NEAT.GENES.Connection.alreadyExists(res.node_connect[ran].inNode, newn.nb);
                if (indexC > -1)
                {
                    con1         = NEAT.GENES.Connection.existing_connections[indexC].Clone();
                    con1.w       = 1f;
                    con1.enabled = true;
                }
                else
                {
                    con1 = ScriptableObject.CreateInstance <NEAT.GENES.Connection>();
                    con1.init(res.node_connect[ran].inNode, newn.nb, 1f, true);
                    NEAT.GENES.Connection.existing_connections.Add(con1);
                }

                indexC = NEAT.GENES.Connection.alreadyExists(newn.nb, res.node_connect[ran].outNode);
                if (indexC > -1)
                {
                    con2         = NEAT.GENES.Connection.existing_connections[indexC].Clone();
                    con1.w       = res.node_connect[ran].w;
                    con1.enabled = true;
                }
                else
                {
                    con2 = ScriptableObject.CreateInstance <NEAT.GENES.Connection>();
                    con2.init(newn.nb, res.node_connect[ran].outNode, res.node_connect[ran].w, true);
                    NEAT.GENES.Connection.existing_connections.Add(con2);
                }

                //NEAT.GENES.Connection con1 = new NEAT.GENES.Connection(res.node_connect[ran].inNode, newn.nb, 1f, true);
                //NEAT.GENES.Connection con2 = new NEAT.GENES.Connection(newn.nb, res.node_connect[ran].outNode, res.node_connect[ran].w, true);

                res.node_gene.Add(newn);
                res.node_gene = res.node_gene.OrderBy(n => n.nb).ToList();

                res.node_connect.Add(con1);
                res.node_connect.Add(con2);
            }
            return(res);
        }