Tính xác suất chính xác


9

Nhiệm vụ này là về viết mã để tính xác suất chính xác. Đầu ra phải là một xác suất chính xác được viết dưới dạng phân số ở dạng giảm nhất. Đó là nó không bao giờ nên đầu ra 4/8mà là 1/2.

Đối với một số số nguyên dương n, hãy xem xét một chuỗi ngẫu nhiên đồng nhất có độ dài 1s và -1 nvà gọi nó là A. Bây giờ nối với Agiá trị đầu tiên của nó. Đó là A[1] = A[n+1]nếu lập chỉ mục từ 1. Abây giờ có độ dài n+1. Bây giờ cũng xem xét một chuỗi độ dài ngẫu nhiên thứ hai nncác giá trị đầu tiên là -1, 0 hoặc 1 với xác suất 1 / 4,1 / 2, 1/4 mỗi và gọi nó là B.

Ví dụ, xem xét n=3. Các giá trị có thể cho ABcó thể là A = [-1,1,1,-1]B=[0,1,-1]. Trong trường hợp này, hai sản phẩm bên trong là 02.

Bây giờ hãy xem xét sản phẩm bên trong của A[1,...,n]Bvà sản phẩm bên trong của A[2,...,n+1]B.

Mã của bạn phải xuất xác suất rằng cả hai sản phẩm bên trong đều bằng không.

Đối với n=1xác suất này là rõ ràng 1/2.

Tôi không quan tâm làm thế nào nđược chỉ định trong mã nhưng nó rất đơn giản và rõ ràng làm thế nào để thay đổi nó.

Ngôn ngữ và thư viện

Bạn có thể sử dụng bất kỳ ngôn ngữ và thư viện nào bạn thích. Tôi muốn chạy mã của bạn vì vậy vui lòng bao gồm một lời giải thích đầy đủ về cách chạy / biên dịch mã của bạn trong linux nếu có thể.


2
Các trường hợp thử nghiệm cho một vài lần đầu tiên nsẽ hữu ích. Cũng có thể một ví dụ rõ ràng về A, B và hai sản phẩm bên trong có thể giúp ích.
Martin Ender

Nếu chúng ta chọn mã hóa số nguyên, thì có n=4được tính là 0, hai hoặc ba byte không? Liệu đầu ra phải chính xác a/b hoặc sẽ [a b], ví dụ, được cho phép?
Dennis

@Dennis Nó phải chính xác. Nếu bạn mã hóa số nguyên tôi sẽ chỉ phải thay đổi nó ở một nơi để thay đổi n? Mặt khác, tôi nghĩ rằng điều đó là không được phép.

Có, chương trình của tôi chỉ sử dụng số nguyên một lần để tính công suất cartesian. Mọi thứ khác được bắt nguồn từ mảng kết quả.
Dennis

Câu trả lời:


7

Pyth, 48 47 46 44 byte

K,smlf!|Fms*Vd.>Tk2^,1_1Q^+0tM3Q^8Qj\//RiFKK

Dùng thử trực tuyến: Trình diễn

Phiên bản trực tuyến có thể không tính toán n=6. Trên máy tính xách tay của tôi (phiên bản ngoại tuyến), mất khoảng 45 giây.

Phương pháp vũ phu.

Giải trình:

smlf!|Fms*Vd.>Tk2^,1_1Q^+0tM3Q   implicit: Q = input number
                          tM3    the list [-1, 0, 1]
                        +0       add zero, results in [0, -1, 0, 1]
                       ^     Q   all possible lists of length Q using these elements
 m                               map each list d (B in Lembik's notation) to:
                  ,1_1              the list [1, -1]
                 ^    Q             all possible lists of length Q
   f                                filter for lists T (A in Lembik's notation),
                                    which satisfy:
       m        2                      map each k in [0, 1] to:
        s*Vd.>Tk                          scalar-product d*(shifted T by k)
    !|F                                not or (True if both scalar-products are 0)      
  l                                 determine the length                
s                                add all possibilities at the end

K,...^8QQj\//RiFKK   
 ,...^8Q             the list [result of above, 8^Q]
K                    store it in K
              iFK    determine the gcd of the numbers in K
            /R   K   divide the numbers in K by the gcd
         j\/         join the two numbers by "/" and print

dang, quên về gcd, biết có một cái gì đó tôi đã bỏ lỡ
Maltysen

+0r1_2ngắn hơn /R2r2_2.
isaacg

Tôi nghĩ để công bằng thì nó phải là phiên bản 89/512 mà bạn tính.

@Lembik Ok Thay đổi nó.
Jakube

Tôi phải thừa nhận, nó chưa bao giờ xảy ra với tôi điều này có thể được thực hiện trong 47 ký tự!

8

Toán học, 159 100 87 86 85 byte

n=3;1-Mean@Sign[##&@@Norm/@({1,0,0,-1}~t~n.Partition[#,2,1,1])&/@{1,-1}~(t=Tuples)~n]

Để thay đổi nchỉ cần thay đổi định nghĩa biến ở đầu.

Vì nó vũ phu nên nó khá chậm, nhưng đây là tám kết quả đầu tiên:

n   P(n)
1   1/2
2   3/8
3   7/32
4   89/512
5   269/2048
6   903/8192
7   3035/32768
8   169801/2097152

Lần cuối cùng đã mất 231 giây và thời gian chạy là theo cấp số nhân khủng khiếp.

Giải trình

Như tôi đã nói đó là sức mạnh vũ phu. Về cơ bản, tôi chỉ liệt kê tất cả những gì có thể AB, tính hai sản phẩm chấm cho mỗi cặp có thể và sau đó tìm phần nhỏ của các cặp mang lại {0, 0}. Các tổ hợp của Mathicala và các hàm đại số tuyến tính khá hữu ích trong việc chơi gôn này:

{1,-1}~(t=Tuples)~n

Điều này tạo ra tất cả các n-tup chứa 1hoặc -1, tức là tất cả có thể A. Vì n = 3đó là:

{{1, 1, 1}, 
 {1, 1, -1}, 
 {1, -1, 1}, 
 {1, -1, -1}, 
 {-1, 1, 1}, 
 {-1, 1, -1}, 
 {-1, -1, 1}, 
 {-1, -1, -1}}

Để tính toán Bchúng tôi làm gần như giống nhau:

{1,0,0,-1}~t~n

Bằng cách lặp lại 0, chúng tôi nhân đôi từng bộ dữ liệu cho mỗi bộ 0chứa, do đó 0có khả năng gấp đôi 1hoặc -1. Một lần nữa sử dụng n = 3làm ví dụ:

{{-1, -1, -1},
 {-1, -1, 0}, {-1, -1, 0},
 {-1, -1, 1},
 {-1, 0, -1}, {-1, 0, -1},
 {-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0},
 {-1, 0, 1}, {-1, 0, 1},
 {-1, 1, -1},
 {-1, 1, 0}, {-1, 1, 0},
 {-1, 1, 1},
 {0, -1, -1}, {0, -1, -1},
 {0, -1, 0}, {0, -1, 0}, {0, -1, 0}, {0, -1, 0},
 {0, -1, 1}, {0, -1, 1},
 {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1},
 {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
 {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1},
 {0, 1, -1}, {0, 1, -1},
 {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
 {0, 1, 1}, {0, 1, 1},
 {1, -1, -1},
 {1, -1, 0}, {1, -1, 0},
 {1, -1, 1},
 {1, 0, -1}, {1, 0, -1},
 {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
 {1, 0, 1}, {1, 0, 1},
 {1, 1, -1},
 {1, 1, 0}, {1, 1, 0},
 {1, 1, 1}}

Bây giờ, đối với mỗi khả năng A, chúng tôi muốn sản phẩm chấm của từng loại có thể B, cả với A[1 .. n]A[2 .. n+1]. Ví dụ: nếu hiện tại của chúng tôi A{1, 1, -1}, chúng tôi muốn sản phẩm chấm có cả {1, 1, -1}và với {1, -1, 1}. Vì tất cả chúng ta Bđều đã thuận tiện các hàng của một ma trận, chúng tôi muốn hai danh sách con Adưới dạng cột của một ma trận khác, để chúng tôi có thể tính toán một sản phẩm chấm đơn giản giữa chúng. Nhưng chuyển vị {{1, 1, -1}, {1, -1, 1}}chỉ đơn giản là đưa ra {{1, 1}, {1, -1}, {-1, 1}}một danh sách tất cả các danh sách con theo chu kỳ 2 phần tử của A. Đó là những gì nó làm:

Partition[#,2,1,1]

Vì vậy, chúng tôi tính toán điều đó và lấy sản phẩm chấm với danh sách của chúng tôi B. Vì bây giờ chúng ta có được một danh sách lồng nhau (vì mỗi cái có thể Amang lại một vectơ riêng), chúng ta làm phẳng những cái đó với ##&@@.

Để tìm hiểu xem một cặp {x, y}{0, 0}chúng tôi tính toán Sign[Norm[{x,y}]] nơi Normcho √(x²+y²). Điều này cho 0hay 1.

Cuối cùng, vì bây giờ chúng tôi chỉ muốn biết các phân số của 1s trong danh sách 0s và 1s tất cả những gì chúng tôi cần là trung bình số học của danh sách. Tuy nhiên, điều này mang lại xác suất của cả hai ít nhất một sản phẩm chấm là khác không, vì vậy chúng tôi trừ nó 1để có kết quả mong muốn.


6

Pyth - 65 55 byte

Đã sửa lỗi giảm phân số với chi phí một byte.

Sử dụng phương pháp vũ phu, và có thể được đánh gôn, nhưng chỉ muốn lấy thứ gì đó ra khỏi đó. Rất chậm

*F-KP/Jmms*Vked,thdPhd*makhk^,1_1Q^[1ZZ_1)Q,ZZ2/lJ^2/K2

Nó sử dụng các sản phẩm của Cartesian để tạo cả hai AB, thực hiện các xác suất thay đổi bằng cách 0xuất hiện hai lần trong danh sách nguồn và sau đó đếm những sản phẩm bên trong sản phẩm bằng không. Các sản phẩm bên trong được thực hiện dễ dàng bởi Vđường cú pháp ectorization. Đơn giản hóa phân số ban đầu làm tôi sợ, nhưng nó khá dễ dàng với Pchức năng Factorization rime và nhận ra rằng chúng ta chỉ phải giảm sức mạnh bằng 2.

Hãy thử trực tuyến tại đây .


Làm thế nào để tôi thay đổi n?

@Lembik Chương trình Pyth yêu cầu đầu vào của người dùng, được chỉ định trong hộp văn bản thứ hai (Nếu bạn sử dụng trình biên dịch trực tuyến).
Jakube

@Jakube ơi cảm ơn! Và nó thực sự có vẻ cũng hoạt động :)

6

CJam, 58 57 54 51 46 byte

WX]m*Zm*_{~.+2,@fm<\f.*::+0-!},,__~)&:T/'/@,T/

Để chạy nó, chèn số nguyên mong muốn giữa WX]m*.

Cảm ơn @ jimmy23013 vì phép thuật bit và chơi golf 5 byte!

Hãy thử trực tuyến trong trình thông dịch CJam .

Ý tưởng

Hầu hết các phần của những câu trả lời này đều đơn giản, nhưng nó sử dụng hai thủ thuật gọn gàng:

  • Thay vì ghép tất cả các vectơ {-1, 1} n với tất cả các vectơ {-1, 0, 1} n với xác suất mong muốn, nó xem xét đếm số lượng ba vectơ trong {-1, 1} n thỏa mãn một điều kiện nhất định

    Nếu chúng ta thêm hai vectơ cuối cùng của một bộ ba, kết quả sẽ là một vectơ {-2, 0, 2} n .

    (-1) + 1 = 0 = 1 + (-1) , 0 s sẽ xảy ra gấp đôi so với -2 s và 2 s.

    Chia mỗi thành phần cho 2 sẽ mang lại một vectơ {-1, 0, 1} n với xác suất mong muốn.

    Vì chúng ta chỉ quan tâm nếu sản phẩm vô hướng có 0 hay không, chúng ta có thể bỏ qua phép chia cho 2 .

  • Sau khi đếm tất cả các bộ ba thỏa mãn điều kiện của câu hỏi và tổng số bộ ba, chúng ta phải giảm phần kết quả.

    Thay vì tính GCD của cả hai số, vì mẫu số sẽ luôn là lũy thừa bằng 2, nên đủ để chia cả hai số cho công suất cao nhất là 2 chia cho tử số.

    Để có được công suất cao nhất bằng 2 chia x , chúng ta có thể lấy bit AND của x~ x + 1 .

    ~ x đảo ngược tất cả các bit của x , vì vậy tất cả các 0 0 trở thành 1 s. Bằng cách thêm 1 vào ~ x , 1 s đó sẽ biến thành 0 s và 1 cuối cùng trong ~ x + 1 sẽ khớp với 1 cuối cùng trong x .

    Tất cả các bit khác đều là 0 khác biệt, do đó bit VÀ trả về số nguyên bao gồm 1 cuối cùng của x và tất cả 0 s theo sau nó. Đây là công suất cao nhất của 2 chia x .

WX]    e# Push the array [-1 1].
       e# Insert N here.
m*     e# Cartesian product: Push the array of all vectors of {-1,1}^N.
Zm*    e# Cartesian product: Push the array of all triplets of these vectors.
_      e# Copy the array.
{      e# Filter; for each triplet of vectors U, V and W in {-1,1}^N:
  ~    e#   Dump U, V and W on the stack.
  .+   e#   Compute X := V + W, a vector of {-2,0,2}^N, where each component is
       e#   zero with probability 1/2.
  2,@  e#   Push [0 1]. Rotate U on top of it.
  fm<  e#   Push [U U'], where U' is U rotated one dimension to the left.
  \f.* e#   Push [U*X and U'*X], where * denotes the vectorized product.
  ::+  e#   Add the components of both products.
  0-   e#   Remove zeroes.
       e#   Push the logical NOT of the array.
},     e#   If the array was empty, keep the triplet.
,      e# Push X, the length of the filtered array.
__~)&  e# Push X & ~X + 1.
:T     e# Save the result in T and divide X by T.
'/     e# Push a slash.
@,T/   e# Dividet he length of the unfiltered array by T.

WX]m*Zm*_{~.+2,@fm<\f.*::+0-!},,__W*&:T/'/@,T/.
jimmy23013

@ jimmy23013: Đó là một số phép thuật ấn tượng. Cảm ơn!
Dennis
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.