コード例 #1
0
        private void CheckSinglePoint(KDNode_Rednaxela <T> pCursor)
        {
            // Work out the distance between this point and the search point.
            double fDistance = kDistanceFunction.Distance(pCursor.points[0], tSearchPoint);

            //// Skip if the point exceeds the threshold.
            //// Technically this should never happen, but be prescise.
            //if (fThreshold >= 0 && fDistance >= fThreshold)
            //    continue;

            // Add the point if either need more points or it's closer than furthest on list so far.
            if (pEvaluated.Size < iPointsRemaining || fDistance <= pEvaluated.MaxKey)
            {
                for (int i = 0; i < pCursor.Size; ++i)
                {
                    // If we don't need any more, replace max
                    if (pEvaluated.Size == iPointsRemaining)
                    {
                        pEvaluated.ReplaceMax(fDistance, pCursor.data[i], i);
                    }

                    // Otherwise insert.
                    else
                    {
                        pEvaluated.Insert(fDistance, pCursor.data[i], i);
                    }
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Check for the next iterator item.
        /// </summary>
        /// <returns>True if we have one, false if not.</returns>
        public bool MoveNext()
        {
            // Bail if we are finished.
            if (iPointsRemaining == 0)
            {
                _Current = default(T);
                return(false);
            }

            // While we still have paths to evaluate.
            while (pPending.Size > 0 && (pEvaluated.Size == 0 || (pPending.MinKey < pEvaluated.MinKey)))
            {
                // If there are pending paths possibly closer than the nearest evaluated point, check it out
                KDNode <T> pCursor = pPending.Min;
                pPending.RemoveMin();

                // Descend the tree, recording paths not taken
                while (!pCursor.IsLeaf)
                {
                    KDNode <T> pNotTaken;

                    // If the seach point is larger, select the right path.
                    if (tSearchPoint[pCursor.iSplitDimension] > pCursor.fSplitValue)
                    {
                        pNotTaken = pCursor.pLeft;
                        pCursor   = pCursor.pRight;
                    }
                    else
                    {
                        pNotTaken = pCursor.pRight;
                        pCursor   = pCursor.pLeft;
                    }

                    // Calculate the shortest distance between the search point and the min and max bounds of the kd-node.
                    float fDistance = kDistanceFunction.DistanceToRectangle(tSearchPoint, pNotTaken.tMinBound, pNotTaken.tMaxBound);

                    // If it is greater than the threshold, skip.
                    if (fThreshold >= 0 && fDistance > fThreshold)
                    {
                        //pPending.Insert(fDistance, pNotTaken);
                        continue;
                    }

                    // Only add the path we need more points or the node is closer than furthest point on list so far.
                    if (pEvaluated.Size < iPointsRemaining || fDistance <= pEvaluated.MaxKey)
                    {
                        pPending.Insert(fDistance, pNotTaken);
                    }
                }

                // If all the points in this KD node are in one place.
                if (pCursor.bSinglePoint)
                {
                    // Work out the distance between this point and the search point.
                    float fDistance = kDistanceFunction.Distance(pCursor.tPoints[0], tSearchPoint);

                    // Skip if the point exceeds the threshold.
                    // Technically this should never happen, but be prescise.
                    if (fThreshold >= 0 && fDistance >= fThreshold)
                    {
                        continue;
                    }

                    // Add the point if either need more points or it's closer than furthest on list so far.
                    if (pEvaluated.Size < iPointsRemaining || fDistance <= pEvaluated.MaxKey)
                    {
                        for (int i = 0; i < pCursor.Size; ++i)
                        {
                            // If we don't need any more, replace max
                            if (pEvaluated.Size == iPointsRemaining)
                            {
                                pEvaluated.ReplaceMax(fDistance, pCursor.tData[i]);
                            }

                            // Otherwise insert.
                            else
                            {
                                pEvaluated.Insert(fDistance, pCursor.tData[i]);
                            }
                        }
                    }
                }

                // If the points in the KD node are spread out.
                else
                {
                    // Treat the distance of each point seperately.
                    for (int i = 0; i < pCursor.Size; ++i)
                    {
                        // Compute the distance between the points.
                        float fDistance = kDistanceFunction.Distance(pCursor.tPoints[i], tSearchPoint);

                        // Skip if it exceeds the threshold.
                        if (fThreshold >= 0 && fDistance >= fThreshold)
                        {
                            continue;
                        }

                        // Insert the point if we have more to take.
                        if (pEvaluated.Size < iPointsRemaining)
                        {
                            pEvaluated.Insert(fDistance, pCursor.tData[i]);
                        }

                        // Otherwise replace the max.
                        else if (fDistance < pEvaluated.MaxKey)
                        {
                            pEvaluated.ReplaceMax(fDistance, pCursor.tData[i]);
                        }
                    }
                }
            }

            // Select the point with the smallest distance.
            if (pEvaluated.Size == 0)
            {
                return(false);
            }

            iPointsRemaining--;
            _CurrentDistance = pEvaluated.MinKey;
            _Current         = pEvaluated.Min;
            pEvaluated.RemoveMin();
            return(true);
        }
コード例 #3
0
        private double findDistance(IChromosome chromosome1, IChromosome chromosome2)
        {
            double distance;

            Dictionary <IChromosome, double> distances;

            lock (_distanceMatrix)
            {
                if (_distanceMatrix.TryGetValue(chromosome1, out distances))
                {
                    // chromosome2 existe na lista do chromosome1
                    if (distances.TryGetValue(chromosome2, out distance))
                    {
                        return(distance);
                    }
                }
            }

            // calcula a distancia
            distance = _distanceFunction.Distance(chromosome1, chromosome2);

            lock (_distanceMatrix)
            {
                // chromosome1 existe na lista
                if (_distanceMatrix.TryGetValue(chromosome1, out distances))
                {
                    // Adiciona na lista de distancias do chromosome1 para o chromosome2
                    distances[chromosome2] = distance;

                    // Checa se o Chromosome2 existe na lista geral
                    if (_distanceMatrix.TryGetValue(chromosome2, out distances))
                    {
                        distances[chromosome1] = distance;
                    }
                    else
                    {
                        // Cria a lista de distancias do chromosome2 e adiciona a distancia para o cromosome1 nela
                        distances = new Dictionary <IChromosome, double>();

                        distances[chromosome1] = distance;

                        try
                        {
                            _distanceMatrix.Add(chromosome2, distances);
                        }
                        catch
                        {
                            _distanceMatrix[chromosome2][chromosome1] = distance;
                        }
                    }
                }
                // chromosome1 não existe na lista
                else
                {
                    // calcula a distância
                    distance = _distanceFunction.Distance(chromosome1, chromosome2);

                    // cria a lista de distancias do chromosome1 e adiciona a distancia para o chromosome2 nela
                    distances = new Dictionary <IChromosome, double>();

                    distances[chromosome2] = distance;

                    try
                    {
                        _distanceMatrix.Add(chromosome1, distances);
                    }
                    catch
                    {
                        _distanceMatrix[chromosome1][chromosome2] = distance;
                    }

                    // chromosome2 existe na lista
                    if (_distanceMatrix.TryGetValue(chromosome2, out distances))
                    {
                        // Adiciona na lista de distâncias do chromosome2 para o chromosome1
                        distances[chromosome1] = distance;
                    }
                    // chromosome2 não existe na lista
                    else
                    {
                        // Cria a lista de distâncias para o chromosome2 e adiciona a lista para o chromosome1 nela
                        distances = new Dictionary <IChromosome, double>();

                        distances[chromosome1] = distance;

                        try
                        {
                            _distanceMatrix.Add(chromosome2, distances);
                        }
                        catch
                        {
                            _distanceMatrix[chromosome2][chromosome1] = distance;
                        }
                    }
                }
            }

            return(distance);
        }