Một cách để giải quyết điều này là suy nghĩ lại cách cây tìm kiếm nhị phân của bạn chứa tổng tích lũy được tạo. Thay vì xây dựng cây tìm kiếm nhị phân, hãy suy nghĩ về việc mỗi nút được giải thích như sau:
- Mỗi nút lưu trữ một loạt các giá trị được dành riêng cho nút đó.
- Các nút trong nhánh phụ bên trái đại diện lấy mẫu từ phân phối xác suất ở bên trái của phạm vi đó.
- Các nút trong nhánh phụ phải thể hiện lấy mẫu từ phân phối xác suất ở bên phải của phạm vi đó.
Ví dụ: giả sử trọng số của chúng tôi là 3, 2, 2, 2, 2, 1 và 1 cho các sự kiện A, B, C, D, E, F và G. Chúng tôi xây dựng cây nhị phân này A, B, C, D, E, F và G:
D
/ \
B F
/\ /\
A C E G
Bây giờ, chúng tôi chú thích cây có xác suất.Vì A, C, E và G là tất cả các lá, chúng tôi cung cấp cho mỗi xác suất khối lượng một:
D
/ \
B F
/\ /\
A C E G
1 1 1 1
Bây giờ, hãy xem cây cho B. B có trọng lượng 2 được chọn, A có trọng lượng 3 được chọn, và C có xác suất 2 được chọn. Nếu chúng ta chuẩn hóa chúng thành phạm vi [0, 1), thì A sẽ chiếm 3/7 xác suất và B và C mỗi tài khoản trong 2/7 giây. Vì vậy, chúng tôi có nút cho B nói rằng bất cứ điều gì trong phạm vi [0, 3/7) đi đến subtree trái, bất cứ điều gì trong phạm vi [3/7, 5/7) bản đồ để B, và bất cứ điều gì trong phạm vi [5/7, 1) ánh xạ tới đúng cây con:
D
/ \
B F
[0, 3/7)/\ [5/7, 1)/\
A C E G
1 1 1 1
Tương tự, hãy xử lý F. E có trọng số 2 được chọn trong khi F và G có trọng số xác suất 1 được chọn. Vì vậy, subtree cho E chiếm 1/2 khối lượng xác suất ở đây, nút F chiếm 1/4, và subtree cho G chiếm 1/4. Điều này có nghĩa là chúng tôi có thể chỉ định xác suất là
D
/ \
B F
[0, 3/7)/\ [5/7, 1) [0, 1/2)/\ [3/4, 1)
A C E G
1 1 1 1
Cuối cùng, hãy nhìn vào thư mục gốc. Trọng lượng kết hợp của cây con trái là 3 + 2 + 2 = 7. Trọng lượng kết hợp của cây con phải là 2 + 1 + 1 = 4. Trọng lượng của D chính là 2. Vì vậy, cây con trái có xác suất 7/13 của được chọn, D có xác suất 2/13 được chọn, và cây con phải có xác suất 4/13 được chọn. do đó chúng ta có thể hoàn thành các xác suất như
D
[0, 7/13)/ \ [9/13, 1)
B F
[0, 3/7)/\ [5/7, 1) [0, 1/2)/\ [3/4, 1)
A C E G
1 1 1 1
Để tạo ra một giá trị ngẫu nhiên, bạn sẽ lặp lại như sau:
- Bắt đầu từ gốc rễ:
- Chọn một giá trị thống nhất-ngẫu nhiên trong phạm vi [0, 1).
- Nếu nó nằm trong phạm vi cho cây con trái, hãy đi sâu vào nó.
- Nếu nó nằm trong phạm vi cho cây con phù hợp, hãy đi sâu vào nó.
- Nếu không, hãy trả về giá trị tương ứng với nút hiện tại.
Xác suất bản thân có thể được xác định một cách đệ quy khi cây được xây dựng:
- trái và xác suất đúng là 0 đối với bất kỳ nút lá.
- Nếu một nút nội thất chính nó có trọng lượng W, cây trái của nó có tổng trọng lượng W L, và cây quyền của mình có tổng trọng lượng W R, sau đó xác suất trái là (W L)/(W + W L + W R) và xác suất đúng là (W R)/(W + W L + W R).
Lý do cải cách này hữu ích là nó cho chúng ta một cách để cập nhật xác suất trong thời gian O (log n) trên mỗi xác suất được cập nhật. Đặc biệt, chúng ta hãy suy nghĩ về những bất biến sẽ thay đổi nếu chúng ta cập nhật một số trọng lượng của nút cụ thể. Để đơn giản, giả sử nút bây giờ là một chiếc lá.Khi chúng tôi cập nhật trọng lượng của nút lá, xác suất vẫn chính xác cho nút lá, nhưng chúng không chính xác cho nút ngay phía trên nó, vì trọng số của một trong các subtrees của nút đó đã thay đổi. Do đó chúng ta có thể (trong thời gian O (1)) tính lại các xác suất cho nút cha bằng cách chỉ sử dụng công thức giống như trên. Nhưng sau đó, phụ huynh của nút đó không còn có giá trị chính xác vì một trong các trọng số subtree của nó đã thay đổi, vì vậy chúng tôi có thể tính toán lại xác suất ở đó. Quá trình này lặp lại tất cả các cách trở lại lên đến gốc của cây, với chúng tôi làm O (1) tính toán cho mỗi cấp độ để khắc phục các trọng số được giao cho mỗi cạnh. Giả sử rằng cây được cân bằng, do đó chúng ta phải thực hiện tổng công việc O (log n) để cập nhật một xác suất. Logic giống hệt nếu nút không phải là nút lá; chúng ta chỉ bắt đầu ở đâu đó trong cây.
Nói tóm lại, điều này sẽ cho
- O (n) thời gian để xây dựng cây (sử dụng một cách tiếp cận từ dưới lên),
- O (log n) thời gian để tạo ra một giá trị ngẫu nhiên, và
- O (nhật ký n) thời gian để cập nhật bất kỳ giá trị nào.
Hy vọng điều này sẽ hữu ích!
Ý anh là gì bằng cách tốt hơn so với O (n) thời gian? Nếu bạn chỉ tính toán lại Cj ... Cn của mảng tích lũy của bạn, nó sẽ trung bình tốt hơn O (n) trừ khi j luôn luôn là 0. – biziclop
@biziclop Nếu trung bình anh tính toán lại các phần tử 'n/2', đó không phải là" tốt hơn "so với' O (n) 'vì' O (n/2) = O (n) '. –
@Michael McGowan Tất nhiên bạn nói đúng, tôi thực sự nên đi ngủ. – biziclop