예제 #1
0
        public void PaintNetwork(Graphics g,
                                 NetworkModel nm,
                                 float zoomFactor,
                                 Point viewportOrigin,
                                 Size viewportSize,
                                 double connectionWeightMin,
                                 double connectionWeightRange)
        {
            // Store painting parameters.
            this.zoomFactor            = zoomFactor;
            this.viewportOrigin        = viewportOrigin;
            this.viewportSize          = viewportSize;
            this.connectionWeightMin   = connectionWeightMin;
            this.connectionWeightRange = connectionWeightRange;

            // Some pre-calculated values.
            this.viewportBound = new Point(viewportOrigin.X + viewportSize.Width,
                                           viewportOrigin.Y + viewportSize.Height);

            neuronDiameter          = (int)(NEURON_DIAMETER_BASE * zoomFactor);
            neuronDiameterHalfed    = (int)((NEURON_DIAMETER_BASE * zoomFactor) / 2.0F);
            backConnectionLegLength = (NEURON_DIAMETER_BASE * zoomFactor * 1.6F);
            connectionWidthFactor   = (float)(connectionWeightRange / 2.0);
            fontNeuronId            = new Font("Microsoft Sans Serif", (float)Math.Min(Math.Max(0.2, 7.0F * zoomFactor), Single.MaxValue));

            // Assign a ConnectionPoints object to each neuron.
            int neuronCount = nm.MasterNeuronList.Count;

            for (int neuronIdx = 0; neuronIdx < neuronCount; neuronIdx++)
            {
                nm.MasterNeuronList[neuronIdx].AuxPaintingData = new ConnectionPoints();
            }

            //----- Painting code.
            // Paint all connections first. The neurons are painted over the top to
            // cover up any loose ends.
            for (int neuronIdx = 0; neuronIdx < neuronCount; neuronIdx++)
            {
                ModelNeuron neuron = nm.MasterNeuronList[neuronIdx];

                // Incoming connections.
                int connectionCount = neuron.InConnectionList.Count;
                for (int connectionIdx = 0; connectionIdx < connectionCount; connectionIdx++)
                {
                    PaintConnection(g, neuron.InConnectionList[connectionIdx]);
                }
            }

            foreach (ModelNeuron neuron in nm.MasterNeuronList)
            {
                PaintNeuron(g, neuron);
            }
        }
예제 #2
0
        public void Layout(NetworkModel nm, Size areaSize)
        {
            // Use this to keep track of the coordinate bounds of the network (maxX, maxY).
            bounds = new Size(0, 0);

            //----- Determine how many layers we are going arrange the neurons into.
            int   inputCount       = nm.InputNeuronList.Count;
            int   outputCount      = nm.OutputNeuronList.Count;
            int   hiddenCount      = nm.MasterNeuronList.Count - (inputCount + outputCount);
            float heightWidthRatio = (float)areaSize.Height / (float)areaSize.Width;

            // Default to 2 (input and output layers).
            int numLayers       = 2;
            int numHiddenLayers = 0;

            if (hiddenCount > 0)
            {
                // Arrange as if there no input/output layers.
                double sqrtHidden = Math.Sqrt(hiddenCount);
                numHiddenLayers = (int)Math.Floor(sqrtHidden * heightWidthRatio);

                // Now factor in the input/output layers.
                numHiddenLayers = Math.Max(1, numHiddenLayers - 2);
                numLayers       = 2 + numHiddenLayers;
            }

            //----- Arrange the neurons.
            int    heightLayers     = areaSize.Height - 2 * MARGIN_Y;
            int    yIncrement       = areaSize.Height / (numLayers + 1);
            int    yCurrent         = MARGIN_Y + yIncrement;
            double yIncrementHalfed = yIncrement / 2.0;

            // Input layer. Place all input neurons in one layer.
            int widthLayer = areaSize.Width - 2 * MARGIN_X;
            int xIncrement = widthLayer / (inputCount + 1);
            int xCurrent   = MARGIN_X + xIncrement;

            foreach (ModelNeuron modelNeuron in nm.InputNeuronList)
            {
                modelNeuron.Position        = new Point(xCurrent, yCurrent);
                modelNeuron.HasPositionInfo = true;
                UpdateModelBounds(modelNeuron);
                xCurrent += xIncrement;
            }
            // Increment yCurrent, ready for the next layer.
            yCurrent += yIncrement;

            // Hidden layers.
            if (numLayers > 0)
            {
                // Keep track of which neuron is being positioned.
                int neuronIdx = 0;

                // calculate the max number of neurons in any hidden layer.
                int layerNeuronsMax = (int)Math.Ceiling((float)hiddenCount / (float)numHiddenLayers);

                // Keep track of how many neurons remain to be positioned.
                int neuronsRemaining = hiddenCount;
                for (int hiddenLayer = 0; hiddenLayer < numHiddenLayers; hiddenLayer++)
                {
                    // Calculate the number of neurons in this layer.
                    int layerNeuronCount = Math.Min(neuronsRemaining, layerNeuronsMax);

                    // Position neurons in this layer.
                    xIncrement = widthLayer / (layerNeuronCount + 1);
                    xCurrent   = MARGIN_X + xIncrement;

                    for (int i = 0; i < layerNeuronCount; i++)
                    {
                        ModelNeuron modelNeuron = nm.HiddenNeuronList[neuronIdx++];
                        modelNeuron.Position = new Point(
                            xCurrent,
                            yCurrent);
                        //yCurrent + (int)(((random.NextDouble()*(double)yIncrement)-yIncrementHalfed)*JIGGLE_PROPORTION));
                        modelNeuron.HasPositionInfo = true;
                        UpdateModelBounds(modelNeuron);

                        xCurrent += xIncrement;
                    }
                    // Increment yCurrent, ready for the next layer.
                    yCurrent += yIncrement;

                    neuronsRemaining -= layerNeuronCount;
                }
            }

            // Output layer.
            xIncrement = widthLayer / (outputCount + 1);
            xCurrent   = MARGIN_X + xIncrement;

            foreach (ModelNeuron modelNeuron in nm.OutputNeuronList)
            {
                modelNeuron.Position = new Point(
                    xCurrent,
                    yCurrent);
                //yCurrent + (int)(((random.NextDouble()*(double)yIncrement)-yIncrementHalfed)*JIGGLE_PROPORTION));
                modelNeuron.HasPositionInfo = true;
                UpdateModelBounds(modelNeuron);

                xCurrent += xIncrement;
            }

            nm.Bounds = bounds;
        }