BAIndividual.py
1 import numpy as np 2 import ObjFunction 3 4 5 class BAIndividual: 6 7 ''' 8 individual of bat algorithm 9 ''' 10 11 def __init__(self, vardim, bound): 12 ''' 13 vardim: dimension of variables 14 bound: boundaries of variables 15 ''' 16 self.vardim = vardim 17 self.bound = bound 18 self.fitness = 0. 19 self.trials = 0 20 21 def generate(self): 22 ''' 23 generate a random chromsome for bat algorithm 24 ''' 25 len = self.vardim 26 rnd = np.random.random(size=len) 27 self.chrom = np.zeros(len) 28 self.velocity = np.random.random(size=len) 29 for i in xrange(0, len): 30 self.chrom[i] = self.bound[0, i] + 31 (self.bound[1, i] - self.bound[0, i]) * rnd[i] 32 33 def calculateFitness(self): 34 ''' 35 calculate the fitness of the chromsome 36 ''' 37 self.fitness = ObjFunction.GrieFunc( 38 self.vardim, self.chrom, self.bound)
BA.py
1 import numpy as np 2 from BAIndividual import BAIndividual 3 import random 4 import copy 5 import matplotlib.pyplot as plt 6 7 8 class BatAlgorithm: 9 10 ''' 11 the class for bat algorithm 12 ''' 13 14 def __init__(self, sizepop, vardim, bound, MAXGEN, params): 15 ''' 16 sizepop: population sizepop 17 vardim: dimension of variables 18 bound: boundaries of variables 19 MAXGEN: termination condition 20 params: algorithm required parameters, it is a list which is consisting of[fmax, fmin, Amax, Amin, alpha, gamma] 21 ''' 22 self.sizepop = sizepop 23 self.vardim = vardim 24 self.bound = bound 25 self.MAXGEN = MAXGEN 26 self.params = params 27 self.population = [] 28 self.fitness = np.zeros(self.sizepop) 29 self.freq = np.zeros(self.sizepop) 30 self.loudness = np.zeros(self.sizepop) 31 self.emissionrate = np.zeros(self.sizepop) 32 self.initEmissionrate = np.zeros(self.sizepop) 33 self.trace = np.zeros((self.MAXGEN, 2)) 34 35 def initialize(self): 36 ''' 37 initialize the population of ba 38 ''' 39 for i in xrange(0, self.sizepop): 40 ind = BAIndividual(self.vardim, self.bound) 41 ind.generate() 42 self.population.append(ind) 43 self.freq[i] = self.params[1] + 44 (self.params[0] - self.params[1]) * np.random.random(1) 45 self.loudness[i] = self.params[3] + 46 (self.params[2] - self.params[3]) * np.random.random(1) 47 self.initEmissionrate[i] = np.random.random(1) 48 self.emissionrate[i] = self.initEmissionrate[i] 49 50 def evaluation(self): 51 ''' 52 evaluation the fitness of the population 53 ''' 54 for i in xrange(0, self.sizepop): 55 self.population[i].calculateFitness() 56 self.fitness[i] = self.population[i].fitness 57 58 def solve(self): 59 ''' 60 the evolution process of the bat algorithm 61 ''' 62 self.t = 0 63 self.initialize() 64 self.evaluation() 65 bestIndex = np.argmax(self.fitness) 66 self.best = copy.deepcopy(self.population[bestIndex]) 67 while self.t < self.MAXGEN: 68 self.t += 1 69 self.update() 70 # idx = self.select() 71 self.evaluation() 72 best = np.max(self.fitness) 73 bestIndex = np.argmax(self.fitness) 74 if best > self.best.fitness: 75 self.best = copy.deepcopy(self.population[bestIndex]) 76 77 self.avefitness = np.mean(self.fitness) 78 self.trace[self.t - 1, 0] = 79 (1 - self.best.fitness) / self.best.fitness 80 self.trace[self.t - 1, 1] = (1 - self.avefitness) / self.avefitness 81 print("Generation %d: optimal function value is: %f; average function value is %f" % ( 82 self.t, self.trace[self.t - 1, 0], self.trace[self.t - 1, 1])) 83 print("Optimal function value is: %f; " % self.trace[self.t - 1, 0]) 84 print "Optimal solution is:" 85 print self.best.chrom 86 self.printResult() 87 88 def update(self): 89 ''' 90 update the population 91 ''' 92 for i in xrange(0, self.sizepop): 93 self.freq[i] = self.params[1] + 94 (self.params[0] - self.params[1]) * np.random.random(1) 95 self.population[ 96 i].velocity += (self.best.chrom - self.population[i].chrom) * self.freq[i] 97 98 self.population[i].chrom += self.population[i].velocity 99 for k in xrange(0, self.vardim): 100 if self.population[i].chrom[k] < self.bound[0, k]: 101 self.population[i].chrom[k] = self.bound[0, k] 102 if self.population[i].chrom[k] > self.bound[1, k]: 103 self.population[i].chrom[k] = self.bound[1, k] 104 rnd = np.random.random(1) 105 A = np.mean(self.emissionrate) 106 tmpInd = copy.deepcopy(self.best) 107 if rnd > self.emissionrate[i]: 108 tmpInd.chrom += np.random.uniform(low=-1, 109 high=1.0, size=self.vardim) * A 110 for k in xrange(0, self.vardim): 111 if tmpInd.chrom[k] < self.bound[0, k]: 112 tmpInd.chrom[k] = self.bound[0, k] 113 if tmpInd.chrom[k] > self.bound[1, k]: 114 tmpInd.chrom[k] = self.bound[1, k] 115 tmpInd.calculateFitness() 116 if tmpInd.fitness > self.best.fitness and random.random() < self.loudness[i]: 117 self.population[i] = tmpInd 118 self.loudness[i] *= self.params[4] 119 self.emissionrate[i] = self.initEmissionrate[ 120 i] * (1 - np.exp(self.params[5] * self.t)) 121 if tmpInd.fitness > self.best.fitness: 122 self.best = copy.deepcopy(tmpInd) 123 124 def selectOne(self): 125 ''' 126 select one individual from the population 127 ''' 128 totalFitness = np.sum(self.fitness) 129 accuFitness = np.zeros(self.sizepop) 130 131 sum1 = 0. 132 for i in xrange(0, self.sizepop): 133 accuFitness[i] = sum1 + self.fitness[i] / totalFitness 134 sum1 = accuFitness[i] 135 136 r = random.random() 137 idx = 0 138 for j in xrange(0, self.sizepop - 1): 139 if j == 0 and r < accuFitness[j]: 140 idx = 0 141 break 142 elif r >= accuFitness[j] and r < accuFitness[j + 1]: 143 idx = j + 1 144 break 145 return idx 146 147 def printResult(self): 148 ''' 149 plot the result of bat algorithm 150 ''' 151 x = np.arange(0, self.MAXGEN) 152 y1 = self.trace[:, 0] 153 y2 = self.trace[:, 1] 154 plt.plot(x, y1, 'r', label='optimal value') 155 plt.plot(x, y2, 'g', label='average value') 156 plt.xlabel("Iteration") 157 plt.ylabel("function value") 158 plt.title("Bat algorithm for function optimization") 159 plt.legend() 160 plt.show()
运行程序:
1 if __name__ == "__main__": 2 3 bound = np.tile([[-600], [600]], 25) 4 ba = BA(60, 25, bound, 1000, [1, 0, 1, 0, 0.8, 0.9]) 5 ba.solve()
ObjFunction见简单遗传算法-python实现。