Ejemplo n.º 1
0
        //determine the variance of a certain region
        public float variance(QuadPoint p)
        {
            if (p.childs.Count == 0)
            {
                return(0.0f);
            }

            List <float> l = new List <float>();

            getCPPNValues(ref l, p);

            float m = 0.0f, v = 0.0f;

            foreach (float f in l)
            {
                m += f;
            }
            m /= l.Count;
            foreach (float f in l)
            {
                v += (float)Math.Pow(f - m, 2);
            }
            v /= l.Count;
            return(v);
        }
        public static List <Quad> AsAnnotationQuads(this Highlight highlight)
        {
            int pageIndex = highlight.GetPage().GetIndex();

            List <Quad> highlightAsAnnotationQuads = new List <Quad>();

            for (int l = 0; l < highlight.GetQuadPointCount(); l++)
            {
                List <double> xValues = new List <double>();
                List <double> yValues = new List <double>();

                QuadPoint quadPoint = highlight.GetQuadPoint(l);

                xValues.AddRange(new List <double> {
                    quadPoint.p1.x, quadPoint.p2.x, quadPoint.p3.x, quadPoint.p4.x
                });
                yValues.AddRange(new List <double> {
                    quadPoint.p1.y, quadPoint.p2.y, quadPoint.p3.y, quadPoint.p4.y
                });

                highlightAsAnnotationQuads.Add(new Quad(pageIndex, xValues.Min(), yValues.Min(), xValues.Max(), yValues.Max()));
            }

            return(highlightAsAnnotationQuads);
        }
Ejemplo n.º 3
0
 //Collect the CPPN values stored in a given quadtree p
 //Used to estimate the variance in a certain region in space
 private void getCPPNValues(ref List <float> l, QuadPoint p)
 {
     if (p != null && p.childs.Count > 0)
     {
         for (int i = 0; i < 4; i++)
         {
             getCPPNValues(ref l, p.childs[i]);
         }
     }
     else
     {
         l.Add(p.w);
     }
 }
Ejemplo n.º 4
0
        /*
         * Input: Coordinates of source (outgoing = true) or target node (outgoing = false) at (a,b)
         * Output: Quadtree, in which each quadnode at (x,y) stores CPPN activation level for its
         *         position. The initialized quadtree is used in the PruningAndExtraction phase to
         *         generate the actual ANN connections.
         */
        public QuadPoint QuadTreeInitialisation(float a, float b, bool outgoing, int initialDepth, int maxDepth)
        {
            QuadPoint        root  = new QuadPoint(0.0f, 0.0f, 1.0f, 1); //x, y, width, level
            List <QuadPoint> queue = new List <QuadPoint>();

            queue.Add(root);

            while (queue.Count > 0)
            {
                QuadPoint p = queue[0];//dequeue
                queue.RemoveAt(0);

                // Divide into sub-regions and assign children to parent
                p.childs.Add(new QuadPoint(p.x - p.width / 2, p.y - p.width / 2, p.width / 2, p.level + 1));
                p.childs.Add(new QuadPoint(p.x - p.width / 2, p.y + p.width / 2, p.width / 2, p.level + 1));
                p.childs.Add(new QuadPoint(p.x + p.width / 2, p.y - p.width / 2, p.width / 2, p.level + 1));
                p.childs.Add(new QuadPoint(p.x + p.width / 2, p.y + p.width / 2, p.width / 2, p.level + 1));

                foreach (QuadPoint c in p.childs)
                {
                    if (outgoing)                                     // Querying connection from input or hidden node
                    {
                        c.Outputs = queryCPPNOutputs(a, b, c.x, c.y); // Outgoing connectivity pattern
                        c.w       = c.Outputs[0];
                    }
                    else // Querying connection to output node
                    {
                        c.Outputs = queryCPPNOutputs(c.x, c.y, a, b); // Incoming connectivity pattern
                        c.w       = c.Outputs[0];
                    }
                }

                // Divide until initial resolution or if variance is still high
                if (p.level < initialDepth || (p.level < maxDepth && variance(p) > divisionThreshold))
                {
                    foreach (QuadPoint c in p.childs)
                    {
                        queue.Add(c);
                    }
                }
            }
            return(root);
        }
Ejemplo n.º 5
0
 //Collect the CPPN values stored in a given quadtree p
 //Used to estimate the variance in a certain region in space
 private void getCPPNValues(ref List<float> l, QuadPoint p)
 {
     if (p != null && p.childs.Count > 0)
     {
         for (int i = 0; i < 4; i++)
         {
             getCPPNValues(ref l, p.childs[i]);
         }
     }
     else
     {
         l.Add(p.w);
     }
 }
Ejemplo n.º 6
0
        //determine the variance of a certain region
        public float variance(QuadPoint p)
        {
            if (p.childs.Count == 0)
            {
                return 0.0f;
            }

            List<float> l = new List<float>();
            getCPPNValues(ref l, p);

            float m = 0.0f, v = 0.0f;
            foreach (float f in l)
            {
                m += f;
            }
            m /= l.Count;
            foreach (float f in l)
            {
                v += (float)Math.Pow(f - m, 2);
            }
            v /= l.Count;
            return v;
        }
Ejemplo n.º 7
0
        /*
         * Input: Coordinates of source (outgoing = true) or target node (outgoing = false) at (a,b)
         * Output: Quadtree, in which each quadnode at (x,y) stores CPPN activation level for its
         *         position. The initialized quadtree is used in the PruningAndExtraction phase to
         *         generate the actual ANN connections.
         */
        public QuadPoint QuadTreeInitialisation(float a, float b, bool outgoing, int initialDepth, int maxDepth)
        {
            QuadPoint root = new QuadPoint(0.0f, 0.0f, 1.0f, 1); //x, y, width, level
            List<QuadPoint> queue = new List<QuadPoint>();
            queue.Add(root);

            while (queue.Count > 0)
            {
                QuadPoint p = queue[0];//dequeue
                queue.RemoveAt(0);

                // Divide into sub-regions and assign children to parent
                p.childs.Add(new QuadPoint(p.x - p.width / 2, p.y - p.width / 2, p.width / 2, p.level + 1));
                p.childs.Add(new QuadPoint(p.x - p.width / 2, p.y + p.width / 2, p.width / 2, p.level + 1));
                p.childs.Add(new QuadPoint(p.x + p.width / 2, p.y - p.width / 2, p.width / 2, p.level + 1));
                p.childs.Add(new QuadPoint(p.x + p.width / 2, p.y + p.width / 2, p.width / 2, p.level + 1));

                foreach (QuadPoint c in p.childs)
                {
                    if (outgoing) // Querying connection from input or hidden node
                    {
                        c.Outputs = queryCPPNOutputs(a, b, c.x, c.y); // Outgoing connectivity pattern
                        c.w = c.Outputs[0];
                    }
                    else // Querying connection to output node
                    {
                        c.Outputs = queryCPPNOutputs(c.x, c.y, a, b); // Incoming connectivity pattern
                        c.w = c.Outputs[0];
                    }
                }

                // Divide until initial resolution or if variance is still high
                if (p.level < initialDepth || (p.level < maxDepth && variance(p) > divisionThreshold))
                {
                    foreach (QuadPoint c in p.childs)
                    {
                        queue.Add(c);
                    }
                }
            }
            return root;
        }
Ejemplo n.º 8
0
        /*
         * Input : Coordinates of source (outgoing = true) or target node (outgoing = false) at (a,b) and initialized quadtree p.
         * Output: Adds the connections that are in bands of the two-dimensional cross-section of the
         *         hypercube containing the source or target node to the connections list.
         *
         */
        public void PruneAndExpress(float a, float b, ref List<TempConnection> connections, QuadPoint node, bool outgoing, float maxDepth)
        {
            float left = 0.0f, right = 0.0f, top = 0.0f, bottom = 0.0f;

            if (node.childs[0] == null) return;

            // Traverse quadtree depth-first
            foreach (QuadPoint c in node.childs)
            {
                float childVariance = variance(c);

                if (childVariance >= varianceThreshold)
                {
                    PruneAndExpress(a, b, ref connections, c, outgoing, maxDepth);
                }
                else //this should always happen for at least the leaf nodes because their variance is zero
                {
                    // Determine if point is in a band by checking neighbor CPPN values
                    if (outgoing)
                    {
                        left = Math.Abs(c.w - queryCPPNWeight(a, b, c.x - node.width, c.y));
                        right = Math.Abs(c.w - queryCPPNWeight(a, b, c.x + node.width, c.y));
                        top = Math.Abs(c.w - queryCPPNWeight(a, b, c.x, c.y - node.width));
                        bottom = Math.Abs(c.w - queryCPPNWeight(a, b, c.x, c.y + node.width));
                    }
                    else
                    {
                        left = Math.Abs(c.w - queryCPPNWeight(c.x - node.width, c.y, a, b));
                        right = Math.Abs(c.w - queryCPPNWeight(c.x + node.width, c.y, a, b));
                        top = Math.Abs(c.w - queryCPPNWeight(c.x, c.y - node.width, a, b));
                        bottom = Math.Abs(c.w - queryCPPNWeight(c.x, c.y + node.width, a, b));
                    }

                    if (Math.Max(Math.Min(top, bottom), Math.Min(left, right)) > bandThrehold)
                    {
                        TempConnection tc = null;
                        if (outgoing)
                        {
                            //check for LEO
                            if(useLEO && c.Outputs[1] > 0)
                                tc = new TempConnection(a, b, c.x, c.y, c.w, c.Outputs);
                            else if(!useLEO)
                                tc = new TempConnection(a, b, c.x, c.y, c.w, c.Outputs);

                        }
                        else
                        {
                            //check against leo!
                            if (useLEO && c.Outputs[1] > 0)
                                tc = new TempConnection(c.x, c.y, a, b, c.w, c.Outputs);
                            else if(!useLEO)
                                tc = new TempConnection(c.x, c.y, a, b, c.w, c.Outputs);

                        }

                        if(tc!= null)
                            connections.Add(tc);
                    }

                }
            }
        }
Ejemplo n.º 9
0
        /*
         * The main method that generations a list of ANN connections based on the information in the
         * underlying hypercube.
         * Input : CPPN, InputPositions, OutputPositions, ES-HyperNEAT parameters
         * Output: Connections, HiddenNodes
         */
        public void generateSubstrate(List <PointF> inputNeuronPositions, List <PointF> outputNeuronPositions,
                                      INetwork genome, int initialDepth, float varianceThreshold, float bandThreshold, int ESIterations,
                                      float divsionThreshold, int maxDepth,
                                      uint inputCount, uint outputCount,
                                      ref ConnectionGeneList connections, ref List <PointF> hiddenNeurons, bool useLeo = false)
        {
            List <TempConnection> tempConnections = new List <TempConnection>();
            int  sourceIndex, targetIndex = 0;
            uint counter = 0;

            this.genome            = (ModularNetwork)genome;
            this.initialDepth      = initialDepth;
            this.maxDepth          = maxDepth;
            this.varianceThreshold = varianceThreshold;
            this.bandThrehold      = bandThreshold;
            this.divisionThreshold = divsionThreshold;

            //CONNECTIONS DIRECTLY FROM INPUT NODES
            sourceIndex = 0;
            foreach (PointF input in inputNeuronPositions)
            {
                // Analyze outgoing connectivity pattern from this input
                QuadPoint root = QuadTreeInitialisation(input.X, input.Y, true, (int)initialDepth, (int)maxDepth);
                tempConnections.Clear();
                // Traverse quadtree and add connections to list
                PruneAndExpress(input.X, input.Y, ref tempConnections, root, true, maxDepth);

                foreach (TempConnection p in tempConnections)
                {
                    PointF newp = new PointF(p.x2, p.y2);

                    targetIndex = hiddenNeurons.IndexOf(newp);
                    if (targetIndex == -1)
                    {
                        targetIndex = hiddenNeurons.Count;
                        hiddenNeurons.Add(newp);
                    }
                    connections.Add(new ConnectionGene(counter++, (sourceIndex), (targetIndex + inputCount + outputCount), p.weight * HyperNEATParameters.weightRange, new float[] { p.x1, p.y1, p.x2, p.y2 }, p.Outputs));
                }
                sourceIndex++;
            }

            tempConnections.Clear();

            List <PointF> unexploredHiddenNodes = new List <PointF>();

            unexploredHiddenNodes.AddRange(hiddenNeurons);

            for (int step = 0; step < ESIterations; step++)
            {
                foreach (PointF hiddenP in unexploredHiddenNodes)
                {
                    tempConnections.Clear();
                    QuadPoint root = QuadTreeInitialisation(hiddenP.X, hiddenP.Y, true, (int)initialDepth, (int)maxDepth);
                    PruneAndExpress(hiddenP.X, hiddenP.Y, ref tempConnections, root, true, maxDepth);

                    sourceIndex = hiddenNeurons.IndexOf(hiddenP);   //TODO there might a computationally less expensive way

                    foreach (TempConnection p in tempConnections)
                    {
                        PointF newp = new PointF(p.x2, p.y2);

                        targetIndex = hiddenNeurons.IndexOf(newp);
                        if (targetIndex == -1)
                        {
                            targetIndex = hiddenNeurons.Count;
                            hiddenNeurons.Add(newp);
                        }
                        connections.Add(new ConnectionGene(counter++, (sourceIndex + inputCount + outputCount), (targetIndex + inputCount + outputCount), p.weight * HyperNEATParameters.weightRange, new float[] { p.x1, p.y1, p.x2, p.y2 }, p.Outputs));
                    }
                }
                // Remove the just explored nodes
                List <PointF> temp = new List <PointF>();
                temp.AddRange(hiddenNeurons);
                foreach (PointF f in unexploredHiddenNodes)
                {
                    temp.Remove(f);
                }

                unexploredHiddenNodes = temp;
            }

            tempConnections.Clear();

            //CONNECT TO OUTPUT
            targetIndex = 0;
            foreach (PointF outputPos in outputNeuronPositions)
            {
                // Analyze incoming connectivity pattern to this output
                QuadPoint root = QuadTreeInitialisation(outputPos.X, outputPos.Y, false, (int)initialDepth, (int)maxDepth);
                tempConnections.Clear();
                PruneAndExpress(outputPos.X, outputPos.Y, ref tempConnections, root, false, maxDepth);


                PointF target = new PointF(outputPos.X, outputPos.Y);

                foreach (TempConnection t in tempConnections)
                {
                    PointF source = new PointF(t.x1, t.y1);
                    sourceIndex = hiddenNeurons.IndexOf(source);

                    /* New nodes not created here because all the hidden nodes that are
                     *  connected to an input/hidden node are already expressed. */
                    if (sourceIndex != -1)  //only connect if hidden neuron already exists
                    {
                        connections.Add(new ConnectionGene(counter++, (sourceIndex + inputCount + outputCount), (targetIndex + inputCount), t.weight * HyperNEATParameters.weightRange, new float[] { t.x1, t.y1, t.x2, t.y2 }, t.Outputs));
                    }
                }
                targetIndex++;
            }
        }
Ejemplo n.º 10
0
        /*
         * Input : Coordinates of source (outgoing = true) or target node (outgoing = false) at (a,b) and initialized quadtree p.
         * Output: Adds the connections that are in bands of the two-dimensional cross-section of the
         *         hypercube containing the source or target node to the connections list.
         *
         */

        public void PruneAndExpress(float a, float b, ref List <TempConnection> connections, QuadPoint node, bool outgoing, float maxDepth)
        {
            float left = 0.0f, right = 0.0f, top = 0.0f, bottom = 0.0f;

            if (node.childs[0] == null)
            {
                return;
            }

            // Traverse quadtree depth-first
            foreach (QuadPoint c in node.childs)
            {
                float childVariance = variance(c);

                if (childVariance >= varianceThreshold)
                {
                    PruneAndExpress(a, b, ref connections, c, outgoing, maxDepth);
                }
                else //this should always happen for at least the leaf nodes because their variance is zero
                {
                    // Determine if point is in a band by checking neighbor CPPN values
                    if (outgoing)
                    {
                        left   = Math.Abs(c.w - queryCPPNWeight(a, b, c.x - node.width, c.y));
                        right  = Math.Abs(c.w - queryCPPNWeight(a, b, c.x + node.width, c.y));
                        top    = Math.Abs(c.w - queryCPPNWeight(a, b, c.x, c.y - node.width));
                        bottom = Math.Abs(c.w - queryCPPNWeight(a, b, c.x, c.y + node.width));
                    }
                    else
                    {
                        left   = Math.Abs(c.w - queryCPPNWeight(c.x - node.width, c.y, a, b));
                        right  = Math.Abs(c.w - queryCPPNWeight(c.x + node.width, c.y, a, b));
                        top    = Math.Abs(c.w - queryCPPNWeight(c.x, c.y - node.width, a, b));
                        bottom = Math.Abs(c.w - queryCPPNWeight(c.x, c.y + node.width, a, b));
                    }

                    if (Math.Max(Math.Min(top, bottom), Math.Min(left, right)) > bandThrehold)
                    {
                        TempConnection tc = null;
                        if (outgoing)
                        {
                            //check for LEO
                            if (useLEO && c.Outputs[1] > 0)
                            {
                                tc = new TempConnection(a, b, c.x, c.y, c.w, c.Outputs);
                            }
                            else if (!useLEO)
                            {
                                tc = new TempConnection(a, b, c.x, c.y, c.w, c.Outputs);
                            }
                        }
                        else
                        {
                            //check against leo!
                            if (useLEO && c.Outputs[1] > 0)
                            {
                                tc = new TempConnection(c.x, c.y, a, b, c.w, c.Outputs);
                            }
                            else if (!useLEO)
                            {
                                tc = new TempConnection(c.x, c.y, a, b, c.w, c.Outputs);
                            }
                        }

                        if (tc != null)
                        {
                            connections.Add(tc);
                        }
                    }
                }
            }
        }