Beispiel #1
0
    public void MutateAgent_Weight_Test()
    {
        MutationLog mutationLog = new MutationLog();

        AgentObject customAgent = new CustomAgent(populationManager, parent2Genome, 10);

        Assert.AreEqual(6, customAgent.Genome.Nodes.Count);
        Assert.AreEqual(9, customAgent.Genome.Connections.Count);

        Dictionary <int, double> weights = new Dictionary <int, double>();

        foreach (int key in customAgent.Genome.Connections.Keys)
        {
            weights.Add(key, customAgent.Genome.Connections[key].Weight);
        }

        //Mutate weights
        populationManager.MutateAgent(customAgent, 0f, 0f, 1f, nodeInnovationCounter, connectionInnovationCounter, mutationLog);

        //Nodes should not have changed
        Assert.AreEqual(6, customAgent.Genome.Nodes.Count);
        Assert.AreEqual(9, customAgent.Genome.Connections.Count);
        Assert.AreEqual(14, connectionInnovationCounter.GetNewNumber());
        Assert.AreEqual(11, nodeInnovationCounter.GetNewNumber());


        foreach (int key in weights.Keys)
        {
            Assert.AreNotEqual(weights[key], customAgent.Genome.Connections[key].Weight);
        }
    }
Beispiel #2
0
    public void MutateAgent_Node_Test()
    {
        MutationLog mutationLog = new MutationLog();

        AgentObject customAgent = new CustomAgent(populationManager, parent2Genome, 10);

        Assert.AreEqual(6, customAgent.Genome.Nodes.Count);
        Assert.AreEqual(9, customAgent.Genome.Connections.Count);

        Dictionary <int, double> weights = new Dictionary <int, double>();

        foreach (int key in customAgent.Genome.Connections.Keys)
        {
            weights.Add(key, customAgent.Genome.Connections[key].Weight);
        }

        //Can fail sometimes, when a disabled connection is selected
        populationManager.MutateAgent(customAgent, 0f, 1f, 0f, nodeInnovationCounter, connectionInnovationCounter, mutationLog);

        //1 Node shoudl be added and 2 connections
        Assert.AreEqual(7, customAgent.Genome.Nodes.Count);
        Assert.AreEqual(12, nodeInnovationCounter.GetNewNumber());

        Assert.AreEqual(11, customAgent.Genome.Connections.Count);
        Assert.AreEqual(16, connectionInnovationCounter.GetNewNumber());

        //WEights should not have changed
        foreach (int key in weights.Keys)
        {
            Assert.AreEqual(weights[key], customAgent.Genome.Connections[key].Weight);
        }
    }
Beispiel #3
0
    public void CreateInitialPopulation(Genome startingGenome, GeneCounter nodeInnovationCounter, GeneCounter connectionInnovationCounter, int populationSize, bool randomizeWeights)
    {
        _generation                  = 0;
        _nodeInnovationCounter       = nodeInnovationCounter;
        _connectionInnovationCounter = connectionInnovationCounter;
        _populationSize              = populationSize;
        _mutationLog                 = new MutationLog();

        _agents  = new List <AgentObject>();
        _species = new List <Species>();

        for (int i = 0; i < _populationSize; i++)
        {
            Genome randomGenome = new Genome(startingGenome);

            if (randomizeWeights)
            {
                foreach (ConnectionGene con in randomGenome.Connections.Values)
                {
                    con.Weight = Random.Range(-1f, 1f);
                }
            }

            AgentObject agent = _callback.InitNewAgent(this, randomGenome);
            _agents.Add(agent);
        }

        PlaceAgentInSpecies(_agents, _species);

        //Notify the callback if not existing
        if (_callback != null)
        {
            _callback.AgentsInitializedCallback(_agents, _species, _generation);
        }
    }
    public void SetUp()
    {
        mutationLog = new MutationLog();

        node1 = new NodeGene(1, NodeGeneType.HIDDEN, 0.5f);
        node2 = new NodeGene(2, NodeGeneType.OUTPUT, 1f);

        connection1 = new ConnectionGene(1, 2, 0.5f, true, 1);
        connection2 = new ConnectionGene(2, 1, 1f, false, 2);

        mutationLog.AddConnectionMutation(connection1);
        mutationLog.AddNodeMutation(connection1, node1);
    }
Beispiel #5
0
    public void AddConnectionMutation(AgentObject agent, int amountTries, MutationLog mutationLog, GeneCounter connectionInnovationCounter)
    {
        List <int> nodeKeys = agent.Genome.Nodes.Keys.ToList();

        for (int i = 0; i < amountTries; i++)
        {
            //Selet two random nodes
            NodeGene inNode  = agent.Genome.Nodes[nodeKeys[Random.Range(0, nodeKeys.Count)]];
            NodeGene outNode = agent.Genome.Nodes[nodeKeys[Random.Range(0, nodeKeys.Count)]];

            //If mutation is possible, mutate the agent
            if (agent.Genome.IsConnectionPossible(inNode, outNode))
            {
                int innovationNumber = mutationLog.GetConnectionInnovationNumber(inNode.ID, outNode.ID, connectionInnovationCounter);
                agent.Genome.AddConnectionMutation(inNode, outNode, innovationNumber);

                break;
            }
        }
    }
Beispiel #6
0
    public void MutateAgent_Connection_Test()
    {
        MutationLog mutationLog = new MutationLog();

        AgentObject customAgent = new CustomAgent(populationManager, parent2Genome, 10);

        Assert.AreEqual(6, customAgent.Genome.Nodes.Count);
        Assert.AreEqual(9, customAgent.Genome.Connections.Count);

        Dictionary <int, double> weights = new Dictionary <int, double>();

        foreach (int key in customAgent.Genome.Connections.Keys)
        {
            weights.Add(key, customAgent.Genome.Connections[key].Weight);
        }

        //Mutate connections, test multiple times, because there can be invalid connecionts
        for (int i = 0; i < 100; i++)
        {
            populationManager.MutateAgent(customAgent, 1f, 0f, 0f, nodeInnovationCounter, connectionInnovationCounter, mutationLog);

            //If a connection occurs, leave the loop
            if (customAgent.Genome.Connections.Count >= 10)
            {
                break;
            }
        }

        //Nodes should not have changed
        Assert.AreEqual(6, customAgent.Genome.Nodes.Count);
        Assert.AreEqual(11, nodeInnovationCounter.GetNewNumber());

        Assert.AreEqual(10, customAgent.Genome.Connections.Count);
        Assert.AreEqual(15, connectionInnovationCounter.GetNewNumber());

        //WEights should not have changed
        foreach (int key in weights.Keys)
        {
            Assert.AreEqual(weights[key], customAgent.Genome.Connections[key].Weight);
        }
    }
Beispiel #7
0
    public void AddNodeMutation(AgentObject agent, int amountTries, MutationLog mutationLog, GeneCounter connectionInnovationCounter, GeneCounter nodeCounter)
    {
        List <int> connectionKeys = agent.Genome.Connections.Keys.OrderBy(x => x).ToList();

        if (connectionKeys.Count <= 0)
        {
            return;
        }

        for (int i = 0; i < amountTries; i++)
        {
            ConnectionGene connection = null;
            //Check the size of the genome, if the genome is small, take an older gene
            if (agent.Genome.Nodes.Keys.Count <= _SIZE_THRESHOLD)
            {
                connection = agent.Genome.Connections[connectionKeys[Random.Range(0, Mathf.RoundToInt(connectionKeys.Count - (Mathf.Sqrt(connectionKeys.Count))))]];
            }
            else
            {
                //Select random connection
                connection = agent.Genome.Connections[connectionKeys[Random.Range(0, connectionKeys.Count)]];
            }

            //If mutation is possible, mutate the agent
            if (agent.Genome.IsNodePossible(connection))
            {
                //int nodeID = mutationLog.GetNodeID(connection.InnovationNumber, nodeCounter);
                int nodeID = mutationLog.GetNodeID(connection.InnovationNumber, agent.Genome.Nodes.Keys.ToList(), nodeCounter);

                int innovationNumberInToNewNode  = mutationLog.GetConnectionInnovationNumber(connection.InNode, nodeID, connectionInnovationCounter);
                int innovationNumberNewNodeToOut = mutationLog.GetConnectionInnovationNumber(nodeID, connection.OutNode, connectionInnovationCounter);

                agent.Genome.AddNodeMutation(connection, nodeID, innovationNumberInToNewNode, innovationNumberNewNodeToOut);
                break;
            }
        }
    }
Beispiel #8
0
    /// <summary>
    /// Mutate the given agent with different probabilities
    /// </summary>
    /// <param name="agent">The agent that should be mutated</param>
    /// <param name="addConnectionMutationChance">chance to add a connection. Should be between 0f and 1f</param>
    /// <param name="addNodeMutationChance">chance to add a node. Should be between 0f and 1f</param>
    /// <param name="mutationWeightChance">chance to mutate the weights. Should be between 0f and 1f</param>
    /// <param name="nodeInnovationCounter">a node innovation counter</param>
    /// <param name="connectionInnovationCounter">a connection innovation counter</param>
    public void MutateAgent(AgentObject agent,
                            float addConnectionMutationChance,
                            float addNodeMutationChance,
                            float mutationWeightChance,
                            GeneCounter nodeInnovationCounter, GeneCounter connectionInnovationCounter, MutationLog mutationLog)
    {
        //Mutate weights
        if (Random.Range(0f, 1f) <= mutationWeightChance)
        {
            agent.Genome.MutateConnectionWeight();
        }

        //Mutate Node
        if (Random.Range(0f, 1f) <= addNodeMutationChance)
        {
            AddNodeMutation(agent, _AMOUNT_MUTATION_TRIES, mutationLog, connectionInnovationCounter, nodeInnovationCounter);
        }

        //Mutate Connection
        if (Random.Range(0f, 1f) <= addConnectionMutationChance)
        {
            AddConnectionMutation(agent, _AMOUNT_MUTATION_TRIES, mutationLog, connectionInnovationCounter);
        }
    }