def caixa_preta( algorithm=1, generations=50, population=[], is_single=False, is_uniform=True, is_elitist=True, is_ultra_elitist=False, elitism=0.85, xfactor=0.3, win_factor=1 ): """Realiza o algoritmo evlutivo para o problema""" data_fit = [] if algorithm == 1: for gen in range(generations): # calcula o fitness da população fit = fitness(population) # faz a seleção por torneio f_selec_torn, f_perd_torn = torneio(population, fit, win_factor) # faz o cruzamento child_sliced = cruzamento(f_selec_torn, is_single=is_single, is_uniform=is_uniform) # faz a mutação do filho child_mutaded = mutacao(child_sliced, xfactor=xfactor) # seleciona a nova população population = substituicao(population, father=f_selec_torn, children=child_mutaded, elitism=elitism, is_ultra_elitist=is_ultra_elitist, is_elitist=is_elitist) if type(population[0][0]) != int: import pdb;pdb.set_trace() fit = fitness(population) data_fit.append(best_fitness(fit)) else: for gen in range(generations): # calcula o fitness da população fit = fitness(population) # calcula a média do fitness do conjunto fit_avg = fitness_medio(fit) # calcula a probabilidade de seleção prob_selec = selecao_prob(population, fit, fit_avg) # faz a seleção por rodeio f_selec_rol = roleta(population, prob_selec) # faz o cruzamento child_sliced = cruzamento(f_selec_rol, is_single=is_single, is_uniform=is_uniform) # faz a mutação do filho child_mutaded = mutacao(child_sliced, xfactor) # seleciona a nova população population = substituicao(population, f_selec_rol, child_mutaded, elitism, is_elitist) fit = fitness(population) data_fit.append(best_fitness(fit)) return data_fit
def test(): nIter = 100 nPop = 100 nAr = 100 nChr = 3 func = function c1 = 1.49445 c2 = 2 lb = -2 rb = 2 Vmax = 0.2 Vmin = -0.2 M = 50 paretoPops, paretoFits = MOPSO(nIter, nPop, nAr, nChr, \ func, c1, c2, lb, rb, Vmax, Vmin, M) print(paretoPops.shape) print('=' * 20) #print(paretoPops) # 理论最优解集合 x = np.linspace(-1 / np.sqrt(3), 1 / np.sqrt(3), 116).reshape(116, 1) X = np.tile(x, 3) # 理论最佳帕累托解集 thFits = fitness(X, function) plt.rcParams['font.sans-serif'] = 'KaiTi' # 设置显示中文 fig = plt.figure(dpi=400) ax = fig.add_subplot(111) ax.plot(thFits[:,0], thFits[:,1], color='green',\ label="理论帕累托前沿") ax.scatter(paretoFits[:,0], paretoFits[:,1], \ color='red', label="实际求解") ax.legend() fig.savefig('test.png', dpi=400)
def main(): nIter = 50 nChr = 3 nPop = 100 pc = 0.6 pm = 0.1 etaC = 1 etaM = 1 func = function lb = -2 rb = 2 paretoPops, paretoFits = NSGA2(nIter, nChr, nPop, pc, pm, etaC, etaM, func, lb, rb) print(paretoFits) print(f"paretoFront: {paretoFits.shape}") # 理论最优解集合 x = np.linspace(-1 / np.sqrt(3), 1 / np.sqrt(3), 116).reshape(116, 1) X = np.concatenate((x, x, x), axis=1) thFits = fitness(X, function) plt.rcParams['font.sans-serif'] = 'KaiTi' # 设置显示中文 fig = plt.figure(dpi=400) ax = fig.add_subplot(111) ax.plot(thFits[:, 0], thFits[:, 1], color='green', label='理论帕累托前沿') ax.scatter(paretoFits[:, 0], paretoFits[:, 1], color='red', label='实际解集') ax.legend() fig.savefig('test.png', dpi=400) print(paretoPops)
def main(): nIter = 100 nChr = 3 nPop = 50 F = 0.2 Cr = 0.9 func = function lb = -2 rb = 2 paretoPops, paretoFits = MODE(nIter, nChr, nPop, F, Cr, func, lb, rb) # print(paretoFits) print(f"paretoFront: {paretoFits.shape}") # 理论最优解集合 x = np.linspace(-1/np.sqrt(3), 1/np.sqrt(3), 116).reshape(116,1) X = np.tile(x, 3) # 理论最佳帕累托解集 thFits = fitness(X, function) plt.rcParams['font.sans-serif'] = 'KaiTi' # 设置显示中文 fig = plt.figure(dpi=400) ax = fig.add_subplot(111) ax.plot(thFits[:,0], thFits[:,1], color='green',\ label="理论帕累托前沿") ax.scatter(paretoFits[:,0], paretoFits[:,1], \ color='red', label="实际求解") ax.legend() fig.savefig('test.png', dpi=400)
def sel(k,l,n,alpha,c,beta): w = fitness(0,k,n,c) wm = fitness_m(k,n,c) p = 0 if wm == 0 else k*w/(n*wm) termoInd = comb(n,l)*p**l*(1-p)**(n-l) #termoGr = (1-beta+2*beta*pVencer(alpha,k,n)) if beta > 0 else wm termoGr = 1-beta+2*beta*pVencer(alpha,k,n) return termoGr*termoInd
def sel(k, l, n, delta, alpha, b, c, w0, beta): w = fitness(0, k, n, delta, b, c, w0) wm = fitness_m(k, n, delta, b, c, w0) p = 0 if wm == 0 else k * w / (n * wm) termoInd = scipy.misc.comb(n, l) * p**l * (1 - p)**(n - l) #termoGr = (1-beta+2*beta*pVencer(alpha,k,n)) if beta > 0 else wm termoGr = 1 - beta + 2 * beta * pVencer(alpha, k, n) return termoGr * termoInd
def sel(k,l,n,delta, alpha,b,c,w0,beta): w = fitness(0,k,n,delta,b,c,w0) wm = fitness_m(k,n,delta,b,c,w0) p = 0 if wm == 0 else k*w/(n*wm) termoInd = scipy.misc.comb(n,l)*p**l*(1-p)**(n-l) #termoGr = (1-beta+2*beta*pVencer(alpha,k,n)) if beta > 0 else wm termoGr = 1-beta+2*beta*pVencer(alpha,k,n) return termoGr*termoInd
def intial_population(population_size, num_queens): population = [] for chromo in range(population_size): individual = [] for gene in range(num_queens): new_ind = Chromosome(num_queens) individual.append(new_ind) individual = fitness(individual) population.append(individual) return population
def sel(k, l, n, alpha, c, beta): """ Calculates the average number of groups of type `k` that become type `l` by selection forces """ w = fitness(0, c) wm = avg_fitness(n, k, c) p = 0 if wm == 0 else k * w / (n * wm) indiv_term = comb(n, l) * p**l * (1 - p)**(n - l) group_term = 1 - beta + 2 * beta * winning_prob(alpha, k, n) return group_term * indiv_term
def rotate(funfcn,Best,fBest,SE,Range,alpha,beta): Pop_Lb = np.tile(Range[0],(SE,1)) Pop_Ub = np.tile(Range[1],(SE,1)) oldBest = Best State = op_rotate(Best,SE,alpha) changeRows = State > Pop_Ub State[changeRows] = Pop_Ub[changeRows] changeRows = State < Pop_Lb State[changeRows] = Pop_Lb[changeRows] newBest,fGBest = fitness(funfcn,State) if fGBest < fBest: fBest,Best = fGBest,newBest State = op_translate(oldBest,Best,SE,beta) changeRows = State > Pop_Ub State[changeRows] = Pop_Ub[changeRows] changeRows = State < Pop_Lb State[changeRows] = Pop_Lb[changeRows] newBest,fGBest = fitness(funfcn,State) if fGBest < fBest: fBest,Best = fGBest,newBest return Best,fBest
def Experiment1(): #Experiment 1 - loss of gradient1 pop1 = list() pop2 = list() for i in range(POP_SIZE): pop1.append(resident(dimensions=1)) pop2.append(resident(dimensions=1)) for i in range(GENERATIONS): # repeat if (i % 10) == 0: print '.', #plot data Plot(i, pop1 + pop2 ) #i is generation, pop1+pop2 gives all the residents in one list #write data Write(pop1, pop2) #evaluate fitness of all individuals for a in pop1: #for each member in population 1 #make a sample of SAMPLE_SIZE from pop2 sample = list() for z in range(SAMPLE_SIZE): i = int(math.floor(random.random() * POP_SIZE)) sample.append(pop2[i]) a.fitness = fitness(a, sample) for a in pop2: #for each member in population 2 #make a sample of SAMPLE_SIZE from pop1 sample = list() for z in range(SAMPLE_SIZE): i = int(math.floor(random.random() * POP_SIZE)) #pick one from the population sample.append(pop1[i]) # a.fitness = fitness(a, sample) #select and replace pop1 = FPS(pop1) pop2 = FPS(pop2)
def substituicao(population, father, children, elitism=0.85, is_elitist=True, is_ultra_elitist=False, loser=[], is_loser=False): """Realiza substituição do conjunto de dados""" father_order = order_by_fitness(father, fitness(father), True) children_order = order_by_fitness(children, fitness(children), True) population = order_by_fitness(population, fitness(population), False) if is_ultra_elitist == True: best_pop = father_order + children_order best_gen = order_by_fitness(best_pop, fitness(best_pop), True) population = order_by_fitness(population, fitness(population), False) slice_point = int(len(population)*elitism) population = best_gen[0:slice_point] + population[slice_point:] elif is_elitist: for i in range(int(len(population)/2)): if r.random() < elitism: if children_order[i] > father_order[i]: population[i] = children_order[i] else: population[i] = father_order[i] else: population[i] = children_order[i] if is_loser: for i in range(int(len(population)/2)): population[int(len(population)/2) + i] = loser[i] else: population = father_order + children_order return population
def NSGA2(nIter, nChr, nPop, pc, pm, etaC, etaM, func, lb, rb): """非支配遗传算法主程序 Params: nIter: 迭代次数 nPop: 种群大小 pc: 交叉概率 pm: 变异概率 func: 优化的函数 lb: 自变量下界 rb: 自变量上界 """ # 生成初始种群 pops = initPops(nPop, nChr, lb, rb) fits = fitness(pops, func) # 开始第1次迭代 iter = 1 while iter <= nIter: # 进度条 print("【进度】【{0:20s}】【正在进行{1}代...】【共{2}代】".\ format('▋'*int(iter/nIter*20), iter, nIter), end='\r') ranks = nonDominationSort(pops, fits) # 非支配排序 distances = crowdingDistanceSort(pops, fits, ranks) # 拥挤度 pops, fits = select1(nPop, pops, fits, ranks, distances) chrpops = crossover(pops, pc, etaC, lb, rb) # 交叉产生子种群 chrpops = mutate(chrpops, pm, etaM, lb, rb) # 变异产生子种群 chrfits = fitness(chrpops, func) # 从原始种群和子种群中筛选 pops, fits = optSelect(pops, fits, chrpops, chrfits) iter += 1 # 对最后一代进行非支配排序 ranks = nonDominationSort(pops, fits) # 非支配排序 distances = crowdingDistanceSort(pops, fits, ranks) # 拥挤度 paretoPops = pops[ranks == 0] paretoFits = fits[ranks == 0] return paretoPops, paretoFits
def Experiment1(): #Experiment 1 - loss of gradient1 pop1 = list() pop2 = list() for i in range(POP_SIZE): pop1.append(resident(dimensions=1)) pop2.append(resident(dimensions=1)) for i in range(GENERATIONS): # repeat if (i % 10) == 0: print '.', #plot data Plot(i, pop1 + pop2) #i is generation, pop1+pop2 gives all the residents in one list #write data Write(pop1, pop2) #evaluate fitness of all individuals for a in pop1: #for each member in population 1 #make a sample of SAMPLE_SIZE from pop2 sample = list() for z in range(SAMPLE_SIZE): i = int(math.floor(random.random() * POP_SIZE)) sample.append(pop2[i]) a.fitness = fitness(a, sample) for a in pop2: #for each member in population 2 #make a sample of SAMPLE_SIZE from pop1 sample = list() for z in range(SAMPLE_SIZE): i = int(math.floor(random.random() * POP_SIZE))#pick one from the population sample.append(pop1[i])# a.fitness = fitness(a, sample) #select and replace pop1 = FPS(pop1) pop2 = FPS(pop2)
def Test(): a = resident(size = 10, dimensions = 1) print(a._string) print(a._value) b = resident(size = 10, dimensions = 1) c = resident(size = 10, dimensions = 1) population = list() population.append(b) population.append(c) print("values:\n\ta=") print(a._value) print("\tb=") print(b._value) print("\tc=") print(c._value) a.fitness = fitness(a, population) print("fitness of a = %d" % a.fitness) #test 2D a = resident(size = 10) b = resident(size = 10) c = resident(size = 10) a._value = [1, 6] b._value = [4, 5] c._value = [2, 4] population = list() population.append(a) population.append(b) population.append(c) print("values:\n\ta=") print(a._value) print("\tb=") print(b._value) print("\tc=") print(c._value) a.fitness = fitness2(a, population) b.fitness = fitness2(b, population) c.fitness = fitness2(c, population) print("fitness2 of a = %d" % a.fitness) print("fitness2 of b = %d" % b.fitness) print("fitness2 of c = %d" % c.fitness) a.fitness = fitness3(a, population) b.fitness = fitness3(b, population) c.fitness = fitness3(c, population) print("fitness3 of a = %d" % a.fitness) print("fitness3 of b = %d" % b.fitness) print("fitness3 of c = %d" % c.fitness)
def Test(): a = resident(size=10, dimensions=1) print(a._string) print(a._value) b = resident(size=10, dimensions=1) c = resident(size=10, dimensions=1) population = list() population.append(b) population.append(c) print("values:\n\ta=") print(a._value) print("\tb=") print(b._value) print("\tc=") print(c._value) a.fitness = fitness(a, population) print("fitness of a = %d" % a.fitness) #test 2D a = resident(size=10) b = resident(size=10) c = resident(size=10) a._value = [1, 6] b._value = [4, 5] c._value = [2, 4] population = list() population.append(a) population.append(b) population.append(c) print("values:\n\ta=") print(a._value) print("\tb=") print(b._value) print("\tc=") print(c._value) a.fitness = fitness2(a, population) b.fitness = fitness2(b, population) c.fitness = fitness2(c, population) print("fitness2 of a = %d" % a.fitness) print("fitness2 of b = %d" % b.fitness) print("fitness2 of c = %d" % c.fitness) a.fitness = fitness3(a, population) b.fitness = fitness3(b, population) c.fitness = fitness3(c, population) print("fitness3 of a = %d" % a.fitness) print("fitness3 of b = %d" % b.fitness) print("fitness3 of c = %d" % c.fitness)
def __init__(self, pop_size, LIMITS, param_no, precision, fitness): """ :param pop_size: number of chromosomes in population :param LIMITS: limits of chromosome's parameters :param param_no: number of parameters for a chromosome :param precision: precision of parameters' float values """ self.MEMBERS = [ Chromosome(param_no, LIMITS, precision) for _ in xrange(pop_size) ] for member in self.MEMBERS: member.fitness = (round(fitness(member.params_float), precision)) self.__fitness = fitness self.__precision = precision self.__LIMITS = LIMITS
def __init__(self, f, x0, ranges=[ ], fmt='f', fitness=Fitness, selection=RouletteWheel, crossover=TwoPoint, mutation=BitToBit, elitist=True): ''' Initializes the population and the algorithm. On the initialization of the population, a lot of parameters can be set. Those will deeply affect the results. The parameters are: :Parameters: f A multivariable function to be evaluated. The nature of the parameters in the objective function will depend of the way you want the genetic algorithm to process. It can be a standard function that receives a one-dimensional array of values and computes the value of the function. In this case, the values will be passed as a tuple, instead of an array. This is so that integer, floats and other types of values can be passed and processed. In this case, the values will depend of the format string (see below) If you don't supply a format, your objective function will receive a ``Chromosome`` instance, and it is the responsability of the function to decode the array of bits in any way. Notice that, while it is more flexible, it is certainly more difficult to deal with. Your function should process the bits and compute the return value which, in any case, should be a scalar. Please, note that genetic algorithms maximize functions, so project your objective function accordingly. If you want to minimize a function, return its negated value. x0 A population of first estimates. This is a list, array or tuple of one-dimension arrays, each one corresponding to an estimate of the position of the minimum. The population size of the algorithm will be the same as the number of estimates in this list. Each component of the vectors in this list are one of the variables in the function to be optimized. ranges Since messing with the bits can change substantially the values obtained can diverge a lot from the maximum point. To avoid this, you can specify a range for each of the variables. ``range`` defaults to ``[ ]``, this means that no range checkin will be done. If given, then every variable will be checked. There are two ways to specify the ranges. It might be a tuple of two values, ``(x0, x1)``, where ``x0`` is the start of the interval, and ``x1`` its end. Obviously, ``x0`` should be smaller than ``x1``. If ``range`` is given in this way, then this range will be used for every variable. It can be specified as a list of tuples with the same format as given above. In that case, the list must have one range for every variable specified in the format and the ranges must appear in the same order as there. That is, every variable must have a range associated to it. fmt A ``struct``-format string. The ``struct`` module is a standard Python module that packs and unpacks informations in bits. These are used to inform the algorithm what types of data are to be used. For example, if you are maximizing a function of three real variables, the format should be something like ``"fff"``. Any type supported by the ``struct`` module can be used. The GA will decode the bit array according to this format and send it as is to your fitness function -- your function *must* know what to do with them. Alternatively, the format can be an integer. In that case, the GA will not try to decode the bit sequence. Instead, the bits are passed without modification to the objective function, which must deal with them. Notice that, if this is used this way, the ``ranges`` property (see below) makes no sense, so it is set to ``None``. Also, no sanity checks will be performed. It defaults to `"f"`, that is, a single floating point variable. fitness A fitness method to be applied over the objective function. This parameter must be a ``Fitness`` instance or subclass. It will be applied over the objective function to compute the fitness of every individual in the population. Please, see the documentation on the ``Fitness`` class. selection This specifies the selection method. You can use one given in the ``selection`` sub-module, or you can implement your own. In any case, the ``selection`` parameter must be an instance of ``Selection`` or of a subclass. Please, see the documentation on the ``selection`` module for more information. Defaults to ``RouletteWheel``. If made ``None``, then selection will not be present in the GA. crossover This specifies the crossover method. You can use one given in the ``crossover`` sub-module, or you can implement your own. In any case, the ``crossover`` parameter must be an instance of ``Crossover`` or of a subclass. Please, see the documentation on the ``crossover`` module for more information. Defaults to ``TwoPoint``. If made ``None``, then crossover will not be present in the GA. mutation This specifies the mutation method. You can use one given in the ``mutation`` sub-module, or you can implement your own. In any case, the ``mutation`` parameter must be an instance of ``Mutation`` or of a subclass. Please, see the documentation on the ``mutation`` module for more information. Defaults to ``BitToBit``. If made ``None``, then mutation will not be present in the GA. elitist Defines if the population is elitist or not. An elitist population will never discard the fittest individual when a new generation is computed. Defaults to ``True``. ''' list.__init__(self, [ ]) self.__fx = [ ] for x in x0: x = array(x).ravel() c = Chromosome(fmt) c.encode(tuple(x)) self.append(c) self.__fx.append(f(x)) self.__f = f self.__csize = self[0].size self.elitist = elitist '''If ``True``, then the population is elitist.''' if type(fmt) == int: self.ranges = None elif ranges is None: self.ranges = zip(amin(self, axis=0), amax(self, axis=1)) else: ranges = list(ranges) if len(ranges) == 1: self.ranges = array(ranges * len(x0[0])) else: self.ranges = array(ranges) '''Holds the ranges for every variable. Although it is a writable property, care should be taken in changing parameters before ending the convergence.''' # Sanitizes the first estimate. It is not expected that the values # received as first estimates are outside the ranges, but a check is # made anyway. If any estimate is outside the bounds, a new random # vector is choosen. if self.ranges is not None: self.sanity() # Verifies the validity of the fitness method try: issubclass(fitness, Fitness) fitness = fitness() except TypeError: pass if not isinstance(fitness, Fitness): raise TypeError, 'not a valid fitness function' else: self.__fit = fitness self.__fitness = self.__fit(self.__fx) # Verifies the validity of the selection method try: issubclass(selection, Selection) selection = selection() except TypeError: pass if not isinstance(selection, Selection): raise TypeError, 'not a valid selection method' else: self.__select = selection # Verifies the validity of the crossover method try: issubclass(crossover, Crossover) crossover = crossover() except TypeError: pass if not isinstance(crossover, Crossover) and crossover is not None: raise TypeError, 'not a valid crossover method' else: self.__crossover = crossover # Verifies the validity of the mutation method try: issubclass(mutation, Mutation) mutation = mutation() except TypeError: pass if not isinstance(mutation, Mutation) and mutation is not None: raise TypeError, 'not a valid mutation method' else: self.__mutate = mutation
def __init__(self, f, x0, ranges=[], fmt='f', fitness=Fitness, selection=RouletteWheel, crossover=TwoPoint, mutation=BitToBit, elitist=True): ''' Initializes the population and the algorithm. On the initialization of the population, a lot of parameters can be set. Those will deeply affect the results. The parameters are: :Parameters: f A multivariable function to be evaluated. The nature of the parameters in the objective function will depend of the way you want the genetic algorithm to process. It can be a standard function that receives a one-dimensional array of values and computes the value of the function. In this case, the values will be passed as a tuple, instead of an array. This is so that integer, floats and other types of values can be passed and processed. In this case, the values will depend of the format string (see below) If you don't supply a format, your objective function will receive a ``Chromosome`` instance, and it is the responsability of the function to decode the array of bits in any way. Notice that, while it is more flexible, it is certainly more difficult to deal with. Your function should process the bits and compute the return value which, in any case, should be a scalar. Please, note that genetic algorithms maximize functions, so project your objective function accordingly. If you want to minimize a function, return its negated value. x0 A population of first estimates. This is a list, array or tuple of one-dimension arrays, each one corresponding to an estimate of the position of the minimum. The population size of the algorithm will be the same as the number of estimates in this list. Each component of the vectors in this list are one of the variables in the function to be optimized. ranges Since messing with the bits can change substantially the values obtained can diverge a lot from the maximum point. To avoid this, you can specify a range for each of the variables. ``range`` defaults to ``[ ]``, this means that no range checkin will be done. If given, then every variable will be checked. There are two ways to specify the ranges. It might be a tuple of two values, ``(x0, x1)``, where ``x0`` is the start of the interval, and ``x1`` its end. Obviously, ``x0`` should be smaller than ``x1``. If ``range`` is given in this way, then this range will be used for every variable. It can be specified as a list of tuples with the same format as given above. In that case, the list must have one range for every variable specified in the format and the ranges must appear in the same order as there. That is, every variable must have a range associated to it. fmt A ``struct``-format string. The ``struct`` module is a standard Python module that packs and unpacks informations in bits. These are used to inform the algorithm what types of data are to be used. For example, if you are maximizing a function of three real variables, the format should be something like ``"fff"``. Any type supported by the ``struct`` module can be used. The GA will decode the bit array according to this format and send it as is to your fitness function -- your function *must* know what to do with them. Alternatively, the format can be an integer. In that case, the GA will not try to decode the bit sequence. Instead, the bits are passed without modification to the objective function, which must deal with them. Notice that, if this is used this way, the ``ranges`` property (see below) makes no sense, so it is set to ``None``. Also, no sanity checks will be performed. It defaults to `"f"`, that is, a single floating point variable. fitness A fitness method to be applied over the objective function. This parameter must be a ``Fitness`` instance or subclass. It will be applied over the objective function to compute the fitness of every individual in the population. Please, see the documentation on the ``Fitness`` class. selection This specifies the selection method. You can use one given in the ``selection`` sub-module, or you can implement your own. In any case, the ``selection`` parameter must be an instance of ``Selection`` or of a subclass. Please, see the documentation on the ``selection`` module for more information. Defaults to ``RouletteWheel``. If made ``None``, then selection will not be present in the GA. crossover This specifies the crossover method. You can use one given in the ``crossover`` sub-module, or you can implement your own. In any case, the ``crossover`` parameter must be an instance of ``Crossover`` or of a subclass. Please, see the documentation on the ``crossover`` module for more information. Defaults to ``TwoPoint``. If made ``None``, then crossover will not be present in the GA. mutation This specifies the mutation method. You can use one given in the ``mutation`` sub-module, or you can implement your own. In any case, the ``mutation`` parameter must be an instance of ``Mutation`` or of a subclass. Please, see the documentation on the ``mutation`` module for more information. Defaults to ``BitToBit``. If made ``None``, then mutation will not be present in the GA. elitist Defines if the population is elitist or not. An elitist population will never discard the fittest individual when a new generation is computed. Defaults to ``True``. ''' list.__init__(self, []) self.__fx = [] for x in x0: x = array(x).ravel() c = Chromosome(fmt) c.encode(tuple(x)) self.append(c) self.__fx.append(f(x)) self.__f = f self.__csize = self[0].size self.elitist = elitist '''If ``True``, then the population is elitist.''' if type(fmt) == int: self.ranges = None elif ranges is None: self.ranges = zip(amin(self, axis=0), amax(self, axis=1)) else: ranges = list(ranges) if len(ranges) == 1: self.ranges = array(ranges * len(x0[0])) else: self.ranges = array(ranges) '''Holds the ranges for every variable. Although it is a writable property, care should be taken in changing parameters before ending the convergence.''' # Sanitizes the first estimate. It is not expected that the values # received as first estimates are outside the ranges, but a check is # made anyway. If any estimate is outside the bounds, a new random # vector is choosen. if self.ranges is not None: self.sanity() # Verifies the validity of the fitness method try: issubclass(fitness, Fitness) fitness = fitness() except TypeError: pass if not isinstance(fitness, Fitness): raise TypeError, 'not a valid fitness function' else: self.__fit = fitness self.__fitness = self.__fit(self.__fx) # Verifies the validity of the selection method try: issubclass(selection, Selection) selection = selection() except TypeError: pass if not isinstance(selection, Selection): raise TypeError, 'not a valid selection method' else: self.__select = selection # Verifies the validity of the crossover method try: issubclass(crossover, Crossover) crossover = crossover() except TypeError: pass if not isinstance(crossover, Crossover) and crossover is not None: raise TypeError, 'not a valid crossover method' else: self.__crossover = crossover # Verifies the validity of the mutation method try: issubclass(mutation, Mutation) mutation = mutation() except TypeError: pass if not isinstance(mutation, Mutation) and mutation is not None: raise TypeError, 'not a valid mutation method' else: self.__mutate = mutation
## Now we have to sort the globalScheduleMap on value i.e fitness. ## But as a map has no order inherently, it would be a wise decision ## to get a sorted list of tuples of the form [(timeTableSchedule,fitness)], ## where the elements of the list are sorted on the fitness value sortedGlobalScheduleMapList=sorted(globalScheduleMap.iteritems(),key=operator.itemgetter(1),reverse=True) while(sortedGlobalScheduleMapList[0][1]<=requiredFitness): ## Now perform crossover of first numInitialSelectedSchedules pairs of schedules and store them in a list newTimeTablesList=[] for i in range(numInitialSelectedSchedules): newTimeTablesList+=[crossover(sortedGlobalScheduleMapList[2*i][0],sortedGlobalScheduleMapList[2*i+1][0])] ## Perform mutation of the generated Time Tables for i in range(len(newTimeTablesList)): newTimeTablesList[i]=mutate(newTimeTablesList[i]) ## Check if the mutated time tables finess is better than the timetable with least fitness in the sortedGlobalScheduleMapList ## If so replace that time table in the globalScheduleMap with the current map ## else skip the current map for i in range (len(newTimeTablesList)): curFitness=fitness(newTimeTablesList[i]) if curFitness>sortedGlobalScheduleMapList[len(sortedGlobalScheduleMapList)-1][1]): globalScheduleMap.pop(sortedGlobalScheduleMapList[len(sortedGlobalScheduleMapList)-1][0]) globalScheduleMap[newTimeTablesList[i]]=curFitness ## Update the sortedGlobalScheduleMapList as the globalScheduleMap is updated sortedGlobalScheduleMapList=sorted(globalScheduleMap.iteritems(),key=operator.itemgetter(1),reverse=True) print "Timetable Schedule is finalized with required Fitness" print sortedGlobalScheduleMapList[0][0]