<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Trivial sequence shuffling</title>
	<atom:link href="http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/</link>
	<description>Leslie P. Polzer on code, music, literature, design and free software business.</description>
	<lastBuildDate>Fri, 09 Dec 2011 14:52:23 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
	<item>
		<title>By: Joseph Oswald</title>
		<link>http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/comment-page-1/#comment-1298</link>
		<dc:creator>Joseph Oswald</dc:creator>
		<pubDate>Sun, 06 Apr 2008 14:52:34 +0000</pubDate>
		<guid isPermaLink="false">http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/#comment-1298</guid>
		<description>Sorry, I could have been clearer in my description.

The problem is not necessarily that the comparison is not transitive: that is the difference between a partial order and a complete order (and SORT isn&#039;t required to maintain a partial order). The predicate itself could have that problem.

The problem I was referring to is that two elements, let&#039;s call them A and B, should be in the same order every time the sort algorithm checks them. If the key values of A and B jump around at random, what is the sort supposed to assume? The comparison function is not well-defined at all, not just with respect to transitivity.

Now, it may be that an efficient sort algorithm does not often compare the same elements pairwise; however, the problem is not restricted to pairs of elements. Consider just the element A. The key function ranges from 0 to 1.0 (exclusive); 0 is interpreted to mean &quot;I should be at the very beginning&quot;, 0.999... interpreted to mean &quot;I should be at the very end.&quot; 

Any individual element is going to be changing its stated destination every time it is checked. A particular random order, however, is just *one* order. The random seed should pick one order out of the n! possible orders, with equal likelihood, then *stick to* that order. Instead this algorithm jumps around between orders, giving mixed messages to the sort algorithm. It will be hard to predict the outcome of the sort, but also unlikely to guarantee the uniform distribution among the n! outcomes that a random shuffle desires.</description>
		<content:encoded><![CDATA[<p>Sorry, I could have been clearer in my description.</p>
<p>The problem is not necessarily that the comparison is not transitive: that is the difference between a partial order and a complete order (and SORT isn&#8217;t required to maintain a partial order). The predicate itself could have that problem.</p>
<p>The problem I was referring to is that two elements, let&#8217;s call them A and B, should be in the same order every time the sort algorithm checks them. If the key values of A and B jump around at random, what is the sort supposed to assume? The comparison function is not well-defined at all, not just with respect to transitivity.</p>
<p>Now, it may be that an efficient sort algorithm does not often compare the same elements pairwise; however, the problem is not restricted to pairs of elements. Consider just the element A. The key function ranges from 0 to 1.0 (exclusive); 0 is interpreted to mean &#8220;I should be at the very beginning&#8221;, 0.999&#8230; interpreted to mean &#8220;I should be at the very end.&#8221; </p>
<p>Any individual element is going to be changing its stated destination every time it is checked. A particular random order, however, is just *one* order. The random seed should pick one order out of the n! possible orders, with equal likelihood, then *stick to* that order. Instead this algorithm jumps around between orders, giving mixed messages to the sort algorithm. It will be hard to predict the outcome of the sort, but also unlikely to guarantee the uniform distribution among the n! outcomes that a random shuffle desires.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Space Station Lambda &#187; Sequence shuffling revisited</title>
		<link>http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/comment-page-1/#comment-1286</link>
		<dc:creator>Space Station Lambda &#187; Sequence shuffling revisited</dc:creator>
		<pubDate>Sun, 06 Apr 2008 08:22:30 +0000</pubDate>
		<guid isPermaLink="false">http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/#comment-1286</guid>
		<description>[...] In my post &#8220;Trivial Sequence Shuffling&#8221; from yesterday I showed a simple hack to shuffle a sequence. [...]</description>
		<content:encoded><![CDATA[<p>[...] In my post &#8220;Trivial Sequence Shuffling&#8221; from yesterday I showed a simple hack to shuffle a sequence. [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Phil Bewig</title>
		<link>http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/comment-page-1/#comment-1283</link>
		<dc:creator>Phil Bewig</dc:creator>
		<pubDate>Sun, 06 Apr 2008 00:29:03 +0000</pubDate>
		<guid isPermaLink="false">http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/#comment-1283</guid>
		<description>Here is my preferred method for shuffling a list in Scheme.

(define (shuffle x)
  (do ((v (list-&gt;vector x)) (n (length x) (- n 1)))
      ((zero? n) (vector-&gt;list v))
    (let* ((r (random n)) (t (vector-ref v r)))
      (vector-set! v r (vector-ref v (- n 1)))
      (vector-set! v (- n 1) t))))</description>
		<content:encoded><![CDATA[<p>Here is my preferred method for shuffling a list in Scheme.</p>
<p>(define (shuffle x)<br />
  (do ((v (list-&gt;vector x)) (n (length x) (- n 1)))<br />
      ((zero? n) (vector-&gt;list v))<br />
    (let* ((r (random n)) (t (vector-ref v r)))<br />
      (vector-set! v r (vector-ref v (- n 1)))<br />
      (vector-set! v (- n 1) t))))</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Phil Bewig</title>
		<link>http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/comment-page-1/#comment-1282</link>
		<dc:creator>Phil Bewig</dc:creator>
		<pubDate>Sun, 06 Apr 2008 00:28:05 +0000</pubDate>
		<guid isPermaLink="false">http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/#comment-1282</guid>
		<description>That got garbled.

I agree with Joseph that the algorithm is flawed.  The problem is that the comparison procedure isn&#039;t transitive: it is possible that a&lt;b and b&lt;c does not imply a&lt;c.  Depending on the underlying sort algorithm, bad things may happen, and it is possible that the sort will never terminate.  Worse, it is unlikely given this method that all permutations of the input list are not equally likely in the shuffled output, which could be a problem depending on how the shuffle is used (you wouldn&#039;t want your poker buddies to accuse you of stacking the deck -- it could be hazardous to your health).</description>
		<content:encoded><![CDATA[<p>That got garbled.</p>
<p>I agree with Joseph that the algorithm is flawed.  The problem is that the comparison procedure isn&#8217;t transitive: it is possible that a&lt;b and b&lt;c does not imply a&lt;c.  Depending on the underlying sort algorithm, bad things may happen, and it is possible that the sort will never terminate.  Worse, it is unlikely given this method that all permutations of the input list are not equally likely in the shuffled output, which could be a problem depending on how the shuffle is used (you wouldn&#8217;t want your poker buddies to accuse you of stacking the deck &#8212; it could be hazardous to your health).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Phil Bewig</title>
		<link>http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/comment-page-1/#comment-1281</link>
		<dc:creator>Phil Bewig</dc:creator>
		<pubDate>Sun, 06 Apr 2008 00:23:50 +0000</pubDate>
		<guid isPermaLink="false">http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/#comment-1281</guid>
		<description>Peter proposes perl&#039;s schwartzian transform!

I agree with Joseph that the algorithm is flawed.  The problem is that the comparison procedure isn&#039;t transitive: it is possible that a&lt;b and b&lt;c does not imply avector x)) (n (length x) (- n 1)))
      ((zero? n) (vector-&gt;list v))
    (let* ((r (random n)) (t (vector-ref v r)))
      (vector-set! v r (vector-ref v (- n 1)))
      (vector-set! v (- n 1) t))))</description>
		<content:encoded><![CDATA[<p>Peter proposes perl&#8217;s schwartzian transform!</p>
<p>I agree with Joseph that the algorithm is flawed.  The problem is that the comparison procedure isn&#8217;t transitive: it is possible that a&lt;b and b&lt;c does not imply avector x)) (n (length x) (- n 1)))<br />
      ((zero? n) (vector-&gt;list v))<br />
    (let* ((r (random n)) (t (vector-ref v r)))<br />
      (vector-set! v r (vector-ref v (- n 1)))<br />
      (vector-set! v (- n 1) t))))</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter De Wachter</title>
		<link>http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/comment-page-1/#comment-1280</link>
		<dc:creator>Peter De Wachter</dc:creator>
		<pubDate>Sat, 05 Apr 2008 22:11:40 +0000</pubDate>
		<guid isPermaLink="false">http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/#comment-1280</guid>
		<description>I made a stupid simple shuffle tester, that tries to shuffle a three-element list.
http://paste.lisp.org/display/58653

With SBCL and your function, I get these results:
;; (3 1 2): 25
;; (3 2 1): 25
;; (1 2 3): 17
;; (2 1 3): 17
;; (1 3 2): 8
;; (2 3 1): 8

A nice and simple perfect shuffle is:
(defun better-shuffle (seq)
  (let ((tagged (mapcar (lambda (x) (cons (random 1.0) x)) seq)))
    (mapcar &#039;cdr (sort tagged #&#039;&gt; :key &#039;car))))</description>
		<content:encoded><![CDATA[<p>I made a stupid simple shuffle tester, that tries to shuffle a three-element list.<br />
<a href="http://paste.lisp.org/display/58653" rel="nofollow">http://paste.lisp.org/display/58653</a></p>
<p>With SBCL and your function, I get these results:<br />
;; (3 1 2): 25<br />
;; (3 2 1): 25<br />
;; (1 2 3): 17<br />
;; (2 1 3): 17<br />
;; (1 3 2): 8<br />
;; (2 3 1): 8</p>
<p>A nice and simple perfect shuffle is:<br />
(defun better-shuffle (seq)<br />
  (let ((tagged (mapcar (lambda (x) (cons (random 1.0) x)) seq)))<br />
    (mapcar &#8216;cdr (sort tagged #&#8217;&gt; :key &#8216;car))))</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Juho Snellman</title>
		<link>http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/comment-page-1/#comment-1279</link>
		<dc:creator>Juho Snellman</dc:creator>
		<pubDate>Sat, 05 Apr 2008 22:03:36 +0000</pubDate>
		<guid isPermaLink="false">http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/#comment-1279</guid>
		<description>The thing to be concerned with is that it will not produce a uniform distribution. If you&#039;re just interested in the function terminating, there&#039;s a much simpler solution:

(defun seqrnd (seq)
  seq)</description>
		<content:encoded><![CDATA[<p>The thing to be concerned with is that it will not produce a uniform distribution. If you&#8217;re just interested in the function terminating, there&#8217;s a much simpler solution:</p>
<p>(defun seqrnd (seq)<br />
  seq)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Leslie</title>
		<link>http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/comment-page-1/#comment-1278</link>
		<dc:creator>Leslie</dc:creator>
		<pubDate>Sat, 05 Apr 2008 20:53:25 +0000</pubDate>
		<guid isPermaLink="false">http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/#comment-1278</guid>
		<description>Joseph: the CLHS says:

&lt;em&gt;If the key and predicate always return, then the sorting operation will always terminate, producing a sequence containing the same elements as sequence (that is, the result is a permutation of sequence). This is guaranteed even if the predicate does not really consistently represent a total order (in which case the elements will be scrambled in some unpredictable way, but no element will be lost). If the key consistently returns meaningful keys, and the predicate does reflect some total ordering criterion on those keys, then the elements of the sorted-sequence will be properly sorted according to that ordering.&lt;/em&gt;

Your wording is rather hazy, so I don&#039;t know what exactly you&#039;re concerned with, but for me it suffices that the sort will terminate after having shuffled the elements.</description>
		<content:encoded><![CDATA[<p>Joseph: the CLHS says:</p>
<p><em>If the key and predicate always return, then the sorting operation will always terminate, producing a sequence containing the same elements as sequence (that is, the result is a permutation of sequence). This is guaranteed even if the predicate does not really consistently represent a total order (in which case the elements will be scrambled in some unpredictable way, but no element will be lost). If the key consistently returns meaningful keys, and the predicate does reflect some total ordering criterion on those keys, then the elements of the sorted-sequence will be properly sorted according to that ordering.</em></p>
<p>Your wording is rather hazy, so I don&#8217;t know what exactly you&#8217;re concerned with, but for me it suffices that the sort will terminate after having shuffled the elements.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Joseph Oswald</title>
		<link>http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/comment-page-1/#comment-1276</link>
		<dc:creator>Joseph Oswald</dc:creator>
		<pubDate>Sat, 05 Apr 2008 20:22:43 +0000</pubDate>
		<guid isPermaLink="false">http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/#comment-1276</guid>
		<description>This shuffle algorithm is flawed because there is no guarantee RANDOM as a :KEY function will be called once and only once per element; if RANDOM is called multiple times for an element, then it will likely give inconsistent results, possibly poisoning the sort.</description>
		<content:encoded><![CDATA[<p>This shuffle algorithm is flawed because there is no guarantee RANDOM as a :KEY function will be called once and only once per element; if RANDOM is called multiple times for an element, then it will likely give inconsistent results, possibly poisoning the sort.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: unClog &#187; Trivial Sequence Shuffling - Nice</title>
		<link>http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/comment-page-1/#comment-1274</link>
		<dc:creator>unClog &#187; Trivial Sequence Shuffling - Nice</dc:creator>
		<pubDate>Sat, 05 Apr 2008 18:16:42 +0000</pubDate>
		<guid isPermaLink="false">http://blog.viridian-project.de/2008/04/05/trivial-sequence-shuffling/#comment-1274</guid>
		<description>[...] Polzer has a nice codelet for shuffling a sequence. I had always relied on don&#8217;t lots of rotatefs and had never been [...]</description>
		<content:encoded><![CDATA[<p>[...] Polzer has a nice codelet for shuffling a sequence. I had always relied on don&#8217;t lots of rotatefs and had never been [...]</p>
]]></content:encoded>
	</item>
</channel>
</rss>

