-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Nick Johnson
committed
May 29, 2012
1 parent
3d9c2b5
commit b1d7af8
Showing
8 changed files
with
180 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import inspect | ||
import random | ||
|
||
import piclang | ||
|
||
ATOM_MUTATION_RATE = 1.0 # Atom mutations per organism | ||
OP_MUTATION_RATE = 0.5 # Operator mutations per organism | ||
CHANGE_TYPE_PROBABILITY = 0.1 # Chance an atom will change type | ||
|
||
def cut_and_splice(g1, g2): | ||
p1 = random.randrange(len(g1)) | ||
p2 = random.randrange(len(g2)) | ||
return g1[:p1] + g2[p2:], g2[:p2] + g1[p1:] | ||
|
||
def mutate(genome): | ||
atom_probability = ATOM_MUTATION_RATE / len(genome) | ||
op_probability = OP_MUTATION_RATE / len(genome) | ||
for i in range(len(genome)): | ||
if isinstance(genome[i], (int, float, tuple, piclang.PlatonicCircle, piclang.PlatonicLine)): | ||
if random.random() < atom_probability: | ||
genome[i] = mutate_atom(genome[i]) | ||
else: | ||
if random.random() < op_probability: | ||
genome[i] = mutate_op(genome[i]) | ||
return genome | ||
|
||
def mutate_atom(instruction): | ||
if random.random() < CHANGE_TYPE_PROBABILITY: | ||
return random_atom(instruction) | ||
if isinstance(instruction, (int, float)): | ||
return mutate_number(instruction) | ||
if isinstance(instruction, tuple): | ||
if random.random < 0.5: | ||
return (instruction[0], mutate_number(instruction[1])) | ||
else: | ||
return (mutate_number(instruction[0]), instruction[1]) | ||
atom_curves = (piclang.PlatonicCircle, piclang.PlatonicLine) | ||
if isinstance(instruction, atom_curves): | ||
return random.choice(atom_curves)() | ||
return instruction | ||
|
||
def random_atom(old_atom=None): | ||
typ = random.choice([float, tuple, piclang.PlatonicCircle, piclang.PlatonicLine]) | ||
if typ == float: | ||
return random.random() | ||
if typ == tuple: | ||
return (random.random(), random.random()) | ||
return typ() | ||
|
||
def mutate_number(num): | ||
if random.random() < 0.5: | ||
# Smaller | ||
return num * (1 - random.random() * 0.5) | ||
else: | ||
# Bigger | ||
return num * (1 + random.random()) | ||
|
||
def mutate_op(instruction): | ||
ops = [piclang.translate, piclang.scale, piclang.rotate, piclang.reverse, piclang.concat, piclang.repeat, piclang.step] | ||
return random.choice(ops) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import webapp2 | ||
from google.appengine.ext import ndb | ||
from webapp2_extras import jinja2 | ||
|
||
import model | ||
|
||
class BaseHandler(webapp2.RequestHandler): | ||
@webapp2.cached_property | ||
def jinja2(self): | ||
return jinja2.get_jinja2(app=self.app) | ||
|
||
def render_template(self, filename, **template_args): | ||
self.response.write(self.jinja2.render_template(filename, **template_args)) | ||
|
||
|
||
class IndividualHandler(BaseHandler): | ||
def get(self, id): | ||
individual = model.Individual.get_by_id(int(id)) | ||
self.render_template('individual.html', individual=individual) | ||
|
||
|
||
app = webapp2.WSGIApplication([ | ||
(r'/individual/(\d+)', IndividualHandler), | ||
]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
from google.appengine.api import files | ||
from google.appengine.api import images | ||
from google.appengine.ext import ndb | ||
|
||
import piclang | ||
|
||
class Individual(ndb.Model): | ||
genome = ndb.PickleProperty(compressed=True) | ||
generation = ndb.IntegerProperty(required=True) | ||
parents = ndb.KeyProperty(kind='Individual', repeated=True) | ||
fitness = ndb.IntegerProperty(default=1500) | ||
matches = ndb.IntegerProperty(default=0) | ||
image = ndb.BlobKeyProperty(required=True) | ||
|
||
@classmethod | ||
def create(cls, genome, generation, parents): | ||
fun = piclang.stackparse(genome) | ||
image = piclang.render(fun, points=8192) | ||
filename = files.blobstore.create(mime_type='image/png') | ||
with files.open(filename, 'a') as f: | ||
image.save(f, "PNG") | ||
files.finalize(filename) | ||
blob_key = files.blobstore.get_blob_key(filename) | ||
individual = cls( | ||
genome=genome, | ||
generation=generation, | ||
parents=parents, | ||
image=blob_key | ||
) | ||
individual.put() | ||
return individual | ||
|
||
@property | ||
def image_url(self): | ||
return images.get_serving_url(self.image) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../piclang.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<html> | ||
<head> | ||
<title>{% block title %}Rate My Curve{% endblock %}</title> | ||
{% block head %}{% endblock %} | ||
</head> | ||
<body> | ||
{% block body %}{% endblock %} | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{% extends "base.html" %} | ||
{% block title %}Individual #{{individual.key.id()}}{% endblock %} | ||
{% block body %} | ||
<h2>Individual #{{individual.key.id()}}</h2> | ||
<img src="{{individual.image_url}}" /> | ||
<table> | ||
<tr><th>Generation</th><td>{{individual.generation}}</td></tr> | ||
<tr><th>Parents</th><td> | ||
{% for parent_key in individual.parents %} | ||
<a href="/individual/{{parent_key.id()}}">#{{parent_key.id()}}</a> | ||
{% endfor %} | ||
</td></tr> | ||
<tr><th>Matches</th><td>{{individual.matches}}</td></tr> | ||
<tr><th>Score</th><td>{{individual.fitness}}</td></tr> | ||
</table> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters