在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图表。
答案 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
变体。