private static void SingleInput_WeightOne_Inner(
            IBlackBox <double> net,
            IActivationFunction <double> actFn)
        {
            // Activate and test.
            net.InputVector[0] = 0.0;
            for (int i = 0; i < 10; i++)
            {
                net.Activate();
                Assert.Equal(0.5, net.OutputVector[0]);
            }

            // Activate and test.
            net.InputVector[0] = 1.0;
            for (int i = 0; i < 10; i++)
            {
                net.Activate();
                Assert.Equal(actFn.Fn(1), net.OutputVector[0]);
            }

            // Activate and test.
            net.InputVector[0] = 10.0;
            for (int i = 0; i < 10; i++)
            {
                net.Activate();
                Assert.Equal(actFn.Fn(10), net.OutputVector[0]);
            }
        }
    private static void TwoInputs_WeightHalf_Inner(
        IBlackBox <double> net,
        IActivationFunction <double> actFn)
    {
        double x;
        var    inputs  = net.Inputs.Span;
        var    outputs = net.Outputs.Span;

        // Activate and test.
        inputs[0] = 0.0;
        inputs[1] = 0.0;
        net.Activate();
        Assert.Equal(0.5, outputs[0]);

        // Activate and test.
        inputs[0] = 1.0;
        inputs[1] = 2.0;
        net.Activate();
        x = 1.5; actFn.Fn(ref x);
        Assert.Equal(x, outputs[0]);

        // Activate and test.
        inputs[0] = 10.0;
        inputs[1] = 20.0;
        net.Activate();
        x = 15.0; actFn.Fn(ref x);
        Assert.Equal(x, outputs[0]);
    }
        private static void TwoInputs_WeightHalf_Inner(
            IBlackBox <double> net,
            IActivationFunction <double> actFn)
        {
            double x;

            // Activate and test.
            net.InputVector[0] = 0.0;
            net.InputVector[1] = 0.0;
            net.Activate();
            Assert.Equal(0.5, net.OutputVector[0]);

            // Activate and test.
            net.InputVector[0] = 1.0;
            net.InputVector[1] = 2.0;
            net.Activate();
            x = 1.5; actFn.Fn(ref x);
            Assert.Equal(x, net.OutputVector[0]);

            // Activate and test.
            net.InputVector[0] = 10.0;
            net.InputVector[1] = 20.0;
            net.Activate();
            x = 15.0; actFn.Fn(ref x);
            Assert.Equal(x, net.OutputVector[0]);
        }
    private static void ComplexCyclic_Inner(
        IBlackBox <double> net,
        IActivationFunction <double> actFn)
    {
        // Simulate network in C# and compare calculated outputs with actual network outputs.
        double[] preArr  = new double[3];
        double[] postArr = new double[3];
        var      inputs  = net.Inputs.Span;
        var      outputs = net.Outputs.Span;

        postArr[0] = 3.0;
        inputs[0]  = 3.0;

        for (int i = 0; i < 10; i++)
        {
            preArr[1] = postArr[0] * -2.0 + postArr[2];
            preArr[2] = postArr[0] + postArr[1];

            actFn.Fn(ref preArr[1], ref postArr[1]);
            actFn.Fn(ref preArr[2], ref postArr[2]);

            net.Activate();

            Assert.Equal(postArr[1], outputs[0]);
        }

        // Rest the network's internal state.
        net.Reset();
        Assert.Equal(0.0, outputs[0]);

        // Run the test again.
        Array.Clear(preArr, 0, preArr.Length);
        Array.Clear(postArr, 0, postArr.Length);

        postArr[0] = 3.0;
        inputs[0]  = 3.0;

        for (int i = 0; i < 10; i++)
        {
            preArr[1] = postArr[0] * -2.0 + postArr[2];
            preArr[2] = postArr[0] + postArr[1];

            actFn.Fn(ref preArr[1], ref postArr[1]);
            actFn.Fn(ref preArr[2], ref postArr[2]);

            net.Activate();

            Assert.Equal(postArr[1], outputs[0]);
        }
    }
示例#5
0
        /// <summary>
        /// Evaluate the provided IBlackBox against the MNIST problem domain and return its fitness/novlety score.
        /// </summary>
        public FitnessInfo Evaluate(IBlackBox box)
        {
            //just keep track of evals
            //_evalCount++;

            double fitness, altFitness;

            //these are our inputs and outputs
            ISignalArray inputArr  = box.InputSignalArray;
            ISignalArray outputArr = box.OutputSignalArray;

            List <Sample> sampleList  = LEEAParams.DOMAIN.getSamples();
            int           sampleCount = sampleList.Count;

            fitness = sampleList.Count;

            foreach (Sample sample in sampleList)
            {
                inputArr.CopyFrom(sample.Inputs, 0);
                box.ResetState();
                box.Activate();

                fitness -= Math.Abs(outputArr[0] - sample.Outputs[0]) * Math.Abs(outputArr[0] - sample.Outputs[0]);
            }

            // set alternate fitness to fitness measured against all samples
            if (SharedParams.SharedParams.PERFORMFULLEVAL)
            {
                sampleList = LEEAParams.DOMAIN.getValidationSamples();
                altFitness = sampleList.Count;

                foreach (Sample sample in sampleList)
                {
                    inputArr.CopyFrom(sample.Inputs, 0);
                    box.ResetState();
                    box.Activate();

                    altFitness -= Math.Abs(outputArr[0] - sample.Outputs[0]) * Math.Abs(outputArr[0] - sample.Outputs[0]);
                }
            }
            else
            {
                altFitness = 0;
            }

            fitness = Math.Max(fitness, LEEAParams.MINFITNESS) + LEEAParams.FITNESSBASE;
            return(new FitnessInfo(fitness, altFitness));
        }
示例#6
0
    // Update is called once per frame
    void FixedUpdate()
    {
        /*
         * //Calculate Y Range:
         * float yWidth = 4.5f;
         * float yStart = -4.5f;
         *
         * //XRange
         * float xWidth = 9;
         * float xStart = -9;
         *
         * var tempPos = ball.transform.localPosition;
         * inputSignals[0] = (tempPos.x) / xWidth;
         * inputSignals[1] = (tempPos.y) / yWidth;
         * // Debug.Log(inputSignals[0]);
         * tempPos = transform.localPosition;
         * inputSignals[2] = (tempPos.x) / xWidth;
         * inputSignals[3] = (tempPos.y) / yWidth;
         *
         * tempPos = opponent.transform.localPosition;
         * inputSignals[4] = (tempPos.x) / xWidth;
         * inputSignals[5] = (tempPos.y) / yWidth;
         *
         * //tempPos = ball.velocity.normalized;
         * //inputSignals[6] = tempPos.x;
         * //inputSignals[7] = tempPos.y;
         * brain.InputSignalArray.CopyFrom(inputSignals, 0);*/

        OriginalInputs();
        brain.Activate();
        OriginalInputs();
        brain.Activate();

        float xDirection = Mathf.Clamp((float)(brain.OutputSignalArray[0] - 0.5) * 2, -1, 1);
        float yDirection = Mathf.Clamp((float)(brain.OutputSignalArray[1] - 0.5) * 2, -1, 1);

        if (Mathf.Abs(xDirection) < 0.2f)
        {
            xDirection = 0;
        }
        if (Mathf.Abs(yDirection) < 0.2f)
        {
            yDirection = 0;
        }
        Vector2 targetTranslation = (Vector2)(parent.transform.localToWorldMatrix * new Vector3(xDirection, yDirection));

        rb.velocity = ((targetTranslation * MaxMovementSpeed));
    }
        private double[] activate(IBlackBox box, IList <double> inputs, double[] outputs)
        {
            box.ResetState();

            // Give inputs to the network
            var nodeId = 0;

            foreach (var input in inputs)
            {
                box.InputSignalArray[nodeId++] = input;
            }

            // Activate the network and get outputs back
            box.Activate();
            box.OutputSignalArray.CopyTo(outputs, 0);

            // Normalize outputs when using NEAT
            if (phenotype == Phenotype.Neat)
            {
                NormalizeOutputs(outputs);
            }
            else
            {
                Debug.Assert(outputs.All(x => x >= 0.0 && x <= 1.0));
            }

            return(outputs);
        }
示例#8
0
        public FitnessInfo Test(IBlackBox box)
        {
            double fitness, altFitness;

            //these are our inputs and outputs
            ISignalArray inputArr  = box.InputSignalArray;
            ISignalArray outputArr = box.OutputSignalArray;

            List <Sample> sampleList  = LEEAParams.DOMAIN.getTestSamples();
            int           sampleCount = sampleList.Count;

            fitness = sampleList.Count;

            foreach (Sample sample in sampleList)
            {
                inputArr.CopyFrom(sample.Inputs, 0);
                box.ResetState();
                box.Activate();

                fitness -= Math.Abs(outputArr[0] - sample.Outputs[0]) * Math.Abs(outputArr[0] - sample.Outputs[0]);
            }

            fitness = Math.Max(fitness, LEEAParams.MINFITNESS) + LEEAParams.FITNESSBASE;
            return(new FitnessInfo(fitness, 0));
        }
        /// <summary>
        /// Perform one simulation timestep; provide inputs to the neural net, activate it, read its outputs and assign them to the
        /// relevant motors (leg joints).
        /// </summary>
        public override void Step()
        {
            //---- Feed input signals into black box.
            // Torso state.
            _box.InputSignalArray[0] = _iface.TorsoPosition.Y;  // Torso Y pos.
            _box.InputSignalArray[1] = _iface.TorsoAngle;
            _box.InputSignalArray[2] = _iface.TorsoVelocity.X;
            _box.InputSignalArray[3] = _iface.TorsoVelocity.Y;

            // Left leg state.
            _box.InputSignalArray[4] = _iface.LeftLegIFace.HipJointAngle;
            _box.InputSignalArray[5] = _iface.LeftLegIFace.KneeJointAngle;

            // Right leg state.
            _box.InputSignalArray[6] = _iface.RightLegIFace.HipJointAngle;
            _box.InputSignalArray[7] = _iface.RightLegIFace.KneeJointAngle;

            // Sine wave inputs (one is a 180 degree phase shift of the other).
            double sinWave0   = (Math.Sin(_timestep * _sineWaveIncr) + 1.0) * 0.5;
            double sinWave180 = (Math.Sin((_timestep + 30) * _sineWaveIncr) + 1.0) * 0.5;

            _box.InputSignalArray[8] = sinWave0;
            _box.InputSignalArray[9] = sinWave180;
            _timestep++;

            //---- Activate black box.
            _box.Activate();

            //---- Read joint torque outputs (proportion of max torque).
            // Here we assume neuron activation function with output range [0,1].
            _iface.LeftLegIFace.SetHipJointTorque((float)((_box.OutputSignalArray[0] - 0.5) * 2.0) * _iface.JointMaxTorque);
            _iface.RightLegIFace.SetHipJointTorque((float)((_box.OutputSignalArray[1] - 0.5) * 2.0) * _iface.JointMaxTorque);
            _iface.LeftLegIFace.SetKneeJointTorque((float)((_box.OutputSignalArray[2] - 0.5) * 2.0) * _iface.JointMaxTorque);
            _iface.RightLegIFace.SetKneeJointTorque((float)((_box.OutputSignalArray[3] - 0.5) * 2.0) * _iface.JointMaxTorque);
        }
示例#10
0
        /// <summary>
        /// Refresh/update the view with the provided genome.
        /// </summary>
        public override void RefreshView(object genome)
        {
            NeatGenome neatGenome = genome as NeatGenome;

            if (null == neatGenome)
            {
                return;
            }

            // Decode genome.
            IBlackBox box = _genomeDecoder.Decode(neatGenome);

            // Probe the black box.
            _blackBoxProbe.Probe(box, _yArrTarget);

            // Update plot points.
            double[] xArr = _paramSamplingInfo._xArr;
            for (int i = 0; i < xArr.Length; i++)
            {
                if (!_generativeMode)
                {
                    box.ResetState();
                    box.InputSignalArray[0] = xArr[i];
                }
                box.Activate();
                _plotPointListResponse[i].Y = _yArrTarget[i];
            }

            // Trigger graph to redraw.
            zed.AxisChange();
            Refresh();
        }
示例#11
0
    /// <summary>
    /// Probe the given black box, and record the responses in <paramref name="responseArr"/>.
    /// </summary>
    /// <param name="box">The black box to probe.</param>
    /// <param name="responseArr">Response array.</param>
    public void Probe(IBlackBox <double> box, double[] responseArr)
    {
        Debug.Assert(responseArr.Length == _sampleCount);

        // Reset black box internal state.
        box.Reset();

        // Get the blackbox input and output spans.
        var inputs  = box.Inputs.Span;
        var outputs = box.Outputs.Span;

        // Take the required number of samples.
        for (int i = 0; i < _sampleCount; i++)
        {
            // Set bias input.
            inputs[0] = 1.0;

            // Activate the black box.
            box.Activate();

            // Get the black box's output value.
            // TODO: Review this scheme. This replicates the behaviour in SharpNEAT 2.x but not sure if it's ideal,
            // for one it depends on the output range of the neural net activation function in use.
            double output = outputs[0];
            Clip(ref output);
            responseArr[i] = ((output - 0.5) * _scale) + _offset;
        }
    }
        private double[] activate(IBlackBox box, IEnumerable <double> inputs, double[] outputs)
        {
            box.ResetState();

            // Give inputs to the network
            var nodeId = 0;

            foreach (var input in inputs)
            {
                box.InputSignalArray[nodeId++] = input;
            }

            // Activate the network and get outputs back
            box.Activate();
            box.OutputSignalArray.CopyTo(outputs, 0);

            // Normalize outputs when using NEAT
            if (phenotype == Phenotype.Neat)
            {
                for (var i = 0; i < outputs.Count(); i++)
                {
                    outputs[i] = (outputs[i] + 1.0) / 2.0;
                }
            }
            return(outputs);
        }
示例#13
0
    void FixedUpdate()
    {
        if (isRunning)
        {
            // Set up inputs as array and feed it to the network
            ISignalArray inputArr = neat.InputSignalArray;

            double x = NormalizeValues(max, min, transform.position.x);
            double z = NormalizeValues(max, min, transform.position.z);
            inputArr[0] = x;
            inputArr[1] = z;

            neat.Activate();

            // Get outputs
            //TODO: Make outputs be able to have negative values as well
            ISignalArray outputArr = neat.OutputSignalArray;
            outputArr[0] = (outputArr[0] < 0.5f) ? outputArr[0] * -1 : outputArr[0];
            outputArr[1] = (outputArr[1] < 0.5f) ? outputArr[0] * -1 : outputArr[1];

            float outputX = (float)outputArr[0] * 10.0f;
            float outputZ = (float)outputArr[1] * 10.0f;
            rb.AddForce(new Vector3(outputX, 0.0f, outputZ));

            //DebugNetwork(inputArr, outputArr);
        }
    }
示例#14
0
    private void FixedUpdate()
    {
        if (IsRunning)
        {
            target  = GameObject.FindGameObjectWithTag("Target");
            targetx = target.transform.position.x;
            targety = target.transform.position.y;

            // initialize input and output signal arrays
            ISignalArray inputArr  = box.InputSignalArray;
            ISignalArray outputArr = box.OutputSignalArray;

            inputArr[0] = target.transform.position.x;
            inputArr[1] = target.transform.position.y;
            inputArr[3] = fitness;



            if (b == false)
            {
                box.Activate();
                force.x = (float)outputArr[0] * 2000;
                force.y = (float)outputArr[1] * 2000;
                //Rotate(angle);
                Shoot(force);
                b = true;
            }
            distance = GetDistance();

            if (distance > 0)
            {//cannot divide by zero and cannot be closer to something than 0
                AddFitness(Mathf.Abs(1 / distance));
            }
        }
    }
    private void FixedUpdate()
    {
        if (isRunning)
        {
            // Pass sensor inputs to neural network
            ISignalArray inputArr = box.InputSignalArray;
            int          i        = 0;
            foreach (SectorSensor sectorSensor in sectorSensors)
            {
                for (int j = 0; j < sectorSensor.NumSenses; ++j)
                {
                    inputArr[i] = sectorSensor.GetSectorSense(j);
                    ++i;
                }
            }

            foreach (DistanceSensor distanceSensor in distanceSensors)
            {
                for (int j = 0; j < distanceSensor.numSensors; ++j)
                {
                    inputArr[i] = distanceSensor.GetSense(j);
                    ++i;
                }
            }

            if (attributes.needsFood)
            {
                // Response high at low energy
                inputArr[i] = 1 - attributes.Energy / attributes.maxEnergy;
                ++i;
            }

            if (attributes.needsWater)
            {
                // Response high at low hydration
                inputArr[i] = 1 - attributes.Hydration / attributes.maxHydration;
                ++i;
            }

            if (movementController.senseSpeed)
            {
                inputArr[i] = rb.velocity.magnitude / movementController.moveSpeed;
                ++i;
            }

            if (movementController.senseSwimming)
            {
                inputArr[i] = movementController.IsSwimming ? 1 : 0;
                ++i;
            }

            // Activate neural network
            box.Activate();

            // Read outputs from neural network into movement input.
            ISignalArray outputArr = box.OutputSignalArray;
            xInput = (float)outputArr[0] * 2 - 1;
            yInput = (float)outputArr[1] * 2 - 1;
        }
    }
        private static void HiddenNode_Inner(
            IBlackBox <double> net,
            IActivationFunction <double> actFn)
        {
            // Activate and test.
            net.InputVector[0] = 0.0;
            net.InputVector[1] = 0.0;
            net.Activate();
            Assert.AreEqual(actFn.Fn(1.0), net.OutputVector[0]);

            // Activate and test.
            net.InputVector[0] = 0.5;
            net.InputVector[1] = 0.25;
            net.Activate();
            Assert.AreEqual(actFn.Fn(actFn.Fn(0.375) * 2.0), net.OutputVector[0]);
        }
示例#17
0
        /// <summary>
        /// Refresh/update the view with the provided genome.
        /// </summary>
        public override void RefreshView(object genome)
        {
            NeatGenome neatGenome = genome as NeatGenome;

            if (null == neatGenome)
            {
                return;
            }

            // Decode genome.
            IBlackBox box = _genomeDecoder.Decode(neatGenome);

            // Update plot points.
            double x = _xMin;

            for (int i = 0; i < _sampleCount; i++, x += _xIncr)
            {
                box.ResetState();
                box.InputSignalArray[0] = x;
                box.Activate();
                _plotPointListResponse[i].Y = box.OutputSignalArray[0];
            }

            // Trigger graph to redraw.
            zed.AxisChange();
            Refresh();
        }
示例#18
0
    public double[] GetChampOutput(int nodeDepth, int nodeSiblingNum, int maxDepth, int maxBranching)
    {
        IGenomeDecoder <NeatGenome, IBlackBox> decoder = experiment.CreateGenomeDecoder();
        IBlackBox box = decoder.Decode(contentEA.CurrentChampGenome);

        // Normalize nodeDepth and nodeSiblingNum to range of 0-1. This may affect outputs?
        double normDepth = (double)nodeDepth / (double)maxDepth;
        double normSib;

        if (nodeDepth == 0)
        {
            normSib = 0;             // Only one node at depth 0, prevent a divide by 0 error
        }
        else
        {
            normSib = (double)nodeSiblingNum / (double)(Mathf.Pow(maxBranching, nodeDepth) - 1);
        }

        box.InputSignalArray[0] = normDepth;
        box.InputSignalArray[1] = normSib;

        box.ResetState();
        box.Activate();

        //Debug.Log("(" + normDepth + "," + normSib + ") -> (" + box.OutputSignalArray[0] + "," + box.OutputSignalArray[1] + "," + box.OutputSignalArray[2] + ","
        //+ box.OutputSignalArray[3] + "," + box.OutputSignalArray[4] + "," + box.OutputSignalArray[5] + ")");
        double[] outputs = new double[box.OutputCount];
        for (int i = 0; i < box.OutputCount; i++)
        {
            outputs[i] = box.OutputSignalArray[i];
        }

        return(outputs);
    }
示例#19
0
    private void FixedUpdate()
    {
        if (IsRunning)
        {
            // initialize input and output signal arrays
            ISignalArray inputArr  = box.InputSignalArray;
            ISignalArray outputArr = box.OutputSignalArray;

            inputArr[0] = red;
            inputArr[1] = green;
            inputArr[2] = blue;
            inputArr[3] = fitness;

            distance = Mathf.Sqrt((red - t_red) * (red - t_red) + (green - t_green) * (green - t_green) + (blue - t_blue) * (blue - t_blue));

            box.Activate();

            red   = (float)outputArr[0];
            green = (float)outputArr[1];
            blue  = (float)outputArr[2];

            if (distance > 0)
            {//cannot divide by zero and cannot be closer to something than 0
                AddFitness(Mathf.Abs(1 / distance));
            }
            ChangeColor(red, green, blue);
        }
    }
        public override IPDGame.Choices Choice(IPDGame game)
        {
            if (game.T == 0)
            {
                return(FIRST_CHOICE);
            }

            int i = 0;

            for (int k = 1; k <= _phenome.InputSignalArray.Length / 2; k++)
            {
                IPDGame.Past p = game.GetPast(this, game.T - k);
                //My choice (0 == C, 1 == D)
                _phenome.InputSignalArray[i++] = (p == IPDGame.Past.R || p == IPDGame.Past.S) ? 0 : 1;
                //Opponent choice
                _phenome.InputSignalArray[i++] = (p == IPDGame.Past.T || p == IPDGame.Past.R) ? 0 : 1;
            }

            _phenome.Activate();
            if (!_phenome.IsStateValid)
            {   // Any black box that gets itself into an invalid state is unlikely to be
                // any good, so lets just bail out here.
                return(IPDGame.Choices.R);
            }

            return((_phenome.OutputSignalArray[0] > _phenome.OutputSignalArray[1]) ? IPDGame.Choices.C : IPDGame.Choices.D);
        }
示例#21
0
        public override void Step()
        {
            //---- Feed input signals into black box.
            // Torso state.
            _box.InputSignalArray[0] = _iface.TorsoPosition.Y;  // Torso Y pos.
            _box.InputSignalArray[1] = _iface.TorsoAngle;
            _box.InputSignalArray[2] = _iface.TorsoAnglularVelocity;
            _box.InputSignalArray[3] = _iface.TorsoVelocity.X;
            _box.InputSignalArray[4] = _iface.TorsoVelocity.Y;

            // Left leg state.
            _box.InputSignalArray[5] = _iface.LeftLegIFace.HipJointAngle;
            _box.InputSignalArray[6] = _iface.LeftLegIFace.HipJointVelocity;
            _box.InputSignalArray[7] = _iface.LeftLegIFace.KneeJointAngle;
            _box.InputSignalArray[8] = _iface.LeftLegIFace.KneeJointVelocity;

            // Right leg state.
            _box.InputSignalArray[9]  = _iface.RightLegIFace.HipJointAngle;
            _box.InputSignalArray[10] = _iface.RightLegIFace.HipJointVelocity;
            _box.InputSignalArray[11] = _iface.RightLegIFace.KneeJointAngle;
            _box.InputSignalArray[12] = _iface.RightLegIFace.KneeJointVelocity;

            //---- Activate black box.
            _box.Activate();

            //---- Read joint torque outputs (proportion of max torque).
            // Here we assume neuron activation function with output range [0,1].
            _iface.LeftLegIFace.SetHipJointTorque((float)((_box.OutputSignalArray[0] - 0.5) * 2.0) * _iface.JointMaxTorque);
            _iface.RightLegIFace.SetHipJointTorque((float)((_box.OutputSignalArray[1] - 0.5) * 2.0) * _iface.JointMaxTorque);
            _iface.LeftLegIFace.SetKneeJointTorque((float)((_box.OutputSignalArray[2] - 0.5) * 2.0) * _iface.JointMaxTorque);
            _iface.RightLegIFace.SetKneeJointTorque((float)((_box.OutputSignalArray[3] - 0.5) * 2.0) * _iface.JointMaxTorque);
        }
        /// <summary>
        /// Probe the given black box, and record the responses in <paramref name="responseArr"/>
        /// </summary>
        /// <param name="box">The black box to probe.</param>
        /// <param name="responseArr">Response array.</param>
        public void Probe(IBlackBox <double> box, double[] responseArr)
        {
            Debug.Assert(responseArr.Length == _paramSamplingInfo.SampleResolution);

            double[] xArr = _paramSamplingInfo.XArrNetwork;
            for (int i = 0; i < xArr.Length; i++)
            {
                // Reset black box internal state.
                box.ResetState();

                // Set bias input, and function input value.
                box.InputVector[0] = 1.0;
                box.InputVector[1] = xArr[i];

                // Activate the black box.
                box.Activate();

                // Get the black box's output value.
                // TODO: Review this scheme. This replicates the behaviour in SharpNEAT 2.x but not sure if it's ideal,
                // for one it depends on the output range of the neural net activation function in use.
                double output = box.OutputVector[0];
                Clip(ref output);
                responseArr[i] = ((output - 0.5) * _scale) + _offset;
            }
        }
示例#23
0
        /// <summary>
        /// Run a single cart-pole simulation/trial on the given black box, and with the given initial model state.
        /// </summary>
        /// <param name="box">The black box (neural net) to evaluate.</param>
        /// <param name="cartPos">Cart position on the track.</param>
        /// <param name="poleAngle1">Pole 1 angle in radians.</param>
        /// <param name="poleAngle2">Pole 2 angle in radians.</param>
        /// <returns>Fitness score.</returns>
        public float RunTrial(
            IBlackBox <double> box,
            float cartPos,
            float poleAngle1,
            float poleAngle2)
        {
            // Reset black box state.
            box.ResetState();

            // Reset model state.
            _physics.ResetState(cartPos, poleAngle1, poleAngle2);

            // Get a local variable ref to the internal model state array.
            float[] state = _physics.State;

            // Run the cart-pole simulation.
            int timestep = 0;

            for (; timestep < _maxTimesteps; timestep++)
            {
                // Provide model state to the black box inputs (normalised to +-1.0).
                box.InputVector[0] = 1.0;                                     // Bias input.
                box.InputVector[1] = state[0] * __TrackLengthHalf_Reciprocal; // Cart X position range is +-__TrackLengthHalf; here we normalize to [-1,1].
                box.InputVector[2] = state[1];                                // Cart velocity. Typical range is approx. +-10.
                box.InputVector[3] = state[2] * __MaxPoleAngle_Reciprocal;    // Pole 1 angle. Range is +-__MaxPoleAngle radians; here we normalize to [-1,1].
                box.InputVector[4] = state[3] * 0.2;                          // Pole 1 angular velocity. Typical range is approx. +-5.
                box.InputVector[5] = state[4] * __MaxPoleAngle_Reciprocal;    // Pole 2 angle.
                box.InputVector[6] = state[5] * 0.2;                          // Pole 2 angular velocity.

                // Activate the network.
                box.Activate();

                // Read the output to determine the force to be applied to the cart by the controller.
                float force = (float)(box.OutputVector[0] - 0.5) * 2f;
                ClipForce(ref force);
                force *= __MaxForce;

                // Update model state, i.e. move the model forward by one timestep.
                _physics.Update(force);

                // Check for failure state. I.e. has the cart run off the ends of the track, or has either of the pole
                // angles exceeded the defined threshold.
                if (MathF.Abs(state[0]) > __TrackLengthHalf || MathF.Abs(state[2]) > __MaxPoleAngle || MathF.Abs(state[4]) > __MaxPoleAngle)
                {
                    break;
                }
            }

            // Fitness is given by the combination of two fitness components:
            // 1) Amount of simulation time that elapsed before the pole angle and/or cart position threshold was exceeded. Max score is 99 if the
            //    end of the trial is reached without exceeding any thresholds.
            // 2) Cart position component. Max fitness of 1.0 for a cart position of zero (i.e. the cart is in the middle of the track range);
            //
            // Therefore the maximum possible fitness is 100.0.
            float fitness =
                (timestep * _maxTimesteps_Reciprocal * 99f)
                + (1f - (MathF.Min(MathF.Abs(state[0]), __TrackLengthHalf) * __TrackLengthHalf_Reciprocal));

            return(fitness);
        }
示例#24
0
        public void Step()
        {
            phenome.ResetState();

            foreach (int typeID in NeatConsts.typeIds)
            {
                for (int y = 0; y < NeatConsts.ViewY; y++)
                {
                    for (int x = 0; x < NeatConsts.ViewX; x++)
                    {
                        var xpos  = game.player.position.x + x;
                        var ypos  = game.player.position.y + (NeatConsts.ViewY / 2) - y;
                        var index = typeID * (y * NeatConsts.ViewX + x);
                        if (ypos < 0 || xpos < 0 || ypos >= game.map.map.GetLength(0) || xpos >= game.map.map.GetLength(1))
                        {
                            phenome.InputSignalArray[index] = 0;
                        }
                        else
                        {
                            phenome.InputSignalArray[index] = (game.map.map[ypos, xpos]) == typeID ? 1 : 0;
                        }
                    }
                }
            }


            phenome.Activate();
            game.Step(phenome.OutputSignalArray[0] > 0.5);
        }
示例#25
0
    float ProcessInputPair(Renderer quadrant)
    {
        float output = 0f;

        //Input signals are used in the neural controller
        ISignalArray inputArr = box.InputSignalArray;

        inputArr[0] = input_1;
        inputArr[1] = input_2;
        //The neural network is activated
        box.Activate();
        //And produces output signals (also in an array)
        ISignalArray outputArr = box.OutputSignalArray;

        //Output is between 0 and 1
        output = (float)outputArr[0];

/*		ISignalArray inputArr = box.InputSignalArray;
 *              inputArr[0] = 0.88f;
 *              inputArr[1] = 0.99f;
 *              //inputArr[0] = input_1;
 *              //inputArr[1] = input_2;
 *              //The neural network is activated
 *              box.Activate();
 *              //And produces output signals (also in an array)
 *              ISignalArray outputArr = box.OutputSignalArray;
 *              //Output is between 0 and 1
 *              output = (float)outputArr[0];
 *              Debug.Log(" ");
 *              Debug.Log("Input array: " + inputArr[0] + " " + inputArr[1]);
 *              Debug.Log("Output: " + output);
 *              UnityEditor.EditorApplication.isPlaying = false;*/

        return(output);
    }
示例#26
0
        private void RedrawGraph(NeatGenome genome)
        {
            IBlackBox box = _experiment.GetBlackBox(genome);

            Color trueColor  = panPlot.TrueColor;
            Color falseColor = panPlot.FalseColor;

            var samples = Enumerable.Range(0, 1000).
                          Select(o =>
            {
                Vector3D pos = Math3D.GetRandomVector(new Vector3D(0, 0, 0), new Vector3D(1, 1, 1));

                box.ResetState();

                //box.InputSignalArray.CopyFrom()
                box.InputSignalArray[0] = pos.X;
                box.InputSignalArray[1] = pos.Y;
                box.InputSignalArray[2] = pos.Z;

                box.Activate();

                double percent = box.OutputSignalArray[0];

                Color color = UtilityWPF.AlphaBlend(trueColor, falseColor, percent);

                return(Tuple.Create(pos.ToPoint(), color));
            });

            panPlot.ClearFrame();
            panPlot.AddDots(samples, .01, false);
        }
        /// <summary>
        /// Invoke any required control logic in the Box2D world.
        /// </summary>
        protected override void InvokeController()
        {
            // Provide state info to the black box inputs.
            InvertedDoublePendulumWorld simWorld = (InvertedDoublePendulumWorld)_simWorld;
            // _box is updated by other threads so copy the reference so that we know we are workign with the same IBlackBox within this method.
            IBlackBox box = _box;

            box.InputSignalArray[0] = simWorld.CartPosX / __TrackLengthHalf;     // CartPosX range is +-trackLengthHalf. Here we normalize it to [-1,1].
            box.InputSignalArray[1] = simWorld.CartVelocityX;                    // Cart track velocity x is typically +-0.75.

            box.InputSignalArray[2] = simWorld.CartJointAngle / __TwelveDegrees; // Rescale angle to match range of values during balancing.
            box.InputSignalArray[3] = simWorld.CartJointAngularVelocity;         // Pole angular velocity is typically +-1.0 radians. No scaling required.

            box.InputSignalArray[4] = simWorld.ElbowJointAngle / __TwelveDegrees;
            box.InputSignalArray[5] = simWorld.ElbowJointAngularVelocity;

            // Activate the network.
            box.Activate();

            // Read the network's force signal output.
            // FIXME: Force mag should be configurable somewhere.
            float force = (float)(box.OutputSignalArray[0] - 0.5f) * __MaxForceNewtonsX2;

            simWorld.SetCartForce(force);
        }
        void ObservationsToCommands(JsonObservations observations)
        {
            xPos = observations.XPos;
            zPos = observations.ZPos;
            try
            {
                UpdateTilesInfo(observations);
            }
            catch (IndexOutOfRangeException e)
            {
                System.Diagnostics.Debug.WriteLine(e.Message);
                return;
            }

            /*
             * System.Diagnostics.Debug.WriteLine("Far ahead: " + neighbourTiles.Level0.farAhead +
             *  ". Ahead: " + neighbourTiles.Level0.ahead +
             *  ". Far left: " + neighbourTiles.Level0.farLeft +
             *  ". Left: " + neighbourTiles.Level0.left +
             *  ". Right: " + neighbourTiles.Level0.right +
             *  ". Far right: " + neighbourTiles.Level0.farRight +
             *  ". Back: " + neighbourTiles.Level0.back +
             *  ". Far back: " + neighbourTiles.Level0.farBack);*/
            if (IsGoalMet())
            {
                return;
            }
            ObservationsToBrainInputs();
            brain.Activate();
            OutputsToCommands();
        }
示例#29
0
        /// <summary>
        /// Determine the agent's position in the world relative to the prey and walls, and set its sensor inputs accordingly.
        /// </summary>
        /// <param name="agent"></param>
        public void SetAgentInputsAndActivate(IBlackBox agent)
        {
            // Calc prey's position relative to the agent (in polar coordinate system).
            PolarPoint relPos = CartesianToPolar(_preyPos - _agentPos);

            // Determine agent sensor input values.
            // Reset all inputs.
            agent.InputSignalArray.Reset();

            // Test if prey is in sensor range.
            if (relPos.RadialSquared <= _sensorRangeSquared)
            {
                // Determine which sensor segment the prey is within - [0,7]. There are eight segments and they are tilted 22.5 degrees (half a segment)
                // such that due North, East South and West are each in the centre of a sensor segment (rather than on a segment boundary).
                double thetaAdjusted = relPos.Theta - PiDiv8;
                if (thetaAdjusted < 0.0)
                {
                    thetaAdjusted += 2.0 * Math.PI;
                }
                int segmentIdx = (int)Math.Floor(thetaAdjusted / PiDiv4);

                // Set sensor segment's input.
                agent.InputSignalArray[segmentIdx] = 1.0;
            }

            // Prey closeness detector.
            agent.InputSignalArray[8] = relPos.RadialSquared <= 4.0 ? 1.0 : 0.0;

            // Wall detectors - N,E,S,W.
            // North.
            int d = (_gridSize - 1) - _agentPos._y;

            if (d <= 4)
            {
                agent.InputSignalArray[9] = (4 - d) / 4.0;
            }

            // East.
            d = (_gridSize - 1) - _agentPos._x;
            if (d <= 4)
            {
                agent.InputSignalArray[10] = (4 - d) / 4.0;
            }

            // South.
            if (_agentPos._y <= 4)
            {
                agent.InputSignalArray[11] = (4 - _agentPos._y) / 4.0;
            }

            // West.
            if (_agentPos._x <= 4)
            {
                agent.InputSignalArray[12] = (4 - _agentPos._x) / 4.0;
            }

            // Activate agent.
            agent.Activate();
        }
示例#30
0
    void FixedUpdate()
    {
        if (IsRunning)
        {
            // input array assained to constant because without it output is constantly 0.5f
            ISignalArray inputArr = box.InputSignalArray;

            for (var i = 0; i < 21; i++)
            {
                inputArr[i] = 0.5f;
            }

            box.Activate();

            ISignalArray outputArr = box.OutputSignalArray;

            JointCount = (int)Mathf.Round((float)outputArr[0] * 5 + 1);

            /*
             * string tests = "";
             * for(var i = 0; i < 21; i++)
             * {
             *  tests += i + ": " + (float)outputArr[i] + " ";
             * }
             * Debug.Log(tests);
             */

            for (int i = 0; i < JointCount; i++) // spawning joints
            {
                // get joint position
                float   JointPositionX = Mathf.Cos(i * 2f * Mathf.PI / JointCount);
                float   JointPositionY = Mathf.Sin(i * 2f * Mathf.PI / JointCount);
                Vector3 JointPosition  = new Vector3(JointPositionX, JointPositionY, 0f);

                // get joint rotation
                float      JointRotationZ = 90f + i * (360 / JointCount);
                Quaternion JointRotation  = Quaternion.Euler(new Vector3(transform.rotation.x, transform.rotation.y, JointRotationZ));

                //create joint
                GameObject obj = Instantiate(JointPrefab, JointPosition, JointRotation, transform);

                //change joint scale
                obj.transform.localScale = new Vector3(transform.localScale.x, transform.localScale.y + (float)outputArr[i + 1], transform.localScale.z);

                //fix position based on scale
                float newObjPositionX = obj.transform.position.x + Mathf.Cos(i * 2f * Mathf.PI / JointCount) * obj.transform.localScale.y / 3;
                float newObjPositionY = obj.transform.position.y + Mathf.Sin(i * 2f * Mathf.PI / JointCount) * obj.transform.localScale.y / 3;
                obj.transform.position = new Vector3(newObjPositionX, newObjPositionY, obj.transform.position.z);

                //send wheel radius to joint
                obj.GetComponent <JointScript>().SetWheelRadius((float)outputArr[i + 11]);

                SetupHingeJointComponent(obj);
            }

            Stop();
        }
    }
        /// <summary>
        /// Evaluate the provided IBlackBox.
        /// </summary>
        public override FitnessInfo Evaluate(IBlackBox box)
        {
            _evalCount++;

		    // [0] - Cart Position (meters).
		    // [1] - Cart velocity (m/s).
		    // [2] - Pole 1 angle (radians)
		    // [3] - Pole 1 angular velocity (radians/sec).
		    // [4] - Pole 2 angle (radians)
		    // [5] - Pole 2 angular velocity (radians/sec).
            double[] state = new double[6];
            state[2] = FourDegrees;
            
			// Run the pole-balancing simulation.
            int timestep = 0;
			for(; timestep < _maxTimesteps; timestep++)
			{
				// Provide state info to the network (normalised to +-1.0).
				// Markovian (With velocity info)
                box.InputSignalArray[0] = state[0] / _trackLengthHalf;  // Cart Position is +-trackLengthHalfed
                box.InputSignalArray[1] = state[2] / ThirtySixDegrees;  // Pole Angle is +-thirtysix_degrees. Values outside of this range stop the simulation.
                box.InputSignalArray[2] = state[4] / ThirtySixDegrees;  // Pole Angle is +-thirtysix_degrees. Values outside of this range stop the simulation.

				// Activate the black box.
                box.Activate();

                // Get black box response and calc next timestep state.
				performAction(state, box.OutputSignalArray[0]);
		
				// Check for failure state. Has the cart run off the ends of the track or has the pole
				// angle gone beyond the threshold.
				if(     (state[0]< -_trackLengthHalf) || (state[0]> _trackLengthHalf)
					||  (state[2] > _poleAngleThreshold) || (state[2] < -_poleAngleThreshold)
					||  (state[4] > _poleAngleThreshold) || (state[4] < -_poleAngleThreshold))
                {
					break;
                }
			}

            if(timestep == _maxTimesteps) {
                _stopConditionSatisfied = true;
            }

            // The controller's fitness is defined as the number of timesteps that elapse before failure.
            double fitness = timestep;
            return new FitnessInfo(fitness, fitness);
        }
        public override void RefreshView(object genome)
        {
            currentBox = decoder.Decode(genome as NeatGenome);

            plotChart.Series.Clear();
            for (var cluster = 0; cluster < nbClusters; cluster++)
            {
                var serie = plotChart.Series.Add("Cluster #" + cluster);
                serie.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Point;
            }

            var outputs = new double[nbClusters];

            double xmin = double.PositiveInfinity;
            double xmax = 0;
            double ymin = double.PositiveInfinity;
            double ymax = 0;

            for (var i = 0; i < dataset.InputSamples.Count(); i++)
            {
                for (var j = 0; j < dataset.InputCount; j++)
                {
                    currentBox.InputSignalArray[j] = dataset.InputSamples[i][j];
                }
                currentBox.Activate();
                currentBox.OutputSignalArray.CopyTo(outputs, 0);

                var x = dataset.InputSamples[i][0];
                var y = dataset.InputSamples[i][1];
                var cluster = outputs.MaxIndex();

                if (x < xmin) xmin = x;
                if (x > xmax) xmax = x;
                if (y < ymin) ymin = y;
                if (y > ymax) ymax = y;

                plotChart.Series[cluster].Points.AddXY(x, y);
            }

            plotChart.ChartAreas[0].AxisX.Minimum = xmin;
            plotChart.ChartAreas[0].AxisX.Maximum = xmax;
            plotChart.ChartAreas[0].AxisY.Minimum = ymin;
            plotChart.ChartAreas[0].AxisY.Maximum = xmax;

        }
        private void PaintView(IBlackBox box)
        {
            if(_initializing) {
                return;
            }

            Graphics g = Graphics.FromImage(_image);
            g.FillRectangle(_brushBackground, 0, 0, _image.Width, _image.Height);
            g.SmoothingMode = SmoothingMode.AntiAlias;

            // Get control width and height.
            int width = Width;
            int height = Height;

            // Determine smallest dimension. Use that as the edge length of the square grid.
            width = height = Math.Min(width, height);

            // Pixel size is calculated using integer division to produce cleaner lines when drawing.
            // The inherent rounding down may produce a grid 1 pixel smaller then the determined edge length.
            // Also make room for a combo box above the grid. This will be used allow the user to change the grid resolution.
            int visualFieldPixelSize = (height-GridTop) / _visualFieldResolution;
            width = height = visualFieldPixelSize * _visualFieldResolution;

            // Paint pixel outline grid.
            // Vertical lines.
            int x = GridLeft;
            for(int i=0; i<=_visualFieldResolution; i++, x+=visualFieldPixelSize) {
                g.DrawLine(__penGrey, x, GridTop, x, GridTop+height);
            }

            // Horizontal lines.
            int y = GridTop;
            for(int i=0; i<=_visualFieldResolution; i++, y+=visualFieldPixelSize) {
                g.DrawLine(__penGrey, GridLeft, y, GridLeft+width, y);
            }

            // Apply test case to black box's visual field sensor inputs.
            BoxesVisualDiscriminationEvaluator.ApplyVisualFieldToBlackBox(_testCaseField, box, _visualFieldResolution, _visualOriginPixelXY, _visualPixelSize);

            // Activate the black box.
            box.ResetState();
            box.Activate();

            // Read output responses and paint them to the pixel grid.
            // Also, we determine the range of values so that we can normalize the range of pixel shades used.
            double low, high;
            low = high = box.OutputSignalArray[0];
            for(int i=1; i<box.OutputSignalArray.Length; i++)
            {
                double val = box.OutputSignalArray[i];
                if(val > high) {
                    high = val;
                } else if(val <low) {
                    low = val;
                }
            }

            double colorScaleFactor;
            if(0.0 == (high-low)) {
                colorScaleFactor = 1.0;
            } else {
                colorScaleFactor = 1.0 / (high-low);
            }

            IntPoint maxActivationPoint = new IntPoint(0,0);
            double  maxActivation = -1.0;
            int outputIdx = 0;
            y = GridTop;
            for(int i=0; i<_visualFieldResolution; i++, y+=visualFieldPixelSize)
            {
                x = GridLeft;
                for(int j=0; j<_visualFieldResolution; j++, x+=visualFieldPixelSize, outputIdx++)
                {
                    double output = box.OutputSignalArray[outputIdx];
                    if(output > maxActivation)
                    {
                        maxActivation = output;
                        maxActivationPoint._x = j;
                        maxActivationPoint._y = i;
                    }

                    Color color = GetResponseColor((output-low)*colorScaleFactor);
                    Brush brush = new SolidBrush(color);
                    g.FillRectangle(brush, x+1, y+1, visualFieldPixelSize-2, visualFieldPixelSize-2);
                }
            }

            // Paint lines around the small and large test case boxes to highlight them.
            // Small box.
            int testFieldPixelSize = (_visualFieldResolution / TestCaseField.TestFieldResolution) * visualFieldPixelSize;
            g.DrawRectangle(__penBoxOutline,
                            GridLeft + (_testCaseField.SmallBoxTopLeft._x * testFieldPixelSize),
                            GridTop + (_testCaseField.SmallBoxTopLeft._y * testFieldPixelSize),
                            testFieldPixelSize, testFieldPixelSize);

            // Large box.
            g.DrawRectangle(__penBoxOutline,
                            GridLeft + (_testCaseField.LargeBoxTopLeft._x * testFieldPixelSize),
                            GridTop + (_testCaseField.LargeBoxTopLeft._y * testFieldPixelSize),
                            testFieldPixelSize*3, testFieldPixelSize*3);
            
            // Draw red line around pixel with highest activation.
            g.DrawRectangle(__penSelectedPixel,
                            GridLeft + (maxActivationPoint._x * visualFieldPixelSize),
                            GridTop + (maxActivationPoint._y * visualFieldPixelSize),
                            visualFieldPixelSize, visualFieldPixelSize);

            Refresh();
        }
    public static Mesh Evaluate(IBlackBox phenome, VoxelVolume volume, out EvaluationInfo evaluationInfo)
    {
        var processedOutput = new float[volume.width, volume.height, volume.length];
        var cleanOutput = new float[volume.width, volume.height, volume.length];
        var distanceToCenter = new float[volume.width, volume.height, volume.length];
        var minOutputValue = 1f;
        var maxOutputValue = -1f;

        float r = 0, g = 0, b = 0;

        for (int x = 0; x < volume.width; x++)
        {
            for (int y = 0; y < volume.height; y++)
            {
                for (int z = 0; z < volume.length; z++)
                {
                    AssingInput(phenome, volume, x, y, z);

                    // activate phenome
                    phenome.Activate();

                    // store output values
                    ISignalArray outputArr = phenome.OutputSignalArray;
                    processedOutput[x, y, z] = phenome.OutputSignalArray.Length >= 4 ? (float)outputArr[3] : (float)outputArr[0];
                    cleanOutput[x, y, z] = processedOutput[x, y, z];

                    if (phenome.OutputSignalArray.Length >= 4)
                    {
                        r += (float)outputArr[0];
                        g += (float)outputArr[1];
                        b += (float)outputArr[2];
                    }

                    // store min and max output values
                    if (processedOutput[x, y, z] < minOutputValue)
                        minOutputValue = processedOutput[x, y, z];
                    if (processedOutput[x, y, z] > maxOutputValue)
                        maxOutputValue = processedOutput[x, y, z];

                    // Clamps the final shape within a sphere
                    //distanceToCenter[x, y, z] = DistanceFunctions.DistanceToCenter(x, y, z, volume);
                    //if (DistanceFunctions.DistanceToCenter(x, y, z, volume) > -0.5f)
                    //{
                    //    cleanOutput[x, y, z] = -1;
                    //    processedOutput[x, y, z] = -1;
                    //}

                    // border should have negative values
                    if (x == 0 || x == volume.width - 1 || y == 0 || y == volume.height - 1 || z == 0 || z == volume.length - 1)
                        processedOutput[x, y, z] = -1f;
                }
            }
        }

        r /= volume.width*volume.width*volume.width;
        g /= volume.width*volume.width*volume.width;
        b /= volume.width*volume.width*volume.width;
        artefactColor = new Color((r + 1f) / 2f, (g + 1f) / 2f, (b + 1f) / 2f);
        //Debug.Log(artefactColor);

        //Debug.Log("Output in range [" + minOutputValue + ", " + maxOutputValue + "]");

        // TODO: need to find a workaround for this. It results in cubes. In multiplayer we don't want to spawn cubes as seeds.
        // Either save network to disk, look and see what's wrong or maybe if this happens on the client it could request another regeneration.
        if (Mathf.Approximately(minOutputValue, maxOutputValue))
        {
            //Debug.LogWarning("All output values are the same! Min equals max!");
        }

        for (int index00 = 1; index00 < processedOutput.GetLength(0) - 1; index00++)
            for (int index01 = 1; index01 < processedOutput.GetLength(1) - 1; index01++)
                for (int index02 = 1; index02 < processedOutput.GetLength(2) - 1; index02++)
                {
                    // if initially, border value at 0,0,0 was maxFill, we invert all values so minFill is on the border
                    if (Mathf.Approximately(cleanOutput[0, 0, 0], maxOutputValue))
                        processedOutput[index00, index01, index02] = minOutputValue + (maxOutputValue - processedOutput[index00, index01, index02]);
                    // based on a threshold ( middle value between min and max) we change the value to either 0 or 1. This give a blocky look instead of smooth details
                    processedOutput[index00, index01, index02] = processedOutput[index00, index01, index02] < minOutputValue + (maxOutputValue - minOutputValue) / 2f ? 0f : 1f;
                }

        // fill evaluation info struct with data
        evaluationInfo = new EvaluationInfo();
        evaluationInfo.cleanOutput = cleanOutput.Clone() as float[,,];
        evaluationInfo.processedOutput = processedOutput.Clone() as float[,,];
        evaluationInfo.distanceToCenter = distanceToCenter.Clone() as float[,,];
        evaluationInfo.minOutputValue = minOutputValue;
        evaluationInfo.maxOutputValue = maxOutputValue;

        // Apply marching cubes on processed output and return Mesh
        Profiler.BeginSample("MarchingCubes");
        var mesh = MarchingCubes.CreateMesh(processedOutput);
        Profiler.EndSample();

        return mesh;
    }
        /// <summary>
        /// Evaluate the provided IBlackBox.
        /// </summary>
        public override FitnessInfo Evaluate(IBlackBox box)
        {
            _evalCount++;

		    // [0] - Cart Position (meters).
		    // [1] - Cart velocity (m/s).
		    // [2] - Pole 1 angle (radians)
		    // [3] - Pole 1 angular velocity (radians/sec).
		    // [4] - Pole 2 angle (radians)
		    // [5] - Pole 2 angular velocity (radians/sec).
            double[] state = new double[6];
            state[2] = FourDegrees;

		    JiggleBuffer jiggleBuffer1 = new JiggleBuffer(100);
		    JiggleBuffer jiggleBuffer2 = new JiggleBuffer(100);
            
			// Run the pole-balancing simulation.
            int timestep = 0;
			for(; timestep < _maxTimesteps; timestep++)
			{
				// Provide state info to the network (normalised to +-1.0).
				// Markovian (With velocity info)
                box.InputSignalArray[0] = state[0] / _trackLengthHalf;  // Cart Position is +-trackLengthHalfed
                box.InputSignalArray[1] = state[2] / ThirtySixDegrees;  // Pole Angle is +-thirtysix_degrees. Values outside of this range stop the simulation.
                box.InputSignalArray[2] = state[4] / ThirtySixDegrees;  // Pole Angle is +-thirtysix_degrees. Values outside of this range stop the simulation.

				// Activate the black box.
                box.Activate();

                // Get black box response and calc next timestep state.
				performAction(state, box.OutputSignalArray[0]);
		
                // Jiggle buffer updates..
				if(100 == jiggleBuffer1.Length)
				{	// Feed an old value from buffer 1 into buffer2.
					jiggleBuffer2.Enqueue(jiggleBuffer1.Dequeue());
				}

				// Place the latest jiggle value into buffer1.
				jiggleBuffer1.Enqueue(	Math.Abs(state[0]) + Math.Abs(state[1]) + 
										Math.Abs(state[2]) + Math.Abs(state[3]));

				// Check for failure state. Has the cart run off the ends of the track or has the pole
				// angle gone beyond the threshold.
				if(     (state[0]< -_trackLengthHalf) || (state[0]> _trackLengthHalf)
					||  (state[2] > _poleAngleThreshold) || (state[2] < -_poleAngleThreshold)
					||  (state[4] > _poleAngleThreshold) || (state[4] < -_poleAngleThreshold))
                {
					break;
                }

				// Give the simulation at least 500 timesteps(5secs) to stabilise before penalising instability.
				if(timestep > 499 && jiggleBuffer2.Total > 30.0)
				{	// Too much wiggling. Stop simulation early (30 was an experimentally determined value).
					break;					
				}
			}

            double fitness;
			if(timestep > 499 && timestep < 600)
			{	// For the 100(1 sec) steps after the 500(5 secs) mark we punish wiggling based
				// on the values from the 1 sec just gone. This is on the basis that the values
				// in jiggleBuffer2 (from 2 to 1 sec ago) will refelct the large amount of
				// wiggling that occurs at the start of the simulation when the system is still stabilising.
				fitness = timestep + (10.0 / Math.Max(1.0, jiggleBuffer1.Total));
			}
			else if(timestep > 599)
			{	// After 600 steps we use jiggleBuffer2 to punsih wiggling, this contains data from between
				// 2 and 1 secs ago. This is on the basis that when the system becomes unstable and causes
				// the simulation to terminate prematurely, the immediately prior 1 secs data will reflect that
				// instability, which may not be indicative of the overall stability of the system up to that time.
				fitness = timestep + (10.0 / Math.Max(1.0, jiggleBuffer2.Total));
			}
			else
			{	// Return just the currentTimestep without any extra fitness component.
				fitness = timestep;
			}

            // Max fitness is # of timesteps + max antiwiggle factor of 10 (which is actually impossible - some wiggle is necessary to balance the poles).
            if(timestep == _maxTimesteps + 10.0) {
                _stopConditionSatisfied = true;
            }
            return new FitnessInfo(fitness, fitness);
        }
        private double[] activate(IBlackBox box, IList<double> inputs, double[] outputs)
        {
            box.ResetState();

            // Give inputs to the network
            var nodeId = 0;
            foreach (var input in inputs)
            {
                box.InputSignalArray[nodeId++] = input;
            }

            // Activate the network and get outputs back
            box.Activate();
            box.OutputSignalArray.CopyTo(outputs, 0);

            // Normalize outputs when using NEAT
            if (phenotype == Phenotype.Neat)
            {
                NormalizeOutputs(outputs);
            }
            else
            {
                Debug.Assert(outputs.All(x => x >= 0.0 && x <= 1.0));
            }

            return outputs;
        }
示例#37
0
        /// <summary>
        /// Create a network definition by querying the provided IBlackBox (typically a CPPN) with the 
        /// substrate connection endpoints.
        /// </summary>
        /// <param name="blackbox">The HyperNEAT CPPN that defines the strength of connections between nodes on the substrate.</param>
        /// <param name="lengthCppnInput">Optionally we provide a connection length input to the CPPN.</param>
        public INetworkDefinition CreateNetworkDefinition(IBlackBox blackbox, bool lengthCppnInput)
        {
            // Get the sequence of substrate connections. Either a pre-built list or a dynamically
            // generated sequence.
            IEnumerable<SubstrateConnection> connectionSequence = _connectionList ?? GetConnectionSequence();

            // Iterate over substrate connections. Determine each connection's weight and create a list
            // of network definition connections.
            ISignalArray inputSignalArr = blackbox.InputSignalArray;
            ISignalArray outputSignalArr = blackbox.OutputSignalArray;
            ConnectionList networkConnList = new ConnectionList(_connectionCountHint);
            int lengthInputIdx = inputSignalArr.Length - 1;

            foreach(SubstrateConnection substrateConn in connectionSequence)
            {
                int layerToLayerAdder = ((int)substrateConn._tgtNode._position[2] * 3);
                // Assign the connection's endpoint position coords to the CPPN/blackbox inputs. Note that position dimensionality is not fixed.
                for(int i=0; i<_dimensionality - 1; i++)
                {
                    inputSignalArr[i] = substrateConn._srcNode._position[i];
                    inputSignalArr[i + _dimensionality - 1] = substrateConn._tgtNode._position[i];
                    inputSignalArr[i + 2 * (_dimensionality - 1)] = Math.Abs(substrateConn._srcNode._position[i] - substrateConn._tgtNode._position[i]);
                }

                // Optional connection length input.
                if(lengthCppnInput) {
                    inputSignalArr[lengthInputIdx] = CalculateConnectionLength(substrateConn._srcNode._position, substrateConn._tgtNode._position);
                }

                // Reset blackbox state and activate it.
                blackbox.ResetState();
                blackbox.Activate();

                // Read connection weight from output 0.
                double weight = outputSignalArr[0 + layerToLayerAdder];

                // Skip connections with a weight magnitude less than _weightThreshold.
                double weightAbs = Math.Abs(weight);
                if (outputSignalArr[2 + layerToLayerAdder] >= 0)
                {
                    // For weights over the threshold we re-scale into the range [-_maxWeight,_maxWeight],
                    // assuming IBlackBox outputs are in the range [-1,1].
                    weight = (weightAbs) * _weightRescalingCoeff * Math.Sign(weight);

                    // Create network definition connection and add to list.
                    networkConnList.Add(new NetworkConnection(substrateConn._srcNode._id,
                                                              substrateConn._tgtNode._id, weight));
                }
            }

            // Additionally we create connections from each hidden and output node to a bias node that is not defined at any
            // position on the substrate. The motivation here is that a each node's input bias is independent of any source
            // node (and associated source node position on the substrate). That we refer to a bias 'node' is a consequence of how input
            // biases are handled in NEAT - with a specific bias node that other nodes can be connected to.
            int setCount = _nodeSetList.Count;
            for(int i=1; i<setCount; i++)
            {
                SubstrateNodeSet nodeSet = _nodeSetList[i];
                foreach(SubstrateNode node in nodeSet.NodeList)
                {
                    // Assign the node's position coords to the blackbox inputs. The CPPN inputs for source node coords are set to zero when obtaining bias values.
                    for(int j=0; j<_dimensionality - 1; j++)
                    {
                        inputSignalArr[j] = 0.0;
                        inputSignalArr[j + _dimensionality - 1] = node._position[j];
                    }

                    // Optional connection length input.
                    if(lengthCppnInput) {
                        inputSignalArr[lengthInputIdx] = CalculateConnectionLength(node._position);
                    }

                    // Reset blackbox state and activate it.
                    blackbox.ResetState();
                    blackbox.Activate();

                    // Read bias connection weight from output 1.
                    double weight = outputSignalArr[1+ (i- 1) * 3];

                    // Skip connections with a weight magnitude less than _weightThreshold.
                    double weightAbs = Math.Abs(weight);
                    if(weightAbs > _weightThreshold)
                    {
                        // For weights over the threshold we re-scale into the range [-_maxWeight,_maxWeight],
                        // assuming IBlackBox outputs are in the range [-1,1].
                        weight = (weightAbs - _weightThreshold) * _weightRescalingCoeff * Math.Sign(weight);

                        // Create network definition connection and add to list. Bias node is always ID 0.
                        networkConnList.Add(new NetworkConnection(0, node._id, weight));
                    }
                }
            }

            // Check for no connections.
            // If no connections were generated then there is no point in further evaulating the network.
            // However, null is a valid response when decoding genomes to phenomes, therefore we do that here.
            if(networkConnList.Count == 0) {
                return null;
            }

            // Construct and return a network definition.
            NetworkDefinition networkDef = new NetworkDefinition(_inputNodeCount, _outputNodeCount,
                                                                 _activationFnLibrary, _netNodeList, networkConnList);

            // Check that the definition is valid and return it.
            Debug.Assert(networkDef.PerformIntegrityCheck());
            return networkDef;
        }
示例#38
0
        /// <summary>
        /// Determine the agent's position in the world relative to the prey and walls, and set its sensor inputs accordingly.
        /// </summary>
        /// <param name="agent"></param>
        public void SetAgentInputsAndActivate(IBlackBox agent)
        {
            // Calc prey's position relative to the agent (in polar coordinate system).
            PolarPoint relPos = PolarPoint.FromCartesian(_preyPos - _agentPos);

            // Determine agent sensor input values.
            // Reset all inputs.
            agent.InputSignalArray.Reset();

            // Test if prey is in sensor range.
            if(relPos.Radial <= _sensorRange)
            {
                // Determine which sensor segment the prey is within - [0,7]. There are eight segments and they are tilted 22.5 degrees (half a segment)
                // such that due North, East South and West are each in the center of a sensor segment (rather than on a segment boundary).
                int segmentIdx = (int)Math.Floor((relPos.Theta / PiDiv4) + PiDiv8);
                if(8==segmentIdx) {
                    segmentIdx = 0;
                }
                // Set sensor segment's input.
                agent.InputSignalArray[segmentIdx] = 1.0;
            }

            // Prey closeness detector.
            agent.InputSignalArray[8] = relPos.Radial > 2.0 ? 0.0 : 1.0;

            // Wall detectors - N,E,S,W.
            // North.
            int d = (_gridSize-1) - _agentPos._y;
            if(d < 4) { agent.InputSignalArray[9] = (4-d) / 4.0; }

            // East.
            d = (_gridSize-1) - _agentPos._x;
            if(d < 4) { agent.InputSignalArray[10] = (4-d) / 4.0; }

            // South.
            if(_agentPos._y < 4) { agent.InputSignalArray[11] = (4 - _agentPos._y) / 4.0; }

            // West.
            if(_agentPos._x < 4) { agent.InputSignalArray[12] = (4 - _agentPos._x) / 4.0; }

            // Activate agent.
            agent.Activate();
        }
        private double[] activate(IBlackBox box, IEnumerable<double> inputs, double[] outputs)
        {
            box.ResetState();

            // Give inputs to the network
            var nodeId = 0;
            foreach (var input in inputs)
            {
                box.InputSignalArray[nodeId++] = input;
            }

            // Activate the network and get outputs back
            box.Activate();
            box.OutputSignalArray.CopyTo(outputs, 0);

            // Normalize outputs when necessary
            if (phenotype == Phenotype.Neat)
            {
                for (var i = 0; i < outputs.Count(); i++)
                {
                    outputs[i] = (outputs[i] + 1.0) / 2.0;
                }
            }
            else
            {
                Debug.Assert(outputs.All(x => x >= 0.0 && x <= 1.0));
            }

            return outputs;
        }