lolamontes69

gp.py for Ch11 Programming Collective Intelligence

Sep 14th, 2013
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.85 KB | None | 0 0
  1. from random import random,randint,choice
  2. from copy import deepcopy
  3. from math import log
  4. import os as os
  5.  
  6. class fwrapper:
  7.     def __init__(self,function,childcount,name):
  8.         self.function=function
  9.         self.childcount=childcount
  10.         self.name=name
  11.  
  12. class node:
  13.     def __init__(self,fw,children):
  14.         self.function=fw.function
  15.         self.name=fw.name
  16.         self.children=children
  17.  
  18.     def evaluate(self,inp):
  19.         results=[n.evaluate(inp) for n in self.children]
  20.         return self.function(results)
  21.  
  22.     def display(self,indent=0):
  23.         print (' '*indent)+self.name
  24.         for c in self.children:
  25.             c.display(indent+1)
  26.  
  27.     def display1(self):
  28.         list1=[]
  29.         list1.append(self.name)
  30.         list2=[]
  31.         for c in self.children:
  32.             list2.append(c.display1())
  33.         list1.append(list2)
  34.         return list1
  35.  
  36. class paramnode:
  37.     def __init__(self,idx):
  38.         self.idx=idx
  39.  
  40.     def evaluate(self,inp):
  41.         return inp[self.idx]
  42.  
  43.     def display(self,indent=0):
  44.         print '%sp%d' % (' '*indent,self.idx)
  45.  
  46.     def display1(self):
  47.         return 'p%d' % self.idx
  48.        
  49. class constnode:
  50.     def __init__(self,v):
  51.         self.v=v
  52.  
  53.     def evaluate(self,inp):
  54.         return self.v
  55.  
  56.     def display(self,indent=0):
  57.         print '%s%d' % (' '*indent,self.v)
  58.  
  59.     def display1(self):
  60.         return self.v
  61.  
  62. addw=fwrapper(lambda l:l[0]+l[1],2,'add')
  63. subw=fwrapper(lambda l:l[0]-l[1],2,'subtract')
  64. mulw=fwrapper(lambda l:l[0]*l[1],2,'multiply')
  65.  
  66. def iffunc(l):
  67.     if l[0]>0: return l[1]
  68.     else: return l[2]
  69. ifw=fwrapper(iffunc,3,'if')
  70.  
  71. def isgreater(l):
  72.     if l[0]>l[1]: return 1
  73.     else: return 0
  74. gtw=fwrapper(isgreater,2,'isgreater')
  75.  
  76.  
  77. flist=[addw,mulw,ifw,gtw,subw]
  78.  
  79. def exampletree():
  80.     return node(ifw,[
  81.                     node(gtw,[paramnode(0),constnode(3)]),
  82.                     node(addw,[paramnode(1),constnode(5)]),
  83.                     node(subw,[paramnode(1),constnode(2)]),
  84.                     ]
  85.                 )
  86.                
  87. def makerandomtree(pc,maxdepth=4,fpr=0.5,ppr=0.6):
  88.     if random()<fpr and maxdepth>0:
  89.         f=choice(flist)
  90.         children=[makerandomtree(pc,maxdepth-1,fpr,ppr)
  91.                   for i in range(f.childcount)]
  92.         return node(f,children)
  93.     elif random()<ppr:
  94.         return paramnode(randint(0,pc-1))
  95.     else:
  96.         return constnode(randint(0,10))
  97.  
  98. def hiddenfunction(x,y):
  99.     return x**2+2*y+3*x+5
  100.  
  101. def buildhiddenset():
  102.     rows=[]
  103.     for i in range(200):
  104.         x=randint(0,40)
  105.         y=randint(0,40)
  106.         rows.append([x,y,hiddenfunction(x,y)])
  107.     return rows
  108.  
  109. def scorefunction(tree,s):
  110.     dif=0
  111.     for data in s:
  112.         v=tree.evaluate([data[0],data[1]])
  113.         dif+=abs(v-data[2])
  114.     return dif
  115.  
  116. def mutate(t,pc,probchange=0.1):
  117.     if random()<probchange:
  118.         return makerandomtree(pc)
  119.     else:
  120.         result=deepcopy(t)
  121.         if hasattr(t,"children"):
  122.             result.children=[mutate(c,pc,probchange) for c in t.children]
  123.         return result
  124.  
  125. def crossover(t1,t2,probswap=0.7,top=1):
  126.     if random()<probswap and not top:
  127.         return deepcopy(t2)
  128.     else:
  129.         result=deepcopy(t1)
  130.         if hasattr(t1, 'children') and hasattr(t2, 'children'):
  131.             result.children=[crossover(c,choice(t2.children),probswap,0)
  132.                              for c in t1.children]
  133.         return result
  134.  
  135. def getrankfunction(dataset):
  136.     def rankfunction(population):
  137.         scores=[(scorefunction(t,dataset),t) for t in population]
  138.         scores.sort()
  139.         return scores
  140.     return rankfunction
  141.  
  142. def evolve(pc,popsize,rankfunction,maxgen=500,mutationrate=0.1,breedingrate=0.4,pexp=0.7,pnew=0.05):
  143.     # Returns a random number, tending towards lower numbers.
  144.     # The lower pexp is, more lower numbers you will get
  145.     def selectindex(lenscores):
  146.         while True:
  147.             # Stop selectindex() from returning numbers out of index.
  148.             ind =  int(log(random())/log(pexp))
  149.             if (ind-lenscores>(lenscores*2)-1) or (ind>lenscores): pass
  150.             else: return ind
  151.  
  152.     # Create a random initial population
  153.     population=[makerandomtree(pc) for i in range(popsize)]
  154.     for i in range(maxgen):
  155.         scores=rankfunction(population)
  156.         print scores[0][0]
  157.         if scores[0][0]==0: break
  158.        
  159.         # The two best will always make it
  160.         newpop=[scores[0][1],scores[1][1]]
  161.  
  162.         # Build the next generation
  163.         while len(newpop)<popsize:
  164.             if random()>pnew:
  165.                 newpop.append(mutate(
  166.                                 crossover(scores[selectindex(len(scores))][1],
  167.                                         scores[selectindex(len(scores))][1],
  168.                                         probswap=breedingrate),
  169.                                 pc,probchange=mutationrate))
  170.             else:
  171.                 # Add a random node to mix things up
  172.                 newpop.append(makerandomtree(pc))
  173.         population=newpop
  174.     scores[0][1].display()
  175.     return scores[0][1]
  176.  
  177. def gridgame(p):
  178.     # Board size
  179.     max=(3,3)
  180.  
  181.     # Remember the last move
  182.     lastmove=[-1,-1]
  183.  
  184.     # Remember the player's locations
  185.     location=[[randint(0,max[0]),randint(0,max[1])]]
  186.  
  187.     # Put the second player a sufficient distance from the first
  188.     location.append([(location[0][0]+2)%4,(location[0][1]+2)%4])
  189.  
  190.     # Maximum of 50 moves before a tie
  191.     for o in range(50):
  192.  
  193.         # For each player
  194.         for i in range(2):
  195.             locs=location[i][:]+location[1-i][:]
  196.             locs.append(lastmove[i])
  197.             move=p[i].evaluate(locs)%4
  198.  
  199.             # You lose if you move in the same direction twice in a row
  200.             if lastmove[i]==move: return 1-i
  201.             lastmove[i]=move
  202.             if move==0:
  203.                 location[i][0]-=1
  204.                 # Board limits
  205.                 if location[i][0]<0: location[i][0]=0
  206.             if move==1:
  207.                 location[i][0]+=1
  208.                 if location[i][0]>max[0]: location[i][0]=max[0]
  209.             if move==2:
  210.                 location[i][1]-=1
  211.                 if location[i][0]<0: location[i][1]=0
  212.             if move==3:
  213.                 location[i][1]+=1
  214.                 if location[i][1]>max[1]: location[i][1]=max[1]
  215.  
  216.             # If you have captured the othe player, you win
  217.             if location[i]==location[1-i]: return i
  218.     return -1
  219.  
  220. def tournament(pl):
  221.     # Count losses
  222.     losses=[0 for p in pl]
  223.  
  224.     # Every player plays every other player
  225.     for i in range(len(pl)):
  226.         for j in range(len(pl)):
  227.             if i==j: continue
  228.  
  229.             # Who is the winner?
  230.             winner=gridgame([pl[i],pl[j]])
  231.  
  232.             # Two points for a loss, one point for a tie
  233.             if winner==0:
  234.                 losses[j]+=2
  235.             elif winner==1:
  236.                 losses[i]+=2
  237.             elif winner==-1:
  238.                 losses[i]+=1
  239.                 losses[j]+=1
  240.                 pass
  241.     # Sort and return the results
  242.     z=zip(losses,pl)
  243.     z.sort()
  244.     return z
  245.  
  246. class humanplayer:
  247.     def evaluate(self,board):
  248.         # Get my location and the location, of other players
  249.         me=tuple(board[0:2])
  250.         others=[tuple(board[x:x+2]) for x in range(2,len(board)-1,2)]
  251.         os.system('clear')
  252.         # Display the board
  253.         for i in range(4):
  254.             for j in range(4):
  255.                 if (i,j)==me:
  256.                     print '0',
  257.                 elif (i,j) in others:
  258.                     print 'X',
  259.                 else:
  260.                     print '.',
  261.             print
  262.  
  263.         # Show moves, for reference
  264.         print 'Your last move was %d' % board[len(board)-1]
  265.         print ' 0'
  266.         print '2 3'
  267.         print ' 1'
  268.  
  269.         # Return whatever the user enters
  270.         move=int(raw_input())
  271.         return move
Advertisement
Add Comment
Please, Sign In to add comment