Sorting Algorithms Permutations

Sorting Algorithms Permutations

Sorting Algorithms We can implement this concept of a sort directly in Prolog. We Sorting algorithms are good (a) permute an input list examples of Prolog’s definitional (b) check if it is in sorted order capabilities. In a Prolog definition the “logic” of a sorting algorithm (c) repeat (a) & (b) until a sorting is apparent, stripped of the is found. cumbersome details of data structures and control structures that dominate algorithms in other programming languages. Consider the simplest possible sort imaginable, which we’ll call the “naive sort.” At the simplest level a sorting of a list L requires just two things: • The sorting is a permutation (a reordering) of the values in L. • The values are “in order” (ascending or descending). © © CS 538 Spring 2008 426 CS 538 Spring 2008 427 Permutations The first definition, perm([],[]). Let’s first look at how is trivial. An empty list may only permutations are defined in be permuted into another empty Prolog. In most languages list. generating permutations is non- trivial—you need data structures The second definition is rather to store the permutations you are more complex: generating and control structures perm(L,[H|T]) :- to visit all permutations in some append(V,[H|U],L), order. append(V,U,W), perm(W,T). In Prolog, permutations are This rule says a list L may be defined quite concisely, though permuted in to a list that begins with a bit of subtlety: with H and ends with list T if: perm(X,Y) will be true if list Y is a (1) L may be partitioned into two permutation of list X. lists, V and [H|U]. (That is, H is somewhere in the Only two definitions are needed: “middle” of L). perm([],[]). (2) Lists V and U (all of L except H) perm(L,[H|T]) :- may be appended into list W. append(V,[H|U],L), W T append(V,U,W), perm(W,T). (3) List may be permuted into . © © CS 538 Spring 2008 428 CS 538 Spring 2008 429 Let’s see perm in action: simplifies to | ?- perm([1,2,3],X). append(V,[H|U],[1,2,3]). X = [1,2,3] ; One solution to this goal is X = [1,3,2] ; V = [], H = 1, U = [2,3] X = [2,1,3] ; We next solve append(V,U,W) X = [2,3,1] ; which simplifies to X = [3,1,2] ; append([],[2,3],W). X = [3,2,1] ; The only solution for this is no W=[2,3]. We’ll trace how the first few Finally, we solve perm(W,T), answers are computed. Note though that all permutations are which simplifies to generated, and with no apparent perm([2,3],T). data structures or control One solution to this is T=[2,3]. structures. This gives us our first solution: We start with L=[1,2,3] and [H|T]=[1,2,3]. X=[H|T] . To get our next solution we We first solve backtrack. Where is the most append(V,[H|U],L), which recent place we made a choice of how to solve a goal? © © CS 538 Spring 2008 430 CS 538 Spring 2008 431 It was at perm([2,3],T). We makes our third solution for chose T=[2,3], but T=[3,2] is [H|T] = [2,1,3]. another solution. Using this You can check out the other solution, we get out next answer bindings that lead to the last [H|T]=[1,3,2]. three solutions. Let’s try one more. We backtrack again. No more solutions are possible for perm([2,3],T), so we backtrack to an earlier choice point. At append(V,[H|U],[1,2,3]) another solution is V=[1], H = 2, U = [3] Using this binding, we solve append(V,U,W) which simplifies to append([1],[3],W). The solution to this must be W=[1,3]. We then solve perm(W,T) which simplifies to perm([1,3],T). One solution to this is T=[1,3]. This © © CS 538 Spring 2008 432 CS 538 Spring 2008 433 A Permutation Sort excluding the first element, is checked. Now that we know how to Now our naive permutation sort is generate permutations, the only one line long: definition of a permutation sort is naiveSort(L1,L2) :- almost trivial. perm(L1,L2), inOrder(L2). We define an inOrder relation And the definition works too! that characterizes our notion of when a list is properly sorted: | ?- naiveSort([1,2,3],[3,2,1]). inOrder([]). no inOrder([_]). ?- naiveSort([3,2,1],L). inOrder([A,B|T]) :- L = [1,2,3] ; A =< B, inOrder([B|T]). no These definitions state that a null | ?- list, and a list with only one naiveSort([7,3,88,2,1,6,77, element are always in sorted -23,5],L). order. Longer lists are in order if L = [-23,1,2,3,5,6,7,77,88] the first two elements are in proper order. (A=<B) checks this and then the rest of the list, © © CS 538 Spring 2008 434 CS 538 Spring 2008 435 Though this sort works, it is A Bubble Sort hopelessly inefficient—it repeatedly “shuffles” the input Perhaps the best known sorting until it happens to find an technique is the interchange or ordering that is sorted. The “bubble” sort. The idea is simple. process is largely undirected. We We examine a list of values, don’t “aim” toward a correct looking for a pair of adjacent ordering, but just search until we values that are “out of order.” If get lucky. we find such a pair, we swap the two values (placing them in correct order). Otherwise, the whole list must be in sorted order and we are done. In conventional languages we need a lot of code to search for out-of-order pairs, and to systematically reorder them. In Prolog, the whole sort may be defined in a few lines: © © CS 538 Spring 2008 436 CS 538 Spring 2008 437 bubbleSort(L,L) :- inOrder(L). input L, with A and B swapped bubbleSort(L1,L2) :- into B followed by A. append(X,[A,B|Y],L1), A > B, Finally, we verify that append(X,[B,A|Y],T), bubbleSort(T,L2) holds. That bubbleSort(T,L2). is, T may be bubble-sorted into L2. The first line says that if L is This approach is rather more already in sorted order, we are directed than our permutation done. sort—we look for an out-of-order The second line is a bit more pair of values, swap them, and complex. It defines what it means then sort the “improved” list. for a list L2 to be a sorting for list Eventually there will be no more L1, using our insight that we out-of-order pairs, the list will be should swap out-of-order in sorted order, and we will be neighbors. We first partition list done. L1 into two lists, X and [A,B|Y]. This “exposes” two adjacent values in L, A and B. Next we verify that A and B are out-of- order (A>B). Next, in append(X,[B,A|Y],T), we determine that list T is just our © © CS 538 Spring 2008 438 CS 538 Spring 2008 439 Merge Sort We first need Prolog rules on how to split a list into two equal Another popular sort in the halves: “merge sort” that we have already split([],[],[]). seen in Scheme and ML. The idea split([A],[A],[]). here is to first split a list of length split([A,B|T],[A|P1],[B|P2]) :- L into two sublists of length L/2. split(T,P1,P2). Each of these two lists is The first two lines characterize recursively sorted. Finally, the two trivial splits. The third rule sorted sublists are merged distributes one of the first two together to form a complete elements to each of the two sorted list. sublists, and then recursively The bubble sort can take time splits the rest of the list. proportional to n2 to sort n elements (as many as n2/2 swaps may be needed). The merge sort does better—it takes time proportional to n log2 n to sort n elements (a list of size n can only be split in half log2 n times). © © CS 538 Spring 2008 440 CS 538 Spring 2008 441 We also need rules that With the above definitions, a characterize how to merge two merge sort requires only three sorted sublists into a complete lines: sorted list: mergeSort([],[]). mergeSort([A],[A]). merge([],L,L). mergeSort(L1,L2) :- merge(L,[],L). split(L1,P1,P2), merge([A|T1],[B|T2],[A|L2]) :- mergeSort(P1,S1), A =< B, merge(T1,[B|T2],L2). mergeSort(P2,S2), merge([A|T1],[B|T2],[B|L2]) :- merge(S1,S2,L2). A > B, merge([A|T1],T2,L2). The first two lines handle the The first 2 lines handle merging trivial cases of lists of length 0 or null lists. The third line handles 1. The last line contains the full the case where the head of the “logic” of a merge sort: split the first sublist is ≤ the head of the input list, L into two half-sized second sublist; the final rule lists P1 and P2. Then merge sort handles the case where the head P1 into S1 and P2 into S2. Finally, of the second sublist is smaller. merge S1 and S2 into a sorted list L2. That’s it! © © CS 538 Spring 2008 442 CS 538 Spring 2008 443 Quick Sort We need a Prolog relation that characterizes how we will do our The merge sort partitions its input partitioning.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    7 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us