What clojure parallelism method to use when looking for a growing solution space?

What is the correct way in Clojure to do parallel processing when each processing job can be executed in complete isolation and can generate a list of additional jobs that need to be evaluated?

My actual problem is the problem of calculating for food, but I will put it in the form of chess, which share the same problems as my calculations.

Suppose, for example, that I'm trying to find all the moves in Checkmate in a game in Chess. When searching for board states, I started with 20 possible states, each of which would represent a different possible opening course. Each of them must be evaluated, accepted or rejected, and then for each adopted move a new list of tasks will be created representing all possible next steps. The works will look as follows:

initial: '([] proposed-move)
accepted: '([move] proposed-response)
          '([move move] proposed-response)

The number of states for evaluations grows as a result of each calculation, and each state can be estimated in complete isolation from all others.

The solution I'm playing with is as follows:

; a list of all final solutions, each of which is a sequence of moves
(def solutions (agent []))
; a list of all jobs pending evaluation
(def jobs (agent []))

, java, ( , ). , . , .

? , ?

java.util.concurrent.LinkedBlockingQueue, - ?

+5
3

:

:

(def jobs (atom '(1 10 100)))

(defn process-element [value]
  (if (< (rand) 0.8)
    [(inc value)]
    []))

(defn do-processing []
  (swap! jobs 
         (fn [job-list] (apply concat (pmap process-element job-list)))))

(while (seq @jobs)
  (prn @jobs)
  (do-processing))

Whick , :

(1 10 100)
(2 11 101)
(3 12 102)
(4 13 103)
(5 14 104)
(6 15 105)
(7 106)
(107)
(108)
(109)
nil

, , , ! , , , , , , (while...).

+3

( ) clojure.

, , "clojure like", pmap , . pmap , pmap clojure, . chunking (, , ).

+2

You can also use channels. Maybe something like this:

(def jobs (chan))
(def solutions (chan))
(def accepted-solutions (atom (vector)))

(go (loop [job (<! jobs)]
      (when job
        (go (doseq [solution (process-job-into-solutions job)]
              (>! solutions)))
        (recur (<! jobs)))))

(go (loop [solution (<! solutions)]
      (when (acceptable? solution)
        (swap! accepted-solutions conj solution)
        (doseq [new-job (generate-new-jobs solution)]
          (>! jobs))
        (recur (<! solutions)))))

(>!! jobs initial-job)
0
source

All Articles