To me, it sounds like you&#39;re trying to do the following:<br><br>Each genome is a small chunk of random code that looks at the MIDI file and calculates a number; in the machine learning literature, I believe this is often called a &quot;feature&quot; of the data. To be redundant for the sake of clarity, each of these genomes, or &quot;features&quot;, is a function from the MIDI file to a real number. Then, each critic takes a subset of all created genomes, and adds them together to create a judgement on the MIDI. This may or may not involve learning weights that the critic uses to make certain genomes more important than others. You then plan on breeding critics by having them swap genomes between each other, but not changing the code of the genomes.<br>

<br>To me, this sounds more like a machine learning articulation of the problem than a genetic programming articulation. If you were doing machine learning, you would have a single critic that has all of the genomes, and then just learn the weights to use when adding the results of applying genomes to MIDIs. While this could potentially work, it seems unlikely that one would be able to create the right genomes from random code to the extent necessary to solve this problem.<br>

<br>I will try to expound on Lee&#39;s suggestions to try to make it more clear how you could turn this into a genetic programming articulation of the problem. First, as Lee said, it would be good to have each critic be a single function, which takes a MIDI file as input and returns a judgment in the form of a real number. At the beginning of evolution, each critic will be random code. During evolution, you will do things to reproduce critics, which may include things like mutation (taking a single individual and changing some of its code to create one new critic) or crossover (taking two or more individuals and combining their code in some way to create one new critic). To evaluate a critic, you will likely want to run the critic on each MIDI file, comparing how close its judgements are to yours to create a fitness value. The instructions that you make available to your critics to use will be the instructions that you previously planned on using in your genomes. But, critics will be large programs that may arithmetically combine many different aspects of the MIDI, instead of small bits of code as in your genomes.<br>

<br>I hope this is helpful in understanding how your proposed direction, though possibly very interesting, was not really what is normally called &quot;genetic programming&quot;.<br><br>-Tom<br><br>P.S. Lee: This thread is making me wonder if there is some general confusion in the class about actually evolving programs. Maybe we should discuss this more in class?<br>

<br><div class="gmail_quote">On Tue, Oct 18, 2011 at 9:35 AM, Wm. Josiah Erikson <span dir="ltr">&lt;<a href="mailto:wjerikson@hampshire.edu">wjerikson@hampshire.edu</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

Right, yes, I think that randomly GENERATING the genomes to make each critic will be they key, but they will stay the same after they have been generated, otherwise evolution will be impossible. I agree with and understand you here.<br>


Where I don&#39;t understand you, I think, is where you suggest that I should have each genome BE a critic. I&#39;m not sure how I would then breed the critics together, since I was thinking of a genome as being the smallest possible unit that did anything useful (and the combination of these genomes would be what made a critic unique). However, as I go to code this, I may discover what you mean, as perhaps this makes no sense in practical terms. I suppose one could breed the genomes together by giving the arguments that one genome passed to a function to the function in another genome, but I don&#39;t think that will create useful evolution. I was thinking of each genome as being a random function (I would write a set of them that performed operations on the file) and random argument (s) within meaningful parameters (like length of the line, or number of lines in the file). This doesn&#39;t really make for tree-based GP, though, I suppose.... hmm... not sure anything other than a depth of one would work properly or usefully in this context, though. Maybe I&#39;m boxing myself in.<br>

<font color="#888888">
<br>
    -Josiah</font><div><div></div><div class="h5"><br>
<br>
<br>
<br>
On 10/17/11 8:15 PM, Lee Spector wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
[Re-adding the list to the cc: -- hope that&#39;s okay! I do think that others will also benefit from this.]<br>
<br>
Comments below...<br>
<br>
<br>
On Oct 17, 2011, at 4:22 PM, Wm. Josiah Erikson wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
    OK, so each critic is made up of a number of &quot;scoring genomes&quot;, that are either generated randomly or pulled randomly from a large predetermined set of soup of things you could do to get a score. Add all the scoring genomes together and you get a critic, which will then evaluate each song and the total deviation of each individual score from my own will be that critic&#39;s fitness. Then I will breed together the x best critics in each generation of y members (adjustable) and run it again.<br>


</blockquote>
It sounds from the below like each &quot;scoring genome&quot; can itself be a pretty complicated beast, do math and comparisons etc. So why couldn&#39;t *one* of these be able to do all of the things that you&#39;re thinking that a bunch of them could do summed together? You&#39;re saying that a critic will be the sum of a bunch of things, each of which can do a bunch of things including making sums of bunches of things... right? If I&#39;ve got that right then I think it&#39;ll be simpler and probably just as good to make each critic *be* just *one* of these scoring genomes.<br>


<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
    Now each scoring genome could both DO random things (like pull two random characters out from two random lines and compare them to each other, or pull a random character from a random line and compare it to the most common character in the whole file, or a million other possibilities) and could also assign scores to those things, positive, negative, who knows. It could also be that having a particular genome hard-coded with the actual positions in the files that it pulls from, once it&#39;s been randomly generated, or whatever, would be helpful and create more consistent results when breeding the resulting critic with another one.<br>


</blockquote>
My advice is to avoid any randomness in the actions or calculations of the scoring genomes. In other words, the same genome, if evaluated twice on the same file, should produce exactly the same score.<br>
<br>
It&#39;s not that I can&#39;t imagine it being useful to do random stuff (or, as you suggest below, grab random data from a file) as part of a calculating a score, but rather that I predict that randomness here will make evolution impossible.<br>


<br>
If your scores are nondeterministic (giving different scores on different applications to the same data) then your fitnesses (the differences between the scores and your own personal scores) will also be nondeterministic. This means that the &quot;selection&quot; performed in the evolutionary loop will be basing its selections on luck to a fairly large extent, and that this luck factor may well be as important as actual quality in determining who gets selected. This would mean that the evolutionary loop will not be able to amplify quality over generations.<br>


<br>
If you really want to have scoring genomes that involve randomness then I think you&#39;d have to take pretty serious countermeasures, like testing each one by running it a large numbers and averaging the results. But I think it&#39;d be simpler and better just to leave out the randomness altogether.<br>


<br>
Of course, if you&#39;re not going to be using a random number you&#39;ll have to have a non-random number and that will have to come from somewhere. Presumably there could just be numbers in the genome itself, or some functions could operate on *all* lines in a file or all lines of a particular type, etc.<br>


<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
It will be interesting to see what tools I can come up with to try to help this evolve towards something useful, i.e. what to put in the soup. The ideas I have so far involve<br>
<br>
Fetching:<br>
    -set of characters, same random position on each line of the file (that position would be in the genome and would get passed on from generation to generation)<br>
    -getting the most common character in the file<br>
    -random number of random characters from the file on different lines<br>
    -same as above except same line<br>
    -random initial number determines starting number of the position on the line, increase for each line until out of characters<br>
<br>
Operators:<br>
    -modulus division, addition, subtraction, multiplication, division, mode, mean, median, and mixtures of all of these with comparison<br>
<br>
    Maybe this is all too heterogeneous and I need to make everything take two operators or something. I&#39;ll see as I start actually implementing this. I&#39;m going to start with a few simple genomes :)<br>
</blockquote>
All of this looks good except for the randomness...<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
    I figured out the slurp problem - for some reason when I stick it in a vector of lists, it works fine:<br>
<br>
(def rita (vec (string/split-lines (slurp &quot;/Volumes/cs254/group_storage/<u></u>josiah/LovelyRita.csv&quot;))))<br>
<br>
(get rita (rand-int (count rita)))<br>
;&quot;11, 6864, Note_on_c, 9, 42, 0&quot;<br>
<br>
</blockquote>
<br>
Well... I don&#39;t know, but this does have half of the smell of a laziness problem, since calling vec on something lazy forces it to be fully realized. But the doc string on split-lines says it&#39;s not lazy, and neither should slurp be. So this doesn&#39;t fully make sense. Another thing that doesn&#39;t is that you said you had the same problem with the slurp example in clojinc with Jabberwocky.txt, and I haven&#39;t experienced any such problem... it returns instantly for me.<br>


<br>
  -Lee<br>
<br>
<br>
<br>
<br>
<br>
--<br>
Lee Spector, Professor of Computer Science<br>
Cognitive Science, Hampshire College<br>
893 West Street, Amherst, MA 01002-3359<br>
<a href="mailto:lspector@hampshire.edu" target="_blank">lspector@hampshire.edu</a>, <a href="http://hampshire.edu/lspector/" target="_blank">http://hampshire.edu/lspector/</a><br>
Phone: <a href="tel:413-559-5352" value="+14135595352" target="_blank">413-559-5352</a>, Fax: <a href="tel:413-559-5438" value="+14135595438" target="_blank">413-559-5438</a><br>
<br>
</blockquote>
<br></div></div><div class="im">
-- <br>
Wm. Josiah Erikson<br>
Network Engineer<br>
Hampshire College<br>
Amherst, MA 01002<br>
<a href="tel:%28413%29%20559-6091" value="+14135596091" target="_blank">(413) 559-6091</a><br>
<br></div><div><div></div><div class="h5">
______________________________<u></u>_________________<br>
Cs254f11 mailing list<br>
<a href="mailto:Cs254f11@lists.hampshire.edu" target="_blank">Cs254f11@lists.hampshire.edu</a><br>
<a href="https://lists.hampshire.edu/mailman/listinfo/cs254f11" target="_blank">https://lists.hampshire.edu/<u></u>mailman/listinfo/cs254f11</a><br>
</div></div></blockquote></div><br>