Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
alexsosn committed Nov 15, 2015
1 parent 7480b8e commit 13583d1
Show file tree
Hide file tree
Showing 113 changed files with 14,409 additions and 2 deletions.
59 changes: 59 additions & 0 deletions Ch10/PBIL.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

# Code from Chapter 10 of Machine Learning: An Algorithmic Perspective (2nd Edition)
# by Stephen Marsland (http://stephenmonika.net)

# You are free to use, change, or redistribute the code in any way you wish for
# non-commercial purposes, but please maintain the name of the original author.
# This code comes with no warranty of any kind.

# Stephen Marsland, 2008, 2014

# The Population Based Incremental Learning algorithm
# Comment and uncomment fitness functions as appropriate (as an import and the fitnessFunction variable)

import pylab as pl
import numpy as np

#import fourpeaks as fF
import knapsack as fF

def PBIL():
pl.ion()

populationSize = 100
stringLength = 20
eta = 0.005

#fitnessFunction = 'fF.fourpeaks'
fitnessFunction = 'fF.knapsack'
p = 0.5*np.ones(stringLength)
best = np.zeros(501,dtype=float)

for count in range(501):
# Generate samples
population = np.random.rand(populationSize,stringLength)
for i in range(stringLength):
population[:,i] = np.where(population[:,i]<p[i],1,0)

# Evaluate fitness
fitness = eval(fitnessFunction)(population)

# Pick best
best[count] = np.max(fitness)
bestplace = np.argmax(fitness)
fitness[bestplace] = 0
secondplace = np.argmax(fitness)

# Update vector
p = p*(1-eta) + eta*((population[bestplace,:]+population[secondplace,:])/2)

if (np.mod(count,100)==0):
print count, best[count]

pl.plot(best,'kx-')
pl.xlabel('Epochs')
pl.ylabel('Fitness')
pl.show()
#print p

PBIL()
24 changes: 24 additions & 0 deletions Ch10/billsfit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Code from Chapter 10 of Machine Learning: An Algorithmic Perspective (2nd Edition)
# by Stephen Marsland (http://stephenmonika.net)

# You are free to use, change, or redistribute the code in any way you wish for
# non-commercial purposes, but please maintain the name of the original author.
# This code comes with no warranty of any kind.

# Stephen Marsland, 2008, 2014

# A fitness function for the Knapsack problem
import numpy as np

def billsfit(pop):


maxSize = 500
#sizes = np.array([193.71,60.15,89.08,88.98,15.39,238.14,68.78,107.47,119.66,183.70])

sizes = np.array([109.60,125.48,52.16,195.55,58.67,61.87,92.95,93.14,155.05,110.89,13.34,132.49,194.03,121.29,179.33,139.02,198.78,192.57,81.66,128.90])

fitness = np.sum(sizes*pop,axis=1)
fitness = np.where(fitness>maxSize,500-2*(fitness-maxSize),fitness)

return fitness
32 changes: 32 additions & 0 deletions Ch10/exhaustiveKnapsack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

# Code from Chapter 10 of Machine Learning: An Algorithmic Perspective (2nd Edition)
# by Stephen Marsland (http://stephenmonika.net)

# You are free to use, change, or redistribute the code in any way you wish for
# non-commercial purposes, but please maintain the name of the original author.
# This code comes with no warranty of any kind.

# Stephen Marsland, 2008, 2014

# An exhaustive search to solve the Knapsack problem
import numpy as np

def exhaustive():
maxSize = 500
sizes = np.array([109.60,125.48,52.16,195.55,58.67,61.87,92.95,93.14,155.05,110.89,13.34,132.49,194.03,121.29,179.33,139.02,198.78,192.57,81.66,128.90])

best = 0

twos = np.arange(-len(sizes),0,1)
twos = 2.0**twos

for i in range(2**len(sizes)-1):
string = np.remainder(np.floor(i*twos),2)
fitness = np.sum(string*sizes)
if fitness > best and fitness<500:
best = fitness
bestString = string
print best
print bestString

exhaustive()
40 changes: 40 additions & 0 deletions Ch10/fourpeaks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

# Code from Chapter 10 of Machine Learning: An Algorithmic Perspective (2nd Edition)
# by Stephen Marsland (http://stephenmonika.net)

# You are free to use, change, or redistribute the code in any way you wish for
# non-commercial purposes, but please maintain the name of the original author.
# This code comes with no warranty of any kind.

# Stephen Marsland, 2008, 2014

# The four peaks fitness function
import numpy as np
def fourpeaks(population):

T = 15
start = np.zeros((np.shape(population)[0],1))
finish = np.zeros((np.shape(population)[0],1))

fitness = np.zeros((np.shape(population)[0],1))

for i in range(np.shape(population)[0]):
s = np.where(population[i,:]==1)
f = np.where(population[i,:]==0)
if np.size(s)>0:
start = s[0][0]
else:
start = 0

if np.size(f)>0:
finish = np.shape(population)[1] - f[-1][-1] -1
else:
finish = 0

if start>T and finish>T:
fitness[i] = np.maximum(start,finish)+100
else:
fitness[i] = np.maximum(start,finish)

fitness = np.squeeze(fitness)
return fitness
163 changes: 163 additions & 0 deletions Ch10/ga.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@

# Code from Chapter 10 of Machine Learning: An Algorithmic Perspective (2nd Edition)
# by Stephen Marsland (http://stephenmonika.net)

# You are free to use, change, or redistribute the code in any way you wish for
# non-commercial purposes, but please maintain the name of the original author.
# This code comes with no warranty of any kind.

# Stephen Marsland, 2008, 2014


# The Genetic algorithm
# Comment and uncomment fitness functions as appropriate (as an import and the fitnessFunction variable)

import pylab as pl
import numpy as np
import fourpeaks as fF

class ga:

def __init__(self,stringLength,fitnessFunction,nEpochs,populationSize=100,mutationProb=-1,crossover='un',nElite=4,tournament=True):
""" Constructor"""
self.stringLength = stringLength

# Population size should be even
if np.mod(populationSize,2)==0:
self.populationSize = populationSize
else:
self.populationSize = populationSize+1

if mutationProb < 0:
self.mutationProb = 1/stringLength
else:
self.mutationProb = mutationProb

self.nEpochs = nEpochs

self.fitnessFunction = fitnessFunction

self.crossover = crossover
self.nElite = nElite
self.tournment = tournament

self.population = np.random.rand(self.populationSize,self.stringLength)
self.population = np.where(self.population<0.5,0,1)

def runGA(self,plotfig):
"""The basic loop"""
pl.ion()
#plotfig = pl.figure()
bestfit = np.zeros(self.nEpochs)

for i in range(self.nEpochs):
# Compute fitness of the population
fitness = eval(self.fitnessFunction)(self.population)

# Pick parents -- can do in order since they are randomised
newPopulation = self.fps(self.population,fitness)

# Apply the genetic operators
if self.crossover == 'sp':
newPopulation = self.spCrossover(newPopulation)
elif self.crossover == 'un':
newPopulation = self.uniformCrossover(newPopulation)
newPopulation = self.mutate(newPopulation)

# Apply elitism and tournaments if using
if self.nElite>0:
newPopulation = self.elitism(self.population,newPopulation,fitness)

if self.tournament:
newPopulation = self.tournament(self.population,newPopulation,fitness,self.fitnessFunction)

self.population = newPopulation
bestfit[i] = fitness.max()

if (np.mod(i,100)==0):
print i, fitness.max()
#pl.plot([i],[fitness.max()],'r+')
pl.plot(bestfit,'kx-')
#pl.show()

def fps(self,population,fitness):

# Scale fitness by total fitness
fitness = fitness/np.sum(fitness)
fitness = 10*fitness/fitness.max()

# Put repeated copies of each string in according to fitness
# Deal with strings with very low fitness
j=0
while np.round(fitness[j])<1:
j = j+1

newPopulation = np.kron(np.ones((np.round(fitness[j]),1)),population[j,:])

# Add multiple copies of strings into the newPopulation
for i in range(j+1,self.populationSize):
if np.round(fitness[i])>=1:
newPopulation = np.concatenate((newPopulation,np.kron(np.ones((np.round(fitness[i]),1)),population[i,:])),axis=0)

# Shuffle the order (note that there are still too many)
indices = range(np.shape(newPopulation)[0])
np.random.shuffle(indices)
newPopulation = newPopulation[indices[:self.populationSize],:]
return newPopulation

def spCrossover(self,population):
# Single point crossover
newPopulation = np.zeros(np.shape(population))
crossoverPoint = np.random.randint(0,self.stringLength,self.populationSize)
for i in range(0,self.populationSize,2):
newPopulation[i,:crossoverPoint[i]] = population[i,:crossoverPoint[i]]
newPopulation[i+1,:crossoverPoint[i]] = population[i+1,:crossoverPoint[i]]
newPopulation[i,crossoverPoint[i]:] = population[i+1,crossoverPoint[i]:]
newPopulation[i+1,crossoverPoint[i]:] = population[i,crossoverPoint[i]:]
return newPopulation

def uniformCrossover(self,population):
# Uniform crossover
newPopulation = np.zeros(np.shape(population))
which = np.random.rand(self.populationSize,self.stringLength)
which1 = which>=0.5
for i in range(0,self.populationSize,2):
newPopulation[i,:] = population[i,:]*which1[i,:] + population[i+1,:]*(1-which1[i,:])
newPopulation[i+1,:] = population[i,:]*(1-which1[i,:]) + population[i+1,:]*which1[i,:]
return newPopulation

def mutate(self,population):
# Mutation
whereMutate = np.random.rand(np.shape(population)[0],np.shape(population)[1])
population[np.where(whereMutate < self.mutationProb)] = 1 - population[np.where(whereMutate < self.mutationProb)]
return population

def elitism(self,oldPopulation,population,fitness):
best = np.argsort(fitness)
best = np.squeeze(oldPopulation[best[-self.nElite:],:])
indices = range(np.shape(population)[0])
np.random.shuffle(indices)
population = population[indices,:]
population[0:self.nElite,:] = best
return population

def tournament(self,oldPopulation,population,fitness,fitnessFunction):
newFitness = eval(self.fitnessFunction)(population)
for i in range(0,np.shape(population)[0],2):
f = np.concatenate((fitness[i:i+2],newFitness[i:i+2]),axis=1)
indices = np.argsort(f)
if indices[-1]<2 and indices[-2]<2:
population[i,:] = oldPopulation[i,:]
population[i+1,:] = oldPopulation[i+1,:]
elif indices[-1]<2:
if indices[0]>=2:
population[i+indices[0]-2,:] = oldPopulation[i+indices[-1]]
else:
population[i+indices[1]-2,:] = oldPopulation[i+indices[-1]]
elif indices[-2]<2:
if indices[0]>=2:
population[i+indices[0]-2,:] = oldPopulation[i+indices[-2]]
else:
population[i+indices[1]-2,:] = oldPopulation[i+indices[-2]]
return population

30 changes: 30 additions & 0 deletions Ch10/greedyKnapsack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

# Code from Chapter 10 of Machine Learning: An Algorithmic Perspective (2nd Edition)
# by Stephen Marsland (http://stephenmonika.net)

# You are free to use, change, or redistribute the code in any way you wish for
# non-commercial purposes, but please maintain the name of the original author.
# This code comes with no warranty of any kind.

# Stephen Marsland, 2008, 2014

# A greedy algorithm to solve the Knapsack problem
import numpy as np

def greedy():
maxSize = 500
sizes = np.array([109.60,125.48,52.16,195.55,58.67,61.87,92.95,93.14,155.05,110.89,13.34,132.49,194.03,121.29,179.33,139.02,198.78,192.57,81.66,128.90])

sizes.sort()
newSizes = sizes[-1:0:-1]
space = maxSize

while len(newSizes)>0 and space>newSizes[-1]:
# Pick largest item that will fit
item = np.where(space>newSizes)[0][0]
print newSizes[item]
space = space-newSizes[item]
newSizes = np.concatenate((newSizes[:item],newSizes[item+1:]))
print "Size = ",maxSize-space

greedy()
23 changes: 23 additions & 0 deletions Ch10/knapsack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

# Code from Chapter 10 of Machine Learning: An Algorithmic Perspective (2nd Edition)
# by Stephen Marsland (http://stephenmonika.net)

# You are free to use, change, or redistribute the code in any way you wish for
# non-commercial purposes, but please maintain the name of the original author.
# This code comes with no warranty of any kind.

# Stephen Marsland, 2008, 2014

# A fitness function for the Knapsack problem
import numpy as np

def knapsack(pop):
maxSize = 500
#sizes = np.array([193.71,60.15,89.08,88.98,15.39,238.14,68.78,107.47,119.66,183.70])

sizes = np.array([109.60,125.48,52.16,195.55,58.67,61.87,92.95,93.14,155.05,110.89,13.34,132.49,194.03,121.29,179.33,139.02,198.78,192.57,81.66,128.90])

fitness = np.sum(sizes*pop,axis=1)
fitness = np.where(fitness>maxSize,500-2*(fitness-maxSize),fitness)

return fitness
18 changes: 18 additions & 0 deletions Ch10/onemax.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

# Code from Chapter 10 of Machine Learning: An Algorithmic Perspective (2nd Edition)
# by Stephen Marsland (http://stephenmonika.net)

# You are free to use, change, or redistribute the code in any way you wish for
# non-commercial purposes, but please maintain the name of the original author.
# This code comes with no warranty of any kind.

# Stephen Marsland, 2008, 2014

# A fitness function for the onemax problem
import numpy as np

def onemax(pop):

fitness = np.sum(pop,axis=1)

return fitness
Loading

0 comments on commit 13583d1

Please sign in to comment.