Tôi cần tính toán trung bình đang chạy:
Đầu vào: , k , vectơ ( x 1 , x 2 , Mạnh , x n ) .
Output: vector , nơi y i là trung bình ( x i , x i + 1 , ... , x i + k - 1 ) .
(Không gian lận với xấp xỉ; tôi muốn có các giải pháp chính xác. Các yếu tố là các số nguyên lớn.)
Có một thuật toán tầm thường duy trì một cây tìm kiếm có kích thước ; tổng thời gian chạy là O ( n log k ) . (Ở đây, "cây tìm kiếm" đề cập đến một số cấu trúc dữ liệu hiệu quả hỗ trợ chèn, xóa và truy vấn trung bình trong thời gian logarit.)
Tuy nhiên, điều này có vẻ hơi ngu ngốc đối với tôi. Chúng tôi sẽ tìm hiểu một cách hiệu quả tất cả các số liệu thống kê đơn hàng trong tất cả các cửa sổ có kích thước , không chỉ trung bình. Hơn nữa, điều này không quá hấp dẫn trong thực tế, đặc biệt nếu k lớn (cây tìm kiếm lớn có xu hướng chậm, chi phí sử dụng bộ nhớ không tầm thường, hiệu quả bộ nhớ cache thường kém, v.v.).
Chúng ta có thể làm bất cứ điều gì tốt hơn đáng kể?
Có bất kỳ giới hạn thấp hơn (ví dụ, thuật toán tầm thường là tối ưu không có triệu chứng cho mô hình so sánh)?
Chỉnh sửa: David Eppstein đã đưa ra một giới hạn dưới tốt đẹp cho mô hình so sánh! Tôi tự hỏi liệu tuy nhiên có thể làm một cái gì đó thông minh hơn một chút so với thuật toán tầm thường không?
Ví dụ, chúng ta có thể làm gì đó dọc theo các dòng này không: chia vectơ đầu vào cho các phần có kích thước ; sắp xếp từng phần (theo dõi các vị trí ban đầu của từng yếu tố); và sau đó sử dụng vectơ được sắp xếp piecewise để tìm các trung vị đang chạy một cách hiệu quả mà không có bất kỳ cấu trúc dữ liệu phụ trợ nào? Tất nhiên đây vẫn là O ( n log k ) , nhưng trong thực tế, việc sắp xếp các mảng có xu hướng nhanh hơn nhiều so với việc duy trì các cây tìm kiếm.
Chỉnh sửa 2: Saeed muốn xem một số lý do tại sao tôi nghĩ sắp xếp nhanh hơn hoạt động của cây tìm kiếm. Dưới đây là các điểm chuẩn rất nhanh, cho , n = 10 8 :
- 8s: sắp xếp các vectơ với k phần tử mỗi phần tử
- 10s: sắp xếp một vectơ với phần tử
- 80s: chèn và xóa trong bảng băm có kích thước k
- ≈ 390s: chèn và xóa trong cây tìm kiếm cân bằng có kích thước k
Bảng băm là có để so sánh; nó không được sử dụng trực tiếp trong ứng dụng này.
Tóm lại, chúng tôi có sự khác biệt gần như 50 nhân tố trong hiệu suất sắp xếp so với các hoạt động của cây tìm kiếm cân bằng. Và mọi thứ trở nên tồi tệ hơn nếu chúng ta tăng .
(Chi tiết kỹ thuật: Dữ liệu = số nguyên 32 bit ngẫu nhiên. Máy tính = máy tính xách tay hiện đại điển hình. Mã kiểm tra được viết bằng C ++, sử dụng các thường trình thư viện tiêu chuẩn (std :: sort) và cấu trúc dữ liệu (std :: multiset, std :: unsort_multiset). Tôi đã sử dụng hai trình biên dịch C ++ khác nhau (GCC và Clang) và hai triển khai khác nhau của thư viện chuẩn (libstdc ++ và libc ++). Theo truyền thống, std :: multiset đã được triển khai như một cây đen tối ưu hóa cao.)