<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ethan Fast &#187; Genetic Algorithms</title>
	<atom:link href="http://blog.ethanjfast.com/tag/genetic-algorithms/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ethanjfast.com</link>
	<description>Lambdas, Hacks, and Fiction</description>
	<lastBuildDate>Mon, 24 May 2010 14:37:34 +0000</lastBuildDate>
	
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Gajure Now on Clojars</title>
		<link>http://blog.ethanjfast.com/2010/02/gajure-now-on-clojars/</link>
		<comments>http://blog.ethanjfast.com/2010/02/gajure-now-on-clojars/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 18:39:03 +0000</pubDate>
		<dc:creator>Ethan</dc:creator>
				<category><![CDATA[Clojure]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Gajure]]></category>
		<category><![CDATA[Genetic Algorithms]]></category>

		<guid isPermaLink="false">http://blog.ethanjfast.com/?p=351</guid>
		<description><![CDATA[Gajure, my small genetic algorithm framework, is now up on Clojars. Hopefully, this should make it much more convenient to use in a real project. I also added Leiningen support, and if you use Clojure with any frequency, I&#8217;d recommend checking that out.
 ]]></description>
			<content:encoded><![CDATA[<p><a href="http://github.com/Ejhfast/Gajure">Gajure</a>, my small genetic algorithm framework, is now up on <a href="http://clojars.org/gajure">Clojars</a>. Hopefully, this should make it much more convenient to use in a real project. I also added <a href="http://github.com/technomancy/leiningen">Leiningen</a> support, and if you use Clojure with any frequency, I&#8217;d recommend checking that out.</p>
 <img src="http://blog.ethanjfast.com/wp-content/plugins/feed-statistics.php?view=1&post_id=351" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://blog.ethanjfast.com/2010/02/gajure-now-on-clojars/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Clojure :pre and :post</title>
		<link>http://blog.ethanjfast.com/2009/12/clojure-pre-and-post/</link>
		<comments>http://blog.ethanjfast.com/2009/12/clojure-pre-and-post/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 14:54:11 +0000</pubDate>
		<dc:creator>Ethan</dc:creator>
				<category><![CDATA[Clojure]]></category>
		<category><![CDATA[Functional Programming]]></category>
		<category><![CDATA[Gajure]]></category>
		<category><![CDATA[Genetic Algorithms]]></category>

		<guid isPermaLink="false">http://blog.ethanjfast.com/?p=248</guid>
		<description><![CDATA[Courtesy of Hacker News, this morning I stumbled upon a blog post mentioning :pre and :post assertions, a new feature in version 1.1 of Clojure. Given the rather messy nature of several functions in Gajure (my toy genetic algorithm framework), it seemed to me that I had an ideal opportunity to make use of this [...]]]></description>
			<content:encoded><![CDATA[<p>Courtesy of Hacker News, this morning I stumbled upon a <a href="http://blog.fogus.me/2009/12/21/clojures-pre-and-post/">blog post</a> mentioning :pre and :post assertions, a new feature in version 1.1 of Clojure. Given the rather messy nature of several functions in <a href="http://github.com/Ejhfast/Gajure">Gajure</a> (my toy genetic algorithm framework), it seemed to me that I had an ideal opportunity to make use of this new functionality.</p>
<p>For instance, although the function <em>run-ga</em> only takes two parameters, both of them are hashes. Naturally, each must contain a few keys for the genetic algorithm to run properly. Using preconditions, it&#8217;s easy to ensure that the function&#8217;s parameters contain these required keys. For instance:</p>
<pre>
(defn keys-not-nil [lst hash]
  (reduce #(and %1 %2) (map #(not (nil? (hash %))) lst)))
</pre>
<p>This checks each key in a list of keys, and returns false if one or more of these keys maps to a value of nil. Obviously, I could go further here, but checking for non-nil values seemed a reasonable (and easy) generalization (e.g. if <em>:init-fn</em> or <em>:mut-r</em> map to nil, then the <em>ga-run</em> function will have a problem). Now, making use of the :pre tag.</p>
<pre>
(defn run-ga
[func-map setting-map]
{:pre [(and
  (keys-not-nil
    (list :init-fn :fit-fn :mut-fn :sel-fn :cross-fn)
    func-map)
  (keys-not-nil
    (list :pop-sz :gen :children :mut-r)
    setting-map))]}
... actual algorithm ...)
</pre>
<p>So I can now enforce the (arbitrary) required keys, and return assertion errors on some improper uses of <em>ga-run</em>. For a more specific example, look to the algorithm&#8217;s mutation function.</p>
<pre>
(defn generic-mutation
  "Randomly mutates lists with elements from other lists in the population."
  [list prob]
  {:pre [(and (>= prob 1) (<= prob 100))]
   :post [(list? %)]}
  (map
   (fn [s-list]
     (map
      (fn [test]
        (if (> prob (rand-int 100))
          (let [r-s (rand-int (count list))
                r-t (rand-int (count (nth list r-s)))]
            (nth (nth list r-s)
                 r-t))
          test))
      s-list))
   list))
</pre>
<p>Here, the :pre tag ensures that the value of <em>prob</em> is between one and one hundred. Similarly, :post asserts that the function returns a list (although I haven&#8217;t mentioned it, the :post tag operates much like :pre, using a function&#8217;s return value within its assertion). So in spite of my trivial examples, perhaps you can begin to appreciate how these tags can be used to create safer and more predictable code.</p>
 <img src="http://blog.ethanjfast.com/wp-content/plugins/feed-statistics.php?view=1&post_id=248" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://blog.ethanjfast.com/2009/12/clojure-pre-and-post/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>On Parallelism</title>
		<link>http://blog.ethanjfast.com/2009/10/on-parallelism/</link>
		<comments>http://blog.ethanjfast.com/2009/10/on-parallelism/#comments</comments>
		<pubDate>Wed, 07 Oct 2009 13:50:38 +0000</pubDate>
		<dc:creator>Ethan</dc:creator>
				<category><![CDATA[Clojure]]></category>
		<category><![CDATA[Functional Programming]]></category>
		<category><![CDATA[Gajure]]></category>
		<category><![CDATA[Genetic Algorithms]]></category>

		<guid isPermaLink="false">http://blog.ethanjfast.com/?p=70</guid>
		<description><![CDATA[Recently, I read an article describing someone&#8217;s experiments in parallel genetic programming, and so I decided to run my own. As has been mentioned, I am quite fond of functional languages; for me, easy parallelism is simply a pleasant bonus. I do think its worth noting, however, that while functional programming may be generally awesome, throwing [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I read an article describing someone&#8217;s <a href="http://jan.rychter.com/enblog/2009/8/26/experiments-with-parallel-genetic-programming-in-clojure.html">experiments in parallel genetic programming</a>, and so I decided to run my own. As has been mentioned, I am <a href="http://blog.ethanjfast.com/2009/09/ga-framework/">quite fond</a> of functional languages; for me, easy parallelism is simply a pleasant bonus. I do think its worth noting, however, that while functional programming may be generally awesome, throwing in massive amounts of parallelism is often overkill (certainly when one runs his programs on a lowly Macbook).</p>
<p>Take <a href="http://github.com/Ejhfast/Gajure">Gajure</a>, my unfeature-full framework for creating genetic algorithms. On a whim, I changed out most <em>map</em> functions with <em>pmap</em>, its parallel counterpart, and ran the example code included on github. This took literally two seconds &#8212; for instance, something like roulette-select was changed by two characters:</p>
<pre>(defn roulette-select
  "Select num individuals from pop, with an individual's
   fitness porportional to selection likelihood."
  [pop fit-fn num]
  (let [pop-fits (pmap fit-fn pop)
        inc-fits (iterate (fn [[pfit idx]]
                          [(+ (nth pop-fits
                           (+ idx 1)) pfit) (+ idx 1)])
                          [(first pop-fits) 0])
        max-fitness (apply + pop-fits)
        pick-one (fn [num] (second (first (drop-while
                                         #(&lt; (first %) num)
                                         inc-fits))))]
    (pmap (fn [x] (nth pop (pick-one (rand-int max-fitness))))
               (range num))))</pre>
<p>On the face of things, a genetic algorithm would seem to be a perfect target for parallelism. Within a single generation, fitness computations and mutation operations can be run for each population member completely independent of its compatriots. Alas, such performance gains were not realized &#8212; not, at least, on my humble dual-core machine.</p>
<p>The bottom line: running time more than <strong>doubled</strong> for evolving &#8220;hello world.&#8221; What previously took 1450 ms takes 3162 ms with the new implementation. I will be gathering more representative statistics later on, but probably, the overhead involved in creating parallel mappings outweighs any benefits, given that I only have two processors (on that note, I&#8217;d be curious to know how much nicer things would run in Erlang, where the threads are more lightweight). Another contributing factor is simply the inane simplicity of the problem space; in an ideal case, each fitness evaluation would be doing a bit more work.</p>
<p>So in some sense, my dimwitted &#8220;hello world&#8221; example represents a worse case for the parallel implementation, particularly when run on my relatively underpowered machine. With that, I&#8217;m committing the <em>pmap</em> changes to github under a separate branch, <a href="http://github.com/Ejhfast/Gajure/tree/parallel">here</a>.</p>
 <img src="http://blog.ethanjfast.com/wp-content/plugins/feed-statistics.php?view=1&post_id=70" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://blog.ethanjfast.com/2009/10/on-parallelism/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>A Genetic Algorithm Framework in Clojure</title>
		<link>http://blog.ethanjfast.com/2009/09/ga-framework/</link>
		<comments>http://blog.ethanjfast.com/2009/09/ga-framework/#comments</comments>
		<pubDate>Thu, 03 Sep 2009 18:51:22 +0000</pubDate>
		<dc:creator>Ethan</dc:creator>
				<category><![CDATA[Clojure]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[Functional Programming]]></category>
		<category><![CDATA[Gajure]]></category>
		<category><![CDATA[Genetic Algorithms]]></category>

		<guid isPermaLink="false">http://blog.ethanjfast.com/?p=18</guid>
		<description><![CDATA[ functional languages. They are wonderfully powerful, and can easily abstract away a basic algorithm that one might apply to many kinds of problems. With this in mind, I decided to build a framework for constructing genetic algorithms in Clojure.]]></description>
			<content:encoded><![CDATA[<p>I love functional languages. They are wonderfully powerful, and can easily abstract away a basic algorithm that one might apply to many kinds of problems. With this in mind, I decided to build a framework for constructing genetic algorithms in Clojure.  While the definition of <em>framework</em> is surely debatable, what I mean by this (mostly) is that I built something I can reuse. For instance, the first thing I did with with my framework was optimize test suite subsets as part of a program repair technique &#8212; but as you will see, this is far from the only thing it can do!  First, I planned out in pseudocode how I wanted my framework to run. For my readers unfamiliar with them, genetic algorithms apply an evolutionary model to complex problems, attempting to <em>evolve</em> solutions from what is initially a population of random states. But really, a genetic algorithm is just a process, and (at least for my purposes) it boils down to this:</p>
<pre>(defn genetic-algorithm [some-params]
  (initialize-population)
    (loop (generations-that-remain)
      (if (no-generations-left)
         (print-stuff-and-exit)
         (pass-again-to-loop
          (mutate-population
            (crossover-population
              (select-population
               (population))))))</pre>
<p>Since Clojure is a functional language, we can pass problem-specific functions to this process, and it will give us a result. For instance, I might want to define my genetic algorithm such that it accepts functions for initializing population members, sorting them (fitness function), crossing them over, and finally, mutating them. Of course, it should also take parameters that convey setting information, like the number of generations to run, or the mutation rate. Here is what I came up with:</p>
<pre>defn run-ga
  [func-map setting-map]
  (let [ipop ((:init-fn func-map) (:pop-sz setting-map))]
    (loop [pop ipop
           num (:gen setting-map)]
      (if (zero? num)
        (do
          (println (first (sort-by (:fit-fn func-map) &gt; pop ))))
            (let [total-left (- (:pop-sz setting-map)
                                      (:children setting-map))]
              (do
                (println (first (sort-by (:fit-fn func-map) &gt; pop ))))
              (recur
               (concat
                ((:mut-fn func-map)
                 (do-crossover
                  ((:sel-fn func-map)
                   pop
                   (:fit-fn func-map)
                   (* (:children setting-map) 2))
                  (:cross-fn func-map)
                  2)
                 (:mut-r setting-map))
                ((:init-fn func-map) total-left))
               (dec num)))))))</pre>
<p>It takes two maps as its parameters, func-map and setting-map. These serve as easy ways to pass in sets of functions and settings for a given problem. The algorithm follows the basic pseudocode layout I showed earlier, and if you want a more detailed description of its parameters, check it out at <a href="http://github.com/Ejhfast/Gajure/blob/51a0473cc8d0bdc92bbb951abd2aebebd90a8f6e/ga.clj">github</a>.  There is one function in run-ga &#8212; <em>do-crossover</em> &#8212; that is not passed as a parameter, but is rather defined elsewhere. What it does is take a list of parents, and run the problem-specific crossover function provided as a parameter to the algorithm. Its code is also on github, but I will display it here as well.</p>
<pre>(defn do-crossover
  [p-list cross-fn num-parents]
  (map cross-fn (partition num-parents p-list)))</pre>
<p>But now, lets move on to an example problem, and put the framework through its paces! I will pick a very easy problem &#8212; lets evolve &#8220;helloworld&#8221;.  To begin, I will define some aspects of the problem space. The supposed DNA of &#8220;helloworld&#8221; is nothing but a list of characters:</p>
<pre>(def dna (map str
              ['q 'w 'e 'r 't 'y 'u 'i 'o 'p 'a 's 'd 'f 'g 'h 'j 'k 'l
               'z 'x 'c 'v 'b 'n 'm]))</pre>
<p>I also wrote a few helper functions for the genetic algorithm framework, <em>rand-from-list</em> and <em>rand-pop</em>. These are generally useful for creating random populations. The first will return a &#8220;random&#8221; list from a list of elements, made up of the elements in that list. The second will return a list of these random lists. Here they are:</p>
<pre>(defn rand-from-list
  [lst num]
  (let [total-el (count lst)]
    (map (fn [x] (nth lst (rand-int total-el))) (range 0 num))))

(defn rand-pop
  [lst num num-pop]
  (map (fn [x] (rand-from-list lst num)) (range 0 num-pop)))</pre>
<p>Now, lets apply them to dna. A function that initializes a random population of strings might look like this (we are limiting our population to strings of 10 characters):</p>
<pre>(defn some-strings [num]
 (rand-pop dna 10 num))</pre>
<p>This is actually not what I end up doing (in the func-map I end up using a <em>partial</em>) but it is effectively the same thing. On to crossover and mutation:</p>
<pre>(defn list-crossover
  [[s1 s2]]
  (let [point (rand-int
               (min (count s1)
                    (count s2)))]
    (concat (take point s1)
            (drop point s2))))

(defn generic-mutation
  [list prob]
  (map
   (fn [s-list]
     (map
      (fn [test]
        (if (&gt; prob (rand-int 100))
          (let [r-s (rand-int (count list))
                r-t (rand-int (count (nth list r-s)))]
            (nth (nth list r-s)
                 r-t))
          test))
      s-list))
   list))</pre>
<p>These are defined for you by the framework (optionally, if you want to use them). The function <em>list-crossover</em> chooses a cross-point, x, on two lists, and creates a new list made up of the first x elements of one list, and the last (length &#8211; x) elements of the other. Mutation was hard to make generic (and so it is very much imperfect), but it uses the base elements of other population members as an approximation for all the &#8220;genetic material&#8221; that can be swapped in or out of a mutated member. These functions work on most kinds of list populations. In many cases, however, you may need more complex behavior, so they are not hard-coded into the algorithm itself.   Although nearly done, we still lack what is perhaps the most important part, the fitness function. This can be defined in many ways, but I use a system of one point for every directly matching character in the string. Like follows:</p>
<pre>(defn hello-fitness
     [lst]
     (reduce
      +
      (map #(if (= %1 %2) 1 0)
           lst
           '("h" "e" "l" "l" "o" "w" "o" "r" "l" "d"))))</pre>
<p>So, now we can define the maps:</p>
<pre>(def func-map {:fit-fn hello-fitness :mut-fn generic-mutation
               :sel-fn roulette-select :init-fn (partial rand-pop dna 10)
               :cross-fn list-crossover})

(def set-map {:pop-sz 100 :children 50 :mut-r 1 :gen 100})</pre>
<p>Note that roulette-select is another helper created for the framework. Its a simple function, and selects population members with a likelihood proportional to the fitness of each. For the curious, here it is:</p>
<pre>(defn roulette-select
  [pop fit-fn num]
  (let [pop-fits (map fit-fn pop)
        inc-fits (iterate (fn [[pfit idx]]
                             [(+ (nth pop-fits (+ idx 1)) pfit) (+ idx 1)])
                          [(first pop-fits) 0])
        max-fitness (apply + pop-fits)
        pick-one (fn [num] (second (first (drop-while #(&lt; (first %) num)
                        inc-fits))))]
    (map (fn [x] (nth pop (pick-one (rand-int max-fitness)))) (range num))))</pre>
<p>Now, we are finished, so run the algorithm!</p>
<pre>(run-ga func-map set-map)</pre>
<p>Again, all this code (and some missing detail) is available at <a href="http://github.com/Ejhfast/Gajure/tree/51a0473cc8d0bdc92bbb951abd2aebebd90a8f6e">github</a>. Hopefully you found this useful!</p>
 <img src="http://blog.ethanjfast.com/wp-content/plugins/feed-statistics.php?view=1&post_id=18" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://blog.ethanjfast.com/2009/09/ga-framework/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
