def go_rand(iters): berr, bdist = None, None for i in xrange(iters): err, dist = evaluate(instance, random_solution(instance[0]), True) if not berr or (err <= berr and dist <= bdist): berr, bdist = err, dist print berr, bdist
def crossover(self, population, param_c): weighted = [(evaluate(instance, elem), elem) for elem in population] # exponential scaling results = [(math.exp(w / self.T), x) for (w, x) in weighted] min_f = min([w for (w, x) in weighted]) sum_f = 0. for w in weighted: sum_f += w[0] - min_f if sum_f == 0.0: print "Population has 1 unique element" return [] results = [((w-min_f)/sum_f, x) for (w, x) in weighted] roulette = [] s = 0 for w, x in results: s += w roulette.append((s, x)) np = [] while len(np) < self.M: parents = [] while len(parents) < 2: parents.append(self.lower_bound(roulette)) if random.uniform(0, 1) < param_c: c1, c2 = self.pmx(parents[0], parents[1]) else: c1, c2 = parents[0], parents[1] # small probability of no crossover np.append(c1) np.append(c2) return np
def go(self, iters, temp, modif): vect = self.random_perm() best = vect, abs(evaluate(self.instance, vect)) solution, score = best for i in xrange(iters): if temp == 0: break nsolution, nscore = self.get_neighbour(solution) if nscore < best[1]: best = nsolution, nscore if nscore < score or math.exp((score - nscore) / temp) > random.random(): solution, score = nsolution, nscore temp = temp * modif return best[1], evaluate(self.instance, best[0], True)
def go(self, iters, temp, modif): vect = self.random_perm() best = vect, abs(evaluate(self.instance, vect)) solution, score = best for i in xrange(iters): if temp == 0: break nsolution, nscore = self.get_neighbour(solution) if nscore < best[1]: best = nsolution, nscore if nscore < score or math.exp( (score - nscore) / temp) > random.random(): solution, score = nsolution, nscore temp = temp * modif return best[1], evaluate(self.instance, best[0], True)
def get_neighbour(self, solution): ls = len(solution) c1 = c2 = random.randrange(0, ls) excl = [c1, ls - 1 if c1 == 0 else c1 - 1, 0 if c1 == ls - 1 else c1 + 1] while c2 in excl: c2 = random.randrange(0, ls) c1, c2 = min(c1, c2), max(c1, c2) solution = solution[:c1+1] + solution[c2:c1:-1] + solution[c2+1:] return solution, abs(evaluate(self.instance, solution))
def get_neighbour(self, solution): ls = len(solution) c1 = c2 = random.randrange(0, ls) excl = [ c1, ls - 1 if c1 == 0 else c1 - 1, 0 if c1 == ls - 1 else c1 + 1 ] while c2 in excl: c2 = random.randrange(0, ls) c1, c2 = min(c1, c2), max(c1, c2) solution = solution[:c1 + 1] + solution[c2:c1:-1] + solution[c2 + 1:] return solution, abs(evaluate(self.instance, solution))
def go(self, size, iterations, M, param_c, param_m): self.param_m = param_m self.size = size self.M = M self.T = 100000. self.Tn = 0.97 population = self.random_population(size) self.evaluate_population(population) for i in xrange(1, iterations): self.i = i ps = self.crossover(population, param_c) if not ps: break childs = self.mutation(ps, self.param_m) population = self.replacement(population, childs) #print population[0] #print evaluate(self.instance, population[0]) self.evaluate_population(population) print evaluate(instance, self.best[1], True), self.i return self.log, evaluate(instance, self.best[1], True)
def go(self, size, iterations, M, param_c, param_m): self.size = size self.M = M self.T = 10000. self.Tn = 0.95 self.iterations = iterations population = self.random_population(size) self.evaluate_population(population) for i in xrange(1, iterations): self.i = i ps = self.crossover(population, param_c) if not ps: break childs = self.mutation(ps, param_m) population = self.replacement(population, childs) #print population[0] #print evaluate(self.instance, population[0]) self.evaluate_population(population) print evaluate(instance, self.best[1], True), return (self.log, self.log_avg)
def evaluate_population(self, population): weighted = sorted([(evaluate(self.instance, elem), elem) for elem in population]) self.log[0].append(self.i) self.log[1].append(abs(weighted[0][0])) uniq = len(set([w for w, x in weighted])) # prints number of unique elements in population ratio = 1. * uniq / self.size self.param_m = max(0.05, (1. - ratio) / 4.) if not self.best or self.best[0] < weighted[0][0]: #if self.best: #print "improved from %d to %d (iter %d, T=%f)" % (self.best[0], weighted[0][0], self.i, self.T) self.best = weighted[0] self.T = self.T * self.Tn
def evaluate_population(self, population): weighted = sorted([(evaluate(self.instance, elem), elem) for elem in population]) self.log[0].append(self.i) self.log[1].append(abs(weighted[0][0])) uniq = len(set([w for w, x in weighted ])) # prints number of unique elements in population ratio = 1. * uniq / self.size self.param_m = max(0.05, (1. - ratio) / 4.) if not self.best or self.best[0] < weighted[0][0]: #if self.best: #print "improved from %d to %d (iter %d, T=%f)" % (self.best[0], weighted[0][0], self.i, self.T) self.best = weighted[0] self.T = self.T * self.Tn
def crossover(self, population, param_c): weighted = [(evaluate(instance, elem), elem) for elem in population] # exponential scaling results = [(math.exp(w / self.T), x) for (w, x) in weighted] min_f = min([w for (w, x) in weighted]) sum_f = 0. for w in weighted: sum_f += w[0] - min_f if sum_f == 0.0: print "Population has 1 unique element" return [] results = [((w - min_f) / sum_f, x) for (w, x) in weighted] roulette = [] s = 0 for w, x in results: s += w roulette.append((s, x)) np = [] while len(np) < self.M: parents = [] while len(parents) < 2: parents.append(self.lower_bound(roulette)) if random.uniform(0, 1) < param_c: c1, c2 = self.pmx(parents[0], parents[1]) else: c1, c2 = parents[0], parents[ 1] # small probability of no crossover np.append(c1) np.append(c2) return np
def replacement(self, population, childs): l = population + childs weighted = sorted([(evaluate(self.instance, elem), elem) for elem in l]) new_population = weighted[len(childs):] return map((lambda (w, e): e), new_population)
def get_weighted(self, population): return sorted([(evaluate(self.instance, elem), elem) for elem in population])