lolamontes69

psyco_gp_ch11ex2.py for Programming Collective Intelligence

Sep 14th, 2013
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.10 KB | None | 0 0
  1. """ This is a version of Chapter 11 Exercise 2 for use with psyco that speeds it up somewhat :)
  2.    Note display1 added to the classes is to output a nested list of the tree to
  3.    make it a bit easier to recreate the outputted function.
  4.       -lolamontes69
  5. """
  6.  
  7. from random import random,randint,choice
  8. from copy import deepcopy
  9. from math import log
  10. import os as os
  11.  
  12.  
  13. class fwrapper:
  14.     def __init__(self,function,childcount,name):
  15.         self.function=function
  16.         self.childcount=childcount
  17.         self.name=name
  18.  
  19. class node:
  20.     def __init__(self,fw,children):
  21.         self.function=fw.function
  22.         self.name=fw.name
  23.         self.children=children
  24.  
  25.     def evaluate(self,inp):
  26.         results=[n.evaluate(inp) for n in self.children]
  27.         return self.function(results)
  28.  
  29.     def display(self,indent=0):
  30.         print (' '*indent)+self.name
  31.         for c in self.children:
  32.             c.display(indent+1)
  33.  
  34.     def display1(self):
  35.         list1=[]
  36.         list1.append(self.name)
  37.         list2=[]
  38.         for c in self.children:
  39.             list2.append(c.display1())
  40.         list1.append(list2)
  41.         return list1
  42.  
  43. class paramnode:
  44.     def __init__(self,idx):
  45.         self.idx=idx
  46.  
  47.     def evaluate(self,inp):
  48.         return inp[self.idx]
  49.  
  50.     def display(self,indent=0):
  51.         print '%sp%d' % (' '*indent,self.idx)
  52.  
  53.     def display1(self):
  54.         return 'p%d' % self.idx
  55.        
  56. class constnode:
  57.     def __init__(self,v):
  58.         self.v=v
  59.  
  60.     def evaluate(self,inp):
  61.         return self.v
  62.  
  63.     def display(self,indent=0):
  64.         print '%s%d' % (' '*indent,self.v)
  65.  
  66.     def display1(self):
  67.         return self.v
  68.  
  69. addw=fwrapper(lambda l:l[0]+l[1],2,'add')
  70. subw=fwrapper(lambda l:l[0]-l[1],2,'subtract')
  71. mulw=fwrapper(lambda l:l[0]*l[1],2,'multiply')
  72.  
  73. def iffunc(l):
  74.     if l[0]>0: return l[1]
  75.     else: return l[2]
  76. ifw=fwrapper(iffunc,3,'if')
  77.  
  78. def iffunc1(l):
  79.     if l[0]>l[1] and l[0]<l[2]: return 1
  80.     elif l[0]>l[2] and l[0]<l[1]: return 1
  81.     else: return 0
  82. ifw1=fwrapper(iffunc1,3,'if1')
  83.  
  84. def iffunc2(l):
  85.     lst1=[l[1],l[2]]
  86.     if max(lst1)-min(lst1)>l[0]: return 1
  87.     else: return 0
  88. ifw2=fwrapper(iffunc2,3,'if2')
  89.  
  90. def isgreater(l):
  91.     if l[0]>l[1]: return 1
  92.     else: return 0
  93. gtw=fwrapper(isgreater,2,'isgreater')
  94.  
  95. # Returns either 1 or 6
  96. def tanimoto(l):
  97.     v1=l[:2]
  98.     v2=l[2:]
  99.     c1,c2,shr=0,0,0
  100.     for i in range(len(v1)):
  101.         if v1[i]!=0: c1+=1
  102.         if v2[i]!=0: c2+=1
  103.         if v1[i]!=0 and v2[i]!=0: shr+=1
  104.     return int((1.0-(float(shr)/(c1+c2-shr+0.00001))*10)%10)
  105. taniw=fwrapper(tanimoto,4,'tanimoto')
  106.  
  107. def euclidean(l):
  108.     p=l[:2]
  109.     q=l[2:]
  110.     sumSq=0.0
  111.     for i in range(len(p)):
  112.         sumSq+=(p[i]-q[i])**2
  113.     # take the square root
  114.     return int(sumSq**0.5)
  115. eucw=fwrapper(euclidean,4,'euclidean')
  116.  
  117. flist=[addw,mulw,ifw,gtw,subw]
  118. # flist=[addw,mulw,ifw,ifw1,ifw2,gtw,subw,eucw,taniw]
  119.  
  120. def exampletree():
  121.     return node(ifw,[
  122.                     node(gtw,[paramnode(0),constnode(3)]),
  123.                     node(addw,[paramnode(1),constnode(5)]),
  124.                     node(subw,[paramnode(1),constnode(2)]),
  125.                     ]
  126.                 )
  127.                
  128. def makerandomtree(pc,maxdepth=4,fpr=0.5,ppr=0.6):
  129.     if random()<fpr and maxdepth>0:
  130.         f=choice(flist)
  131.         children=[makerandomtree(pc,maxdepth-1,fpr,ppr)
  132.                   for i in range(f.childcount)]
  133.         return node(f,children)
  134.     elif random()<ppr:
  135.         return paramnode(randint(0,pc-1))
  136.     else:
  137.         return constnode(randint(0,10))
  138.  
  139. def hiddenfunction(x,y):
  140.     return x**2+2*y+3*x+5
  141.  
  142. def buildhiddenset():
  143.     rows=[]
  144.     for i in range(200):
  145.         x=randint(0,40)
  146.         y=randint(0,40)
  147.         rows.append([x,y,hiddenfunction(x,y)])
  148.     return rows
  149.  
  150. def scorefunction(tree,s):
  151.     dif=0
  152.     for data in s:
  153.         v=tree.evaluate([data[0],data[1]])
  154.         dif+=abs(v-data[2])
  155.     return dif
  156.  
  157. def mutate(t,pc,probchange=0.1):
  158.     if random()<probchange:
  159.         return makerandomtree(pc)
  160.     else:
  161.         result=deepcopy(t)
  162.         if hasattr(t,"children"):
  163.             result.children=[mutate(c,pc,probchange) for c in t.children]
  164.         return result
  165.  
  166. def mutateRandomNode(t,pc,probchange):
  167.     if not hasattr(t,"children") or random() < probchange:
  168.         if isinstance(t,paramnode):
  169.             a=randint(0,pc-1)
  170.             return paramnode(a)
  171.         elif isinstance(t,constnode):
  172.             a=randint(0,10)  
  173.             return constnode(a)
  174.         else:
  175.             return makerandomtree(pc)
  176.     else:
  177.         c = randint(0,len(t.children)-1)
  178.         t.children[c]=mutateRandomNode(t.children[c],pc,probchange)
  179.     return t
  180.  
  181. def newMutate(t,pc,probchange):
  182.     frog=deepcopy(t)
  183.     mutateRandomNode(frog,2,probchange)
  184.     return frog
  185.  
  186. def crossover(t1,t2,probswap=0.7,top=1):
  187.     if random()<probswap and not top:
  188.         return deepcopy(t2)
  189.     else:
  190.         result=deepcopy(t1)
  191.         if hasattr(t1, 'children') and hasattr(t2, 'children'):
  192.             result.children=[crossover(c,choice(t2.children),probswap,0)
  193.                              for c in t1.children]
  194.         return result
  195.  
  196. def getrankfunction(dataset):
  197.     def rankfunction(population):
  198.         scores=[(scorefunction(t,dataset),t) for t in population]
  199.         scores.sort()
  200.         return scores
  201.     return rankfunction
  202.  
  203. def evolve(pc,popsize,rankfunction,maxgen=500,mutationrate=0.1,breedingrate=0.4,pexp=0.7,pnew=0.05):
  204.     # Returns a random number, tending towards lower numbers.
  205.     # The lower pexp is, more lower numbers you will get
  206.     def selectindex(lenscores):
  207.         while True:
  208.             # Stop selectindex() from returning numbers out of index.
  209.             ind =  int(log(random())/log(pexp))
  210.             if (ind-lenscores>(lenscores*2)-1) or (ind>lenscores): pass
  211.             else: return ind
  212.  
  213.     # Create a random initial population
  214.     population=[makerandomtree(pc) for i in range(popsize)]
  215.     for i in range(maxgen):
  216.         scores=rankfunction(population)
  217.         print scores[0][0]
  218.         if scores[0][0]==0: break
  219.        
  220.         # The two best will always make it
  221.         newpop=[scores[0][1],scores[1][1]]
  222.  
  223.         # Build the next generation
  224.         while len(newpop)<popsize:
  225.             if random()>pnew:
  226.                 newpop.append(newMutate(
  227.                                 crossover(scores[selectindex(len(scores))][1],
  228.                                         scores[selectindex(len(scores))][1],
  229.                                         probswap=breedingrate),
  230.                                 pc,probchange=mutationrate))
  231.             else:
  232.                 # Add a random node to mix things up
  233.                 newpop.append(makerandomtree(pc))
  234.         population=newpop
  235.     scores[0][1].display()
  236.     return scores[0][1]
  237.  
  238.  
  239. if __name__ == "__main__":
  240.     try:
  241.         import psyco
  242.         psyco.full()
  243.     except ImportError:
  244.         print 'Unable to import psyco'
  245.  
  246.     rf=getrankfunction(buildhiddenset())
  247.     frog = evolve(2,500,rf,mutationrate=0.2,breedingrate=0.1,pexp=0.7,pnew=0.3)
  248.     print "frog =",frog.display1()
Advertisement
Add Comment
Please, Sign In to add comment