的問題
我需要創建,鑑於潛在的無限序列的有限序列時,它產生是他們的「笛卡爾積」的序列的功能。潛在的無限序列的有限序列的笛卡爾乘積
即給定的順序
'((1 2) (3 4))
功能產生(的某種排序):
'((1 3) (1 4) (2 3) (2 4)
重要,爲每一位p
在笛卡爾積ps
名單,必須有一些自然數n
,例如(= p (last (take n ps)))
。或者,非正式地說,您只需要遍歷有限數量的序列以到達其中的任何元素。
這個條件在處理無限列表時變得很重要。在Haskell
在Haskell
解決方案,這是我會怎麼做它:
interleave :: [a] -> [a] -> [a]
interleave [] ys = ys
interleave (x:xs) ys = x : interleave ys xs
combine :: [[a]] -> [[a]]
combine = foldr prod [[]]
where
prod xs css = foldr1 interleave [ [x:cs | cs <- css] | x <- xs]
,把它你會得到如下:Clojure中
combine [[0..] [0..]] = [[0,0,0],[1,0,0],[,1,0],[2,0,0],[0,0,1],[1,1,0],...
解決方案
所以我試圖在Clojure中複製它,就像這樣(這幾乎是一個直接的t ranslation):
(defn interleave
"Returns a lazy sequence of the interleavings of sequences `xs` and `ys`
(both potentially infinite), leaving no elements discarded."
[xs ys]
(lazy-seq
(if-let [[x & xs*] (seq xs)]
(cons x (interleave ys xs*))
ys)))
(defn interleave*
"Converts a sequence of potentially infinite sequences into its lazy
interleaving."
[xss]
(lazy-seq
(when-let [[xs & xss*] (seq xss)]
(interleave xs (interleave* xss*)))))
(defn combine
"Takes a finite sequence of potentially infinite sequences, and combines
them to produce a possibly infinite sequence of their cartesian product."
[xss]
(if-let [[xs & xss*] (seq xss)]
(interleave*
(for [x xs]
(for [cs (combine xss*)]
(lazy-seq (cons x cs)))))
'(())))
但是當我運行:
(take 1 (combine [(range) (range)]))
我得到:
StackOverflowError cfg.util/combine/iter--3464--3468/fn--3469/fn--3470/iter--3471--3475/fn--3476
所以,我怎麼讓它偷懶足夠,以免造成堆棧溢出?真的,我不明白Clojure的惰性序列模型是如何工作的,這是主要問題。
你是對的,因爲序列到達[100 10]所需的時間是不合理的。然而,這不是因爲重複的工作,而是因爲排序:在'interleave *'的定義中使用本質上摺疊在列表上的東西給最後一個給予'combine'的集合帶來了偏見:該集合中的數字上升指數級地比第一次收集快。例如,'[10 100]'會比'[100 10]'快得多。儘管如此,您的解決方案確實很好,但我完全無法理解它。 – amnn 2014-09-28 20:18:47
@asQuirreL。啊!相反,正如你可能已經收集到的,我很難理解你的解決方案:)。我的收益平均通過所有收藏品 - 有點像康托爾列舉的理性。理解它的方法是返回幾個例子的'entries',然後在'seens'旁邊看看它們。一旦構建了「條目」序列,它就會驅動剩下的過程。 – Thumbnail 2014-09-28 20:40:54
我想我只是想把你的解決方案包裹起來。我也相信自己也穿越了整個空間,而且相當容易(如果不是n維的話),通過連續向上移動一個維度,對嗎?這是很不錯的。爲了記錄,我給出的解決方案速度大約快兩倍,如果您不在意它會產生偏見的樣本。然而,我很在乎,所以這看起來很有希望。非常感謝! – amnn 2014-09-28 21:09:46