Esempio n. 1
0
        static QGraph SmartMutateQGraph(QGraph graph)
        {
            QGraph mutant = new QGraph(ref graph);

            mutant.edgeMutationChance          += mutant.mutationIncrement * (0.5f - UnityEngine.Random.value);
            mutant.actionMutationChance        += mutant.mutationIncrement * (0.5f - UnityEngine.Random.value);
            mutant.addNodeChance               += mutant.mutationIncrement * (0.5f - UnityEngine.Random.value);
            mutant.changeInterruptWeightChance += mutant.mutationIncrement * (0.5f - UnityEngine.Random.value);
            //			float mutationIncrement = 0.001f;
            //
            //			float edgeMutationChance = 0.1f;
            //			float actionMutationChance = 0.1f;
            //			float addNodeChance = 0.8f;
            //			float changeInterruptWeightChance = 0.01f;
            //mutate edges
            List <QGraphNode> t_nodes    = new List <QGraphNode> (mutant.nodes);
            float             n_c        = t_nodes.Count;
            float             numChanges = n_c;

            t_nodes = Utils.ShuffleList <QGraphNode> (t_nodes);
            float max_delta_reward = 0;
            float min_delta_reward = 0;

            //calculate max and min change in reward between two nodes
            for (int i = 0; i < n_c; ++i)
            {
                for (int j = 0; j < mutant.nodes [i].outgoingEdges.Count; ++j)
                {
                    float delta = (mutant.nodes [mutant.nodes [i].outgoingEdges [j].targetNode].Reward - mutant.nodes [i].Reward);
                    if (max_delta_reward < delta)
                    {
                        max_delta_reward = delta;
                    }
                    if (min_delta_reward > delta)
                    {
                        min_delta_reward = delta;
                    }
                }
            }
            for (int i = 0; i < numChanges; ++i)
            {
                for (int j = 0; j < mutant.nodes [i].outgoingEdges.Count; ++j)
                {
                    float mutationChance = (mutant.nodes [mutant.nodes [i].outgoingEdges [j].targetNode].Reward - mutant.nodes [i].Reward) / (max_delta_reward - min_delta_reward);
                    if (UnityEngine.Random.value > mutationChance * 0.8f)
                    {
                        mutant.nodes [i].outgoingEdges [j] = QGraphEdge.MutateEdge(mutant.nodes [i].outgoingEdges [j], mutant.possibleStates, mutant.mutationIncrement, mutant.stateConstraints);
                    }
                }
            }
            //mutate nodes
            //numChanges = mutant.nodes.Count * mutant.actionMutationChance;
            t_nodes = Utils.ShuffleList <QGraphNode> (t_nodes);
            for (int i = 0; i < numChanges; ++i)
            {
                int nodeToChange = UnityEngine.Random.Range(0, t_nodes.Count);
                t_nodes [nodeToChange] = QGraphNode.MutateNode(t_nodes [nodeToChange], mutant.possibleActions, mutant.actionConstraints);
            }
            //add nodes
            numChanges = mutant.nodes.Count * mutant.addNodeChance;
            t_nodes    = Utils.ShuffleList <QGraphNode> (t_nodes);
            if (numChanges < 1)
            {
                numChanges = 1f;
            }
            for (int i = 0; i < numChanges; ++i)
            {
                QGraphNode newNode = new QGraphNode(t_nodes [UnityEngine.Random.Range(0, t_nodes.Count - 1)]);
                newNode = QGraphNode.MutateNode(newNode, mutant.possibleActions, mutant.actionConstraints);
                int numNodesToConnectTo = (int)(n_c * mutant.numNodesToConnectToNewNode);
                if (numNodesToConnectTo < 1)
                {
                    numNodesToConnectTo = 1;
                }
                List <QGraphNode> nodesToRandomlyConnectToTemp = new List <QGraphNode> (mutant.nodes);
                nodesToRandomlyConnectToTemp = Utils.ShuffleList(nodesToRandomlyConnectToTemp);
                //connect nodes to the new node
                for (int j = 0; j < numNodesToConnectTo; ++j)
                {
                    QGraphEdge temp_edge = new QGraphEdge(mutant.nodes.Count);
                    if (mutant.possibleStates.Count > 0)
                    {
                        temp_edge.RequiredStates = new List <string> {
                            mutant.possibleStates [j % mutant.possibleStates.Count]
                        };
                    }
                    temp_edge.Float_restrictions = new List <float> (mutant.float_restriction_range.Count);
                    for (int k = 0; k < temp_edge.Float_restrictions.Count; ++k)
                    {
                        temp_edge.Float_restrictions.Add(UnityEngine.Random.Range(mutant.float_restriction_range [k].min, mutant.float_restriction_range [k].max));
                    }
                    temp_edge.Float_mult           = new List <float> (mutant.float_mult);
                    temp_edge.Comparison_operators = new List <ComparisonOperator> (mutant.comparison_operators);
                    nodesToRandomlyConnectToTemp [j].AddEdge(temp_edge);
                }
                numNodesToConnectTo = (int)(n_c * mutant.numNodesToConnectNewNodeTo);
                if (numNodesToConnectTo < 1)
                {
                    numNodesToConnectTo = 1;
                }
                //connect the new node to other nodes;
                nodesToRandomlyConnectToTemp = Utils.ShuffleList(nodesToRandomlyConnectToTemp);
                for (int j = 0; j < numNodesToConnectTo; ++j)
                {
                    QGraphEdge temp_edge = new QGraphEdge(mutant.nodes.IndexOf(nodesToRandomlyConnectToTemp [j]));
                    if (mutant.possibleStates.Count > 0)
                    {
                        temp_edge.RequiredStates = new List <string> {
                            mutant.possibleStates [j % mutant.possibleStates.Count]
                        };
                    }
                    temp_edge.Float_restrictions = new List <float> (mutant.float_restriction_range.Count);
                    for (int k = 0; k < temp_edge.Float_restrictions.Count; ++k)
                    {
                        temp_edge.Float_restrictions.Add(UnityEngine.Random.Range(mutant.float_restriction_range [k].min, mutant.float_restriction_range [k].max));
                    }
                    temp_edge.Float_mult           = new List <float> (mutant.float_mult);
                    temp_edge.Comparison_operators = new List <ComparisonOperator> (mutant.comparison_operators);
                    newNode.AddEdge(temp_edge);
                }
                mutant.nodes.Add(newNode);
            }
            mutant.ResetCurrentNodeToRoot();
            mutant.memoryWindow = new List <QGraphNode> (graph.memoryWindow.Count);
            mutant.windowSize   = graph.windowSize;
            mutant.windowIndex  = 0;
            mutant.memoryWindow.Add(mutant.currentNode);
            return(mutant);
        }