Hiệu quả Đường ngắm Java 2d cho rất nhiều thực thể?


7

Vấn đề của tôi hôm nay là thế này:

Hình ảnh của một tấn người trong bản đồ

Tôi có nhiều thường dân đi khắp nơi, họ là những lớp được lưu trữ bởi một danh sách mảng.

Ý tưởng là khi họ thấy một sự hoảng loạn dân sự khác, họ sẽ bắt đầu hoảng loạn và nó sẽ lan rộng.

Đầu tiên tôi gọi mỗi Step()hàm lớp bằng cách lặp qua một trình vòng lặp. Sau đó, trong Step()chức năng, nó đi qua một trình lặp dân sự khác Khi đi qua, nó cố gắng phát hiện xem nó có thể nhìn thấy các thường dân khác trong trình vòng lặp hay không, đây là lúc thời gian thực hiện từ 0 đến 50 Millisecond vì có 100 thường dân.

Đây là vấn đề tôi cần khắc phục, tôi đã cố gắng thực hiện một cách dễ dàng để phát hiện xem có bất kỳ đối tượng nào theo cách từ điểm a đến điểm b không.

Đây là mã cho đường ngắm:

public static Object LOS(int x, int y, int x2, int y2, String Scan, Object Me, Object You) {
   DirectionX = (x-x2)/Quality;
   DirectionY = (y-y2)/Quality;
   CurrentX = x;
   CurrentY = y;
   String[] ScanArray = Scan.split(":");
   for(int I=0;I<=Quality;I++) {
      for(String Type: ScanArray) {
         if(Type.equals("Boxs")) {
            Iterator it=Level.Boxs.iterator();
            while(it.hasNext()) {
               Box Box = (Box)it.next();
               if(Me!=Box&&You!=Box) {
                  //Collision = Tools.Collision((int)(CurrentX-(Width/2)), (int)(CurrentY-(Width/2)), Width, Width, Box.GetX(), Box.GetY(), Box.GetWidth(), Box.GetHeight(), 1);
                  boolean Col = Tools.BasicCollision((int)(CurrentX-(Width/2)), (int)(CurrentY-(Width/2)), Width, Width, Box.GetX(), Box.GetY(), Box.GetWidth(), Box.GetHeight());
               }
            }
         }
      }

      CurrentX-=DirectionX;
      CurrentY-=DirectionY;
   }
   return null;
}

Nếu bạn đau đầu, các nguyên tắc cơ bản là:

Nó chỉ ra 10 điểm ở giữa và phát hiện xem nó có ở bên trong hay không, bằng cách sử dụng BasicCollision:

public static boolean BasicCollision(int x, int y, int width, int height, int x2, int y2, int width2, int height2) {
   if(x<x2+width&&x+width>x2&&y<y2+height&&y+height>y2) {
      return true;
   } else {
      return false;
   }
}

Câu hỏi của tôi là: Có cách nào dễ dàng hơn để phát hiện Đường ngắm này mà không ảnh hưởng nghiêm trọng đến hiệu suất của tôi với số lượng lớn không? Bất kỳ thông tin phản hồi?


2
1. 404'd ngày LOS.txt2. Chúng tôi không muốn xem tất cả mã của bạn. Cung cấp một SSCCE .
Matt Ball

Cảm ơn đã giúp Matt chỉnh sửa, tôi đã sửa lỗi 404 :) Tôi chỉ hiển thị mã quan trọng.

Câu trả lời:


5

Một suy nghĩ sẽ là duy trì những người không hoảng loạn và hoảng loạn trong các danh sách riêng biệt N và P, sau đó giới hạn kiểm tra LOS của bạn ở <n, p> ∈ N × P. Bằng cách đó, bạn không bao giờ kiểm tra những người cùng trạng thái, điều này sẽ tăng tốc mọi thứ lên.

Một điều nữa (mà bạn có thể đã làm - không chắc chắn) sẽ là đảm bảo rằng một khi bạn xác định rằng một người không phải là người hay nói dối, ngay lập tức hãy dừng việc kiểm tra lại cho người không phải là người trước đó. Điều này sẽ giúp quy mô thuật toán của bạn tăng kích thước dân số cho một bản đồ cố định. Khi dân số trở nên rất lớn thì bạn nên hội tụ 100% hoảng loạn khá nhanh, điều đó có nghĩa là không cần kiểm tra thêm như đã nêu trong các bình luận dưới đây.


Lời khuyên tốt, tôi vừa thêm bộ lọc đó, ở mức 0% hoảng loạn là 1Millisecond, ở mức 100%, nó đạt 50, nhưng điều này chắc chắn làm cho nó thực tế, cảm ơn.

Một cái gì đó không đúng - số lượng kiểm tra phải là (tp) * p, trong đó t = tổng, p = hoảng loạn. Vì vậy, khi p = t thì số kiểm tra sẽ là 0. Theo trực giác, một khi mọi người đang hoảng loạn, không có lý do gì để thực hiện bất kỳ kiểm tra nào nữa. Bạn có chắc chắn rằng danh sách N của bạn chứa những người không phải là người chơi, trái ngược với việc chứa toàn bộ dân số không? Tôi đoán rằng 100% bạn đang so sánh mọi người hoảng loạn với toàn bộ dân số, đó là lý do tại sao nó chậm hơn.

2

Từ mô tả của bạn, có vẻ như mã của bạn đang lặp đi lặp lại trên mỗi cặp đôi thường dân có thể. Bản vẽ cho thấy điều này là không cần thiết. Bạn có thể sử dụng một số loại lập chỉ mục hình học để theo dõi dân thường gần đó. Sau đó kiểm tra chúng trước. Nếu họ ở trong LOS, thì hoảng loạn. Nếu không thì kiểm tra xa dân thường.


Cảm ơn, tôi đã thực hiện điều đó, trước khi tối ưu hóa, nó ở mức 100 mili giây.

0

Bạn có một vài lựa chọn:

A) Giả sử rằng mọi người có thể hoảng loạn cũng nghe thấy tiếng người khác la hét, vì vậy dòng mã tầm nhìn không phải là XD quan trọng.

B) Trong trường hợp A không phải là một lựa chọn, bạn phải làm điều này cho mỗi thường dân:

  1. Tính xem đoạn giữa hai thường dân có độ dài nhỏ hơn hoặc bằng một số giá trị không đổi.
  2. Tính toán nếu đoạn này giao với một poligon (hình chữ nhật, trong trường hợp của bạn).

Bạn phải thực hiện 1 trước 2 vì nó làm giảm đáng kể số lượng công việc, vì 2 là tính toán đắt nhất. Ngoài ra, bạn phải xem xét một số loại "bộ nhớ" về các tính toán bạn đã thực hiện, ví dụ: Nếu bạn vừa xử lý phân đoạn C1-C2, đừng làm lại C2-C1.

Ngoài ra, bạn phải tối ưu hóa 2. Kiểm tra xem một đoạn có giao với hình chữ nhật tương đương với kiểm tra nếu một đoạn đã cho có giao với 4 đoạn không. Khi bạn đã giao nhau với một trong số họ, chúng tôi chắc chắn rằng dân thường không nhìn thấy nhau, vì vậy sẽ không có ý nghĩa gì khi xử lý các phân đoạn còn lại trong hình chữ nhật.

Vì đây là một vấn đề hình học điển hình, được gọi là vấn đề giao cắt đoạn đường , bạn có thể tìm thấy rất nhiều mã nguồn mở trên internet. Hầu hết mọi người sử dụng thuật toán quét dòng cùng với một số cấu trúc dữ liệu.


Cảm ơn về cái nhìn sâu sắc, tôi đang thực hiện một số nghiên cứu wiki về các thuật toán này.
user940982

0

Nếu bạn coi các phòng là khu vực, được nối bởi các cổng , bạn chỉ phải thực hiện quét tầm nhìn trong mỗi phòng và các phần của phòng liền kề có thể nhìn thấy qua các cổng được xác định trước.

Tầm nhìn của bạn có khả năng không tính đến hướng mà dân thường đang phải đối mặt? Trong trường hợp như vậy, nếu bạn chia các phòng có chướng ngại vật như cột trụ hoặc đi vòng quanh các góc thành các khu vực lồi riêng biệt và giả sử rằng tất cả thường dân trong cùng khu vực đều có thể nhìn thấy nhau. Bạn có thể tiến xa hơn bằng cách có các vùng lõm chồng chéo và cho phép dân thường ở nhiều khu vực cùng một lúc để tìm được càng nhiều càng tốt trong cùng khu vực với dân thường khác để tránh tất cả các kiểm tra tầm nhìn khác.

Nếu địa hình của bạn không bằng phẳng và bạn có một số lượng lớn các tác nhân thì bạn có thể quan tâm đến việc quét O (n) này (trong đó N là độ chi tiết của lưới mà bạn đã chia địa hình):nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.