2008-09-25 24 views
16

Tôi đang cố gắng xác định một cách nhanh chóng để lưu trữ một bộ đối tượng, mỗi đối tượng có giá trị tọa độ x và y, sao cho tôi có thể nhanh chóng truy xuất tất cả các đối tượng trong một hình chữ nhật hoặc hình tròn. Đối với các bộ đối tượng nhỏ (~ 100) cách tiếp cận ngây thơ của việc lưu trữ chúng đơn giản trong một danh sách, và lặp lại thông qua nó, tương đối nhanh. Tuy nhiên, đối với các nhóm lớn hơn nhiều, đó là dự kiến ​​chậm. Tôi đã thử lưu trữ chúng trong một cặp Bản đồ cây là tốt, một sắp xếp trên tọa độ x, và một sắp xếp trên tọa độ y, sử dụng mã này:Lưu trữ các đối tượng để định vị theo toạ độ x, y

xSubset = objectsByX.subSet(minX, maxX); 
ySubset = objectsByY.subSet(minY, maxY); 
result.addAll(xSubset); 
result.retainAll(ySubset); 

này cũng làm việc, và là nhanh hơn cho lớn hơn bộ đối tượng, nhưng vẫn chậm hơn tôi muốn. Một phần của vấn đề cũng là các đối tượng này di chuyển xung quanh, và cần phải được đưa trở lại vào bộ nhớ này, có nghĩa là loại bỏ chúng khỏi và thêm chúng vào cây/danh sách. Tôi không thể không nghĩ rằng phải có giải pháp tốt hơn trên mạng. Tôi đang thực hiện điều này trong Java, nếu nó làm cho bất kỳ sự khác biệt, mặc dù tôi hy vọng bất kỳ giải pháp sẽ được nhiều hơn trong các hình thức của một mô hình/thuật toán hữu ích.

Trả lời

1

Hãy xem Kd-Trees.

+0

Rất tiếc, quá chậm ... –

14

Quadtrees dường như giải quyết được vấn đề cụ thể mà tôi đã hỏi. Kd-Trees là một dạng tổng quát hơn, cho bất kỳ số thứ nguyên nào, thay vì chỉ hai.

R-Trees cũng có thể hữu ích nếu các đối tượng được lưu trữ có hình chữ nhật bị ràng buộc, thay vì chỉ là một điểm đơn giản.

Thuật ngữ chung cho các loại cấu trúc này là Spatial Index.

Có triển khai Java QuadtreeR-Tree.

0

Bạn có thể đặt tất cả các x dây vào bản đồ và các dây y trong bản đồ khác và có giá trị bản đồ trỏ đến đối tượng.

 TreeMap<Integer, TreeMap<Integer, Point>> xMap = new TreeMap<Integer, TreeMap<Integer, Point>>(); 
     for (int x = 1; x < 100; x += 2) 
      for (int y = 0; y < 100; y += 2) 
       { 
        Point p = new Point(x, y); 
        TreeMap<Integer, Point> tempx = xMap.get(x); 
        if (tempx == null) 
         { 
          tempx = new TreeMap<Integer, Point>(); 
          xMap.put(x, tempx); 
         } 
        tempx.put(y, p); 
       } 
     SortedMap<Integer, TreeMap<Integer, Point>> tempq = xMap.subMap(5, 8); 
     Collection<Point> result = new HashSet<Point>(); 
     for (TreeMap<Integer, Point> smaller : tempq.values()) 
      { 
       SortedMap<Integer, Point> smallerYet = smaller.subMap(6, 12); 
       result.addAll(smallerYet.values()); 
      } 
     for (Point q : result) 
      { 
       System.out.println(q); 
      } 
    } 
+0

Nếu bạn đang làm việc với các điểm trên một mặt phẳng tiếp giáp thay vì một vài điểm rời rạc, bạn có thể cải thiện điều này bằng cách sử dụng "nhóm" có kích thước cụ thể. Không tốt bằng cây quad, nhưng đơn giản hơn để thực hiện. –

Các vấn đề liên quan