2010-09-05 30 views
5

tôi muốn tạo một boolean ngẫu nhiên trong JavaScript, nhưng tôi muốn lấy giá trị trước đó vào tài khoản. Nếu giá trị trước đó là đúng, tôi muốn nó có nhiều khả năng cho giá trị tiếp theo là đúng. Tại thời điểm này tôi đã có này (đây là trong bối cảnh của một đóng cửa - goUplastGoUp là người dân địa phương với phạm vi chứa):cách thanh lịch để thiên vị boolean ngẫu nhiên

function setGoUp() { 
    goUp = getRandomBoolean(); 

    if(lastGoUp) { 
     goUp = getRandomBoolean() || goUp; 
    } 
    else { 
     goUp = getRandomBoolean() && goUp; 
    } 
    lastGoUp = goUp; 
} 

Vì vậy, thuật toán đi:

  1. Nhận một ngẫu nhiên boolean
  2. Nếu boolean ngẫu nhiên từ các cuộc gọi trước đây là Đúng:

    a) nhận được một boolean ngẫu nhiên, và or hai cùng

    b) khác nhận được một boolean ngẫu nhiên và and này lại với nhau.

Tôi chắc chắn thuật toán này có thể được đơn giản hóa. Tôi băn khoăn về việc làm:

if(lastGoUp && goUp) { 
    goUp = goUp * (getRandomBoolean() || goUp); 
} 

nhưng điều đó có vẻ thực sự dơ bẩn.

Ngoài ra còn có một vấn đề với thuật toán này có nghĩa là tôi chỉ có thể tăng gấp đôi khả năng mắc boolean cùng một lần nữa - tôi không thể tinh chỉnh nó một cách dễ dàng. Bất kỳ ý tưởng?

Trả lời

11

Bạn nên xác định sự phân bố mà bạn muốn, nhưng có lẽ bạn đang tìm kiếm những điều sau đây?

if (lastGoUp) { 
    goUp = Math.random() < 0.8; 
} else { 
    goUp = Math.random() < 0.2; 
} 
+0

Tất nhiên! Tôi đã không bắt đầu với bất kỳ loại thiên vị, vì vậy tôi đã cố gắng để làm việc ra làm thế nào để thiên vị một boolean trước tồn tại. Cảm ơn :) – Skilldrick

+1

Btw, tôi quyết định đi với '< 0.8' and '> 0.8' vì điều đó có ý nghĩa hơn đối với tôi. Nó cũng rõ ràng hơn để biến 0.8 thành hằng số có tên. – Skilldrick

+0

'GetRandomFloatBetween0And1' (nghĩa là, trong khoảng' [0, 1) ') chỉ là những gì' Math.random() 'thực hiện. –

0

Tôi sẽ chỉ làm cho xác suất nhận được giá trị true là một số float biến rõ ràng p. Sau đó, tôi có thể tinh chỉnh nó một cách dễ dàng, bằng cách tăng p một cách nào đó nếu tôi có true lần cuối cùng hoặc không làm gì với nó nếu tôi có 'false'.

4

Thay vì nhận được một boolean ngẫu nhiên, có một số ngẫu nhiên, nói giữa 0 và 99. Giữ một giá trị ngưỡng thay vì số cuối cùng, và điều chỉnh ngưỡng theo kết quả:

var threshold = 50; 

function setGoUp() { 
    goUp = getRandomNumber() < threshold; 
    threshold += goUp ? -10 : 10; 
} 

Điều này sẽ giữ một tab đang chạy, vì vậy nếu bạn nhận được kết quả liên tiếp giống nhau, xác suất sẽ tiếp tục giảm cho kết quả đó.

Nếu bạn chỉ muốn xem xét các kết quả cuối cùng, bạn sẽ thay thiết lập các ngưỡng tới một giá trị cụ thể:

threshold = goUp ? 40 : 60; 
+0

Cảm ơn. Tôi chắc chắn sẽ ghi nhớ điều này nếu tôi cần xem xét nhiều hơn một kết quả. – Skilldrick

0

có thể thay thế Math.random cho một Randomizer tốt hơn.

var setGoUp = (function(){ 
    var last; 
    return function(){ 
     // if last 66% chance for true else 50% chance of true. 
     return !!(last ? Math.random()*3 : Math.random()*2); 
    } 
}()); 

!! chuyển đổi bất kỳ thứ gì thành boolean, 0 = false.

2

Nếu bạn chỉ muốn xác suất của sự kiện tiếp theo phụ thuộc vào giá trị hiện tại và không phải là lịch sử của giá trị cho đến bây giờ, thì bạn muốn được gọi là quy trình Markov.Thường thì chúng được thực hiện với một bảng xác suất 2D mà bạn tra cứu (đầu ra của mỗi kết quả kế tiếp cho hiện tại), nhưng với một sự kiện có giá trị bool đơn giản, câu lệnh if là đủ (xem câu trả lời của meriton), lưu ý rằng nó tương ứng với bảng xác suất [0,8 0,2; 0,2 0,8]).

Nếu bạn muốn thứ gì đó có nhiều khả năng hơn, bạn cần phải tạo ra một chuỗi xác suất để thành công mà có thể tiếp cận, nhưng không vượt quá, 1. Có bất kỳ số nào các công thức có thể làm điều này, tùy thuộc vào mức độ mạnh mẽ mà bạn muốn thiên vị trở thành và tốc độ bạn muốn nó đạt được ở đó.

+0

Giải pháp cũ đã làm việc, bởi vì tôi đã tạo ra hai booleans ngẫu nhiên mỗi lần. Nếu 'lastGoUp' là' true' thì tôi 'hoặc'd hai booleans cùng nhau (1 trong 4 cơ hội cũng đúng), và nếu' lastGoUp' là 'false' tôi' và 'hai booleans cùng nhau (1 in 4 cơ hội cũng sai). Đó là một thuật toán khá lộn xộn. – Skilldrick

+0

Ah, tôi hiểu, bạn nói đúng - vì vậy nó có hiệu lực khi làm một việc gì đó như [.75 .25; .25 .75]. Tôi đã xóa xác nhận của tôi rằng điều đó sẽ không hoạt động. –

+0

Không sao cả. Như tôi đã nói, đó không phải là mã sạch nhất! – Skilldrick

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