lolamontes69

optimization.py for Ch5 Programming Collective Intelligence

Jul 5th, 2013
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.33 KB | None | 0 0
  1. import time as time
  2. import math
  3. import random as random
  4.  
  5. people = [('Seymour','BOS'),('Franny','DAL'),('Zooey','CAK'),('Walt','MIA'),('Buddy','ORD'),('Les','OMA')]
  6.  
  7. # LaGuardia airport in New York
  8. destination = 'LGA'
  9.  
  10. flights={}
  11. for line in file('schedule.txt'):
  12.     origin,dest,depart,arrive,price=line.strip().split(',')
  13.     flights.setdefault((origin,dest),[])
  14.  
  15.     # Add details to the list of possible flights
  16.     flights[(origin,dest)].append((depart,arrive,int(price)))
  17.  
  18. def getminutes(t):
  19.     x=time.strptime(t,'%H:%M')
  20.     return x[3]*60+x[4]
  21.  
  22. def printschedule(r):
  23.     for d in range(len(r)/2):
  24.         name=people[d][0]
  25.         origin=people[d][1]
  26.         out=flights[(origin,destination)][r[2*d]]              # Corrected for iterating wrongly
  27.         ret=flights[(destination,origin)][r[(2*d)+1]]          # Corrected for iterating wrongly
  28.         print '%10s%10s %5s-%5s $%3s %5s-%5s $%3s' % (name,origin,out[0],out[1],out[2],ret[0],ret[1],ret[2])
  29.  
  30. def schedulecost(sol):
  31.     totalprice=0
  32.     latestarrival=0
  33.     earliestdep=24*60
  34.     for d in range(len(sol)/2):
  35.         # Get the inbound and outbound flights
  36.         origin = people[d][1]
  37.         outbound = flights[(origin,destination)][int(sol[2*d])]    # Corrected for iterating wrongly
  38.         returnf = flights[(destination,origin)][int(sol[(2*d)+1])] # Corrected for iterating wrongly
  39.  
  40.         # Total price is the price of all outbound and return flights
  41.         totalprice+=outbound[2]
  42.         totalprice+=returnf[2]
  43.  
  44.         # Track the latest arrival and earliest departure
  45.         if latestarrival<getminutes(outbound[1]): latestarrival=getminutes(outbound[1])
  46.         if earliestdep>getminutes(returnf[0]): earliestdep=getminutes(returnf[0])
  47.  
  48.     # Every person must wait at the airport until the latest person arrives.
  49.     # They must also arrive at the same time and wait for their flights
  50.     totalwait=0
  51.     for d in range(len(sol)/2):
  52.         origin=people[d][1]
  53.         outbound=flights[(origin,destination)][int(sol[2*d])]    # Corrected for iterating wrongly
  54.         returnf=flights[(destination,origin)][int(sol[(2*d)+1])] # Corrected for iterating wrongly
  55.         totalwait+=latestarrival-getminutes(outbound[1])
  56.         totalwait+=getminutes(returnf[0])-earliestdep
  57.  
  58.     # Does this solution require an extra day of car rental? That'll be $50
  59.     if latestarrival<earliestdep: totalprice+=50  # Corrected
  60.  
  61.     return totalprice+totalwait
  62.  
  63. def randomoptimize(domain,costf):
  64.     best=999999999
  65.     bestr=None
  66.     for i in range(1000):
  67.         # Create a random solution
  68.         r=[random.randint(domain[i][0],domain[i][1]) for i in range(len(domain))]
  69.  
  70.         # Get the cost
  71.         cost=costf(r)
  72.  
  73.         # Compare it to the best one so far
  74.         if cost<best:
  75.             best=cost
  76.             bestr=r
  77.  
  78.     return bestr                # Typo corrected 'bestr' for 'r'
  79.  
  80. def hillclimb(domain,costf):
  81.     # Create a random solution
  82.     sol=[random.randint(domain[i][0],domain[i][1]) for i in range(len(domain))]
  83.  
  84.     # Main loop
  85.     while 1:
  86.  
  87.         #Create list of neighboring solutions
  88.         neighbors=[]
  89.         for j in range(len(domain)):
  90.             # One away in each direction
  91.             if (domain[j][0] == 0) and (domain[j][1] == 0): pass   # Workaround for when domain is (0,0)
  92.             else:
  93.                 if sol[j] > domain[j][0] and sol[j] < domain[j][1]:
  94.                     neighbors.append(sol[0:j]+[sol[j]+1]+sol[j+1:])
  95.                     neighbors.append(sol[0:j]+[sol[j]-1]+sol[j+1:])
  96.                 if sol[j] == domain[j][0]:
  97.                     neighbors.append(sol[0:j]+[sol[j]+1]+sol[j+1:])
  98.                 if sol[j] == domain[j][1]:
  99.                     neighbors.append(sol[0:j]+[sol[j]-1]+sol[j+1:])
  100.  
  101.         # See what the best solution amongst the neighbors is
  102.         current=costf(sol)
  103.         best=current
  104.         for j in range(len(neighbors)):
  105.             cost=costf(neighbors[j])
  106.             if cost<best:
  107.                 best=cost
  108.                 sol=neighbors[j]
  109.  
  110.         # If there's no improvement, then we've reached the top
  111.         if best==current:
  112.             break
  113.  
  114.     return sol
  115.  
  116. def annealingoptimize(domain,costf,T=10000.0,cool=0.95,step=1):
  117.     # Initialize the values randomly
  118.     vec=[(random.randint(domain[i][0],domain[i][1])) for i in range(len(domain))]
  119.  
  120.     while T>0.1:
  121.         # Choose one of the indices
  122.         i=random.randint(0,len(domain)-1)
  123.  
  124.         # Choose a direction to change it
  125.         dir=random.randint(-step,step)
  126.  
  127.         # Create a new list with one of the values changed
  128.         vecb=vec[:]
  129.         vecb[i]+=dir
  130.         if vecb[i]<domain[i][0]: vecb[i]=domain[i][0]
  131.         elif vecb[i]>domain[i][1]: vecb[i]=domain[i][1]
  132.  
  133.         # Calculate the current cost and the new cost
  134.         ea=costf(vec)
  135.         eb=costf(vecb)
  136.         p=pow(math.e,(-eb-ea)/T)
  137.  
  138.         # Is it better, or does it make the probability cutoff?
  139.         if (eb<ea or random.random()<p):
  140.             vec=vecb
  141.  
  142.         # Decrease the temperature
  143.         T=T*cool
  144.     return vec
  145.  
  146. def geneticoptimize(domain,costf,popsize=50,step=1,mutprob=0.2,elite=0.2,maxiter=100):
  147.  
  148.     # Mutation Operation
  149.     def mutate(vec):
  150.         i=random.randint(0,len(domain)-1)
  151.         # Corrected so different step values can be added
  152.         if random.random()<0.5 and vec[i]-step>domain[i][0]:
  153.             return vec[0:i]+[vec[i]-step]+vec[i+1:]
  154.         elif vec[i]+step<domain[i][1]:
  155.             return vec[0:i]+[vec[i]+step]+vec[i+1:]
  156.         else:
  157.             return vec           # Corrected otherwise if vec[i] is unsatisfactory nothing returns
  158.  
  159.     # Crossover Operation
  160.     def crossover(r1,r2):
  161.         i=random.randint(1,len(domain)-2)
  162.         return r1[0:i]+r2[i:]
  163.  
  164.     # Build the initial population
  165.     pop=[]
  166.     for i in range(popsize):
  167.         vec=[random.randint(domain[i][0],domain[i][1]) for i in range(len(domain))]
  168.         pop.append(vec)
  169.  
  170.     # How many winners from each generation?
  171.     topelite=int(elite*popsize)
  172.  
  173.     # Main loop
  174.     for i in range(maxiter):
  175.         scores=[(costf(v),v) for v in pop]
  176.         scores.sort()
  177.         if i == maxiter-1: pass            # Corrected from here for last iteration
  178.         else:
  179.             ranked=[v for (s,v) in scores]
  180.  
  181.             # Start with the pure winers
  182.             pop=ranked[0:topelite]
  183.  
  184.             # Add mutated and bred forms of the winners
  185.             while len(pop)<popsize:
  186.                 if random.random()<mutprob:
  187.  
  188.                     # Mutation
  189.                     c=random.randint(0,topelite)
  190.                     pop.append(mutate(ranked[c]))
  191.                 else:
  192.  
  193.                     # Crossover
  194.                     c1=random.randint(0,topelite)
  195.                     c2=random.randint(0,topelite)
  196.                     pop.append(crossover(ranked[c1],ranked[c2]))
  197.  
  198.             # Print current best score
  199.             print scores[0][0]
  200.  
  201.     return scores[0][1]
  202.  
  203.  
  204.  
  205. """ Corrections to printschedule() for wrong iterations through list r
  206.    Corrections to schedulecost() for wrong iterations through list r
  207.    Correction to randomoptimize() was returning r instead of bestr
  208.    Correction to mutate() in geneticoptimize()
  209.    Corrected misspelled mutprod to mutprob
  210.    Correction to mutate() so different step values can be added
  211.    Corrected hillclimb for when domain[x]=(0,0)
  212. """
Advertisement
Add Comment
Please, Sign In to add comment