sc/permutations [ Modules ]
NAME
permutations File: permutations.lsp Class Hierarchy: none, no classes defined. Version: 1.0.0-beta1 Project: slippery chicken (algorithmic composition) Purpose: Various permutation functions. Author: Michael Edwards: m@michael-edwards.org Creation date: 10th November 2002 $$ Last modified: 19:13:04 Tue May 8 2012 BST SVN ID: $Id: permutations.lsp 1764 2012-05-17 11:49:59Z medward2 $
permutations/inefficient-permutations [ Functions ]
[ Top ] [ permutations ] [ Functions ]
FUNCTION
Return a shuffled, non-systematic list of all possible permutations of a set of consecutive integers beginning with zero. The function's first argument, <level>, is an integer that determines how many consecutive integers from 0 are to be used for the process. An optional keyword argument <max> allows the user to specify the maximum number of permutations to return. This function differs from the "permutations" function in that it's result is not ordered systematically. The function simply returns a list of <max> permutations of the numbers less than <level>; it does not permutate a given list. The function is inefficient in so far as it simply shuffles the numbers and so always has to check whether the new list already contains the shuffled before storing it. The order of the permutations returned will always be the same unless <fix> is set to NIL. Keyword argument <skip> allows the user to skip a number of permutations, which is only sensible if :fix is set to T.
ARGUMENTS
An integer that indicates how many consecutive integers from 0 are to be used for the process.
OPTIONAL ARGUMENTS
- keyword argument :max. An integer that indicates the maximum number of permutations to be returned. - keyword argument :skip. An integer that indicates a number of permutations to skip. - keyword argument :fix. T or NIL to indicate whether the given sequence should always be shuffled with the same (fixed) random seed (thus always producing the same result). T = fixed seed. Default = T.
RETURN VALUE
A list.
EXAMPLE
;; Creating a shuffled, non-systematic list of all permutations of consecutive ;; integers 0 to 4 (inefficient-permutations 4) => ((2 3 0 1) (3 1 2 0) (2 0 3 1) (1 0 2 3) (1 2 3 0) (0 2 3 1) (2 1 0 3) (0 1 2 3) (2 3 1 0) (1 2 0 3) (3 0 1 2) (3 1 0 2) (1 3 2 0) (1 0 3 2) (2 0 1 3) (3 2 1 0) (2 1 3 0) (3 2 0 1) (1 3 0 2) (0 2 1 3) (3 0 2 1) (0 1 3 2) (0 3 2 1) (0 3 1 2)) ;; Using 0 to 4 again, but limiting the number of results returned to a maximum ;; of 7 (inefficient-permutations 4 :max 7) => ((2 3 0 1) (3 1 2 0) (2 0 3 1) (1 0 2 3) (1 2 3 0) (0 2 3 1) (2 1 0 3)) ;; The same call will return the same "random" results each time by default (loop repeat 4 do (print (inefficient-permutations 3 :max 5))) => ((2 0 1) (2 1 0) (0 2 1) (1 0 2) (1 2 0)) ((2 0 1) (2 1 0) (0 2 1) (1 0 2) (1 2 0)) ((2 0 1) (2 1 0) (0 2 1) (1 0 2) (1 2 0)) ((2 0 1) (2 1 0) (0 2 1) (1 0 2) (1 2 0)) ;; Setting the :fix argument to NIL will result in differnt returns (loop repeat 4 do (print (inefficient-permutations 3 :max 5 :fix nil))) => ((1 0 2) (0 1 2) (1 2 0) (2 1 0) (0 2 1)) ((1 2 0) (2 0 1) (2 1 0) (1 0 2) (0 1 2)) ((0 1 2) (1 0 2) (2 0 1) (1 2 0) (2 1 0)) ((0 2 1) (1 2 0) (0 1 2) (2 0 1) (1 0 2))
SYNOPSIS
(defun inefficient-permutations (level &key (max nil) (skip 0) (fix t))
permutations/inefficiently-permutate [ Functions ]
[ Top ] [ permutations ] [ Functions ]
FUNCTION
Return a shuffled, non-systematically ordered list of all possible permutations of an original sequence of elements of any type. An optional keyword argument <max> allows the user to specify the maximum number of permutations to return. As opposed to the function "permutate", inefficiently-permutate returns the elements of the specified <list> as a flat list, unless the keyword argument <sublists> is set to T, whereupon the function returns the result as a list of lists, each one being a permutation of <list>. The function is inefficient in so far as it simply shuffles the numbers and so always has to check whether the new list already contains the shuffled before storing it. The order of the permutations returned will always be the same unless <fix> is set to NIL. Keyword argument <skip> allows the user to skip a number of permutations, which is only sensible if :fix is set to T.
ARGUMENTS
- A list.
OPTIONAL ARGUMENTS
- keyword argument :max. An integer that indicates the maximum number of permutations to be returned. - keyword argument :skip. An integer that indicates a number of permutations to skip. - keyword argument :fix. T or NIL to indicate whether the given sequence should always be shuffled with the same (fixed) random seed (thus always producing the same result). T = fixed seed. Default = T. - keyword argument :sublists. T or NIL to indicate whether the returned result should be flattened into a one-dimensional list or should be left as a list of lists. T = leave as list of lists. Default = NIL.
RETURN VALUE
A list.
EXAMPLE
;; By default the function returns a flattened list of all possible ;; permutations in a shuffled (random) order (inefficiently-permutate '(a b c)) => (C A B C B A A C B B A C B C A A B C) ;; The length of the list returned can be potentially shortened using the :max ;; keyword argument. Note here that the value given here refers to the number ;; of permutations before the list is flattened, not to the number of ;; individual items in the flattened list. (inefficiently-permutate '(a b c) :max 3) => (C A B C B A A C B) ;; By default the function is set to using a fixed random seed, causing it to ;; return the same result each time (loop repeat 4 do (print (inefficiently-permutate '(a b c)))) => (C A B C B A A C B B A C B C A A B C) (C A B C B A A C B B A C B C A A B C) (C A B C B A A C B B A C B C A A B C) (C A B C B A A C B B A C B C A A B C) ;; Setting the :fix keyword argument to NIL allows the function to produce ;; different output each time (loop repeat 4 do (print (inefficiently-permutate '(a b c) :fix nil))) => (B A C A C B B C A A B C C B A C A B) (A C B B A C C B A C A B B C A A B C) (A C B B A C B C A A B C C A B C B A) (B A C A B C C A B C B A B C A A C B) ;; Setting the :sublists keyword argument to T causes the function to return a ;; list of lists instead (inefficiently-permutate '(a b c) :sublists t) => ((C A B) (C B A) (A C B) (B A C) (B C A) (A B C))
SYNOPSIS
(defun inefficiently-permutate (list &key (max nil) (skip 0) (fix t) (sublists nil))
permutations/move-repeats [ Functions ]
[ Top ] [ permutations ] [ Functions ]
FUNCTION
Move, when possible, any elements within a given list that are repeated consecutively. When two consecutive elements repeat, such as the c in '(a b c c b a), the function moves the repeated element to the next place in the given list that won't produce a repetition. When no such place can be found in the remainder of the list, the offending element is moved to the end of the given list and a warning is printed. This function can be applied to simple lists and lists with sublists. However, due to this function being designed--but not limited--for use with the results of permutations, if the list has sublists, then instead of repeating sublists being moved, the last element of a sublist is checked for repetition with the first element of the next sublist. See the first example below. NB: This function only move elements further along the list; it won't place them earlier than their original position. Thus: (move-repeats '(3 3 1)) will return (3 1 3), while (move-repeats '(1 3 3)) will leave the list untouched and print a warning.
ARGUMENTS
- A list.
OPTIONAL ARGUMENTS
- A function that serves as the comparison test. Default = #'eq.
RETURN VALUE
A list.
EXAMPLE
;;; Used with a list of lists. Note that the repeating C, end of sublist 1, ;;; beginning of sublist 2, is moved, not the whole repeating sublist (c a b). (move-repeats '((a b c) (c a b) (c a b) (d e f) (a b c) (g h i))) => ((A B C) (D E F) (C A B) (C A B) (A B C) (G H I)) ;;; Works with simple lists too: (move-repeats '(1 2 3 3 4 5 6 7 8 8 9 10)) => (1 2 3 4 3 5 6 7 8 9 8 10) ;; Moves the offending element to the end of the list and prints a warning when ;; no solution can be found (move-repeats '((a b c d) (d c b a) (b c a d) (c a b d))) => ((A B C D) (B C A D) (C A B D) (D C B A)) WARNING: move-repeats: can't find non-repeating place! present element: (D C B A), elements left: 1
SYNOPSIS
(defun move-repeats (list &optional (test #'eq))
permutations/multi-shuffle [ Functions ]
[ Top ] [ permutations ] [ Functions ]
FUNCTION
Applies the shuffle function a specified number of times to a specified list. NB: As with the plain shuffle function, the order of the permutations returned will always be the same unless the keyword argument :fix is set to NIL.
ARGUMENTS
- A sequence.
OPTIONAL ARGUMENTS
- keyword argument :start. A zero-based index integer indicating the first element of a subsequence to be shuffled. Default = 0. - keyword argument :end. A zero-based index integer indicating the last element of a subsequence to be shuffled. Default = the length of the given sequence. - keyword argument :copy. T or NIL to indicate whether the given sequence should be copied before it is modified or should be destructively shuffled. T = copy. Default = T. - keyword argument :fix. T or NIL to indicate whether the given sequence should always be shuffled with the same (fixed) random seed (thus always producing the same result). T = fixed seed. Default = T. - keyword argument :reset. T or NIL to indicate whether the random state should be reset before the function is performed. T = reset. Default = T.
RETURN VALUE
- A sequence.
EXAMPLE
;; Simple multi-shuffle with default keywords. (multi-shuffle '(a b c d e f g) 3) => (B A C E D G F) ;; Always returns the same result by default. (loop repeat 4 do (print (multi-shuffle '(a b c d e f g) 3))) => (B A C E D G F) (B A C E D G F) (B A C E D G F) (B A C E D G F) ;; Set keyword argument :fix to NIL to return different results each time (loop repeat 4 do (print (multi-shuffle '(a b c d e f g) 3 :fix nil))) => (G C F B D E A) (A G F B D C E) (A B D G C F E) (G C A D E F B) ;; Set keyword arguments :start and :end to shuffle just a subsequence of the ;; given sequence (loop repeat 4 do (print (multi-shuffle '(a b c d e f g) 3 :fix nil :start 2 :end 5))) => (A B D E C F G) (A B E C D F G) (A B E D C F G) (A B D C E F G)
SYNOPSIS
(defun multi-shuffle (seq num-shuffles &key (start 0) (end (length seq)) (copy t) (fix t) (reset t))
permutations/multi-shuffle-with-perms [ Functions ]
[ Top ] [ permutations ] [ Functions ]
FUNCTION
Returns a shuffled (random and unordered) list of permutations of the specified list after a specified number of shuffles. Similar to the "multi-shuffle" function, but uses the function "inefficient-permutations" as part of the process. The <num-shuffles> argument allows the user to always return the same specific permutation. NB: This function always uses a fixed random seed and has no optional arguments to allow the user to alter that setting.
ARGUMENTS
- A list. - An integer that is the number of permutations to be returned.
RETURN VALUE
- A list that is a single permutation of the specified list.
EXAMPLE
;; Returns a random and unordered permutation of the specified list (let ((l '(0 1 2 3 4))) (multi-shuffle-with-perms l 7)) => (3 1 4 2 0) ;; Always returns the same result (loop repeat 4 do (print (multi-shuffle-with-perms '(0 1 2 3 4) 7))) => (3 1 4 2 0) (3 1 4 2 0) (3 1 4 2 0) (3 1 4 2 0) ;; Different <num-shuffles> values return different permutations (loop for i from 0 to 5 do (print (multi-shuffle-with-perms '(0 1 2 3 4) i))) => (0 1 2 3 4) (1 4 2 0 3) (0 3 1 4 2) (4 0 2 1 3) (1 2 3 4 0) (2 1 3 0 4)
SYNOPSIS
(defun multi-shuffle-with-perms (seq num-shuffles)
permutations/permutate [ Functions ]
[ Top ] [ permutations ] [ Functions ]
FUNCTION
Systematically produce a list of all possible permutations of an original list of elements of any type. NB: Such lists can quickly become very long, so slippery-chicken automatically defaults to outputting the resulting list to a file and printing a warning when the results exceed a certain length.
ARGUMENTS
- A list with elements of any type.
RETURN VALUE
A list of lists that are all possible permutations of the original, specified list. Interrupts with an error if the method is passed anything but a list.
EXAMPLE
;; Simple usage (permutate '(a b c)) => ((A B C) (B A C) (A C B) (C A B) (B C A) (C B A)) ;; When the list is more than 8 elements long, the resulting permutations are ;; written to a file due to the very high number of results (permutate '(1 2 3 4 5 6 7 8 9)) => WARNING: permutations::permutations: This call will return 362880 results so they are being written to the file '/tmp/permutations.txt'.
SYNOPSIS
(defun permutate (list)
permutations/permutations [ Functions ]
[ Top ] [ permutations ] [ Functions ]
FUNCTION
Systematically produce a list of all possible permutations of a set of consecutive integers beginning with zero. The function's only argument, <level>, is an integer that determines how many consecutive integers from 0 are to be used for the process. This is a more efficient permutation algorithm, but the results will always be in a certain order, with the same number at the end until that permutation is exhausted, then the number below that etc.
ARGUMENTS
An integer that indicates how many consecutive integers from 0 are to be used for the process.
RETURN VALUE
A list of sequences (lists), each of which is a permutation of the original.
EXAMPLE
;; Produce a list consisting of all permutations that can be made of 4 ;; consecutive integers starting with 0 (i.e., (0 1 2 3)) (permutations 4) => ((0 1 2 3) (1 0 2 3) (0 2 1 3) (2 0 1 3) (1 2 0 3) (2 1 0 3) (0 1 3 2) (1 0 3 2) (0 3 1 2) (3 0 1 2) (1 3 0 2) (3 1 0 2) (0 2 3 1) (2 0 3 1) (0 3 2 1) (3 0 2 1) (2 3 0 1) (3 2 0 1) (1 2 3 0) (2 1 3 0) (1 3 2 0) (3 1 2 0) (2 3 1 0) (3 2 1 0))
SYNOPSIS
(defun permutations (level)
permutations/random-rep [ Functions ]
[ Top ] [ permutations ] [ Functions ]
FUNCTION
Return a non-negative random number that is less than the specified value. An optional argument allows for the random state to be reset.
ARGUMENTS
- A number.
OPTIONAL ARGUMENTS
- T or NIL to indicate whether the random state should be reset before the function is performed. T = reset. Default = NIL.
RETURN VALUE
A number.
EXAMPLE
;; By default returns a different value each time (loop repeat 10 do (print (random-rep 5))) => 1 3 4 4 3 4 2 0 2 0 ;; Setting the optional argument to T resets the random state before ;; performing the function (loop repeat 10 do (print (random-rep 5 t))) => 3 3 3 3 3 3 3 3 3 3
SYNOPSIS
(defun random-rep (below &optional (reset nil))
permutations/shuffle [ Functions ]
[ Top ] [ permutations ] [ Functions ]
FUNCTION
Create a random ordering of a given sequence or a subsequence of a given sequence. By default we used fixed-seed randomness so we can guarantee the same results each time (perhaps counter-intuitively). So the order of the permutations returned will always be the same unless keyword argument :fix is set to NIL. NB: This function is a modified form of Common Music's shuffle function.
ARGUMENTS
- A sequence (list, vector (string)).
OPTIONAL ARGUMENTS
- keyword argument :start. A zero-based index integer indicating the first element of a subsequence to be shuffled. Default = 0. - keyword argument :end. A zero-based index integer indicating the last element of a subsequence to be shuffled. Default = the length of the given sequence. - keyword argument :copy. T or NIL to indicate whether the given sequence should be copied before it is modified or should be destructively shuffled. T = copy. Default = T. - keyword argument :fix. T or NIL to indicate whether the given sequence should always be shuffled with the same (fixed) random seed (thus always producing the same result). T = fixed seed. Default = T. - keyword argument :reset. T or NIL to indicate whether the random state should be reset before the function is performed. T = reset. Default = T.
RETURN VALUE
A list.
EXAMPLE
;; Simple shuffle with default keywords. (shuffle '(1 2 3 4 5 6 7)) => (5 4 3 6 7 1 2) ;; Always returns the same result by default. (loop repeat 4 do (print (shuffle '(1 2 3 4 5 6 7)))) => (5 4 3 6 7 1 2) (5 4 3 6 7 1 2) (5 4 3 6 7 1 2) (5 4 3 6 7 1 2) ;; Set keyword argument :fix to NIL to return different results each time (loop repeat 4 do (print (shuffle '(1 2 3 4 5 6 7) :fix nil))) => (1 2 6 3 5 4 7) (1 3 5 2 7 4 6) (4 7 2 5 1 6 3) (1 5 3 7 4 2 6) ;; Set the keyword argument :reset to t only at the beginning so we get the ;; same result that time but different (but repeatable) results thereafter. (loop repeat 3 do (print 'start) (loop for i below 4 do (print (shuffle '(1 2 3 4 5 6 7) :reset (zerop i))))) => START (5 4 3 6 7 1 2) (4 6 5 2 3 1 7) (3 4 1 6 5 7 2) (3 2 7 4 1 6 5) START (5 4 3 6 7 1 2) (4 6 5 2 3 1 7) (3 4 1 6 5 7 2) (3 2 7 4 1 6 5) START (5 4 3 6 7 1 2) (4 6 5 2 3 1 7) (3 4 1 6 5 7 2) (3 2 7 4 1 6 5) ;; Set keyword arguments :start and :end to shuffle just a subsequence of the ;; given sequence (loop repeat 4 do (print (shuffle '(1 2 3 4 5 6 7) :fix nil :start 2 :end 5))) => (1 2 5 4 3 6 7) (1 2 3 5 4 6 7) (1 2 4 5 3 6 7) (1 2 3 4 5 6 7)
SYNOPSIS
(defun shuffle (seq &key (start 0) (end (length seq)) (copy t) (fix t) (reset t) &aux (width (- end start)))