Một bài toán đố

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. Bookmark the permalink. Trackbacks are closed, but you can post a comment.

9 Comments

  1. Posted 08/02/2008 at 12:21 am | Permalink

    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. Posted 08/02/2008 at 10:30 am | Permalink

    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. Cường
    Posted 08/02/2008 at 7:02 pm | Permalink

    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. Posted 08/02/2008 at 7:15 pm | Permalink

    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. Posted 09/02/2008 at 12:25 am | Permalink

    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. trang
    Posted 09/02/2008 at 2:51 pm | Permalink

    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. Posted 10/02/2008 at 5:44 pm | Permalink

    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. Posted 11/02/2008 at 6:32 am | Permalink

    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. acrab
    Posted 16/03/2008 at 12:07 pm | Permalink

    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.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>