1 / 20

Inventing A Really Bad Sort: It Seemed Like A Good Idea At The Time

Inventing A Really Bad Sort: It Seemed Like A Good Idea At The Time. Jim Huggins Kettering University jhuggins@kettering.edu http://www.kettering.edu/~jhuggins. Bless me, Father Knuth, for I have sinned …. The Set-Up.

calida
Download Presentation

Inventing A Really Bad Sort: It Seemed Like A Good Idea At The Time

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Inventing A Really Bad Sort:It Seemed Like A Good Idea At The Time Jim Huggins Kettering University jhuggins@kettering.edu http://www.kettering.edu/~jhuggins

  2. Bless me, Father Knuth, for I have sinned …

  3. The Set-Up Writing questions for take-home exam for Advanced Algorithms course (sophomore) Desired: an algorithm which: • does something useful • is simple to analyze • hasn’t been done before on the web

  4. Inspiration: StoogeSort public void StoogeSort(int[] arr, int start, int stop) { if (arr[start] > arr[stop]) { int swap = arr[start]; arr[start] = arr[stop]; arr[stop] = swap; } if (start+1 >= stop) return; int third = (stop - start + 1) / 3; StoogeSort(arr, start, stop-third); // First two-thirds StoogeSort(arr, start+third, stop); // Last two-thirds StoogeSort(arr, start, stop-third); // First two-thirds } Comparison count: T(n) = 3T(⅔n) + 1; T(0)=0, T(1)=0, T(2) = 1 T(n) = Θ(nlog3/2 3) ≈ Θ(n2.7)

  5. My Idea: GoofySort public void goofySort (int[] array, int start, int stop) { if (start>=stop) return; goofySort(array, start, stop-1); // first n-1 items if (array[stop-1] > array[stop]) { int swap = array[stop-1]; // swap last item array[stop-1] = array[stop]; array[stop] = swap; goofySort(array, start, stop-1); // first n-1 items } // again } An added bonus: different behavior in best case, worst case. (More questions!)

  6. Analysis of GoofySort: Best Case public void goofySort (int[] array, int start, int stop) { if (start>=stop) return; goofySort(array, start, stop-1); if (array[stop-1] > array[stop]) { // best case: false int swap = array[stop-1]; array[stop-1] = array[stop]; array[stop] = swap; goofySort(array, start, stop-1); } } Comparison count: T(n) = T(n-1) + 1, T(1) = 0 T(n) = O(n)

  7. Analysis of GoofySort: Worst Case public void goofySort (int[] array, int start, int stop) { if (start>=stop) return; goofySort(array, start, stop-1); if (array[stop-1] > array[stop]) { // worst case: true int swap = array[stop-1]; array[stop-1] = array[stop]; array[stop] = swap; goofySort(array, start, stop-1); } } Comparison count: T(n) = 2T(n-1) + 1, T(1) = 0 T(n) = O(2n)

  8. “Beware of bugs in the above code; I have only proved it correct, not tried it.”

  9. And so, to avoid embarrassment … • Coded the algorithm in Java • Tested with a variety of random inputs • Tested with a variety of list sizes 20, 30, 40, … • And it all works! Great! (What could possibly go wrong?)

  10. Actual Student Answers: • T(n) = O(n3) • T(n) = T(n-1) + O(n2) = O(n3) • T(n) = T(n-1) + Σ1n i = ? • T(n) = O(2n) • One bright student, at least!

  11. Preparing to hand them back… • Preparing my rant … • “you completely missed the point” • “we did this in class … ” • “I even tested this on lots of inputs ...” • And then I remember: • If this is really exponential time, how did I run it on an input of size 40? • @#@!. What if I’m wrong and they’re right?

  12. Bentley: Three Beautiful Quicksorts Paraphrasing: “If you double the input size, and the instruction count quadruples, you’ve got a quadratic algorithm.” (Watch the Google TechTalk … it’s neat.)

  13. Racing to the computer Take the average over 100 random runs … @#$!. It looks like it’s cubic!

  14. How could this be cubic? public void goofySort (int[] array, int start, int stop) { if (start>=stop) return; goofySort(array, start, stop-1); if (array[stop-1] > array[stop]) { int swap = array[stop-1]; array[stop-1] = array[stop]; array[stop] = swap; goofySort(array, start, stop-1); } } The first recursive call is always bad;the array could be completely unordered The second recursive call is always good;all but the last item are ordered

  15. How badly cubic? • What’s the worst case input? • Reverse sorted, right? • At this point, I don’t trust myself, so … • Generate all permutations on a list of size n • We just covered this in class! (Lucky this is an algorithms course!) • Verified: worst case happens in reverse order

  16. So, what’s the worst-case time? • Do a bunch of input sizes … • … and putz around with a calculator … • The closed-form formula appears to be: T(n) = n(n-1)(n-2)/6 + (n-1) • So this does appear to be cubic after all. (Now, how do I prove it?)

  17. A quick overview of the proof • T(n) = 1 + T(n-1) + GT(n-1); T(1) = 0 • GT(n) = (n-1) + GT(n-1); GT(1) = 0 …GT(n) = n(n-1)/2 • T(n) = 1 + T(n-1) + (n-1)(n-2)/2; T(1) = 0 …T(n) = (n-1) + n(n-1)(n-2)/6 (see me for the full proof … it’s not that bad)

  18. Aftermath • Deep apologies to the students • They were gracious • Q: “How did y’all know it was cubic?”A: “We ran it and it looked cubic.” • They had no idea how to proceed …so they did the empirical analysis first to find the “right” answer!

  19. “Beware of bugs in the above code; I have only proved it correct, not tried it.”

  20. “Beware of bugs in the above analysis; I have only proved it correct, not verified it empirically.”

More Related