Пример #1
0
    public static Genome CrossOver(Genome parent1, Genome parent2, Fitter f)
    {
        Genome child = new Genome();

        var rand = new Random();

        // Add Disjoint and Excess Connections from Fitter Parent
        if (f == Fitter.Parent1)
        {
            // Add all nodes from the fitter parent
            foreach (Node n in parent1.Nodes.Values)
            {
                child.AddNodeCopy(n);
            }
            foreach (Connection c in parent1.Connections.Values)
            {
                if (!parent2.Connections.ContainsKey(c.Innovation))
                {
                    child.AddConnectionCopy(c);
                }
            }
        }
        else
        {
            foreach (Node n in parent2.Nodes.Values)
            {
                child.AddNodeCopy(n);
            }
            foreach (Connection c in parent2.Connections.Values)
            {
                if (!parent1.Connections.ContainsKey(c.Innovation))
                {
                    child.AddConnectionCopy(c);
                }
            }
        }

        // Go through again to add all the matching gene randomly
        foreach (Connection c1 in parent1.Connections.Values)
        {
            foreach (Connection c2 in parent2.connections.Values)
            {
                // If matching gene --> pick randomly (50/50)
                if (c1.Innovation == c2.Innovation)
                {
                    if (rand.Next(0, 2) == 0)
                    {
                        child.AddConnectionCopy(c1);
                    }
                    else
                    {
                        child.AddConnectionCopy(c2);
                    }
                    // Randomly enable disabled inherited connection
                    if (!c1.Expressed && !c2.Expressed)
                    {
                        double r = rand.NextDouble();
                        if (r < NEATController.ENABLE_CHANCE)
                        {
                            c2.Expressed = true;
                        }
                    }
                }
            }
        }

        return(child);
    }