Tạo trình tạo số ngẫu nhiên trong Javascript


372

Có thể chọn trình tạo số ngẫu nhiên (Math.random) trong Javascript không?


không rõ liệu bạn có muốn gieo hạt giống để bạn nhận được kết quả tương tự lặp đi lặp lại cho các lần chạy thử khác nhau hay bạn muốn gieo hạt giống với 'thứ gì đó duy nhất' cho mỗi người dùng để có sự ngẫu nhiên tốt hơn giữa việc sử dụng.
simbo1905

2
Không, thật không may là nó không thể. jsrand là một thư viện nhỏ tôi đã viết khi tôi cần một PRNG có thể gieo hạt. Ngoài ra còn có các thư viện phức tạp khác mà bạn có thể tìm thấy sự cho phép của nó.
Domenico De Felice

4
Thêm vào câu hỏi: làm thế nào có thể là một ý tưởng tốt để cung cấp một PRNG mà không có phương tiện để gieo nó ?? Có bất kỳ lý do tốt cho việc này?
Alan

Câu trả lời:



159

LƯU Ý: Mặc dù (hoặc đúng hơn, vì) cô đọng và thanh lịch rõ ràng, thuật toán này không có nghĩa là một thuật toán chất lượng cao về tính ngẫu nhiên. Hãy tìm ví dụ như những người được liệt kê trong câu trả lời này để có kết quả tốt hơn.

(Ban đầu được điều chỉnh từ một ý tưởng thông minh được trình bày trong một bình luận cho một câu trả lời khác.)

var seed = 1;
function random() {
    var x = Math.sin(seed++) * 10000;
    return x - Math.floor(x);
}

Bạn có thể đặt thành seedbất kỳ số nào, chỉ cần tránh số không (hoặc bất kỳ bội số nào của Math.PI).

Theo tôi, sự thanh lịch của giải pháp này xuất phát từ việc không có bất kỳ số "ma thuật" nào (ngoài 10000, đại diện cho số lượng chữ số tối thiểu bạn phải vứt đi để tránh các mẫu lẻ - xem kết quả với các giá trị 10 , 100 , 1000 ). Brevity cũng tốt

Nó chậm hơn một chút so với Math.random () (theo hệ số 2 hoặc 3), nhưng tôi tin rằng nó nhanh như bất kỳ giải pháp nào khác được viết bằng JavaScript.


20
Có cách nào để chứng minh RNG này tạo ra các số được phân phối đồng đều không? Thực tế có vẻ như: jsfiddle.net/bhrLT
Nathan Breit

6
6.000.000 ops / giây là khá nhanh, tôi không có kế hoạch tạo ra hơn ~ 3.000.000 mỗi lần nhấp. Đùa, đây là tuyệt vời.
AMK

59
-1, Đây hoàn toàn không phải là một bộ lấy mẫu thống nhất - nó khá thiên về 0 và 1 (xem jsfiddle.net/bhrLT/17 , có thể mất một lúc để tính toán). Các giá trị liên tiếp được tương quan - mỗi 355 giá trị, và thậm chí nhiều hơn nữa cứ sau mỗi 710, có liên quan. Vui lòng sử dụng một cái gì đó cẩn thận hơn suy nghĩ!
Spencer nelson

37
Câu hỏi không phải là về việc tạo một trình tạo số ngẫu nhiên an toàn bằng mật mã, mà là một cái gì đó hoạt động trong javascript, hữu ích cho các bản demo nhanh, v.v. Tôi sẽ lấy một cái gì đó nhanh chóng và đơn giản để phân phối tốt hơn một triệu số ngẫu nhiên cho mục đích đó.
Jason Goemaat

15
Hãy cẩn thận. Math.sin () có thể cho các kết quả khác nhau trên máy khách và máy chủ. Tôi sử dụng Meteor (sử dụng javascript trên máy khách và máy chủ).
Obiwahn

145

Tôi đã triển khai một số trình tạo số Pseudorandom tốt, ngắn và nhanh hàm (PRNG) trong JavaScript đơn giản. Tất cả chúng có thể được gieo hạt và cung cấp số lượng chất lượng tốt.

Trước hết, hãy cẩn thận để khởi tạo PRNG của bạn đúng cách. Hầu hết các trình tạo bên dưới không có quy trình tạo hạt tích hợp (vì đơn giản), nhưng chấp nhận một hoặc nhiều giá trị 32 bit làm trạng thái ban đầu của PRNG. Các hạt tương tự (ví dụ: hạt giống đơn giản là 1 và 2) có thể gây ra mối tương quan trong các PRNG yếu hơn, dẫn đến đầu ra có các thuộc tính tương tự (chẳng hạn như các mức được tạo ngẫu nhiên là tương tự nhau). Để tránh điều này, cách tốt nhất là khởi tạo PRNG với một hạt giống được phân phối tốt.

Rất may, các hàm băm rất tốt trong việc tạo hạt giống cho PRNG từ các chuỗi ngắn. Hàm băm tốt sẽ tạo ra kết quả rất khác nhau ngay cả khi hai chuỗi tương tự nhau. Đây là một ví dụ dựa trên chức năng trộn của MurmurHash3:

function xmur3(str) {
    for(var i = 0, h = 1779033703 ^ str.length; i < str.length; i++)
        h = Math.imul(h ^ str.charCodeAt(i), 3432918353),
        h = h << 13 | h >>> 19;
    return function() {
        h = Math.imul(h ^ h >>> 16, 2246822507);
        h = Math.imul(h ^ h >>> 13, 3266489909);
        return (h ^= h >>> 16) >>> 0;
    }
}

Mỗi lệnh gọi tiếp theo đến hàm trả về xmur3tạo ra giá trị băm 32 bit "ngẫu nhiên" mới sẽ được sử dụng làm hạt giống trong PRNG. Đây là cách bạn có thể sử dụng nó:

// Create xmur3 state:
var seed = xmur3("apples");
// Output four 32-bit hashes to provide the seed for sfc32.
var rand = sfc32(seed(), seed(), seed(), seed());

// Output one 32-bit hash to provide the seed for mulberry32.
var rand = mulberry32(seed());

// Obtain sequential random numbers like so:
rand();
rand();

Ngoài ra, chỉ cần chọn một số dữ liệu giả để đệm hạt giống và tiến bộ tạo một vài lần (12-20 lần lặp) để trộn kỹ trạng thái ban đầu. Điều này thường thấy trong các triển khai PRNG tham chiếu, nhưng nó giới hạn số lượng trạng thái ban đầu.

var seed = 1337 ^ 0xDEADBEEF; // 32-bit seed with optional XOR value
// Pad seed with Phi, Pi and E.
// https://en.wikipedia.org/wiki/Nothing-up-my-sleeve_number
var rand = sfc32(0x9E3779B9, 0x243F6A88, 0xB7E15162, seed);
for (var i = 0; i < 15; i++) rand();

Đầu ra của các hàm PRNG này tạo ra số 32 bit dương (0 đến 2 32 -1), sau đó được chuyển đổi thành số dấu phẩy động trong khoảng 0-1 (bao gồm 0, loại trừ 1) tương đương Math.random(), nếu bạn muốn số ngẫu nhiên của một phạm vi cụ thể, đọc bài viết này trên MDN . Nếu bạn chỉ muốn các bit thô, chỉ cần loại bỏ hoạt động phân chia cuối cùng.

Một điều cần lưu ý là những hạn chế của JS. Các số chỉ có thể biểu thị toàn bộ số nguyên có độ phân giải lên tới 53 bit. Và khi sử dụng các thao tác bitwise, điều này đã giảm xuống còn 32. Điều này gây khó khăn cho việc triển khai các thuật toán được viết bằng C hoặc C ++, sử dụng các số 64 bit. Chuyển mã 64 bit yêu cầu các miếng chêm có thể làm giảm đáng kể hiệu năng. Vì vậy, để đơn giản và hiệu quả, tôi chỉ xem xét các thuật toán sử dụng toán 32 bit, vì nó tương thích trực tiếp với JS.

Bây giờ, trở đi đến các máy phát điện. (Tôi duy trì danh sách đầy đủ với các tài liệu tham khảo ở đây )


sfc32 (Bộ đếm nhanh đơn giản)

sfc32 là một phần của bộ kiểm tra số ngẫu nhiên PracticeRand (tất nhiên là nó vượt qua). sfc32 có trạng thái 128 bit và rất nhanh trong JS.

function sfc32(a, b, c, d) {
    return function() {
      a >>>= 0; b >>>= 0; c >>>= 0; d >>>= 0; 
      var t = (a + b) | 0;
      a = b ^ b >>> 9;
      b = c + (c << 3) | 0;
      c = (c << 21 | c >>> 11);
      d = d + 1 | 0;
      t = t + d | 0;
      c = c + t | 0;
      return (t >>> 0) / 4294967296;
    }
}

Dâu tằm32

Mulberry32 là một trình tạo đơn giản với trạng thái 32 bit, nhưng cực kỳ nhanh và có chất lượng tốt (tác giả cho biết nó vượt qua tất cả các thử nghiệm của bộ thử nghiệm gjrand và có thời gian 2 32 đầy đủ , nhưng tôi chưa xác minh).

function mulberry32(a) {
    return function() {
      var t = a += 0x6D2B79F5;
      t = Math.imul(t ^ t >>> 15, t | 1);
      t ^= t + Math.imul(t ^ t >>> 7, t | 61);
      return ((t ^ t >>> 14) >>> 0) / 4294967296;
    }
}

Tôi muốn giới thiệu điều này nếu bạn chỉ cần một PRNG đơn giản nhưng đàng hoàng và không cần hàng tỷ số ngẫu nhiên (xem vấn đề Sinh nhật ).

xoshiro128 **

Kể từ tháng 5 năm 2018, xoshiro128 ** là thành viên mới của gia đình Xorshift , bởi Vigna / Blackman (người cũng đã viết xoroshiro, được sử dụng trong Chrome). Nó là trình tạo nhanh nhất cung cấp trạng thái 128 bit.

function xoshiro128ss(a, b, c, d) {
    return function() {
        var t = b << 9, r = a * 5; r = (r << 7 | r >>> 25) * 9;
        c ^= a; d ^= b;
        b ^= c; a ^= d; c ^= t;
        d = d << 11 | d >>> 21;
        return (r >>> 0) / 4294967296;
    }
}

Các tác giả tuyên bố nó vượt qua các bài kiểm tra ngẫu nhiên tốt ( mặc dù có cảnh báo ). Các nhà nghiên cứu khác đã chỉ ra rằng thất bại một số thử nghiệm trong TestU01 (đặc biệt là linearComp và BinaryRank). Trong thực tế, nó không gây ra vấn đề khi sử dụng float (chẳng hạn như các triển khai này), nhưng có thể gây ra vấn đề nếu dựa vào các bit thấp thô.

JSF (Nhỏ nhanh của Jenkins)

Đây là JSF hoặc 'smallprng' của Bob Jenkins (2007), anh chàng đã tạo ra ISAACSpookyHash . Nó vượt qua các bài kiểm tra PracticeRand và sẽ khá nhanh, mặc dù không nhanh như SFC.

function jsf32(a, b, c, d) {
    return function() {
        a |= 0; b |= 0; c |= 0; d |= 0;
        var t = a - (b << 27 | b >>> 5) | 0;
        a = b ^ (c << 17 | c >>> 15);
        b = c + d | 0;
        c = d + t | 0;
        d = a + t | 0;
        return (d >>> 0) / 4294967296;
    }
}

LCG (còn gọi là Lehmer / Park-Miller RNG hoặc MCG)

LCG cực kỳ nhanh chóng và đơn giản, nhưng chất lượng ngẫu nhiên của nó rất thấp, việc sử dụng không đúng cách thực sự có thể gây ra lỗi trong chương trình của bạn! Tuy nhiên, nó tốt hơn đáng kể so với một số câu trả lời gợi ý sử dụng Math.sinhoặc Math.PI! Đó là một lót mặc dù, đó là tốt đẹp :).

var LCG=s=>()=>(2**31-1&(s=Math.imul(48271,s)))/2**31;

Việc triển khai này được gọi là RNG tiêu chuẩn tối thiểu theo đề xuất của Park House Miller vào năm 1988 & 1993 và được thực hiện trong C ++ 11 như minstd_rand. Hãy nhớ rằng trạng thái là 31 bit (31 bit cho 2 tỷ trạng thái có thể, 32 bit cho gấp đôi số đó). Đây là loại PRNG mà những người khác đang cố gắng thay thế!

Nó sẽ hoạt động, nhưng tôi sẽ không sử dụng nó trừ khi bạn thực sự cần tốc độ và không quan tâm đến chất lượng ngẫu nhiên (dù sao thì ngẫu nhiên là gì?). Tuyệt vời cho một trò chơi kẹt hoặc một bản demo hoặc một cái gì đó. LCG chịu các tương quan hạt giống, vì vậy tốt nhất là loại bỏ kết quả đầu tiên của LCG. Và nếu bạn khăng khăng sử dụng LCG, việc thêm giá trị gia tăng có thể cải thiện kết quả, nhưng có lẽ đó là một bài tập vô ích khi tồn tại nhiều lựa chọn tốt hơn.

Dường như có các bội số khác cung cấp trạng thái 32 bit (tăng không gian trạng thái):

var LCG=s=>()=>(s=Math.imul(741103597,s)>>>0)/2**32;
var LCG=s=>()=>(s=Math.imul(1597334677,s)>>>0)/2**32;

Các giá trị LCG này là từ: P. Bencuyer: Một bảng gồm các bộ tạo cộng tuyến tuyến có kích thước khác nhau và cấu trúc mạng tốt, ngày 30 tháng 4 năm 1997.


5
Đây là một câu trả lời tuyệt vời. Tôi chắc chắn sẽ trở lại với điều này.
DavidsKanal

1
Tôi tin rằng các giá trị bạn đã trích dẫn từ "Bảng của Trình tạo cộng tuyến tuyến tính ..." của Pierre L'ecuyer có thể vượt quá kích thước số nguyên tối đa trong Javascript. Hạt giống tối đa của (2 ^ 32-1) * 741103597 3e18, lớn hơn kích thước int tối đa của JavaScript là ≈ 9e15. Tôi nghĩ rằng các giá trị sau từ cuốn sách của Pierre có thời gian lớn nhất trong giới hạn bản địa : seed = (seed * 185852 + 1) % 34359738337.
Lachmanski

1
@Lachmanski đúng, nhưng những cái đó bị ràng buộc bởi 32 bit (và Park-Miller 31 bit). Việc sử dụng Math.imulcho phép nó tràn như khi sử dụng phép nhân trong C trên các số nguyên 32 bit. Những gì bạn đang đề xuất là một LCG sử dụng toàn bộ không gian số nguyên của JS, đây chắc chắn là một khu vực thú vị để khám phá. :)
bryc

1
Điều này thật tuyệt! Tôi có thể sao chép sfc32 của bạn vào chương trình LGPL không?
dùng334639

4
@ blobber2 không chắc ý của bạn là gì, nhưng mã gốc là từ đây (với những người khác): github.com/bryc/code/blob/master/jshash/PRNGs.md . nhiều hơn hoặc ít hơn một ý chính trong kho lưu trữ :-)
bryc

39

Không, nhưng đây là một trình tạo giả ngẫu nhiên đơn giản, việc triển khai Multiply-with-carry I được điều chỉnh từ Wikipedia (đã bị xóa từ đó):

var m_w = 123456789;
var m_z = 987654321;
var mask = 0xffffffff;

// Takes any integer
function seed(i) {
    m_w = (123456789 + i) & mask;
    m_z = (987654321 - i) & mask;
}

// Returns number between 0 (inclusive) and 1.0 (exclusive),
// just like Math.random().
function random()
{
    m_z = (36969 * (m_z & 65535) + (m_z >> 16)) & mask;
    m_w = (18000 * (m_w & 65535) + (m_w >> 16)) & mask;
    var result = ((m_z << 16) + (m_w & 65535)) >>> 0;
    result /= 4294967296;
    return result;
}

EDIT: chức năng seed cố định bằng cách đặt lại m_z
EDIT2: Lỗi thực thi nghiêm trọng đã được sửa


3
Có ai đã thử nghiệm chức năng này cho tính ngẫu nhiên của nó?
Justin

3
Đây là máy phát ngẫu nhiên nhân với số mang (MWC) với thời gian khá dài. Chuyển thể từ Trình tạo số ngẫu nhiên wikipedia
Michael_Scharf

10
Các seedchức năng không reset máy phát ngẫu nhiên, bởi vì các mz_zbiến được thay đổi khi random()được gọi. Do đó, đặt mz_z = 987654321(hoặc bất kỳ giá trị nào khác) vàoseed
Michael_Scharf

Khi tôi sử dụng nó với trình tạo màu ngẫu nhiên (HSL), nó chỉ tạo ra màu xanh lục và lục lam. Trình tạo ngẫu nhiên ban đầu tạo ra tất cả các màu. Vì vậy, nó không giống nhau hoặc nó không hoạt động.
Tomas Kubes

@Michael_Scharf 1) Thay đổi hạt giống m_w, không m_z. 2) Cả hai m_wm_zđược thay đổi DỰA trên các giá trị trước đó của chúng, do đó, nó sẽ sửa đổi kết quả.
ESL

26

Thuật toán của Antti Sykäri rất hay và ngắn. Ban đầu tôi đã thực hiện một biến thể thay thế Math.random của Javascript khi bạn gọi Math.seed (s), nhưng sau đó Jason nhận xét rằng trả về hàm sẽ tốt hơn:

Math.seed = function(s) {
    return function() {
        s = Math.sin(s) * 10000; return s - Math.floor(s);
    };
};

// usage:
var random1 = Math.seed(42);
var random2 = Math.seed(random1());
Math.random = Math.seed(random2());

Điều này cung cấp cho bạn một chức năng khác mà Javascript không có: nhiều trình tạo ngẫu nhiên độc lập. Điều đó đặc biệt quan trọng nếu bạn muốn có nhiều mô phỏng lặp lại chạy cùng một lúc.


3
Nếu bạn trả về hàm thay vì cài đặt Math.randomsẽ cho phép bạn có nhiều trình tạo độc lập, phải không?
Jason Goemaat

1
Hãy chắc chắn để xem các nhận xét ở trên về phân phối ngẫu nhiên nếu điều đó quan trọng với bạn: stackoverflow.com/questions/521295/iêu
mẹo jocull

Làm thế nào randoms tạo ra bởi điều này có thể được lặp đi lặp lại? Nó liên tục đưa ra số mới mỗi lần
SMUsamaShah

Mỗi lần bạn thực hiện Math.seed(42);nó sẽ thiết lập lại chức năng, vì vậy nếu var random = Math.seed(42); random(); random();bạn nhận được 0.70..., thì 0.38.... Nếu bạn đặt lại bằng cách gọi var random = Math.seed(42);lại, thì lần sau bạn gọi random()bạn sẽ nhận được0.70... lại và lần sau bạn sẽ nhận 0.38...lại.
WOUNDEDStevenJones

1
Xin vui lòng không sử dụng này. Thay vào đó, hãy dành thời gian để sử dụng một biến cục bộ có tên randomthay vì ghi đè một hàm javascript gốc. Ghi đè Math.randomcó thể khiến trình biên dịch JIST không thể tối đa hóa tất cả mã của bạn.
Jack Giffin

11

Xin vui lòng xem công việc của Pierre Giancuyer trở lại vào cuối những năm 1980 và đầu những năm 1990. Có những người khác là tốt. Tự tạo một trình tạo số ngẫu nhiên (giả), nếu bạn không phải là chuyên gia, thì khá nguy hiểm, vì có nhiều khả năng kết quả không ngẫu nhiên về mặt thống kê hoặc trong một khoảng thời gian nhỏ. Pierre (và những người khác) đã kết hợp một số trình tạo số ngẫu nhiên (giả) tốt, dễ thực hiện. Tôi sử dụng một trong những máy phát LFSR của anh ấy.

https://www.iro.umontreal.ca/~lecuyer/myftp/ con / handstat.pdf

Phil Troy


1
Câu trả lời tuyệt vời, nhưng không liên quan đến javascript :)
Nikolay Fominyh

3
Mã để triển khai công việc của Giáo sư Bencuyer có sẵn công khai cho java và hầu hết các lập trình viên có thể dịch sang Javascript.
dùng2383235

6

Kết hợp một số câu trả lời trước đây, đây là hàm ngẫu nhiên có thể tìm được mà bạn đang tìm kiếm:

Math.seed = function(s) {
    var mask = 0xffffffff;
    var m_w  = (123456789 + s) & mask;
    var m_z  = (987654321 - s) & mask;

    return function() {
      m_z = (36969 * (m_z & 65535) + (m_z >>> 16)) & mask;
      m_w = (18000 * (m_w & 65535) + (m_w >>> 16)) & mask;

      var result = ((m_z << 16) + (m_w & 65535)) >>> 0;
      result /= 4294967296;
      return result;
    }
}

var myRandomFunction = Math.seed(1234);
var randomNumber = myRandomFunction();

4
Điều này tạo ra kết quả rất giống nhau ở đầu chuỗi với các hạt khác nhau. Ví dụ, Math.seed(0)()trả về 0.2322845458984375Math.seed(1)()trả về 0.23228873685002327. Thay đổi cả hai m_wm_ztheo hạt giống dường như giúp đỡ. var m_w = 987654321 + s; var m_z = 123456789 - s;tạo ra một phân phối tốt đẹp của các giá trị đầu tiên với các hạt giống khác nhau.
không xác định

1
@und xác định sự cố mà bạn mô tả đã được khắc phục kể từ lần chỉnh sửa cuối cùng, đó là một lỗi trong quá trình triển khai MWC.
bryc

Làm việc tốt ngay bây giờ, kể từ tháng 1 năm 2020. Hạt giống có 0, nhận 0,7322976540308446. Hạt giống với 1, 0,16818441334180534, với 2: 0,6040864314418286, với 3: 0,03998844954185188. Cảm ơn cả hai người!
Eureka

3

Để viết trình tạo ngẫu nhiên giả của riêng bạn khá đơn giản.

Gợi ý của Dave Scotese rất hữu ích nhưng, như được chỉ ra bởi những người khác, nó không được phân phối đồng đều.

Tuy nhiên, nó không phải là do các đối số nguyên của tội lỗi. Nó đơn giản là vì phạm vi tội lỗi, đó là hình chiếu một chiều của một vòng tròn. Nếu bạn lấy góc của hình tròn thì nó sẽ đồng nhất.

Vì vậy, thay vì sin (x) sử dụng arg (exp (i * x)) / (2 * PI).

Nếu bạn không thích thứ tự tuyến tính, hãy trộn nó lên một chút với xor. Yếu tố thực tế cũng không thành vấn đề.

Để tạo n số ngẫu nhiên giả, người ta có thể sử dụng mã:

function psora(k, n) {
  var r = Math.PI * (k ^ n)
  return r - Math.floor(r)
}
n = 42; for(k = 0; k < n; k++) console.log(psora(k, n))

Cũng xin lưu ý rằng bạn không thể sử dụng các chuỗi ngẫu nhiên giả khi cần entropy thực.


Tôi không phải là chuyên gia, nhưng hạt giống tuần tự theo một mô hình không đổi . Pixel màu là> = 0,5. Tôi đoán nó chỉ lặp đi lặp lại qua bán kính?
bryc


1

Math.randomkhông, nhưng thư viện đã chạy giải quyết điều này Nó có hầu hết tất cả các bản phân phối mà bạn có thể tưởng tượng và hỗ trợ tạo số ngẫu nhiên. Thí dụ:

ran.core.seed(0)
myDist = new ran.Dist.Uniform(0, 1)
samples = myDist.sample(1000)

-1

Tôi đã viết một hàm trả về một số ngẫu nhiên có hạt, nó sử dụng Math.sin để có một số ngẫu nhiên dài và sử dụng hạt giống để chọn các số từ đó.

Sử dụng :

seedRandom("k9]:2@", 15)

nó sẽ trả về số đã gieo của bạn, tham số đầu tiên là bất kỳ giá trị chuỗi nào; hạt giống của bạn. tham số thứ hai là có bao nhiêu chữ số sẽ trả về.

     function seedRandom(inputSeed, lengthOfNumber){

           var output = "";
           var seed = inputSeed.toString();
           var newSeed = 0;
           var characterArray = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','y','x','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','U','R','S','T','U','V','W','X','Y','Z','!','@','#','$','%','^','&','*','(',')',' ','[','{',']','}','|',';',':',"'",',','<','.','>','/','?','`','~','-','_','=','+'];
           var longNum = "";
           var counter = 0;
           var accumulator = 0;

           for(var i = 0; i < seed.length; i++){
                var a = seed.length - (i+1);
                for(var x = 0; x < characterArray.length; x++){
                     var tempX = x.toString();
                     var lastDigit = tempX.charAt(tempX.length-1);
                     var xOutput = parseInt(lastDigit);
                     addToSeed(characterArray[x], xOutput, a, i); 
                }                  
           }

                function addToSeed(character, value, a, i){
                     if(seed.charAt(i) === character){newSeed = newSeed + value * Math.pow(10, a)}
                }
                newSeed = newSeed.toString();

                var copy = newSeed;
           for(var i=0; i<lengthOfNumber*9; i++){
                newSeed = newSeed + copy;
                var x = Math.sin(20982+(i)) * 10000;
                var y = Math.floor((x - Math.floor(x))*10);
                longNum = longNum + y.toString()
           }

           for(var i=0; i<lengthOfNumber; i++){
                output = output + longNum.charAt(accumulator);
                counter++;
                accumulator = accumulator + parseInt(newSeed.charAt(counter));
           }
           return(output)
      }

1
Các dãy số được tạo ra bởi điều này không thực sự gần đúng các thuộc tính của các chuỗi số ngẫu nhiên. Tạo 15 số với nó và chuỗi kết quả hầu như luôn bắt đầu bằng số 7 cho gần như bất kỳ khóa nào, chẳng hạn.
Gabriel

-2

Một cách tiếp cận đơn giản cho một hạt giống cố định:

function fixedrandom(p){
    const seed = 43758.5453123;
    return (Math.abs(Math.sin(p)) * seed)%1;
}

-6

Đối với một số từ 0 đến 100.

Number.parseInt(Math.floor(Math.random() * 100))

3
Câu hỏi là về việc gieo hạt Math.randomsao cho bất cứ khi nào Math.randomđược gieo cùng một hạt giống, nó sẽ tạo ra một chuỗi các số ngẫu nhiên liên tiếp giống nhau. Câu hỏi này không phải là về việc sử dụng / trình diễn thực tế củaMath.random .
Jack Giffin
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.