2012-04-01 5 views
11

Tôi có một chương trình phân tán lớn trên nhiều máy chủ vật lý khác nhau, mỗi chương trình sinh ra nhiều chủ đề, mỗi thread sử dụng Math.random() trong hoạt động của nó để vẽ một phần từ nhiều các nhóm tài nguyên chung.cách thức ngẫu nhiên là Math.random() trong java trên các jvms khác nhau hoặc các máy khác nhau

Mục đích là sử dụng đồng đều các hồ bơi trên tất cả các hoạt động. Đôi khi, nó không xuất hiện ngẫu nhiên bằng cách nhìn vào một ảnh chụp nhanh trên một hồ bơi tài nguyên để xem những phần nào nó nhận được ngay lập tức (nó thực sự có thể được, nhưng thật khó để đo lường và tìm ra chắc chắn).

Có điều gì tốt hơn Math.random() và hoạt động tốt không (ít nhất là kém hơn nhiều)?

+0

+1 cho một câu hỏi hay. Vui lòng cho tôi biết nếu bạn tìm thấy câu trả lời :) –

+0

Vui lòng xem liên kết sau. http: //www.coderanch.com/t/510167/java/java/Random-generator-failing –

+0

Tại sao không sử dụng một số bộ lập lịch cho các tài nguyên chung? –

Trả lời

2

Math.random() được dựa trên java.util.Random, dựa trên linear congruential generator. Điều đó có nghĩa là sự ngẫu nhiên của nó không hoàn hảo, nhưng đủ tốt cho hầu hết các nhiệm vụ, và có vẻ như nó là đủ cho nhiệm vụ của bạn.

Tuy nhiên, có vẻ như bạn đang sử dụng giá trị trả lại double của Math.random() để chọn giữa số lượng lựa chọn cố định, có thể làm giảm thêm chất lượng của tính ngẫu nhiên. Nó sẽ là tốt hơn để sử dụng java.util.Random.nextInt() - chỉ cần chắc chắn để tái sử dụng cùng một đối tượng Random.

Đôi khi, nó không xuất hiện để ngẫu nhiên bằng cách nhìn vào một bản chụp trên một hồ bơi tài nguyên để xem những mẩu nó nhận được ngay lúc đó

não của chúng tôi là thực sự tốt tại đốm mẫu trong ngẫu nhiên hoàn hảo , điều đó có nghĩa là hầu như không có gì.

+0

điểm tốt trên Random.nextInt(), hiện tại tôi chỉ nhân đôi số ngẫu nhiên với n và sau đó làm tròn nó thành số nguyên gần nhất, là rất khác với Random(). NextInt()? – user881480

+0

@ user881480: yes - Ngẫu nhiên tạo ra các số nguyên, Math.random() thực hiện thêm công việc để chuyển đổi số đó thành giá trị gấp đôi, chỉ để bạn chuyển đổi nó trở lại thành int. Chuyển đổi kép này có thể làm giảm chất lượng của sự ngẫu nhiên (không thực sự chắc chắn, nhưng có thể). –

0

chủ đề này có thể có ích: How good is java.util.Random?

khác lựa chọn:

  • tạo một hạt giống ngẫu nhiên khi init trường hợp ngẫu nhiên
  • nếu bạn sử dụng sử dụng Linux/dev/urandom
+0

Tôi không muốn gọi quá trình bên ngoài từ Java vì nó làm giảm hiệu suất, tôi đang chạy ở tốc độ 1 hoạt động mỗi giây và có rất nhiều (hàng trăm nghìn hoặc triệu) mỗi ngày trên máy chủ. – user881480

+0

do đó điều đơn giản nhất mà tôi có thể làm là tạo ra máy phát điện của riêng bạn với thời gian dài hơn (như được mô tả trong liên kết). bạn cũng phải nhớ rằng cơ hội nhận được 1,1,1,1,1 là cơ hội giống như 45,1002,783,199,6 – shem

1

Thuật toán Math.Random là "đủ ngẫu nhiên" cho bất kỳ nền tảng nào. Mô hình toán học được sử dụng để tạo các số psuedo-random là một số tốt. Nó phụ thuộc vào số lượng chủ đề bạn sử dụng. Đối với bất cứ điều gì, nhưng một số lượng lớn các chủ đề, điều này sẽ không cung cấp cho bạn thậm chí phân phối (bản chất của các số ngẫu nhiên), và sau đó Math.random() sẽ cung cấp cho bạn rất nhiều chi phí.

Hãy thử tùy chọn tốt hơn: tạo lớp học tài nguyên, phân phối chúng đồng đều - và sau đó chỉ giữ phần quan trọng trong phương pháp "phân phối" được bảo vệ.

+0

tại sao các số ngẫu nhiên không cung cấp cho bạn một bản phân phối đồng đều? trong trường hợp của tôi số lượng chủ đề cho mỗi chương trình là vài trăm, nhưng mỗi luồng thực hiện nhiều thao tác (1 mỗi giây, trong đó mỗi thao tác gọi Math.random()). – user881480

+0

lớp tài nguyên sẽ phân phối tài nguyên một cách ngẫu nhiên như thế nào? nó có phải sử dụng Math.random() không? – user881480

+0

Bạn không cần phân phối ngẫu nhiên, chỉ cần tạo một lớp đơn giản được gọi là Tài nguyên, một phương thức nextResource() được đồng bộ hóa. Bằng cách đó bạn cứ tiếp tục trải qua từng cái một, đảm bảo phân phối đều. Ngoài ra, việc sử dụng hàng trăm chuỗi tạo nhiều chi phí hơn so với thời gian đã lưu ngoại trừ một số trường hợp rất cụ thể; bạn nên giới hạn số lượng luồng cho những gì hệ thống của bạn có thể sử dụng hiệu quả. – user1304831

0

Mỗi thuật toán javadoc Math.random() chỉ là một cách dễ dàng để sử dụng java.util.Random. Điều đó nói rằng nó chỉ là một giả ngẫu nhiên algorythm. Một cách dễ dàng để kiểm tra ngẫu nhiên như thế nào một algorythm thực sự là, là bằng cách vẽ các điểm ngẫu nhiên trên lưới x/y. Bạn không nên tìm thấy bất kỳ mẫu nào.

Để nhận số ramdom thực, bạn có thể sử dụng các dịch vụ như http://www.random.org. Nếu điều này là để làm chậm, có thể gọi nó thường xuyên để hạt giống java.util.Random có ​​thể giúp bạn gần gũi hơn với sự thật ngẫu nhiên.

+0

java.util.Random() có được một hạt giống khác biệt nào? – user881480