Итеративное накопление информации выглядит как сокращающая функция, если разделить ее на две части:
- Создать группу ребер, которые необходимо учитывать, включая.
- Проверьте каждое ребро и пройдет ли оновключи это.В противном случае передайте результат без изменений
, который можно записать с помощью reduce
user> (defn add-edge [g i j]
(assoc g i j))
#'user/add-edge
user> (add-edge {1 2} 2 1)
{1 2, 2 1}
user> (defn addSomeEdges [v g test-p]
(reduce (fn [graph [i j]] ;; this takes the current graph, the points,
(if (test-p graph i j) ;; decides if the edge should be created.
(add-edge graph i j) ;; and returns the next graph
graph)) ;; or returns the graph unchanged.
g ;; This is the initial graph
(for [i (range v)
j (range (dec i))]
[i j]))) ;; this generates the candidate edges to check.
#'user/addSomeEdges
, и давайте запустим его!
user> (addSomeEdges 4 {1 2} (fn [g i j] (rand-nth [true false])))
{1 2, 2 0}
user> (addSomeEdges 4 {1 2} (fn [g i j] (rand-nth [true false])))
{1 2, 3 0}
user> (addSomeEdges 4 {1 2} (fn [g i j] (rand-nth [true false])))
{1 2, 2 0, 3 1}
Когда вы подумаете одругие тесты, вы можете связать эти вызовы вместе:
user> (as-> {1 2} g
(addSomeEdges 4 g (fn [g i j] (rand-nth [true false])))
(addSomeEdges 7 g (fn [g i j] (< i j)))
(addSomeEdges 9 g (fn [g i j] (contains? (set (keys g)) j))))
{1 2, 3 1, 4 1, 5 3, 6 4, 7 5, 8 6}