<?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>Xavier Llorà &#187; optimization</title>
	<atom:link href="http://www.xavierllora.net/tag/optimization/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.xavierllora.net</link>
	<description>A notebook on data-intensive computing, genetics-based machine learning &#38; more.</description>
	<lastBuildDate>Sun, 08 Jan 2012 19:39:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Squeezing for cycles</title>
		<link>http://www.xavierllora.net/2009/04/01/squeezing-for-cycles/</link>
		<comments>http://www.xavierllora.net/2009/04/01/squeezing-for-cycles/#comments</comments>
		<pubDate>Thu, 02 Apr 2009 01:55:24 +0000</pubDate>
		<dc:creator>Xavier</dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[genetic algorithms]]></category>
		<category><![CDATA[multithreading]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[profiling]]></category>

		<guid isPermaLink="false">http://www.xavierllora.net/?p=491</guid>
		<description><![CDATA[Sometimes thinking a bit helps to rush decisions that may lead to weird places. Today I was going over a simple genetic algorithm for numeric optimization written in C. The code is nothing special, tournament selection without replacement, SBX crossover operator, and polynomial mutation. To the point, I was running a simple OneMax-like problem (in [...]
Related posts:<ol>
<li><a href='http://www.xavierllora.net/2005/11/27/evaluation-consistency-in-igas-user-contradictions-as-cycles-in-partial-ordering-graphs/' rel='bookmark' title='Evaluation consistency in iGAs: User contradictions as cycles in partial-ordering graphs'>Evaluation consistency in iGAs: User contradictions as cycles in partial-ordering graphs</a></li>
<li><a href='http://www.xavierllora.net/2008/11/13/fast-mutation-implementation-for-genetic-algorithms-in-python/' rel='bookmark' title='Fast mutation implementation for genetic algorithms in Python'>Fast mutation implementation for genetic algorithms in Python</a></li>
<li><a href='http://www.xavierllora.net/2006/07/07/analyzing-active-interactive-genetic-algorithms-using-visual-analytics/' rel='bookmark' title='Analyzing active interactive genetic algorithms using visual analytics'>Analyzing active interactive genetic algorithms using visual analytics</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Sometimes thinking a bit helps to rush decisions that may lead to weird places. Today I was going over a simple genetic algorithm for numeric optimization written in C. The code is nothing special, tournament selection without replacement, SBX crossover operator, and polynomial mutation. To the point, I was running a simple OneMax-like problem (in this case, minimize the value of the sum of all the genes), and I was quite surprised the guy was taking so long for. </p>
<pre>
$time ./GATest
----------------------- GA parameters ------------------------------------
Seed: 69
Lower/upper bounds: [1.000000,0.000000]
Genes: 18
Population size: 2000
Iterations: 30
Tournament size: 6
Crossover: pc=0.900000, gwp=0.500000, etaC=10.000000
Mutation: pm=0.100000, etaM=20.000000
----------------------- Evolution Statistics -----------------------------
4.663210	8.974190	13.158102
3.351912	7.405489	11.619360
2.285005	5.375426	9.531691
1.326318	3.711156	7.178203
0.767981	2.432192	4.790854
0.392001	1.543097	3.223604
0.279961	0.977706	2.308249
0.173406	0.600002	1.335702
0.092746	0.359343	0.877080
0.044705	0.216218	0.533978
0.029053	0.130256	0.315306
0.022827	0.078331	0.172908
0.013641	0.047317	0.105886
0.007370	0.028098	0.066994
0.004320	0.016787	0.038499
0.002807	0.010254	0.025155
0.001604	0.006238	0.014528
0.001007	0.003799	0.008883
0.000708	0.002212	0.005627
0.000343	0.001305	0.003263
0.000211	0.000781	0.002025
0.000131	0.000468	0.001155
0.000085	0.000280	0.000774
0.000054	0.000168	0.000392
0.000031	0.000100	0.000243
0.000017	0.000061	0.000144
0.000010	0.000037	0.000083
0.000006	0.000022	0.000054
0.000003	0.000013	0.000035
0.000002	0.000008	0.000020
0.000002	0.000005	0.000011
----------------------- Final outcome ------------------------------------
Min:	(0.000002)	0.000000	0.000000	0.000000	0.000000.000000	0.000000	0.000000	0.000000	0.000000	0.000000.000000	0.000000	0.000000	0.000000	0.000000	0.000000.000000	0.000000
Max:	(0.000011)	0.000000	0.000001	0.000000	0.000000.000001	0.000000	0.000000	0.000001	0.000000	0.000000.000000	0.000003	0.000000	0.000000	0.000000	0.000000.000002	0.000001	

real	0m6.748s
user	0m6.228s
sys	0m0.088s
</pre>
<p>Yup, after turning on all the possible compiler optimizations I could think of, 6.7 seconds was the best I could do on a first generation MacBook Pro. I was wondering if I should spend the time writing a simple multithreaded evaluation. As I said, before making something simple complicated, I decided to put grab <a href="http://developer.apple.com/tools/performance/optimizingwithsystemtrace.html">Shark</a> (Mac&#8217;s free profiler) and get a better picture of what was going. Oh boy! Intuition looking at the wrong place! The outcome: 45% of time spend on tournament selection and 31% generating random number. Mmh, digging a bit further almost all time of tournament selection was spent shuffling an array to guarantee tournaments without replacements.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/** Runs tournament selection without replacement to create a new population
 * 
 * popDest: The destination population
 * popInit: The original population
 * fita: The fitness of the initial populaiton
 * iSize: Tournament size
 * iIndividuals: The population size
 * iGenes: The number of genes of an individual
 */</span>
<span style="color: #993333;">void</span> ga_tournament_selection <span style="color: #009900;">&#40;</span> Population popDest<span style="color: #339933;">,</span> Population popInit<span style="color: #339933;">,</span> Fitness <span style="color: #339933;">*</span> fita<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> iSize<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> iIndividuals <span style="color: #339933;">,</span> <span style="color: #993333;">int</span> iGenes <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">int</span> piaShuffle<span style="color: #009900;">&#91;</span>iSize<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #993333;">int</span> i <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
	<span style="color: #993333;">int</span> j <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #993333;">int</span> iIndTmp <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
	<span style="color: #993333;">int</span> iIndWin <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
&nbsp;
	Fitness fitWin <span style="color: #339933;">=</span> DBL_MAX<span style="color: #339933;">;</span>
	Fitness fitTmp <span style="color: #339933;">=</span> DBL_MAX<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span> i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span> <span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span>iIndividuals <span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #808080; font-style: italic;">/* Initialization for the current tournament */</span>
		fitWin  <span style="color: #339933;">=</span> DBL_MAX<span style="color: #339933;">;</span>
		iIndWin <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
		genrand_shuffle <span style="color: #009900;">&#40;</span>piaShuffle<span style="color: #339933;">,</span>iIndividuals<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span> j<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span> <span style="color: #339933;">;</span> j<span style="color: #339933;">&lt;</span>iSize <span style="color: #339933;">;</span> j<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #666666; font-style: italic;">// A new randomly drawn individual</span>
			iIndTmp <span style="color: #339933;">=</span> piaShuffle<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			fitTmp  <span style="color: #339933;">=</span> fita<span style="color: #009900;">&#91;</span>piaShuffle<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			<span style="color: #666666; font-style: italic;">// If it is the first is the winner</span>
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> iIndWin<span style="color: #339933;">==-</span><span style="color: #0000dd;">1</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				iIndWin  <span style="color: #339933;">=</span> iIndTmp<span style="color: #339933;">;</span>
				fitWin <span style="color: #339933;">=</span> fitTmp<span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
			<span style="color: #666666; font-style: italic;">// If not, chack the fitness (Minimize)</span>
			<span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> fitWin<span style="color: #339933;">&gt;</span>fitTmp <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				iIndWin  <span style="color: #339933;">=</span> iIndTmp<span style="color: #339933;">;</span>
				fitWin <span style="color: #339933;">=</span> fitTmp<span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
		population_copy_individual<span style="color: #009900;">&#40;</span>popDest<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>popInit<span style="color: #009900;">&#91;</span>iIndWin<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>iGenes<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>		
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>It was <code>genrand_shuffle</code> (see below) the one that took most of the time. Also if you take a close inspection you will see that it is also the one to blame for calling calling too many times <code>genrand_int31</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> genrand_shuffle <span style="color: #009900;">&#40;</span> <span style="color: #993333;">int</span> <span style="color: #339933;">*</span> pia<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> iSize <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">int</span> i<span style="color: #339933;">,</span> iOther<span style="color: #339933;">;</span>
	<span style="color: #993333;">register</span> <span style="color: #993333;">int</span> iTmp<span style="color: #339933;">;</span>
	<span style="color: #993333;">int</span> iRndMax <span style="color: #339933;">=</span> iSize<span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Initialize</span>
	<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span> i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span>iSize<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> pia<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> i<span style="color: #339933;">;</span>
	<span style="color: #666666; font-style: italic;">// shuffle</span>
	<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span> i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span>iRndMax<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	    iOther <span style="color: #339933;">=</span> genrand_int31<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">%</span>iSize<span style="color: #339933;">;</span>
	    iTmp <span style="color: #339933;">=</span> pia<span style="color: #009900;">&#91;</span>iOther<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	    pia<span style="color: #009900;">&#91;</span>iOther<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> pia<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	    pia<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> iTmp<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This inherited implementation of tournament selection works well for small populations, but as you increase the population size, each tournament requires shuffling a number proportional to the population size. If you make the numbers, that leads to a quadratic implementation of tournament selection without replacement. Mmh, really needed? Definitely not. The only thing you need to guarantee to provide a tournament selection without replacement is that you provide different individuals for the tournaments (avoiding repetition). If that selection can be done quickly, you can take the complexity of the implementation down to linear. So there I went, and modified the shuffling function as follows.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> genrand_shuffle_fast <span style="color: #009900;">&#40;</span> <span style="color: #993333;">int</span> <span style="color: #339933;">*</span> pia<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> iSize<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> iSlots <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">int</span> i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
	<span style="color: #993333;">int</span> j <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
	pia<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> genrand_int31<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">%</span>iSize<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span> i<span style="color: #339933;">&lt;</span>iSlots <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		pia<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> genrand_int31<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">%</span>iSize<span style="color: #339933;">;</span>
		<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span> j<span style="color: #339933;">=</span>i<span style="color: #339933;">-</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">;</span> j<span style="color: #339933;">&gt;=</span><span style="color: #0000dd;">0</span> <span style="color: #339933;">&amp;&amp;</span> j<span style="color: #339933;">&lt;</span>i <span style="color: #339933;">;</span> j<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span>
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> pia<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span><span style="color: #339933;">==</span>pia<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> 
				<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> j<span style="color: #339933;">==</span>i <span style="color: #009900;">&#41;</span> i<span style="color: #339933;">++</span> <span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Tournaments sizes are usually much much smaller than population sizes (e.g. s=6 for the pop_size=2,000 individuals population used above). Thus, if random numbers are generated, the chances of repeating it are quite small. Also if you also make sure it is not there (and if it is, you generate a new out), basically your are set. (This implementation will only work efficiently if s&lt;&lt;pop_size, otherwise the cost of checking and generated new numbers will be even worst than the original version).</p>
<p>So there I went. I modified the original inherited version of the tournament selection without replacement, and rerun the simple time measures. </p>
<pre>
$ time ./GATest
----------------------- GA parameters ------------------------------------
Seed: 69
Lower/upper bounds: [1.000000,0.000000]
Genes: 18
Population size: 2000
Iterations: 30
Tournament size: 6
Crossover: pc=0.900000, gwp=0.500000, etaC=10.000000
Mutation: pm=0.100000, etaM=20.000000
----------------------- Evolution Statistics -----------------------------
4.663210	8.974190	13.158102
3.350933	7.401935	11.503243
1.964580	5.461794	9.246779
1.297656	3.819533	7.364562
0.810695	2.512797	5.142622
0.478789	1.603199	3.652348
0.305106	0.999304	2.138109
0.191904	0.602315	1.336870
0.108593	0.361237	0.869652
0.060862	0.219145	0.502403
0.040076	0.136125	0.307478
0.028629	0.084893	0.191327
0.016301	0.052274	0.115169
0.009433	0.032699	0.071849
0.003934	0.020275	0.047970
0.002762	0.012328	0.031204
0.001405	0.007259	0.019575
0.001043	0.004280	0.010909
0.000790	0.002550	0.005799
0.000404	0.001530	0.003566
0.000287	0.000950	0.002406
0.000198	0.000600	0.001390
0.000127	0.000386	0.000818
0.000068	0.000245	0.000599
0.000045	0.000153	0.000377
0.000026	0.000093	0.000206
0.000020	0.000058	0.000125
0.000011	0.000035	0.000095
0.000007	0.000022	0.000049
0.000004	0.000014	0.000029
0.000002	0.000009	0.000018
----------------------- Final outcome ------------------------------------
Min:	(0.000002)	0.000000	0.000000	0.000000	0.000000.000000	0.000000	0.000000	0.000000	0.000000	0.000000.000000	0.000000	0.000000	0.000000	0.000000	0.000000.000000	0.000000
Max:	(0.000018)	0.000001	0.000000	0.000000	0.000000.000000	0.000000	0.000001	0.000001	0.000000	0.000000.000004	0.000000	0.000001	0.000001	0.000002	0.000000.000001	0.000001	

real	0m0.258s
user	0m0.246s
sys	0m0.006s
</pre>
<p>Yup. That simple change yielded a speedup of 26.15. Mmh, as I said, a little bit of thinking helped to avoid going down some crazy path in a rushing code fever for the wrong reasons. Yup, the threading will be very useful if the cost of the evaluation is expensive (as most of the real world optimization are), but for this silly OneMax, no need to make it more complicated than it need <img src='http://www.xavierllora.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Related posts:<ol>
<li><a href='http://www.xavierllora.net/2005/11/27/evaluation-consistency-in-igas-user-contradictions-as-cycles-in-partial-ordering-graphs/' rel='bookmark' title='Evaluation consistency in iGAs: User contradictions as cycles in partial-ordering graphs'>Evaluation consistency in iGAs: User contradictions as cycles in partial-ordering graphs</a></li>
<li><a href='http://www.xavierllora.net/2008/11/13/fast-mutation-implementation-for-genetic-algorithms-in-python/' rel='bookmark' title='Fast mutation implementation for genetic algorithms in Python'>Fast mutation implementation for genetic algorithms in Python</a></li>
<li><a href='http://www.xavierllora.net/2006/07/07/analyzing-active-interactive-genetic-algorithms-using-visual-analytics/' rel='bookmark' title='Analyzing active interactive genetic algorithms using visual analytics'>Analyzing active interactive genetic algorithms using visual analytics</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.xavierllora.net/2009/04/01/squeezing-for-cycles/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fast mutation implementation for genetic algorithms in Python</title>
		<link>http://www.xavierllora.net/2008/11/13/fast-mutation-implementation-for-genetic-algorithms-in-python/</link>
		<comments>http://www.xavierllora.net/2008/11/13/fast-mutation-implementation-for-genetic-algorithms-in-python/#comments</comments>
		<pubDate>Thu, 13 Nov 2008 05:31:52 +0000</pubDate>
		<dc:creator>Xavier</dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[genetic algorithms]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.xavierllora.net/?p=312</guid>
		<description><![CDATA[The other day I was playing to see how much I could squeeze out of a genetic algorithm written in Python. The code below shows the example I used. The first part implements a simple two loop version of a traditional allele random mutation. The second part is coded using numpy 2D arrays. The code [...]
Related posts:<ol>
<li><a href='http://www.xavierllora.net/2008/07/01/efficient-storage-for-python/' rel='bookmark' title='Efficient storage for Python'>Efficient storage for Python</a></li>
<li><a href='http://www.xavierllora.net/2008/01/10/profiling-python-code/' rel='bookmark' title='Profiling Python Code'>Profiling Python Code</a></li>
<li><a href='http://www.xavierllora.net/2005/11/24/genetic-algorithms-tools/' rel='bookmark' title='Genetic algorithms tools'>Genetic algorithms tools</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>The other day I was playing to see how much I could squeeze out of a genetic algorithm written in Python. The code below shows the example I used. The first part implements a simple two loop version of a traditional allele random mutation. The second part is coded using <code>numpy</code> 2D arrays. The code also measures the time spent on both implementations using <code>cProfile</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> numpy <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
pop_size = <span style="color: #ff4500;">2000</span>
l = <span style="color: #ff4500;">200</span>
z = zeros<span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>pop_size,l<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> mutate <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> :
        <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">xrange</span><span style="color: black;">&#40;</span>pop_size<span style="color: black;">&#41;</span>:
                <span style="color: #ff7700;font-weight:bold;">for</span> j <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">xrange</span><span style="color: black;">&#40;</span>l<span style="color: black;">&#41;</span> :
                        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">random</span>.<span style="color: #dc143c;">random</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">&lt;</span><span style="color: #ff4500;">0.5</span> :
                                z<span style="color: black;">&#91;</span>i,j<span style="color: black;">&#93;</span> = <span style="color: #dc143c;">random</span>.<span style="color: #dc143c;">random</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> cProfile
cProfile.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'mutate()'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> mutate_matrix <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> :
        r = <span style="color: #dc143c;">random</span>.<span style="color: #dc143c;">random</span><span style="color: black;">&#40;</span>size=<span style="color: black;">&#40;</span>pop_size,l<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">&lt;</span><span style="color: #ff4500;">0.5</span>
        v = <span style="color: #dc143c;">random</span>.<span style="color: #dc143c;">random</span><span style="color: black;">&#40;</span>size=<span style="color: black;">&#40;</span>pop_size,l<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        k = r<span style="color: #66cc66;">*</span>v + logical_not<span style="color: black;">&#40;</span>r<span style="color: black;">&#41;</span><span style="color: #66cc66;">*</span>z
&nbsp;
cProfile.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'mutate_matrix()'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>If you run the code listed above you may get something similar to</p>
<pre>
$ python scan.py
         599933 function calls in 0.857 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.857    0.857 <string>:1(<module>)
        1    0.615    0.615    0.857    0.857 scan.py:7(mutate)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
   599930    0.242    0.000    0.242    0.000 {method 'random_sample' of 'mtrand.RandomState' objects}

         3 function calls in 0.082 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.002    0.002    0.082    0.082 <string>:1(<module>)
        1    0.080    0.080    0.080    0.080 scan.py:16(mutate_matrix)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
</pre>
<p>Also if you make the simple math, the numpy-based version is 10.45 times faster than a simple loop-based implementation. Yup, sometimes the easy way out is not the best, and giving it some thought helps <img src='http://www.xavierllora.net/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Related posts:<ol>
<li><a href='http://www.xavierllora.net/2008/07/01/efficient-storage-for-python/' rel='bookmark' title='Efficient storage for Python'>Efficient storage for Python</a></li>
<li><a href='http://www.xavierllora.net/2008/01/10/profiling-python-code/' rel='bookmark' title='Profiling Python Code'>Profiling Python Code</a></li>
<li><a href='http://www.xavierllora.net/2005/11/24/genetic-algorithms-tools/' rel='bookmark' title='Genetic algorithms tools'>Genetic algorithms tools</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.xavierllora.net/2008/11/13/fast-mutation-implementation-for-genetic-algorithms-in-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ICEIS 2008: Saturday morning jam</title>
		<link>http://www.xavierllora.net/2008/06/14/iceis-2008-saturday-morning-jam/</link>
		<comments>http://www.xavierllora.net/2008/06/14/iceis-2008-saturday-morning-jam/#comments</comments>
		<pubDate>Sat, 14 Jun 2008 10:32:53 +0000</pubDate>
		<dc:creator>Xavier</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[innovation]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[virtualization]]></category>

		<guid isPermaLink="false">http://www.xavierllora.net/?p=246</guid>
		<description><![CDATA[My morning jam involved papers 102, 363, 395, 450 709, 234, 392 and 499&#8212;that included a poster session too. There were some puzzling questions running around my head. Just one example out of paper 450; there are always many terminologies meaning the same and rewrite or revolve around the same problem: where is the difference [...]
Related posts:<ol>
<li><a href='http://www.xavierllora.net/2008/06/13/iceis-2008-blogging-from-barcelona-friday-morning/' rel='bookmark' title='ICEIS 2008: Blogging from Barcelona (Friday Morning)'>ICEIS 2008: Blogging from Barcelona (Friday Morning)</a></li>
<li><a href='http://www.xavierllora.net/2008/06/16/iceis-2008-final-sprint-and-ricardo-baeza-yates/' rel='bookmark' title='ICEIS 2008: Final sprint and Ricardo Baeza-Yates'>ICEIS 2008: Final sprint and Ricardo Baeza-Yates</a></li>
<li><a href='http://www.xavierllora.net/2008/06/13/iceis-2008-jorge-cardoso-keynote-speech/' rel='bookmark' title='ICEIS 2008: Jorge Cardoso keynote speech'>ICEIS 2008: Jorge Cardoso keynote speech</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>My morning jam involved <a title="Saturday papers" href="http://www.iceis.org/program/Program_Saturday.htm" target="_blank">papers 102, 363, 395, 450 709, 234, 392 and 499</a>&#8212;that included a poster session too. There were some puzzling questions running around my head. Just one example out of paper 450; there are always many terminologies meaning the same and rewrite or revolve around the same problem: where is the difference between multicriteria optimization instead of multiobjective optimization. As I said, puzzling.</p>
<p>I also ran into a poster during the jam by <a title="intel" href="http://www.intel.com/">Intel</a> folks (<a title="Saturday paper" href="http://www.iceis.org/program/Program_Saturday.htm">paper 234</a>) worth to mention. It was not proposing new technology but building on the creation of distributed data centers via virtualization technologies. They coined the term SVG&#8217;s to describe virtualization + data isolation + services providing. More on the level of exercise to show how people can move to virtual data centers hosted in the cloud, than on proposing new technology&#8212;they said they run <a title="VMware" href="http://www.vmware.com/">VMWare</a> for all the virtualization. The question still buzzes in my head unanswered: How is this new or different from <a title="Amazon EC2" href="http://www.amazon.com/gp/browse.html?node=201590011">Amazon&#8217;s EC2</a>? The answer was that they focusses on the infrastructure not on hosting&#8212;which puzzled me more after claiming they rely on  <a title="VMware" href="http://www.vmware.com/">VMWare</a>&#8212;I guess that I will need to dig deeper to get a better picture of their work.</p>
<p>Just getting close to the lunch break, <a title="Papers" href="http://www.iceis.org/program/Program_Saturday.htm">paper 195</a> presented some work on an engineering approach to determine the emotional signature on clothing website. Built around the Kansei method, the paper resonate in my head very close to the <a title="Gladwell" href="http://en.wikipedia.org/wiki/Blink_(book)">Gladwell&#8217;s Blink</a> book.</p>
<p>Related posts:<ol>
<li><a href='http://www.xavierllora.net/2008/06/13/iceis-2008-blogging-from-barcelona-friday-morning/' rel='bookmark' title='ICEIS 2008: Blogging from Barcelona (Friday Morning)'>ICEIS 2008: Blogging from Barcelona (Friday Morning)</a></li>
<li><a href='http://www.xavierllora.net/2008/06/16/iceis-2008-final-sprint-and-ricardo-baeza-yates/' rel='bookmark' title='ICEIS 2008: Final sprint and Ricardo Baeza-Yates'>ICEIS 2008: Final sprint and Ricardo Baeza-Yates</a></li>
<li><a href='http://www.xavierllora.net/2008/06/13/iceis-2008-jorge-cardoso-keynote-speech/' rel='bookmark' title='ICEIS 2008: Jorge Cardoso keynote speech'>ICEIS 2008: Jorge Cardoso keynote speech</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.xavierllora.net/2008/06/14/iceis-2008-saturday-morning-jam/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

