This will be easier if you use a utility to insert a new subtree at a particular position in an existing subtree -- that is, to return a new subtree with the insertion. Then to do mutation just use this utility to insert a newly generated subtree at some randomly chosen index.
Following is code for an insertion utility using the zip library. I'm still using Clojure 1.1 and I gather that a few of the things I'm using here have been moved or renamed in 1.2, but the same basic idea should work. FWIW this is a modified version of the mutation code in my PushGP genetic programming system (http://hampshire.edu/lspector/clojush/), changed to count only whole s-expressions or atoms that are not in function position as "points" and hence as candidates for mutation. My Push language has a more liberal syntax, there's no function position as such, and any place can be mutated... But if you're evolving standard lisp s-expressions then I think the following is what you want. (ns gp (:require [clojure.zip :as zip] [clojure.contrib.math :as math] [clojure.contrib.seq-utils :as seq-utils])) (defn insert-code-at-point "Returns a copy of tree with the subtree formerly indexed by point-index (in a depth-first traversal) replaced by new-subtree. Only whole s-expressions and atoms not in function position are counted as points. If index is too high then take it modulo the total number of points." [tree point-index new-subtree] (let [index (mod (math/abs point-index) (count (seq-utils/flatten tree))) zipper (zip/seq-zip tree)] (loop [z zipper i index] (if (zero? i) (zip/root (zip/replace z new-subtree)) (if (seq? (zip/node z)) (recur (zip/next (zip/next z)) (dec i)) (recur (zip/next z) (dec i))))))) ;; show how it works on a range of indices (dotimes [i 10] (println (insert-code-at-point '(+ (* x y) (/ z w)) i '(- a b)))) -Lee On May 22, 2010, at 9:35 PM, krsnewwave wrote: > Hello everyone! > > I am having trouble with genetic programming. I am trying to construct > a random population of trees representing functions. The following is > how I do my random trees: > > (defn makerandomtree-10 > [pc maxdepth maxwidth fpx ppx] > (if-let [output > (if (and (< (rand) fpx) (> maxdepth 0)) > (let [head (nth operations (rand-int (count operations))) > children (doall (loop[function (list) > width maxwidth] > (if (pos? width) > (recur (concat function > (list (makerandomtree-10 pc (dec maxdepth) > (+ 2 (rand-int (- maxwidth 1))) fpx ppx))) > (dec width)) > function)))] > (concat (list head) children)) > (if (and (< (rand) ppx) (>= pc 0)) > (nth parameters (rand-int (count parameters))) > (rand-int 100)))] > output > )) > > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > > And it works. The thing that doesn't work is mutation. I have already > done 10 versions of this, and all doesn't work good enough. The > following is the thing that works the best, but not really good > enough. > > (defn mutate-5 > "chooses a node changes that" > [function pc maxwidth pchange] > (if (< (rand) pchange) > (let [output (makerandomtree-10 pc 3 maxwidth 0.5 0.6)] > (if (seq? output) output (list output))) > ;mutate the children of root > ;declare an empty accumulator list, with root as its head > (let [head (list (first function)) > children (loop [acc(list) > walker (next function)] (println "----------") > (println > walker) (println "-----ACC-----") (println acc) > (if (not walker) > acc > (if (or (seq? (first function)) (contains? (set > operations) > (first function))) > (recur (concat acc (mutate-5 walker pc > maxwidth pchange)) > (next walker)) > (if (< (rand) pchange) > (if (some (set parameters) walker) > (recur (concat acc (list (nth > parameters (rand-int (count > parameters))))) > (if (seq? walker) (next walker) > nil)) > (recur (concat acc (list (rand-int > 100))) > (if (seq? walker) (next walker) > nil))) > (recur acc (if (seq? walker) (next walker) > nil)))) > ))] > (concat head (list children))))) > > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > > > I am sorry that it is somewhat obfuscated. As you can see, I am a > newbie to clojure, and to functional programming in general. > > -- > 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 -- Lee Spector, Professor of Computer Science School of Cognitive Science, Hampshire College 893 West Street, Amherst, MA 01002-3359 lspec...@hampshire.edu, http://hampshire.edu/lspector/ Phone: 413-559-5352, Fax: 413-559-5438 Check out Genetic Programming and Evolvable Machines: http://www.springer.com/10710 - http://gpemjournal.blogspot.com/ -- 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