Làm thế nào tôi có thể có được một số kết hợp có thể có trong R?


8

Đôi khi tôi muốn thực hiện một thử nghiệm chính xác bằng cách kiểm tra tất cả các kết hợp dữ liệu có thể có để xây dựng phân phối theo kinh nghiệm mà tôi có thể kiểm tra sự khác biệt quan sát được giữa các phương tiện. Để tìm các kết hợp có thể, tôi thường sử dụng chức năng kết hợp. Hàm select có thể cho tôi biết có bao nhiêu kết hợp có thể có. Rất dễ dàng để số lượng kết hợp trở nên lớn đến mức không thể lưu trữ kết quả của hàm combn, ví dụ: combn (28,14) yêu cầu vectơ 2.1 Gb. Vì vậy, tôi đã thử viết một đối tượng bước qua logic tương tự như hàm kết hợp để cung cấp các giá trị khỏi một "ngăn xếp" tưởng tượng tại một thời điểm. Tuy nhiên, phương pháp này (như tôi đã khởi tạo nó) dễ dàng chậm hơn 50 lần so với kết hợp ở các kích cỡ kết hợp hợp lý,

Có thuật toán nào tốt hơn để thực hiện loại điều này so với thuật toán được sử dụng trong combn không? Cụ thể có cách nào để tạo và kéo kết hợp Nth có thể mà không tính toán qua tất cả các kết hợp trước đó không?


Có ai để ý rằng số lượng câu hỏi nên có trong StackOverflow R đã tăng vọt ở đây gần đây không?
Giăng

1
Tại sao không lấy mẫu ngẫu nhiên?

4
@ John: Nếu bạn cảm thấy như vậy, hãy thảo luận về vấn đề này tại meta.stats.stackexchange.com/questions/248/ , không cần phải lén lút.
russellpierce

@mbq: Lấy mẫu ngẫu nhiên sẽ nhanh chóng cung cấp một xấp xỉ hợp lý, đặc biệt là với dữ liệu được xử lý tốt. Tuy nhiên, tôi đã xác định rằng mục tiêu của tôi là một bài kiểm tra chính xác.
russellpierce

@drknexus Đó là lý do tại sao nó là một bình luận không phải là một câu trả lời.

Câu trả lời:


6

Nếu bạn muốn trao đổi tốc độ xử lý cho bộ nhớ (mà tôi nghĩ là bạn làm), tôi sẽ đề xuất thuật toán sau:

  • Thiết lập vòng lặp từ 1 đến N Chọn K, được lập chỉ mục bởi i
  • Mỗi i có thể được coi là một chỉ mục cho một tổ hợp , giải mã như vậy
  • Sử dụng kết hợp để thực hiện thống kê kiểm tra của bạn, lưu trữ kết quả, loại bỏ kết hợp
  • Nói lại

Điều này sẽ cung cấp cho bạn tất cả N Chọn K kết hợp có thể có mà không cần phải tạo chúng rõ ràng. Tôi có mã để làm điều này trong R nếu bạn thích nó (bạn có thể gửi email cho tôi tại mark dot m period fredrickson at-icon gmail dot com).


1
Đây là một bài đăng với mã và một số hình ảnh minh họa: markmfredrickson.com/ Dùts / 2010-06-06
Mark M. Fredrickson

Tôi chấp nhận câu trả lời này bởi vì nó giải quyết (những gì tôi nghĩ) là vấn đề khó hơn mà tôi đang tìm kiếm một giải pháp để - chọn một kết hợp cụ thể ra mà không tính toán các giá trị trước đó. Thật không may, nó vẫn còn rất chậm. Có lẽ như đã đề cập ở đây và ở nơi khác, một tìm kiếm nhị phân sẽ giúp tăng tốc mọi thứ. Có lẽ cách tiếp cận tốt nhất là có một luồng tạo ra các kết hợp theo từng bước như trong câu trả lời của mbq và một luồng khác đọc chúng và kiểm tra chúng.
russellpierce

1

Tạo các kết hợp là khá dễ dàng, xem ví dụ này ; viết mã này vào R và sau đó xử lý từng kết hợp tại một thời điểm nó xuất hiện.


Nhưng điều này sẽ đối phó với sự kết hợp rất lớn?
csgillespie

@csgillespie Vâng, tôi tin là như vậy - nó hoạt động tại chỗ , do đó chỉ có một kết hợp được lưu trữ trong bộ nhớ tại một thời điểm và kết quả mô phỏng cũng có thể được tổng hợp để loại bỏ nhu cầu lưu trữ chúng. Điều này tất nhiên sẽ làm việc rất lâu, nhưng tìm kiếm toàn diện thường làm. Đối với tốc độ, nó có thể được viết bằng C, nhưng sau đó cùng với phần mô phỏng, có lẽ chậm hơn một bước của trình tạo.

2
Điều đó trông gần giống với cách chức năng kết hợp của R đã làm việc. Tôi đã viết lên một phiên bản kết hợp loại bỏ các tổ hợp cùng một lúc, và như mbq nói vì nó chỉ lưu trữ một kết hợp trong bộ nhớ tại một thời điểm nó có thể xử lý các kết hợp rất lớn. Vấn đề với việc thực hiện trong R là việc thực hiện một cách tiếp cận từng bước trong một chức năng thường bao gồm việc đọc các biến trạng thái vào hàm, thao tác chúng, sau đó lưu trữ chúng trở lại toàn cầu - dường như chỉ làm chậm mọi thứ / cách / xuống.
russellpierce
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.