Một bài toán đố

Ngô Quang Hưng | 07 tháng 02, 2008 | Bản để in Bản để in

Các routers trên Internet phải xử lý cực nhiều packets với tốc độ cực cao. Giả sử ta phải thiết kế một thuật toán để chỉ ra, trong một dòng các packets đã thấy cho đến thời điểm này (n packets, và n có thể cực lớn), có source-IP nào xuất hiện hơn n/2 lần hay không. Sự xuất hiện của một source-IP như vậy có thể là dấu hiệu của DoS từ IP nọ.

Do tốc độ xử lý phải cao tuyệt, thuật toán phải chạy nhanh và không dùng quá nhiều memory được (dùng cache memory thôi). Tóm lại thuật toán chỉ có thể thực hiện một scan qua dòng packets, dùng càng ít memory càng tốt.

Cách brute-force là dùng 2^{32} counters, mỗi counter cho một (potential) IP. Khi thấy IP mới thì tăng counter lên. Dĩ nhiên cách này không khả thi.

Hãy thiết kế một thuật toán như vậy dùng [O(log n) + 32 bit] memory, cho phép false positive nhưng không cho phép false negative. Nghĩa là thuật toán luôn output một IP address. Nếu có IP xuất hiện hơn n/2 lần thì thuật toán phải output nó. Nếu không có IP xuất hiện hơn n/2 lần thì output gì cũng được.

Chủ đề: Thuật Toán |

9 lời bình cho bài “Một bài toán đố”

  1. 1
    Thang viết:

    Bài này thay vì tìm IP ta tìm giá trị các bit của IP bằng cách đếm số lần xuất hiện của các bit 0, 1 tại 32 vị trí và lấy bit có số lần xuất hiện cao hơn.
    Anh Hưng có cách nào scan một lần, dùng ít memory mà đảm bảo không có false positive lẫn false negative không ạ?

  2. 2
    Ngô Quang Hưng viết:

    Hello Thang, có thể chứng minh được là cần đến linear-space nếu phải output chính xác.

    Cách của Thang rất hay, nhưng cần đến 32x log(n) memory bits. Có cách nào chỉ cần log n + 32 bits of memory không?

  3. 3
    Cường viết:

    Với cách làm của bạn Thắng, liệu có thể dùng 1 counter để lưu lại tất cả những giá trị đếm được của 32 bits không ? Em nghĩ có thể lưu lại những giá trị đếm được bằng cách biểu diễn :
    n = n_{1}p_{1} + n_{2}p_{2} + \ldots + n_{32}p_{32}
    Trong đó p_{i} là số nguyên tố thứ i, n_{i} là số lần xuất hiện bit 1 tại vị trí thứ i.
    Với mỗi IP trong dãy, nếu bit thứ k của IP này là 1 thì ta tăng số n lên p_{k} đơn vị.

  4. 4
    Ngô Quang Hưng viết:

    Hi Cường,

    Biểu diễn muốn duy nhất phải là nhân chứ không phải linear combination. Ngoài ra, tổng số bits (cho dù là n có cách biểu diễn duy nhất thành linear combination của một số các số nguyên tố) cũng vẫn nhiều quá.

  5. 5
    Thang viết:

    Oobs, em không tính kĩ memory. Em xin chỉnh lại thuật toán để giảm a few bits :)
    Ta dùng biến 32 bits S để lưu Source IP, biến đếm log(n) bits C=0 tại thời điểm ban đầu.
    Với mỗi package, nếu package.IP \neq S ta gán C=C-1 ngược lại C=C+1. Mỗi khi C \leq 0 ta cập nhật giá trị mới S=package.IP, C=1.

  6. 6
    trang viết:

    Lần trước trong blog này đã có bài đố về giọt máu gì đó rồi. Về ý tưởng cũng tương tự như bài này. Cả 2 bài cũng có một cách giải chung.

  7. 7
    nvhoang viết:

    Em nghe có mùi hashing hoặc bloom filter. Không biết có đúng hướng không anh Hưng? :D

  8. 8
    Ngô Quang Hưng viết:

    Hello Hoàng, nếu tổng quát hóa bài toán lên thì một biến thể của Bloom filter có thể giải quyết được. Nhưng trong trường hợp câu đố này thì cách giải thứ 2 của Thắng là chính xác.

  9. 9
    acrab viết:

    Mình thấy bài này rất giống một bài trong sách lập trình Pascal của BTT cho học sinh cấp 3 gọi là số chính của một file.

Ghi lời bình của bạn: