>
> How do I construct a combining fn out of 'max-key'  and is there an idiom or
> a pattern for doing so?
You might use the fact that -Infinity is a neutral element for max.
(Or the smallest long if you work with longs).
Alternatively you can represent your value as either a number or nil,
nil being the neutral element.

> Since the docs say that r/fold will only work in parallel for tree-like
> structures like maps and vectors, I've passing the lazy-seq through 'vec'.
> Does that make any sense whatsoever or will the entire thing be realized
> before it ever reaches r/fold?

Yes it will be realised but it does not matter as the children are not realised.
So just the computation of the next moves is done sequentially.

However, as I understand them, reducers will be of any help only if your
trees are highly branching. (They work chunk by chunk and not element
per element. They are tuned
for very simple operations on big data.)
I might be wrong on that though.

Concerning your code altogether, I have multiple remarks:
 - If you use lazyness for generating the tree (which may or not be
the right approach), I would not generate the tree up to a depth, I
would generate the infinite tee and then
  use a depth in the searching function. That way, if your search
function wants to have two level more, it can.
- I would not try to put concurrency in before I understand well the
performance of my sequential code. If you want to use
  eveloutionary algorithm to learn the best evaluation function, you
will have a lot of //ism coming from the evolutionary algorithm
anyway.
- I would profile the code.
- I would try to improve on the algorithm (alpha-beta pruning, a more
selective approach to unfolding nodes, and so on...)

To add concurrency, with the lazyness of the tree generation, I think
it is sufficient to add concurrency in the exploration of the tree.
You should check on the depth before calling a conccurent version.
(Find a depth that gives a reasonable amount of work. For smaller
depth,
run a sequential version of the algorithm.  ).
I am not a concurrency specialist at all, but I would do something like that:
 - realise all the children on one level. (You can also implement a
conccurent version of your valid moves generation, but it is a
different problem. And probably useless, because there is already a
lot of //ism in exploring the tree.)
- create a task per child corresponding to the exploration of said
child. As the operation is CPU bound, you want to have these tasks
executed by a thread pool with a fix number of threads. (There seems
to be Clojure libraries for that. Or you can implement this with
agents.)
- Wait on all the tasks and find the best solution. (best being min or
max depending of level.)
Note that making things concurrent might make it harder to improve the
algorithm.
(For example alpha/beta would need different tasks to communicate in some way.)

Best,

Nicolas.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to