def nextGeneration(self): for i in range(0, self.groupSize): index = numpy.random.randint(0, self.populationSize - 1) self.crossoverIndices[i] = index self.crossoverGroupTourLengths[i] = self.entirePopulationLengths[index] self.crossoverGroup[i] = self.entirePopulation[index] self.sortCrossoverGroup() parentSelect = self.determineParents() children = crossover(self.tsp, self.crossoverGroup[parentSelect[0]], self.crossoverGroup[parentSelect[1]]) child1Index = self.crossoverIndices[self.groupSize - 2] child2Index = self.crossoverIndices[self.groupSize - 1] #set the lowest two tours to the crossovered children self.entirePopulation[child1Index] = children[0] self.entirePopulation[child2Index] = children[1] #attempt to mutate the children self.entirePopulation[child1Index] = self.mutate(self.entirePopulation[child1Index], self.mutationRate) self.entirePopulation[child2Index] = self.mutate(self.entirePopulation[child2Index], self.mutationRate) #update the distance of the children child1Cost = calculateCost(self.entirePopulation[child1Index], self.tsp) child2Cost = calculateCost(self.entirePopulation[child2Index], self.tsp) self.entirePopulationLengths[child1Index] = child1Cost self.entirePopulationLengths[child2Index] = child2Cost self.updateDistance(child1Index, child1Cost) self.updateDistance(child2Index, child2Cost)
def bestSolutionInPair(tsp, pair): firstSolutionCost = calculateCost(pair[0], tsp) secondSolutionCost = calculateCost(pair[1], tsp) if firstSolutionCost < secondSolutionCost: return pair[0], firstSolutionCost else: return pair[1], secondSolutionCost
def averageRatioGreedySolution(tsp, randomSolutions, greedySolutions): sum = 0 count = 0 for randomSolution in randomSolutions: randomCost = calculateCost(randomSolution, tsp) for greedySolution in greedySolutions: greedyCost = calculateCost(greedySolution, tsp) sum += greedyCost/randomCost count += len(greedySolutions) return sum/count
def greedySolutionQuality(tsp, randomSolutions, greedySolutions): sum = 0 count = 0 for randomSolution in randomSolutions: randomCost = calculateCost(randomSolution, tsp) for greedySolution in greedySolutions: greedyCost = calculateCost(greedySolution, tsp) if greedyCost < randomCost: sum += 1 count += len(greedySolutions) return sum/count
def constructGreedySolution(tsp, perm, alpha): candidate = {} # Seleciona um ponto da lista aleatoriamente problemSize = perm.shape[0] candidate["permutation"] = numpy.zeros(problemSize, dtype=numpy.int) candidate["permutation"][0] = perm[random.randrange(0, problemSize)] # Enquanto o tamanho do candidato não for igual ao tamanho da permutação for i in range(1, problemSize - 1): # Pega todos os pontos, exceto os já presentes na solução candidata candidates = [item for item in perm if item not in candidate["permutation"]] # Calcula o custo de adicionar uma característica à solução # A 'feature' ou característica é definida por quão longe os outros pontos estão do último elemento da lista de candidatos costs = [] for item in candidates: costs.append(tsp.getCost(i - 1, item)) # Determina o menor e o maior custo do determinado set rcl, maxCost, minCost = [], max(costs), min(costs) # Construimos o RCL da seguinte maneira: # Adicionamos o que for menor ou igual ao mínimo + o custo da característica pela fórmula da RCL # Quanto menor a distância aqui, menor o custo final do algoritmo # Custo de cada Feature: for index, cost in enumerate(costs): # Para conseguir o index e o item enquanto faz o loop # IF Fcurrent <= Fmin + alpha * (Fmax-Fmin) THEN if (cost <= minCost + alpha * (maxCost - minCost)): # Adiciona ao RCL rcl.append(candidates[index]) # Seleciona feature aleatório do RCL e adiciona à solução candidate["permutation"][i] = rcl[random.randrange(0, len(rcl))] # Calcula o custo final antes de retornar a solução candidata candidate["cost"] = calculateCost(candidate["permutation"], tsp) return candidate
def averageTimesOffspringBetterSolution(tsp, parentSolutionPairs, childSolutionPairs): sum = 0 for i in range(len(parentSolutionPairs)): parentPair = parentSolutionPairs[i] childPair = childSolutionPairs[i] for j in range(2): childCost = calculateCost(childPair[j], tsp) for k in range(2): parentCost = calculateCost(parentPair[k], tsp) if childCost < parentCost: sum += 1 return sum/(len(parentSolutionPairs) * 4)
def randomNeighborSolutionQuality(tsp, randomSolutions, randomNeighborSolutions): sum = 0 count = 0 for i in range(len(randomSolutions)): randomSolution = randomSolutions[i] randomCost = calculateCost(randomSolution, tsp) neighbors = randomNeighborSolutions[i] for j in range(len(neighbors)): neighborCost = calculateCost(neighbors[j], tsp) if neighborCost < randomCost: sum += 1 count += len(neighbors) return sum/count
def search(tsp, maxNoImprove, maxTabu, maxCandidates, timeLimit, updateLambda=None): start = time.time() t_end = start + timeLimit # construct a random tour best = {} best["permutation"] = generateInitialSolution(tsp) best["cost"] = calculateCost(best["permutation"], tsp) tabuList = set() totalIterations = 0 if updateLambda: updateLambda(0, 0, 1, 1, start, maxNoImprove) iterNoImprove = 0 while iterNoImprove < maxNoImprove and time.time() < t_end: # Generates queries using the local search 2-opt algorithm # stochastically, near the best candidate of this iteration. # Uses the tabu list not to visit vertices more than once candidates = [] for index in range(0, maxCandidates): innerLambda = None candidates.append(generateCandidates(best, tabuList, tsp, t_end)) totalIterations += 1 updateLambda(totalIterations, best["cost"], 1, 1, start, maxNoImprove) # Find the best candidate # sorts the list of candidates by cost bestCandidate, bestCandidateEdges = locateBestCandidate(candidates) # compares with the best candidate and updates it if necessary if bestCandidate["cost"] < best["cost"]: iterNoImprove = 0 # defines the current candidate as the best best = bestCandidate # Update the taboo list for edge in bestCandidateEdges: if len(tabuList) < maxTabu: tabuList.add(edge) else: iterNoImprove += 1 totalIterations += 1 if updateLambda: updateLambda(totalIterations, best["cost"], 1, 1, start, maxNoImprove) return best["permutation"]
def bestSolution(tsp, solutions): bestSolution = None minCost = sys.maxsize for i in range(len(solutions)): cost = calculateCost(solutions[i], tsp) if cost < minCost: minCost = cost bestSolution = solutions[i] return bestSolution, minCost
def averageRatioNeighborsWithBetterSolution(tsp, randomSolutions, randomNeighborSolutions): sum = 0.0 for i in range(len(randomSolutions)): randomSolution = randomSolutions[i] randomCost = calculateCost(randomSolution, tsp) neighbors = randomNeighborSolutions[i] _, neighborCost = bestSolution(tsp, neighbors) sum += neighborCost/randomCost return sum/len(randomSolutions)
def proportionsNeighborsWithBetterSolution(tsp, randomSolutions, randomNeighborSolutions): sum = 0 for i in range(len(randomSolutions)): randomSolution = randomSolutions[i] randomCost = calculateCost(randomSolution, tsp) neighbors = randomNeighborSolutions[i] _, neighborCost = bestSolution(tsp, neighbors) if neighborCost < randomCost: sum += 1 return sum/len(randomSolutions)
def generateCandidates(best, tabuList, tsp, timeLimit): permutation, edges, result = [], None, {} while len(permutation) < 1 or isTabu(best["permutation"], tabuList, timeLimit): permutation, edges = stochasticTwoOptWithEdges(best["permutation"]) candidate = {} candidate["permutation"] = permutation candidate["cost"] = calculateCost(candidate["permutation"], tsp) result["candidate"] = candidate result["edges"] = edges return result
def localSearch(tsp, best, maxIter, timeLimit, updateLambda = None): count = 0 totalIterations = 0 while count < maxIter and time.time() < timeLimit: candidate = {} candidate["permutation"] = stochasticTwoOpt(best["permutation"]) candidate["cost"] = calculateCost(candidate["permutation"], tsp) totalIterations += 1 if candidate["cost"] < best["cost"]: best, count = candidate, 0 if updateLambda: updateLambda(totalIterations, best["cost"], 1, 1) else: count += 1 return best, totalIterations
def __init__(self, tsp, mutationRate, populationSize): self.tsp = tsp # Defaults to 10 self.mutationRate = mutationRate # Defaults to 800 self.populationSize = populationSize #s/b 100,000 self.groupSize = 10 #must be >= 5 self.entirePopulation = numpy.empty((self.populationSize, self.tsp.getSize()), dtype = int) self.entirePopulationLengths = numpy.empty(self.populationSize) self.minDistance = None self.minIndex = None self.crossoverGroup = numpy.empty((self.groupSize, self.tsp.getSize()), dtype = int) self.crossoverIndices = numpy.empty(self.groupSize, dtype = int) self.crossoverGroupTourLengths = numpy.empty(self.groupSize) for i in range(0, self.populationSize): tour = generateInitialSolution(tsp) self.entirePopulation[i] = tour self.entirePopulationLengths[i] = calculateCost(tour, self.tsp)
def energy(self): """Calculates the length of the route.""" return calculateCost(self.state, self.tsp)