【问题标题】:Unexpectedly slow memoized function in ClojureClojure 中出乎意料的慢速记忆函数
【发布时间】:2014-05-27 04:03:30
【问题描述】:

在练习 Clojure 时,我正在对只能在图上向右或向下移动的步行进行递归计数(来自 Project Euler)。这是一个微不足道的问题,但我想尝试不同的方法来解决这个问题。

(defn path-count [x y] (cond
                     (or (< y 0) (< x 0)) 0
                     (= y 0) 1
                     :else (+ (path-count x (- y 1))
                              (path-count (- x 1) y))))

(def path-count-memoized (memoize path-count))

(defn cartesian-range [min max]
(for [y (range min max)
      x (range min max)]
     [x y]))

(map 
  (fn [pair] 
    (path-count-memoized 
      (nth pair 0) 
      (nth pair 1))) 
  (cartesian-range 0 20))

看着它,它看起来应该渐近地执行类似于使用 20x20 数组的以 (0,0) 开头的迭代解决方案。但是,它非常缓慢。我不确定我哪里出错了。我在想我误解了记忆缓存的工作原理[或达到了大小限制 - 虽然这看起来很荒谬],或者我误解了 map 评估惰性序列的术语的顺序。

【问题讨论】:

  • 这里的误解是memoize 以某种方式“修改”了现有函数。它没有。它创建一个新函数,它是现有函数的记忆版本。
  • 基本上 - 但是,我实际上假设的情况略有不同 - memoize 创建的函数用记忆版本的递归调用替换了原始函数的递归调用。

标签: recursion clojure memoization


【解决方案1】:

path-count 本身并没有调用 path-count-memoize,所以你实际上并没有得到太多的记忆。设置它有点棘手,在这里可以找到一些技巧:

How do I generate memoized recursive functions in Clojure?

【讨论】:

    猜你喜欢
    • 2014-07-01
    • 2012-06-26
    • 1970-01-01
    • 2021-08-01
    • 1970-01-01
    • 2011-04-23
    • 2014-09-11
    • 2013-07-15
    • 1970-01-01
    相关资源
    最近更新 更多