> > 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