Clojure在自己的实例化中使用let变量声明?

时间:2015-02-24 23:03:28

标签: list clojure

在Clojure的语言中,我试图将我在let中定义的变量作为参数传递给同一let内的函数。变量本身表示表示图中边的向量列表。我想传递它的函数使用列表来确保它不会在列表中生成相同的值。

整个功能

(defn random-WS 
  ([n k] (random-WS (- n 1) k (reg-ring-lattice n k)))
  ([n k graph] 
   (cond (= n -1) graph
         :else
         (let [rem-list (for [j (range (count (graph n))) :when (< (rand) 0.5)]
                          [n (nth (seq (graph n)) j)])
               add-list (for [j (range (count rem-list))]
                          (random-WSE graph n add-list))
               new-graph (reduce add-edge (reduce rem-edge graph rem-list) add-list)]
           (random-WS (- n 1) k new-graph)))))

这里可以看到实际的问题陈述

add-list (for [j (range (count rem-list))]
    (random-WSE graph n add-list))

再次为清楚起见,函数random-WSE根据某些规则为我的图形生成随机边。给定当前graph,当前节点n以及要添加add-list的当前边缘列表,它将根据某些规则生成一个边缘以添加到列表中。

我唯一真正的想法是先让let add-list ()先定义它然后再重新定义它。虽然这仍然有一些相同的问题,但现在定义了add-list,但()语句中的for将是random-WSE。因此,函数add-list不会考虑列表中已有的边。

有没有办法评估&#34; ()在其定义中的某个定义点,以便可以在其定义中使用它?所以我先评估&#34;在for之前到for,然后&#34;评估&#34;每次迭代{{1}}之后。

如果您有兴趣,该功能会用于创建随机Watts-Stogatz图表。

2 个答案:

答案 0 :(得分:3)

根据我对此算法的描述,add-list在有问题的for循环期间增长(累积)。积累(非常广泛地接受积累)是你应该使用reduce的强烈信号:

(reduce (fn [add-list j] (conj add-list (random-WSE graph n add-list))) [] (range (count rem-list))

答案 1 :(得分:0)

基本上你将结果链接到let,因为第一次计算的结果(导致rem-list)是你第二次计算的唯一输入(你的麻烦点)再次是您第三次计算的唯一输入,它最终是您最终计算步骤(递归步骤)的唯一输入。如果这种链接听起来很熟悉,那是因为它是:考虑根据线程宏let重新构造->构造。

即。

的内容
(defn- rem-list [graph n]
   ...)
(defn- add-list [remlist n]
   ...)
(defn- new-graph [addlist]
   ...)

(defn random-ws 
   ([n k] ...)
   ([graph n k] ;; <- note the moved parameter
     (cond (= n -1) graph
           :else    
           (-> graph
               (rem-list n)
               (add-list n)
               (new-graph)
               (random-ws (dec n) k))))

然后,您可以将add-list表示为一个简单的递归函数(可能引入一个累加器变量)或使用cgrand解释的reduce变体。