lolamontes69

Ch11 Ex8-Programming Collective Intelligence

Sep 22nd, 2013
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.29 KB | None | 0 0
  1. """ Chapter 11 Exercise 8: Nodes with datatypes.
  2.  
  3.   "Some ideas were provided in this chapter about implementing nodes with mixed data types.
  4.    Implement this and see if you can evolve a program that learns to return the second, third, sixth and seventh characters of a string (e.g., "genetic" becomes "enic".)"
  5.  
  6.    Implemented. See *end for usage
  7.             -lolamontes69
  8.  
  9. """
  10.  
  11.  
  12. from random import random,randint,choice
  13. from copy import deepcopy
  14. from math import log
  15. import os as os
  16.  
  17. class fwrapper:
  18.     def __init__(self,function,childcount,name):
  19.         self.function=function
  20.         self.childcount=childcount
  21.         self.name=name
  22.  
  23. class node:
  24.     def __init__(self,fw,children):
  25.         self.function=fw.function
  26.         self.name=fw.name
  27.         self.children=children
  28.  
  29.     def evaluate(self,inp):
  30.         results=[n.evaluate(inp) for n in self.children]
  31.         return self.function(results)
  32.  
  33.     def display(self,indent=0):
  34.         print (' '*indent)+self.name
  35.         for c in self.children:
  36.             c.display(indent+1)
  37.  
  38. class paramnode:
  39.     def __init__(self,idx):
  40.         self.idx=idx
  41.  
  42.     def evaluate(self,inp):
  43.         return inp[self.idx]
  44.  
  45.     def display(self,indent=0):
  46.         print '%sp%d' % (' '*indent,self.idx)
  47.  
  48. # String functions that only take a list of string/s as arguements
  49. # So I removed constnode
  50.  
  51. # simple split first half
  52. def zerozerozero(l):
  53.     if len(l[0])>1:
  54.         return l[0][len(l[0])/2:]
  55.     else: return l[0]
  56. zerozerozero=fwrapper(zerozerozero,1,'split1')
  57.  
  58. # simple split second half
  59. def zerozero(l):
  60.     if len(l[0])>1:
  61.         return l[0][:len(l[0])/2]
  62.     else: return l[0]
  63. zerozero=fwrapper(zerozero,1,'split2')
  64.  
  65. # simple concat
  66. def zero(l):
  67.     return l[0]+l[1]
  68. zero=fwrapper(zero,2,'concat1')
  69.  
  70. # mix two together
  71. def one(l):
  72.     a0=l[0][:(len(l[0])/2)]
  73.     if len(a0)==0: a0 = l[0]
  74.     a1=l[1][(len(l[1])/2):]
  75.     if len(a1)==0: a0 = l[1]
  76.     return a0+a1
  77. one=fwrapper(one,2,'concat2')
  78.  
  79. # return 'middle' letter
  80. def two(l):
  81.     a0=l[0][(len(l[0])/2)]
  82.     if len(a0)==0: a0 = l[0]
  83.     return a0
  84. two=fwrapper(two,1,'two')
  85.  
  86. # return first letter
  87. def three(l):
  88.     return l[0][0]
  89. three=fwrapper(three,1,'three')
  90.  
  91. # return last letter
  92. def four(l):
  93.     return l[0][-1]
  94. four=fwrapper(four,1,'four')
  95.  
  96. # return index[0]
  97. def six(l):
  98.         return l[0][0]
  99. six=fwrapper(six,1,'six')
  100.  
  101. # return index[1]
  102. def seven(l):
  103.     if len(l[0])>1:
  104.         return l[0][1]
  105.     else:
  106.         return l[0]
  107. seven=fwrapper(seven,1,'seven')
  108.  
  109. # return index[2]
  110. def eight(l):
  111.     if len(l[0])>2:
  112.         return l[0][2]
  113.     else:
  114.         return l[0]
  115. eight=fwrapper(eight,1,'eight')
  116.  
  117. # return index[3]
  118. def nine(l):
  119.     if len(l[0])>3:
  120.         return l[0][3]
  121.     else:
  122.         return l[0]
  123. nine=fwrapper(nine,1,'nine')
  124.  
  125. # return index[4]
  126. def ten(l):
  127.     if len(l[0])>4:
  128.         return l[0][4]
  129.     else:
  130.         return l[0]
  131. ten=fwrapper(ten,1,'ten')
  132.  
  133. # return index[5]
  134. def eleven(l):
  135.     if len(l[0])>5:
  136.         return l[0][5]
  137.     else:
  138.         return l[0]
  139. eleven=fwrapper(eleven,1,'eleven')
  140.  
  141. # return index[6]
  142. def twelve(l):
  143.     if len(l[0])>6:
  144.         return l[0][6]
  145.     else:
  146.         return l[0]
  147. twelve=fwrapper(twelve,1,'twelve')
  148.  
  149. # return even indexes
  150. def thirteen(l):
  151.     res=""
  152.     count=0
  153.     for a in l[0]:
  154.         if count%2==0: res+=a
  155.         count+=1
  156.     if len(res)==0: return l[0]
  157.     else: return res
  158. thirteen=fwrapper(thirteen,1,'thirteen')
  159.  
  160. # return odd indexes
  161. def fourteen(l):
  162.     res=""
  163.     count=1
  164.     for a in l[0]:
  165.         if count%2==0: res+=a
  166.         count+=1
  167.     if len(res)==0: return l[0]
  168.     else: return res
  169. fourteen=fwrapper(fourteen,1,'fourteen')
  170.  
  171. # triple concat
  172. def fifteen(l):
  173.     return l[0]+l[1]+l[2]
  174. fifteen=fwrapper(fifteen,3,'concat3')
  175.  
  176. # quad concat
  177. def sixteen(l):
  178.     return l[0]+l[1]+l[2]+l[3]
  179. sixteen=fwrapper(sixteen,4,'concat4')
  180.  
  181. # return first two letters
  182. def seventeen(l):
  183.     if len(l[0])>2: return l[0][:2]
  184.     else: return l[0]
  185. seventeen=fwrapper(seventeen,1,'split3')
  186.  
  187. # return first two letters
  188. def eighteen(l):
  189.     if len(l[0])>2: return l[0][-2:]
  190.     else: return l[0]
  191. eighteen=fwrapper(eighteen,1,'split4')
  192.  
  193. # return two letters from index[2] to [4]
  194. def nineteen(l):
  195.     if len(l[0])>4: return l[0][2:4]
  196.     else: return l[0]
  197. nineteen=fwrapper(nineteen,1,'split5')
  198.  
  199. # return two letters from index[2] to [4]
  200. def twenty(l):
  201.     if len(l[0])>5: return l[0][3:5]
  202.     else: return l[0]
  203. twenty=fwrapper(twenty,1,'split6')
  204.  
  205. # return two letters from index[2] to [4]
  206. def twentyone(l):
  207.     if len(l[0])>6: return l[0][4:6]
  208.     else: return l[0]
  209. twentyone=fwrapper(twentyone,1,'split7')
  210.  
  211. # make l[0] repeat itself eg fru becomes frufru
  212. def twentytwo(l):
  213.     return l[0]*2
  214. twentytwo=fwrapper(twentytwo,1,'double')
  215.  
  216. # trim l[0] to len(7)
  217. def twentythree(l):
  218.     if len(l[0])>7: return l[0][:7]
  219.     else: return l[0]
  220. twentythree=fwrapper(twentythree,1,'trim')
  221.    
  222. flist=[zerozerozero,zerozero,zero,one,two,three,four,six,seven,eight,nine,ten,eleven,twelve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen,twenty,twentyone,twentytwo]
  223.  
  224. def exampletree():
  225.     return node(zero,[node(zero,[node(seven,[paramnode(0)]),
  226.                                  node(eight,[paramnode(0)])]),
  227.                       node(zero,[node(eleven,[paramnode(0)]),
  228.                                  node(twelve,[paramnode(0)])])])
  229.                
  230. def makerandomtree(pc,maxdepth=4,fpr=0.5,ppr=0.6):
  231.     if random()<fpr and maxdepth>0:
  232.         f=choice(flist)
  233.         children=[makerandomtree(pc,maxdepth-1,fpr,ppr)
  234.                   for i in range(f.childcount)]
  235.         return node(f,children)
  236.     else:
  237.         return paramnode(randint(0,pc-1))
  238.  
  239. ######################### New score functions #################################
  240.  
  241. def scorefunction(tree,data):
  242.     dif=0
  243.     v=tree.evaluate([data[0]])
  244.     dif+=score_it(v,data[2])    
  245.     v=tree.evaluate([data[1]])
  246.     dif+=score_it(v,data[2])
  247.     return dif
  248.  
  249. def score_it(v,answer):
  250.     dif=0
  251.     if len(v)!=len(answer): dif+=10
  252.     for a in answer:
  253.         if a not in v:
  254.             dif+=5
  255.     if len(v)<len(answer): f0, f1 = v, answer
  256.     else: f0, f1 = answer, v
  257.     for a in range(len(f0)):
  258.         if f0[a]!=f1[a]:
  259.             dif+=1
  260.     return dif
  261.  
  262. ###############################################################################
  263.  
  264. def mutate(t,pc,probchange=0.1):
  265.     if random()<probchange:
  266.         return makerandomtree(pc)
  267.     else:
  268.         result=deepcopy(t)
  269.         if hasattr(t,"children"):
  270.             result.children=[mutate(c,pc,probchange) for c in t.children]
  271.         return result
  272.  
  273. def crossover(t1,t2,probswap=0.7,top=1):
  274.     if random()<probswap and not top:
  275.         return deepcopy(t2)
  276.     else:
  277.         result=deepcopy(t1)
  278.         if hasattr(t1, 'children') and hasattr(t2, 'children'):
  279.             result.children=[crossover(c,choice(t2.children),probswap,0)
  280.                              for c in t1.children]
  281.         return result
  282.  
  283. def getrankfunction(dataset):
  284.     def rankfunction(population):
  285.         scores=[(scorefunction(t,dataset),t) for t in population]
  286.         scores.sort()
  287.         return scores
  288.     return rankfunction
  289.  
  290. def evolve(pc,popsize,rankfunction,maxgen=500,mutationrate=0.1,breedingrate=0.4,pexp=0.7,pnew=0.05):
  291.     def selectindex(lenscores):
  292.         while True:
  293.             # Stop selectindex() from returning numbers out of index.
  294.             ind =  int(log(random())/log(pexp))
  295.             if (ind-lenscores>(lenscores*2)-1) or (ind>lenscores): pass
  296.             else: return ind
  297.  
  298.     population=[makerandomtree(pc) for i in range(popsize)]
  299.     for i in range(maxgen):
  300.         scores=rankfunction(population)
  301.         print scores[0][0]
  302.         if scores[0][0]==0: break
  303.        
  304.         newpop=[scores[0][1],scores[1][1]]
  305.  
  306.         while len(newpop)<popsize:
  307.             if random()>pnew:
  308.                 newpop.append(mutate(
  309.                                 crossover(scores[selectindex(len(scores))][1],
  310.                                         scores[selectindex(len(scores))][1],
  311.                                         probswap=breedingrate),
  312.                                 pc,probchange=mutationrate))
  313.             else:
  314.                 newpop.append(makerandomtree(pc))
  315.         population=newpop
  316.     scores[0][1].display()
  317.     return scores[0][1]
  318.  
  319. """
  320. #########
  321. # USAGE #
  322. #########
  323.  
  324. import gp_ex8 as gp
  325. random1=gp.makerandomtree(1)
  326. exampletree=gp.exampletree()  
  327.  
  328. # use the word, a longer version of the word and the desired result to ensure
  329. # that it is returning letters from specific indexes. I recommend using rainbow
  330. # because it has no repeating letters (special,entropy,frogspawn,sexuality,...)
  331.  
  332. rf=gp.getrankfunction(['rainbow','rainbows','aiow'])
  333. winner=gp.evolve(1,500,rf,mutationrate=0.4,breedingrate=0.6,pexp=0.4,pnew=0.5)
  334.  
  335. winner.evaluate(['genetic'])
  336.  
  337. -------------------------------------------------------------------------------
  338.  
  339. I used a lot of functions, but by looking at the results I can eliminate the
  340. rarely used one or even add weights to the useful looking ones :)
  341.  
  342. Then we evolved a winner too...
  343.  
  344. concat4
  345. seven
  346.  p0
  347. eight
  348.  p0
  349. eleven
  350.  concat3
  351.   concat1
  352.    p0
  353.    eight
  354.     twelve
  355.      split4
  356.       split5
  357.        p0
  358.   p0
  359.   p0
  360. split1
  361.  twelve
  362.   p0
  363.  
  364. """
Advertisement
Add Comment
Please, Sign In to add comment