Clojure:超出gc开销限制,懒惰评估,pi序列

edb*_*ond 5 lisp garbage-collection jvm clojure lazy-evaluation

对于下一个代码:

(ns clojure101.series)

(defn avg [[x y]] (/ (+ x y) 2))

(defn avg-damp
  [seq]
  (map avg (partition 2 seq)))

(defn avg-damp-n
  [n]
  (apply comp (repeat n avg-damp)))

(defn sums
  [seq]
  (reductions + seq))

(defn Gregory-Leibniz-n
  [n]
  (/ (Math/pow -1 n) (inc (* 2 n))))

(def Gregory-Leibniz-pi
     (map #(* 4 (Gregory-Leibniz-n %)) (iterate inc 0)))

(println (first ((avg-damp-n 10) (sums Gregory-Leibniz-pi))))
Run Code Online (Sandbox Code Playgroud)

对于n = 20,我得到"超出gc开销限制"错误.我怎样才能解决这个问题?

更新:我改变了avg-damp-n功能

(defn avg-damp-n
  [n seq]
  (if (= n 0) seq
      (recur (dec n) (avg-damp seq))))
Run Code Online (Sandbox Code Playgroud)

现在我可以得到n = 20的数字

(time
 (let [n 20]
   (println n (first (avg-damp-n n (sums Gregory-Leibniz-pi))))))

20 3.141593197943081
"Elapsed time: 3705.821263 msecs"
Run Code Online (Sandbox Code Playgroud)

更新2 我修复了一些错误,现在它工作得很好:

(ns clojure101.series)

(defn avg [[x y]] (/ (+ x y) 2))

(defn avg-damp
  [seq]
  (map avg (partition 2 1 seq)))

(defn avg-damp-n
  [n]
  (apply comp (repeat n avg-damp)))

(defn sums
  [seq]
  (reductions + seq))

(defn Gregory-Leibniz-n
  [n]
  (/ (int (Math/pow -1 n)) (inc (* 2 n))))

(def Gregory-Leibniz-pi
     (map #(* 4 (Gregory-Leibniz-n %)) (range)))

; ? = 3.14159265358979323846264338327950288419716939937510...

(time
 (let [n 100]
   (println n (double (first ((avg-damp-n n) (sums Gregory-Leibniz-pi)))))))
Run Code Online (Sandbox Code Playgroud)

OUTPUT:

100 3.141592653589793
"Elapsed time: 239.253227 msecs"
Run Code Online (Sandbox Code Playgroud)

kot*_*rak 2

嗯...这对我有用。在 Windows XP 上使用 Clojure 1.2 进行了测试。

user=> (defn avg
         [xs & {:keys [n] :or {n 2}}]
         (/ (reduce + xs) n))
#'user/avg
user=> (defn Gregory-Leibniz-n
         [n]
         (/ (Math/pow -1 n) (inc (+ n n))))
#'user/Gregory-Leibniz-n
user=> (->> (range)
         (map #(* 4 (Gregory-Leibniz-n %)))
         (reductions +)
         (partition 20)
         (map #(avg % :n 20))
         first
         println)
3.1689144018345354
Run Code Online (Sandbox Code Playgroud)

这是正确的答案吗?我不知道这个格雷戈里-莱布尼茨递归,所以我不确定这是否正确。

我注意到一点:你想变得太聪明了。也就是说,你的 avg-damp-n 将惰性序列堆叠在惰性序列上。由于您可以插入 的任意值,因此在这种情况下n您迟早也会遇到大量堆栈溢出。n如果有一个直接的解决方案,您应该更喜欢它。不过,我不确定这是否是您的实际问题。(正如我所说:它对我来说毫无帮助。)