Độ phức tạp thời gian của thuật toán này là gì? Và tại sao?


8

Tôi bị mắc kẹt bằng cách phân tích độ phức tạp thời gian của thuật toán sau:

def fun (r, k, d, p):
    if d > p:
        return r
    if d = 0 and p = 0:
        r <- r + k
        return r
    if d > 0:
        fun (r, k + 1, d - 1, p)
    if p > 0:
        fun (r, k - 1, d, p - 1)

Cuộc gọi gốc sẽ là fun (0, 0, n, n), và nlà kích thước của vấn đề.

Tôi đoán rằng: Mối quan hệ lặp lại là , tương đương với và do đó O (2 ^ m) \ iff O (4 ^ n) .T ( 2 n ) = 2 T ( 2 n - 1 )T(n,n)= =T(n-1,n)+T(n,n-1)O ( 2 m )T(2n)= =2T(2n-1)T(m)= =2T(m-1)Ôi(2m)Ôi(4n)

Phân tích của tôi có đúng không (tôi biết nó không đầy đủ và chính xác)? Nếu nó có lỗi nghiêm trọng, xin vui lòng chỉ ra hoặc cho tôi thấy một bằng chứng chính xác và đầy đủ về độ phức tạp thời gian của thuật toán này.


1
xando, tôi khuyến khích bạn chỉnh sửa câu hỏi để giải thích tại sao các kỹ thuật tiêu chuẩn không hoạt động: giải thích tại sao chúng thất bại. (Cc: @YuvalFilmus) Chẳng hạn, bạn có nhận được mối quan hệ tái phát khó giải quyết không, và nếu vậy, bạn sẽ nhận được điều gì tái phát?
DW

1
Trong các nhận xét với Polyergic, tôi đã nhận ra rằng mã giả không rõ ràng: không rõ ý nghĩa của thuật toán để làm gì, khi cả hai d>0p>0. Bạn không hiển thị những gì hàm trả về nếu chúng ta đạt đến câu lệnh thứ 3 và thứ 4. Bạn có nghĩa là có một returntuyên bố sau mỗi lần gọi đệ quy fun? (bạn ấy có ý fun (r, k + 1, d - 1, p)return fun (r, k + 1, d - 1, p)?) Hoặc bạn đã có nghĩa là để có một returntuyên bố vào cuối, của cơ quan chức năng? Vui lòng chỉnh sửa mã giả của bạn để làm rõ và đảm bảo bạn hiển thị những gì trả về trong tất cả các trường hợp có thể.
DW

Để nói nó theo cách khác: giả sử d<=pd>0p>0tất cả các tổ chức. Điều gì sẽ xảy ra? Liệu thuật toán có thực hiện 2 lệnh đệ quy cho hàm không? Hoặc nó gọi đệ quy fun(r, k + 1, d - 1, p)và sau đó ngay lập tức trở lại, mà không gọi đệ quy fun(r, k - 1, d, p - 1)? Nếu tôi lấy mã giả của bạn theo nghĩa đen, có vẻ như nó tạo ra 2 lệnh đệ quy và sau đó trả về với giá trị trả về không xác định - nhưng điều đó có vẻ kỳ lạ và khiến tôi tự hỏi liệu có lỗi đánh máy / lỗi trong mã giả hay không.
DW

Câu trả lời:


10

Hai đối số duy nhất liên quan đến phân tích tiệm cận là và . Các đối số này (hầu như) thỏa mãn và (chúng ta cần xáo trộn logic trong hàm một chút để có được điều này). Tại mỗi điểm trong quá trình thực thi, bạn lấy cặp hiện tại và sau đó gọi đệ quy hàm với các cặp , tránh các cặp làm mất hiệu lực các ràng buộc đã nêu ở trên .p d , p 0 d p ( d , p ) ( d - 1 , p ) , ( d , p - 1 )dpd,p0dp(d,p)(d1,p),(d,p1)

Chúng ta có thể hình dung cây cuộc gọi kết quả là một đường dẫn bắt đầu từ . Mỗi lần bạn giảm , hãy thêm một bước. Mỗi lần bạn giảm , hãy thêm một bước. Điều kiện đảm bảo rằng bạn không bao giờ đi dưới trục X. Hơn nữa, bạn có một "ngân sách" của mỗi bước. Tổng số trong cây gọi này chính xác là số Catalan và điều này mang lại cho chúng ta giới hạn dưới về thời gian chạy của hàm.p d d p n ( 2 n(0,0)pddpn(2nn)/(n+1)=Θ(4n/n3/2)

Để có giới hạn trên, lưu ý rằng trên đường tới mỗi lá, chúng ta đi qua nút và điều này cho giới hạn trên lớn hơn giới hạn dưới, nghĩa là .2n2nΘ(4n/n)

Chúng tôi có giới hạn dưới là và giới hạn trên của . Các tiệm cận chính xác là gì? Chúng phát triển giống như tổng số đường không đi qua trục X có nhiều nhất bước theo mỗi hướng. Sử dụng định lý lá phiếu của Bertrand, chúng ta có thể có được một biểu thức chính xác cho điều này: Do đó, vẫn còn để ước tính số tiền này không có triệu chứng: Ω(4n/n3/2)Ôi(4n/n)0 d p n p - d + 1n0dpn ( p+d

Σ0dpnp-d+1p+1(p+dp).
Σ0dpn(p+dp)-Σ0dpndp+1(p+dd)= =Σ0dpn(p+dp)-Σ0dpn(p+dp+1)= =Σp= =0n(2p+1p+1)-Σp= =0n(2p+1p+2)= =Σp= =0n1p+1(2p+2p)= =Θ(Σp= =0n4pp3/2)= =Θ(4nn3/2).

1
Tôi thực sự thích cách tiếp cận hình học của bạn bằng cách sử dụng các "bước" này. Đó có phải là một kỹ thuật phổ biến? Tôi chưa từng thấy nó trước đây.
Andreas T

@AndreasT Tôi sẽ không gọi nó là một kỹ thuật phổ biến, thực sự thông thường nó không áp dụng. Ở đây diễn giải tổ hợp là khá rõ ràng, và nó dẫn một đến giải pháp loại này.
Yuval Filmus

0

Từng trường hợp:

  1. d> p : Liên tục thời gian
  2. d = 0 ∧ p = 0 : Liên tục thời gian
  3. d> 0 : Lưu ý rằng d ≯ p, vì vậy chúng ta có 0 <d ≤ p và funđệ quy trên d - 1 cho đến khi d ≯ 0; vì p> 0, đây là tuyến tính trong d + (trường hợp 4) .
  4. p> 0 : Lưu ý rằng d 0, vì vậy chúng ta có d ≤ 0 p (với d <p) và funđệ quy trên p - 1 cho đến khi p 0; đây là tuyến tính trong p + (một trong trường hợp 1, 2 hoặc 5)
  5. d ≤ p <0 : Không xác định; Tôi giả định này là hằng số thời gian

Bắt đầu với d = p = n> 0 lần truy cập trường hợp 3, tiếp theo là trường hợp 4. Nếu n là một số nguyên, trường hợp cuối cùng là 2, nếu không thì trường hợp cuối cùng là 5. Tổng thời gian cho các trường hợp đó là d + p +1 hoặc 2n + 1.


2n. Tôi đoán bạn bị hạ thấp vì tôi tập trung vào lý luận?
ShadSterling

1
Cảm ơn đã chỉnh sửa câu trả lời! Câu đố bây giờ là bạn đã kết luận rằng thời gian chạy là , nhưng Yuval kết luận rằng thời gian chạy là theo cấp số nhân trong . Đó là một sự khác biệt khá lớn. Ôi(n)n
DW

1
Hmm, tôi nghĩ rằng tôi đã lấy mã giả iflà "làm một trong những thứ này" trong khi @Yuval đưa chúng ra để "xem xét từng thứ theo thứ tự". Dĩ nhiên, cái sau này có nghĩa là gì if(không có else) trong mã thực tế; Tôi đã quen với cái trước trong hầu hết mọi bối cảnh khác ngoài mã thực tế (bao gồm cả mã giả, mặc dù cách sử dụng trong mã giả không nhất quán).
ShadSterling

Tôi hiểu ý bạn là gì. Việc thiếu các returncâu lệnh ở nửa sau của mã làm cho điều này khá khó hiểu.
DW
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.