コード例 #1
0
        /// <summary>
        /// Searches the graph for nearby vertices assuming it has been sorted.
        /// </summary>
        /// <typeparam name="TEdgeData"></typeparam>
        public static List <uint> SearchHilbert <TEdgeData>(this GraphBase <TEdgeData> graph, int n, float latitude, float longitude,
                                                            float offset)
            where TEdgeData : struct, IGraphEdgeData
        {
            var targets = HilbertCurve.HilbertDistances(
                System.Math.Max(latitude - offset, -90),
                System.Math.Max(longitude - offset, -180),
                System.Math.Min(latitude + offset, 90),
                System.Math.Min(longitude + offset, 180), n);

            targets.Sort();
            var vertices = new List <uint>();

            var   targetIdx = 0;
            var   vertex1 = (uint)1;
            var   vertex2 = (uint)graph.VertexCount;
            float vertexLat, vertexLon;

            while (targetIdx < targets.Count)
            {
                uint vertex;
                int  count;
                if (GraphExtensions.SearchHilbert(graph, targets[targetIdx], n, vertex1, vertex2, out vertex, out count))
                {         // the search was successful.
                    while (count > 0)
                    {     // there have been vertices found.
                        if (graph.GetVertex((uint)vertex + (uint)(count - 1), out vertexLat, out vertexLon))
                        { // the vertex was found.
                            if (System.Math.Abs(latitude - vertexLat) < offset &&
                                System.Math.Abs(longitude - vertexLon) < offset)
                            { // within offset.
                                vertices.Add((uint)vertex + (uint)(count - 1));
                            }
                        }
                        count--;
                    }

                    // update vertex1.
                    vertex1 = vertex;
                }

                // move to next target.
                targetIdx++;
            }
            return(vertices);
        }
コード例 #2
0
        /// <summary>
        /// Searches the graph for nearby vertices assuming it has been sorted.
        /// </summary>
        /// <typeparam name="TEdgeData"></typeparam>
        public static bool SearchHilbert <TEdgeData>(this GraphBase <TEdgeData> graph, long hilbert, int n,
                                                     uint vertex1, uint vertex2, out uint vertex, out int count)
            where TEdgeData : struct, IGraphEdgeData
        {
            var hilbert1 = GraphExtensions.HilbertDistance(graph, n, vertex1);
            var hilbert2 = GraphExtensions.HilbertDistance(graph, n, vertex2);

            while (vertex1 <= vertex2)
            {
                // check the current hilbert distances.
                if (hilbert1 > hilbert2)
                { // situation is impossible and probably the graph is not sorted.
                    throw new Exception("Graph not sorted: Binary search using hilbert distance not possible.");
                }
                if (hilbert1 == hilbert)
                { // found at hilbert1.
                    var lower = vertex1;
                    while (hilbert1 == hilbert)
                    {
                        lower--;
                        if (lower == 0)
                        { // stop here, not more vertices lower.
                            break;
                        }
                        hilbert1 = GraphExtensions.HilbertDistance(graph, n, lower);
                    }
                    lower++;
                    var upper = vertex1;
                    hilbert1 = GraphExtensions.HilbertDistance(graph, n, upper);
                    while (hilbert1 == hilbert)
                    {
                        upper++;
                        if (upper > graph.VertexCount)
                        { // stop here, no more vertices higher.
                            break;
                        }
                        hilbert1 = GraphExtensions.HilbertDistance(graph, n, upper);
                    }
                    upper--;
                    vertex = lower;
                    count  = (int)(upper - lower) + 1;
                    return(true);
                }
                if (hilbert2 == hilbert)
                { // found at hilbert2.
                    var lower = vertex2;
                    while (hilbert2 == hilbert)
                    {
                        lower--;
                        if (lower == 0)
                        { // stop here, not more vertices lower.
                            break;
                        }
                        hilbert2 = GraphExtensions.HilbertDistance(graph, n, lower);
                    }
                    lower++;
                    var upper = vertex2;
                    hilbert2 = GraphExtensions.HilbertDistance(graph, n, upper);
                    while (hilbert2 == hilbert)
                    {
                        upper++;
                        if (upper > graph.VertexCount)
                        { // stop here, no more vertices higher.
                            break;
                        }
                        hilbert2 = GraphExtensions.HilbertDistance(graph, n, upper);
                    }
                    upper--;
                    vertex = lower;
                    count  = (int)(upper - lower) + 1;
                    return(true);
                }
                if (hilbert1 == hilbert2 ||
                    vertex1 == vertex2 ||
                    vertex1 == vertex2 - 1)
                { // search is finished.
                    vertex = vertex1;
                    count  = 0;
                    return(true);
                }

                // Binary search: calculate hilbert distance of the middle.
                var vertexMiddle  = vertex1 + (uint)((vertex2 - vertex1) / 2);
                var hilbertMiddle = GraphExtensions.HilbertDistance(graph, n, vertexMiddle);
                if (hilbert <= hilbertMiddle)
                { // target is in first part.
                    vertex2  = vertexMiddle;
                    hilbert2 = hilbertMiddle;
                }
                else
                { // target is in the second part.
                    vertex1  = vertexMiddle;
                    hilbert1 = hilbertMiddle;
                }
            }
            vertex = vertex1;
            count  = 0;
            return(false);
        }
コード例 #3
0
 /// <summary>
 /// Searches the graph for nearby vertices assuming it has been sorted.
 /// </summary>
 /// <typeparam name="TEdgeData"></typeparam>
 public static List <uint> SearchHilbert <TEdgeData>(this GraphBase <TEdgeData> graph, float latitude, float longitude,
                                                     float offset)
     where TEdgeData : struct, IGraphEdgeData
 {
     return(GraphExtensions.SearchHilbert(graph, GraphExtensions.DefaultHilbertSteps, latitude, longitude, offset));
 }