Phân tích khấu hao? (Đảm bảo hiệu suất trong trường hợp xấu nhất)


12

Phân tích khấu hao là gì? Và làm thế nào nó có thể giúp tôi đạt được các đảm bảo hiệu suất trong trường hợp xấu nhất trong các chương trình của mình?

Tôi đã đọc rằng các kỹ thuật sau đây có thể giúp lập trình viên đạt được các đảm bảo hiệu suất trong trường hợp xấu nhất (nghĩa là theo cách riêng của tôi: đảm bảo rằng thời gian chạy của chương trình sẽ không vượt quá thời gian chạy trong diễn viên tệ nhất):

  • Các thuật toán ngẫu nhiên (ví dụ thuật toán quicksort là bậc hai trong trường hợp xấu nhất, nhưng việc sắp xếp ngẫu nhiên đầu vào mang lại sự đảm bảo xác suất rằng thời gian chạy của nó là tuyến tính)
  • Trình tự các hoạt động (phân tích của chúng tôi phải tính đến cả dữ liệu và trình tự các hoạt động được thực hiện bởi khách hàng)
  • Phân tích khấu hao (một cách khác để đảm bảo hiệu suất là khấu hao chi phí, bằng cách theo dõi tổng chi phí của tất cả các hoạt động, chia cho số lượng hoạt động. Trong cài đặt này, chúng tôi có thể cho phép một số hoạt động đắt tiền, trong khi vẫn giữ chi phí trung bình Nói cách khác, chúng tôi phân bổ chi phí cho một vài hoạt động đắt tiền, bằng cách chỉ định một phần của nó cho mỗi một số lượng lớn các hoạt động rẻ tiền)

Tác giả đã đề cập đến việc sử dụng thay đổi kích thước cấu trúc dữ liệu mảng cho Stack như một ví dụ về cách đạt được phân tích khấu hao nhưng tôi vẫn không hiểu phân tích khấu hao là gì và làm thế nào nó thực sự có thể được thực hiện (thuật toán cấu trúc dữ liệu?) Để đạt được điều tồi tệ nhất đảm bảo hiệu suất -cast

Câu trả lời:


13

Bạn không thực hiện phân tích khấu hao. Đó là một kỹ thuật để có được Ogiới hạn chính xác hơn .

Quan sát thiết yếu bạn phải thực hiện là, các hoạt động đắt tiền có thể xảy ra bất cứ lúc nào.

Trong trường hợp cấu trúc dữ liệu được hỗ trợ mảng, mảng cần thay đổi kích thước mọi lúc và sau đó - khi nó đầy. Đây là hoạt động tốn kém nhất và mất O(n)thời gian. Tất cả các chèn khác vào mảng là O(1).

Để xác định thời gian chạy để chèn ncác mục, bạn có thể nhân nvới thao tác đắt nhất O(n), dẫn đến hành vi thời gian chạy tổng thể là O(n^2).

Tuy nhiên, điều này là không chính xác vì việc thay đổi kích thước không thể xảy ra rất thường xuyên.

Khi nói về tiền, bạn khấu hao chi phí, khi bạn trả hết nợ bằng nhiều khoản thanh toán nhỏ theo thời gian.

Chúng ta có thể sử dụng mô hình này để suy nghĩ về các thuật toán là tốt. Chúng tôi chỉ đơn giản thay thế "thời gian" bằng "tiền" để tránh ánh xạ tinh thần.

Khi mảng được lấp đầy theo chiều dài của nó n, chúng ta có thể tăng gấp đôi kích thước của nó. Chúng ta cần thực hiện các hoạt động sau:

  • Phân bổ 2nkhối bộ nhớ
  • sao chép ncác mục

Nếu chúng ta giả định rằng cả việc phân bổ bộ nhớ và sao chép xảy ra trong thời gian tuyến tính, thì đây sẽ là một hoạt động rất tốn kém. Tuy nhiên, bây giờ chúng ta có thể sử dụng ý tưởng về nợ và khấu hao nó để phân tích. Chỉ, chúng tôi sẽ khấu hao khoản nợ của chúng tôi trước khi chúng tôi thực sự thực hiện nó.
Giả sử, số dư của chúng tôi (tiền / thời gian) trở về 0 (nghĩa là chúng tôi không có nợ cũng như không có bất kỳ khoản dư nào) khi chúng tôi đã thay đổi kích thước mảng.

Điều này có hàm ý sau:

  • Chèn các nmục tiếp theo sẽ bao gồm chi phí thay đổi kích thước và sao chép (chúng tôi đã nsử dụng các vị trí và các vị trí nkhông sử dụng `)

Bây giờ chúng ta có thể nghĩ về mọi hoạt động chèn cần phải trả cho:

  • Phụ trang
  • Chi phí phân bổ một đoạn bộ nhớ
  • chi phí di chuyển nó vào bộ nhớ mới được phân bổ

Bây giờ chúng tôi đã trang trải chi phí để phân bổ bộ nhớ, sao chép và chèn các nyếu tố tiếp theo . Tuy nhiên, chúng tôi vẫn bỏ qua việc phân bổ không gian cho các nyếu tố cũ cũng như sao chép chúng.

Chúng tôi chỉ đơn giản phân phối chi phí của các nyếu tố cũ của chúng tôi cho các yếu tố mới (chưa được chèn) n:

  • Chi phí phân bổ một đoạn bộ nhớ
  • chi phí di chuyển nó vào bộ nhớ mới được phân bổ

Tổng cộng, mỗi, mọi hoạt động chèn sẽ có giá 5 đơn vị. Điều này trả tiền cho việc chèn riêng của nó, và di chuyển và phân bổ không gian cho chính nó và một trong những yếu tố cũ.

Mọi thao tác chèn vẫn mất một lượng thời gian không đổi, nhưng việc thay đổi kích thước xảy ra miễn phí: Chúng tôi đã khấu hao nó bằng cách dành thời gian "nhiều hơn" cho mỗi lần chèn.

Kết quả là, chèn ncác yếu tố cần có O(n)thời gian.

Các kỹ thuật khác để phân tích khấu hao được giải thích ở đây .


1

Trước hết: Đây là một kỹ thuật để phân tích thời gian chạy chương trình, không phải là một kỹ thuật thực hiện cho các thuật toán.

Ví dụ được đề cập trong danh sách của bạn là một ví dụ hay: Nối một mục duy nhất vào cấu trúc dữ liệu được hỗ trợ mảng. Đối với mỗi hoạt động chắp thêm, trường hợp xấu nhất là phải sao chép tất cả các mục hiện có. Kiểu phân tích đó quá bi quan, vì bạn không phải làm điều đó nếu bạn đang sử dụng chiến lược thay đổi kích thước lành mạnh (nhân kích thước với một số x> 1.0). Phân tích sau đó nói rằng bạn có ràng buộc O (n ^ 2) - O (n) cho mỗi mục nhân với n mục - trong khi thời gian chạy thực tế chỉ là O (n).

Nếu bạn tính trung bình chi phí thay đổi kích thước cho tất cả các mục được chèn (hầu hết trong số đó không cần thay đổi kích thước), bạn đang thực hiện phân tích khấu hao. Kết quả phân tích khấu hao trong giới hạn O (n) phù hợp với hành vi thực tế của thuật toán.

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.