Giải thích sự liên quan của độ phức tạp tiệm cận của thuật toán với thực hành thiết kế thuật toán


40

Trong các thuật toán và độ phức tạp, chúng tôi tập trung vào độ phức tạp tiệm cận của các thuật toán, tức là lượng tài nguyên mà thuật toán sử dụng khi kích thước của đầu vào chuyển sang vô cùng.

Trong thực tế, điều cần thiết là một thuật toán sẽ hoạt động nhanh trên số lượng cá thể hữu hạn (mặc dù có thể rất lớn).

Một thuật toán hoạt động tốt trong thực tế về số lượng các trường hợp hữu hạn mà chúng ta quan tâm không cần phải có độ phức tạp tiệm cận tốt (hiệu suất tốt trên số lượng các trường hợp hữu hạn không ngụ ý bất kỳ điều gì về độ phức tạp tiệm cận). Tương tự, một thuật toán có độ phức tạp tiệm cận tốt có thể không hoạt động tốt trong thực tế trên số lượng hữu hạn của các trường hợp mà chúng ta quan tâm (ví dụ vì các hằng số lớn).

Tại sao chúng ta sử dụng phức tạp tiệm cận? Làm thế nào để những phân tích tiệm cận liên quan đến thiết kế các thuật toán trong thực tế?


Một câu hỏi liên quan khác là: tại sao chúng ta bỏ qua các yếu tố không đổi ?
Raphael

Câu trả lời:


24

Câu hỏi thú vị là: sự thay thế là gì? Phương pháp duy nhất khác mà tôi biết là kiểm tra / điểm chuẩn. Chúng tôi lập trình các thuật toán, để chúng chạy trên (một mẫu đại diện) của bộ đầu vào hữu hạn và so sánh kết quả. Có một vài vấn đề với điều đó.

  • Kết quả không chung chung về máy móc. Chạy điểm chuẩn của bạn trên một máy tính khác và bạn nhận được kết quả khác nhau một cách chắc chắn, định lượng và thậm chí có thể định tính.
  • Kết quả không chung chung về ngôn ngữ lập trình. Các ngôn ngữ khác nhau có thể gây ra kết quả rất khác nhau.
  • Kết quả không chung chung về chi tiết thực hiện. Bạn thực sự so sánh các chương trình , không phải thuật toán; những thay đổi nhỏ trong việc thực hiện có thể gây ra sự khác biệt lớn trong hiệu suất.
  • Nếu trường hợp xấu nhất là hiếm, một mẫu đầu vào ngẫu nhiên có thể không chứa trường hợp xấu. Điều đó là công bằng nếu bạn quan tâm đến hiệu suất trường hợp trung bình, nhưng một số môi trường yêu cầu đảm bảo trường hợp xấu nhất.
  • Trong thực tế, bộ đầu vào thay đổi. Thông thường, đầu vào trở nên lớn hơn theo thời gian. Nếu bạn không lặp lại điểm chuẩn của mình sau mỗi sáu tháng (vâng, một số dữ liệu sẽ tăng nhanh), kết quả của bạn sẽ sớm trở nên vô giá trị¹.

Điều đó nói rằng, bỏ qua tất cả các loại hiệu ứng và hằng số trong phân tích là điển hình, nhưng có thể được gọi là lười biếng (đối với thực hành). Nó phục vụ để so sánh các ý tưởng thuật toán nhiều hơn là xác định hiệu suất của việc thực hiện (thậm chí cả mã giả) nhất định. Cộng đồng đã biết rằng điều này là thô và rằng một cái nhìn gần hơn thường là cần thiết; ví dụ, Quicksort kém hiệu quả hơn so với Sắp xếp chèn cho (rất) đầu vào nhỏ. Để công bằng, phân tích chính xác hơn thường là khó ².

Một lý do khác, một lời biện minh cho posteriori cho quan điểm trừu tượng, chính thức là ở cấp độ này, mọi thứ thường rõ ràng hơn. Do đó, nhiều thập kỷ nghiên cứu lý thuyết đã đưa ra một loạt các ý tưởng thuật toán và cấu trúc dữ liệu được sử dụng trong thực tế. Thuật toán tối ưu về mặt lý thuyết không phải lúc nào cũng là thuật toán bạn muốn sử dụng trong thực tế - có những cân nhắc khác ngoài hiệu năng để thực hiện; nghĩ rằng đống Fibonacci - và nhãn này thậm chí có thể không phải là duy nhất. Thật khó cho một lập trình viên điển hình liên quan đến việc tối ưu hóa các biểu thức số học sẽ đưa ra một ý tưởng mới ở cấp độ này (không nói rằng nó không xảy ra); cô ấy có thể (và nên) thực hiện những tối ưu hóa trên ý tưởng đồng hóa, mặc dù.

Có những công cụ lý thuyết, chính thức để thu hẹp khoảng cách để thực hành ở một mức độ nào đó. Ví dụ là

  • xem xét phân cấp bộ nhớ (và các I / O khác),
  • phân tích trường hợp trung bình (khi thích hợp),
  • phân tích số lượng báo cáo riêng lẻ (thay vì các biện pháp chi phí trừu tượng) và
  • xác định các yếu tố không đổi.

Ví dụ, Knuth được biết đến với nghĩa đen là đếm số lượng các câu lệnh khác nhau (cho một triển khai nhất định trong một mô hình nhất định), cho phép so sánh chính xác các thuật toán. Cách tiếp cận đó là không thể ở mức độ trừu tượng và khó thực hiện trong các mô hình phức tạp hơn (nghĩ Java). Xem [4] cho một ví dụ hiện đại.

Sẽ luôn có một khoảng cách giữa lý thuyết và thực hành. Chúng tôi hiện đang làm việc trên một công cụ - với mục tiêu kết hợp tốt nhất cả hai thế giới để đưa ra dự đoán âm thanh cho cả chi phí thuật toán và thời gian chạy (trung bình), nhưng cho đến nay chúng tôi vẫn chưa thể loại bỏ các tình huống trong đó một thuật toán có mức cao hơn chi phí nhưng thời gian chạy nhỏ hơn (trên một số máy) so với thời gian tương đương (mặc dù chúng tôi có thể phát hiện ra điều đó và hỗ trợ tìm lý do).

Tôi khuyên các nhà thực hành nên sử dụng lý thuyết để lọc không gian của các thuật toán trước khi chạy điểm chuẩn:

if ( input size forever bounded? ) {
  benchmark available implementations, choose best
  schedule new benchmarks for when machine changes
}
else {
  benchmark implementations of all asymptotically good algorithms
  choose the best
  schedule new benchmarks for when machine changes or inputs grow significantly
}

  1. Có thể có những thay đổi điên rồ về hiệu suất tuyệt đối và tương đối một khi số lượng bộ nhớ cache tăng lên, điều này thường xảy ra khi đầu vào tăng nhưng máy vẫn giữ nguyên.
  2. Như trong, các nhà nghiên cứu hàng đầu trong lĩnh vực này không thể làm điều đó.
  3. Tìm công cụ ở đây . Một ví dụ sử dụng đã được xuất bản trong QuickSort Dual Pivot Quicksort của Engineering Java 7 sử dụng MaLiJAn của S. Wild et al. (2012) [ in lại ]
  4. Phân tích trường hợp trung bình của Quicksort Pivot kép của Java 7 bởi S. Wild và M. Nebel (2012) - [ in sẵn ]

3
Có thể cho rằng, hành động thuần túy nghiên cứu lý thuyết về thuật toán sẽ làm sắc nét mắt bạn và rèn luyện trí trừu tượng của bạn cho các thuật toán, cung cấp cho bạn một công cụ khác để đánh giá mã trong lập trình hàng ngày. Tóm tắt ra khỏi mã, đánh giá nguyên tắc, cải thiện nó và dịch lại mã. Ví dụ: "Ah, tôi hiểu rồi, bạn muốn lập trình một từ điển. Nhưng về cơ bản, bạn liệt kê danh sách chương trình; tại sao không thử cây?"
Raphael

Các giới hạn của phân tích tiệm cận trở nên rõ ràng một khi bạn đào sâu hơn; Quicksort là một ví dụ nổi bật .
Raphael

1
FWIW, tôi đã viết một ảnh chụp gần đây hơn về ý kiến ​​của tôi về ký hiệu Landau ở đây .
Raphael

11

Tôi cho rằng câu hỏi này xuất phát từ việc dạy một khóa học bao gồm phân tích tiệm cận. Có một số câu trả lời có thể có về lý do tại sao tài liệu này được dạy trong các lớp giới thiệu:

  • Phân tích tiệm cận là một trừu tượng toán học mang lại chính nó để phân tích. Là nhà toán học (được cho là), chúng tôi muốn có thể phân tích các thuật toán và họ chỉ có cách để chế ngự sự phức tạp của chúng là sử dụng phân tích tiệm cận.

  • Đánh giá hiệu năng tiệm cận của thuật toán chỉ ra một số nguyên tắc hữu ích trong thực tế: ví dụ: tập trung vào phần mã đó chiếm phần lớn thời gian và giảm giá bất kỳ phần nào của mã mất một phần thời gian không đáng kể .

  • Một số kỹ thuật phân tích tiệm cận là hữu ích. Ở đây tôi chủ yếu đề cập đến cái gọi là "định lý chủ", trong nhiều trường hợp là một mô tả hay về thực tế.

  • Ngoài ra còn có một lý do lịch sử: khi mọi người lần đầu tiên bắt đầu phân tích các thuật toán, họ tha thiết nghĩ rằng sự phức tạp tiệm cận phản ánh việc sử dụng thực tế. Tuy nhiên, cuối cùng họ đã được chứng minh là sai. Điều tương tự cũng xảy ra với P là lớp các vấn đề có thể giải quyết hiệu quả và NP là lớp các vấn đề khó giải quyết, cả hai đều gây hiểu lầm trong thực tế.

Cá nhân, tôi nghĩ rằng phân tích tiệm cận là một phần hợp lý của chương trình giảng dạy. Nhiều phần nghi vấn hơn bao gồm lý thuyết ngôn ngữ chính thức và lý thuyết phức tạp (bất cứ điều gì phải làm với máy Turing). Một số người đưa ra lập luận rằng trong khi những môn học này không hữu ích đối với người lập trình viên, họ sẽ thấm nhuần tư tưởng nhất định cần thiết để trở thành một nhà thực hành giỏi. Những người khác cho rằng lý thuyết đôi khi ảnh hưởng đến thực tiễn, và những trường hợp hiếm hoi này là đủ để biện minh cho việc dạy những môn học khá phức tạp này cho khán giả khoa học máy tính nói chung. Tôi muốn họ học lịch sử hoặc văn học, hoặc bất kỳ chủ đề nào khác mà họ thực sự quan tâm; cả hai đều có liên quan đến triển vọng công việc tương lai của họ, và quan trọng hơn đối với họ là con người.


Cảm ơn Yuval. Động lực chủ yếu quan tâm là làm thế nào để giải thích cho sinh viên về tính hữu ích của phân tích tiệm cận và sự liên quan của nó với thực tiễn thiết kế và sử dụng thuật toán trong các ứng dụng thực tế (trong đó hầu hết mọi lúc rõ ràng là chúng ta chỉ quan tâm đến một hữu hạn mặc dù có thể số lượng rất lớn các trường hợp), không biện minh cho chương trình giảng dạy.
Kaveh

1
Tôi bối rối bởi tiền đề của bạn. Bạn dường như cho rằng nhóm mục tiêu vừa là nhà toán học vừa là lập trình viên đầy tham vọng, đây là một sự kết hợp kỳ lạ và không đặc trưng cho các nhà khoa học máy tính. (Ngoài ra, tôi không chia sẻ quan điểm của bạn về các ngôn ngữ chính thức, nhưng đó là một chủ đề khác.)
Raphael

Ngược lại, tôi cho rằng nhóm mục tiêu là những lập trình viên đầy tham vọng. Tuy nhiên, phần lớn chương trình giảng dạy là vì lợi ích của các nhà khoa học máy tính lý thuyết. Tất nhiên, hai nhóm này có nhu cầu xung đột. Vì hầu hết các sinh viên đại học đều là những lập trình viên, tôi nghĩ rằng chương trình giảng dạy nên hướng đến họ, nhưng một số học giả không đồng ý. Có lẽ họ muốn dạy các giáo sư tương lai. Có lẽ bạn có thể giải thích quan điểm của họ.
Yuval Filmus

3
@YuvalFilmus Tôi thường giải thích rằng tôi không tin rằng CS = TCS + Lập trình. Nếu bạn dạy một khóa học CS (tại một trường đại học) và hầu hết các sinh viên của bạn muốn trở thành lập trình viên, một cái gì đó đã bị phá vỡ (imho). Tôi sẽ lập luận rằng bất kỳ nhà khoa học máy tính nào cũng có thể kiếm lợi từ giáo dục vững chắc về thuật toán, ngôn ngữ chính thức và thậm chí một số lý thuyết phức tạp (và nhiều thứ khác, chẳng hạn như cách trình biên dịch và CPU hoạt động).
Raphael

2
@Wildcard Kiến trúc máy tính, đồ họa máy tính, AI, nghiên cứu ngôn ngữ lập trình, ... - danh sách là vô tận! TCS thực sự là một phân khúc thích hợp, và lập trình chỉ là một công cụ cho (hầu hết) các nhà nghiên cứu CS.
Raphael

7

Có hai lý do nghiêm trọng để sử dụng phân tích tiệm cận về thời gian chạy:

  • để trừu tượng đi chi tiết không quan trọng. Trong nhiều ứng dụng mà chúng tôi cần các thuật toán không tầm thường, phần lớn thời gian dành cho các trường hợp có vấn đề đòi hỏi số lượng hoạt động từ trung bình đến lớn và chúng tôi quan tâm đến xu hướng chung hơn là số lượng hoạt động chính xác. Trong các ứng dụng này, hành vi cho nhỏ là không thú vị.n

  • để cho phép tính linh hoạt toán học. Các trường hợp có thể tìm thấy các biểu thức chính xác cho số lượng hoạt động là ngoại lệ. Nghiên cứu tiệm cận mở ra nhiều khả năng hơn (như các xấp xỉ tiệm cận của các hàm phức tạp là tiện dụng).

Và còn nhiều thứ khác (như sự độc lập của máy móc, ý nghĩa, sự so sánh ...).


"Chúng tôi quan tâm đến xu hướng chung hơn là số lượng hoạt động chính xác" - câu này không hoàn toàn đúng. Đó là một lời biện minh trong sách giáo khoa không theo kịp trong tất cả các ứng dụng. "Tối ưu hóa thuật toán là hữu ích cho số lượng hoạt động từ trung bình đến lớn" - đây cũng không phải là hoạt động. Một thuật toán luôn được thực thi trên các đầu vào nhỏ và nhanh nhưng được thực hiện hàng tỷ lần cũng đáng để tối ưu hóa. Ví dụ thực tế: mọi triển khai Quicksort trong thế giới thực chuyển sang thuật toán sắp xếp khác cho nhỏ . n
Raphael

Chà, tôi không nghĩ đó là một quy tắc. Càng nhiều dữ liệu bạn vứt đi, các tuyên bố bạn có thể thực hiện càng yếu. Phối cảnh tiệm cận (và, hơn thế nữa, "big-oh") tạo ra các câu như "Quicksort nhanh hơn Insertionsort", nếu không sai, cũng không hoàn toàn đúng. (Vâng, tôi đang nói rằng phân tích thuật toán thường được dạy sai, imho.)
Raphael

6

Như đã lưu ý trong câu trả lời của Raphael, việc tính toán chính xác thời gian chạy trong trường hợp xấu nhất có thể rất khó khăn. Tính toán chính xác cũng có thể không cần thiết vì mô hình RAM đã đưa ra các xấp xỉ. Ví dụ, tất cả các hoạt động thực sự mất thời gian như nhau? Việc triển khai cụ thể (phần cứng, tối ưu hóa) có thể tăng tốc thuật toán theo các yếu tố không đổi. Chúng tôi muốn hiểu làm thế nào hiệu quả của một thuật toán độc lập với các yếu tố này. Đây là một động lực lớn cho việc sử dụng phân tích tiệm cận.


3

Bởi vì tiệm cận là "đơn giản" (tốt, đơn giản hơn so với việc phân tích chính xác cho các trường hợp hữu hạn, dù sao).

So sánh ví dụ: "Nghệ thuật lập trình máy tính" của Knuth, phân tích chi tiết tất cả các thuật toán quan trọng (và nhiều thuật toán không quan trọng) với phân tích quy tắc thường đủ để có được ước tính tiệm cận ( hoặc chỉ là một ràng buộc), như được thực hành trong hầu hết các cuốn sách "thuật toán".

Bạn chắc chắn đúng. Nếu vấn đề đủ quan trọng, phân tích kiểu Knuth (hoặc có thể ít chi tiết hơn một chút) cũng có thể được bảo hành. Trong nhiều trường hợp, một gợi ý về độ phức tạp tiệm cận (có lẽ là trung bình với độ phân tán) phù hợp với dữ liệu thực nghiệm là đủ. Trong hầu hết các trường hợp , để thực hiện phân loại sơ bộ các thuật toán cạnh tranh, vì một vòng loại trừ đầu tiên so sánh các triệu chứng tiệm cận có thể đủ chính xác. Và nếu không có ứng cử viên, nhận được tin xấu về chi phí chính xác trong chi tiết phút chỉ là khổ dâm.


2
Đây chỉ là một nửa sự thật: đầu tiên, có vẻ như bạn viết với "big-oh" trong đầu (mà câu hỏi không đề cập đến). Thứ hai, tiệm cận "big-oh" nổi tiếng là thất bại một cách ngoạn mục cho "vòng loại trừ" khi chọn thuật toán: đầu vào là hữu hạn trong thực tế.
Raphael

3

Ở đây bằng phân tích tiệm cận tôi giả sử chúng ta có nghĩa là hành vi của thuật toán khi kích thước của đầu vào đi đến vô cùng.

Lý do chúng tôi sử dụng phân tích tiệm cận là vì nó hữu ích trong việc dự đoán hành vi của các thuật toán trong thực tế . Các dự đoán cho phép chúng ta đưa ra quyết định, ví dụ khi chúng ta có các thuật toán khác nhau cho một vấn đề chúng ta nên sử dụng? (Hữu ích không có nghĩa là nó luôn luôn đúng.)

Câu hỏi tương tự có thể được hỏi về bất kỳ mô hình đơn giản hóa nào của thế giới thực. Tại sao chúng ta sử dụng các mô hình toán học đơn giản hóa của thế giới thực?

Hãy nghĩ về vật lý. Vật lý Newton cổ điển không tốt bằng vật lý tương đối tính trong việc dự đoán thế giới thực. Nhưng nó là một mô hình đủ tốt để chế tạo ô tô, tòa nhà chọc trời, tàu ngầm, máy bay, cầu, v.v ... Có những trường hợp nó không đủ tốt, ví dụ nếu chúng ta muốn xây dựng một vệ tinh hoặc gửi tàu thăm dò không gian tới Sao Diêm Vương hoặc dự đoán chuyển động của các thiên thể khổng lồ như sao và hành tinh hoặc các vật thể tốc độ rất cao như electron. Điều quan trọng là phải biết giới hạn của một mô hình là gì.

  1. Nó thường là một xấp xỉ đủ tốt của thế giới thực. Trong thực tế, chúng ta thường thấy rằng một thuật toán có phân tích tiệm cận tốt hơn hoạt động tốt hơn trong thực tế. Rất hiếm khi một thuật toán có hành vi tiệm cận tốt hơn Vì vậy, nếu các yếu tố đầu vào có thể đủ lớn thì chúng ta thường có thể dựa vào phân tích tiệm cận như một dự đoán đầu tiên về hành vi của thuật toán. Nó không phải là như vậy nếu chúng ta biết đầu vào sẽ nhỏ. Tùy thuộc vào hiệu suất mà chúng tôi muốn, chúng tôi có thể cần phân tích cẩn thận hơn, ví dụ: nếu chúng tôi có thông tin về phân phối đầu vào, thuật toán sẽ được cung cấp, chúng tôi có thể phân tích cẩn thận hơn để đạt được các mục tiêu chúng tôi có (ví dụ: nhanh trên 99 % đầu vào). Điểm quan trọng là bước đầu tiên phân tích tiệm cận là điểm khởi đầu tốt. Trong thực tế chúng ta cũng nên thực hiện các bài kiểm tra hiệu suất nhưng hãy nhớ rằng cũng có vấn đề riêng của nó.

  2. Nó là tương đối đơn giản để tính toán trong thực tế. Thông thường chúng ta có thể tính toán ít nhất các giới hạn tốt về độ phức tạp tiệm cận của thuật toán. Để đơn giản, hãy giả sử rằng chúng ta có một thuật toán vượt trội hơn bất kỳ thuật toán nào khác trên mỗi đầu vào. Làm thế nào chúng ta có thể biết tốt hơn những người khác? Chúng ta có thể phân tích tiệm cận và thấy rằngA AAAAcó độ phức tạp tiệm cận tốt hơn. Điều gì không ai trong số họ là tốt hơn so với cái khác trong tất cả các đầu vào? Sau đó, nó trở nên khó khăn hơn và phụ thuộc vào những gì chúng ta quan tâm. Chúng ta quan tâm đến đầu vào lớn hay đầu vào nhỏ? Nếu chúng ta quan tâm đến các đầu vào lớn thì không có gì phổ biến là một thuật toán có độ phức tạp tiệm cận tốt hơn nhưng lại hoạt động kém nhất trên các đầu vào lớn mà chúng ta quan tâm. Nếu chúng ta quan tâm nhiều hơn về các đầu vào nhỏ thì phân tích tiệm cận có thể không hữu ích. Chúng ta nên so sánh thời gian chạy của các thuật toán trên các đầu vào mà chúng ta quan tâm. Trong thực tế, đối với các nhiệm vụ phức tạp với các yêu cầu phức tạp, phân tích tiệm cận có thể không hữu ích. Đối với các vấn đề cơ bản đơn giản mà sách giáo khoa thuật toán bao gồm, nó khá hữu ích.

Trong độ phức tạp tiệm cận ngắn là một phép tính gần đúng tương đối dễ dàng về độ phức tạp thực tế của các thuật toán cho các nhiệm vụ cơ bản đơn giản (các vấn đề trong sách giáo khoa thuật toán). Khi chúng tôi xây dựng các chương trình phức tạp hơn, các yêu cầu về hiệu suất thay đổi và trở nên phức tạp hơn và phân tích tiệm cận có thể không hữu ích.


Thật tốt khi so sánh phân tích tiệm cận với các phương pháp khác để dự đoán hiệu suất của các thuật toán và so sánh chúng. Một cách tiếp cận phổ biến là kiểm tra hiệu suất đối với đầu vào ngẫu nhiên hoặc điểm chuẩn. Điều này là phổ biến khi tính toán độ phức tạp tiệm cận là khó khăn hoặc không khả thi, ví dụ như khi chúng ta đang sử dụng phương pháp phỏng đoán như trong giải quyết SAT. Một trường hợp khác là khi các yêu cầu phức tạp hơn, ví dụ khi hiệu suất của chương trình phụ thuộc vào các yếu tố bên ngoài và mục tiêu của chúng tôi có thể là có một cái gì đó hoàn thành trong một số giới hạn thời gian cố định (ví dụ: nghĩ về việc cập nhật giao diện cho người dùng) trên 99% đầu vào.

Nhưng hãy nhớ rằng phân tích hiệu suất cũng có vấn đề. Nó không cung cấp cho những người được cấp toán học về hiệu suất khi chúng tôi thực sự chạy thử nghiệm hiệu năng trên tất cả các đầu vào sẽ được cung cấp cho thuật toán (thường là infeasbile tính toán) (và thường không thể quyết định một số đầu vào sẽ không bao giờ được đưa ra). Nếu chúng ta thử nghiệm trên đối với một mẫu ngẫu nhiên hoặc một chuẩn mực chúng ta ngầm giả định một số quy luật về hiệu suất của các thuật toán, tức là thuật toán sẽ thực hiện tương tự như trên các đầu vào khác mà không phải là một phần của thử nghiệm hiệu suất.

Vấn đề thứ hai với các bài kiểm tra hiệu suất là chúng phụ thuộc vào môi trường kiểm tra. Tức là hiệu suất của chương trình không chỉ được xác định bởi các yếu tố đầu vào mà là các yếu tố bên ngoài (ví dụ: loại máy, hệ điều hành, hiệu quả của thuật toán mã hóa, sử dụng CPU, thời gian truy cập bộ nhớ, v.v.) một số yếu tố có thể khác nhau giữa các lần chạy khác nhau các thử nghiệm trên cùng một máy. Một lần nữa ở đây, chúng tôi giả định rằng các môi trường cụ thể mà kiểm tra hiệu năng được thực hiện tương tự như môi trường thực tế trừ khi chúng tôi thực hiện kiểm tra hiệu suất trên tất cả các môi trường mà chúng tôi có thể chạy chương trình trên (và làm thế nào chúng tôi có thể dự đoán máy nào có thể chạy phân loại thuật toán trong 10 năm?).

So sánh những điều này với việc tính toán thời gian chạy tiệm cận của MergeSort ( ) và so sánh nó với thời gian chạy của Lựa chọn nói ( ) hoặc BinarySerch ( ) với Tìm kiếm tuyến tính ( ).Θ ( n 2 ) Θ ( lg n ) O ( n )Θ(nlgn)Θ(n2)Θ(lgn)O(n)



Tôi thích câu trả lời này đủ để upvote bây giờ. Hai lưu ý: 1) Tôi sẽ sử dụng "chi phí" thay vì "phức tạp" ở đây. Một phần vì lý do thú cưng, nhưng cũng vì có nhiều biện pháp chi phí có thể hiểu được (làm phức tạp tất cả các cân nhắc bạn đề cập). 2) Bạn có thể muốn thực hiện vượt qua ngôn ngữ đánh bóng. ;)
Raphael

@Raphael, cảm ơn. Tôi đang lên kế hoạch để thực hiện một chỉnh sửa sớm. :)
Kaveh

-2

làm thế nào về một ví dụ minh họa gần trực quan đơn giản bằng cách sử dụng một trong những thuật toán / ứng dụng phổ biến nhất trong CS, cụ thể là sắp xếp? Bubbledort mất cả thời gian trường hợp trung bình và tồi tệ nhất và quicksort vềO ( n log n )O(n2)O(nlogn)O(n2)

Bây giờ hãy tưởng tượng rằng chờ đợi lặp đi lặp lại trong mã nhiều lần như mã được gọi. làm thế nào để một số lượng toán học / chứng minh tính ưu việt rõ ràng này của thuật toán quicksort? (tức là tên của nó thực sự hợp lý hay nó chỉ là một khẩu hiệu tiếp thị?) thông qua các phép đo độ phức tạp tiệm cận. một người đang nhìn vào các hình ảnh động một cách chủ quan cảm thấy rằng bubbleort bằng cách nào đó là một thuật toán yếu hơn và phân tích độ phức tạp tiệm cận có thể chứng minh điều này một cách định lượng. nhưng lưu ý rằng phân tích độ phức tạp tiệm cận chỉ là một công cụ trong túi các công cụ để phân tích các thuật toán và nó không phải lúc nào cũng là công cụ cuối cùng.

và giá trị của nó nhìn vào mã bên cạnh cũng có. bubbleort dường như đơn giản hơn về mặt khái niệm và không sử dụng đệ quy. quicksort không được hiểu ngay lập tức theo nguyên tắc trục "trung vị của 3". bubbleort có thể được thực hiện chỉ trong các vòng mà không có chương trình con, trong khi quicksort thường có ít nhất một chương trình con. điều này cho thấy mô hình rằng sự tinh vi mã nhiều hơn đôi khi có thể cải thiện độ phức tạp tiệm cận với chi phí đơn giản mã. đôi khi có một giao dịch cực đoan tương tự như khái niệm lợi nhuận cận biên giảm dần (nguồn gốc từ kinh tế học) trong đó các mức độ phức tạp mã rất lớn [yêu cầu toàn bộ giấy tờ đầy đủ và bằng chứng để chứng minh] chỉ mua những cải tiến rất nhỏ về độ phức tạp tiệm cận. đây là một ví dụ đặc biệt vớinhân ma trận và thậm chí có thể được vẽ đồ thị .


Có rất nhiều lãnh thổ giữa "nhìn vào hình ảnh động" và phân tích chính thức, chẳng hạn như điểm chuẩn thời gian chạy rộng rãi. Chúng thực sự là một khu vực hợp lệ của riêng chúng, vì chúng tôi không có lý thuyết để giải thích tất cả những thứ ảnh hưởng đến thời gian chạy.
Raphael

@raphael bạn bao gồm điểm chuẩn trong câu trả lời của bạn; đó là một câu trả lời tốt nhưng lưu ý rằng hoạt hình / trực quan hóa có thể liên quan chặt chẽ đến điểm chuẩn. trên thực tế có rất nhiều lời giải thích về những gì ảnh hưởng đến thời gian chạy [được đề cập trong các câu trả lời khác] nhưng ở một mức độ nào đó, "tiếng ồn" và độ phức tạp không triệu chứng của nó "làm mịn / giảm trung bình tiếng ồn". đó là một bài tập khác để xem làm thế nào nó thực sự làm điều đó.
vzn

Ảnh động không lọc tiếng ồn, mặc dù. Thêm vào đó, mắt người dễ bị lừa và không thể xem hoạt hình cho một mẫu danh sách có kích thước hợp lý (giả sử 1000 danh sách cho các kích thước trong hàng triệu thuật toán sắp xếp chuẩn) quyết định thuật toán nào nhanh hơn (trên trung bình).
Raphael

nn

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.