Paste number 11447: Scheme Permutation Generation Algorithm

Index of paste annotations: 2 | 1

Paste number 11447: Scheme Permutation Generation Algorithm
Pasted by: mhall
When:4 years, 5 months ago
Share:Tweet this! | http://paste.lisp.org/+8TZ
Channel:#lisp
Paste contents:
Raw Source | XML | Display As
;; generate all possible perumations of a list of numbers (a set of numbers)
;;
;; assumption is that no two numbers are the same!
;;

;; general strategy:
;;  1. generate all possible permutations that keep the first number fixed.
;;  2. generate all possible permutations that have something else for the
;;     first number.
;;  append lists produces by 1. and 2.
;;
;;
;;  1.1 need to generate all permutations of the rest of the list,
;;   and then add element to the beginning of each of the lists produced.
;;   add-element-to-lists is defined below:


;;
;; add-element-to-lists consumes a number and a list of lists,
;;  and produces a list of lists.
;;
;; (add-element-to-lists elem lists) creates a list of lists, containing
;; one entry for each list found in lists (each element of lists is a list of 
;;  numbers). Each list generated gets elem tacked on the beginning of it.
;;
(define (add-element-to-lists elem lists)
  (cond 
   [(empty? lists) empty]
   [ else
	 (cons 
	  (cons elem (first lists))
	  (add-element-to-lists elem (rest lists)))]))

;;
;; 2. strategy is to step through the original list, picking each element 
;;  and generating all permutations that start with that element.
;;  


;; generates all permutations that start with f  fixed 

;; (generate-permutations alist) consumes a list of numbers and produces
;;  a list of lists of numbers. Each list of numbers is unique in the
;;  ordering of elements, each list of numbers contains exactly the same
;;  numbers as are found in alist.
;;
;; sample: (generate-permutations '(1 2 3))
;;
(define (generate-permutations alist)
  (cond
   ;; empty list has no permutations, but we need to return a list)
   [(empty? alist) (list empty)]
   ;; single element has only one permutation, but we need to
   ;;  return a list of lists.
   [(empty? (rest alist)) (list alist)]
   [ else
	 ;; more than one element - generate all lists by generating
	 ;; the lists (permutations) that start with each element in turn
	 (use-each-element-as-start alist)]))


;;
;; use-each-element-as-start consumes a list and produces a list of
;; lists of numbers. 
;;
;; (use-each-element-as-start alist) basically does the whole job, but does so
;; only by calling the helper function which deals with two lists
;;  (initially one of them is empty).

(define (use-each-element-as-start alist)
  (use-each-element-as-start-helper empty alist))


;;
;; use-each-element-as-start-helper consumes two lists of numbers 
;;    and returns a list of lists of numbers
;;
;; (use-each-element-as-start-helper done remaining) generates all
;; permutations of the elements defined in the two lists combined,
;;  such that the first element in the permutation is found in the list
;;  named remaining. Calls itself recursively to step over all the elements
;;  in remaining.
;;
;;  Note: uses add-element-to-lists to attach an element to the
;;   beginning of lists produces in call to generate-permutations
;;   (sort of a recursive call).
;;

(define (use-each-element-as-start-helper done remaining)
  (cond
   ;; if remaining is empty we don't need to do anything
   [(empty? remaining) empty]
   [else
	;; combine the lists produced by generating all permutations
	;; that start with (first remaining), with the lists produced
	;; that start with everything else.
	(append
	 (add-element-to-lists
	  (first remaining)
	  (generate-permutations
	   (append done (rest remaining))))
	 (use-each-element-as-start-helper
	  (append done (list (first remaining)))
	  (rest remaining)))]))
  
;;(generate-permutations '(1 2 3))

Annotations for this paste:

Annotation number 2: akshay
Pasted by: akshaykadidal
When:2 years, 6 months ago
Share:Tweet this! | http://paste.lisp.org/+8TZ/2
Paste contents:
Raw Source | Display As
111111111
111111112
111111113
111111114
111111115
111111121

Annotation number 1: self
Pasted by: joe
When:3 years, 6 months ago
Share:Tweet this! | http://paste.lisp.org/+8TZ/1
Paste contents:
Raw Source | Display As
1,2,3,4,5

Colorize as:
Show Line Numbers
Index of paste annotations: 2 | 1

Lisppaste pastes can be made by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively.