1 Câu hỏi: Tạo hoán vị theo thứ tự tuần tự - R

câu hỏi được tạo ra tại Wed, May 8, 2019 12:00 AM

Trước đây tôi đã hỏi câu hỏi sau Hoán đổi của n biến ngẫu nhiên trong b

Câu trả lời cho câu hỏi này hoạt động rất tốt, miễn là n tương đối nhỏ (< 30), nếu không sẽ xảy ra mã lỗi sau Lỗi: không thể phân bổ vectơ kích thước 4.0 Gb. Tôi có thể lấy mã để chạy với giá trị lớn hơn một chút bằng cách sử dụng máy tính để bàn của mình tại nơi làm việc nhưng cuối cùng cũng xảy ra lỗi tương tự. Ngay cả đối với các giá trị mà máy tính của tôi có thể xử lý, giả sử 25, mã cực kỳ chậm.

Mục đích của mã này là để tính toán sự khác biệt giữa CDF của một phân phối chính xác (do đó hoán vị) và xấp xỉ bình thường. Tôi tạo ngẫu nhiên một số dữ liệu, tính toán thống kê kiểm tra và sau đó tôi cần xác định CDF bằng cách tổng hợp tất cả các hoán vị dẫn đến giá trị thống kê kiểm tra nhỏ hơn chia cho tổng số hoán vị.

Suy nghĩ của tôi là chỉ tạo một danh sách các hoán vị một lần, lưu ý nếu nó nhỏ hơn giá trị quan sát của tôi và sau đó chuyển sang tiếp theo, tức là lặp lại tất cả các hoán vị có thể, nhưng tôi không thể có một khung dữ liệu của tất cả các hoán vị lặp đi lặp lại vì điều đó sẽ gây ra vấn đề chính xác về kích thước và tốc độ.

Câu chuyện dài ngắn: Tôi cần tạo tất cả các hoán vị có thể có của 1 và 0 cho các thử nghiệm bernoulli, nhưng tôi cần thực hiện điều này tại một thời điểm sao cho tất cả chúng được tạo và không được tạo nhiều lần . Với n = 3, 2 ^ 3 = 8, trước tiên tôi sẽ tạo

000

tính toán nếu thống kê kiểm tra của tôi lớn hơn (1 hoặc 0) thì tạo

001

tính lại, sau đó tạo

010

tính toán, sau đó tạo

100

tính toán, sau đó tạo

011

vv cho đến 111

Tôi ổn với điều này là một vòng lặp trên 2 ^ n, nó tạo ra hoán vị ở mỗi bước của vòng lặp nhưng không lưu tất cả chúng ở đâu đó. Ngoài ra tôi không quan tâm chúng được tạo theo thứ tự nào, ở trên chỉ là cách tôi sẽ liệt kê chúng ra nếu tôi làm bằng tay.

Ngoài ra, nếu có cách nào để tăng tốc mã trước đó cũng sẽ hữu ích.

    
1
1 Câu trả lời                              1                         

Một giải pháp tốt cho vấn đề của bạn là các trình vòng lặp. Có một gói được gọi là arrangements có thể tạo ra hoán vị theo kiểu lặp. Quan sát:

library(arrangements)

# initialize iterator 
iperm <- ipermutations(0:1, 3, replace = T)

for (i in 1:(2^3)) {
    print(iperm$getnext())
}

[1] 0 0 0
[1] 0 0 1
.
.
.
[1] 1 1 1

Nó được viết vào C và rất hiệu quả. Bạn cũng có thể tạo hoán vị m tại một thời điểm như vậy:

iperm$getnext(m)

Điều này cho phép hiệu suất tốt hơn vì các hoán vị tiếp theo đang được tạo bởi vòng lặp for trong C trái ngược với vòng lặp for trong R.

Nếu bạn thực sự cần tăng cường hiệu suất, bạn có thể gói parallel.

iperm <- ipermutations(0:1, 40, replace = T)

parallel::mclapply(1:100, function(x) {
    myPerms <- iperm$getnext(10000)
    # do something
}, mc.cores = parallel::detectCores() - 1)

Lưu ý: Tất cả mã chưa được kiểm tra.

    
2
2019-05-08 19: 51: 01Z
  1. Điều đó hoạt động, cảm ơn!
    2019-05-08 19: 45: 35Z
nguồn đặt đây