Example #1
0
    def elitismSelection(self, individuals: List[Chromosome], elitesRatio = 0.1) -> Tuple[List[Chromosome], List[float], bool]:
        """
        This selection method performs elitism, here the nonElites ratio indicates that (by default), 90% of the individuals of
        the population are non-elites, or 10% of the individuals in the new population are elites.

        The algorithm starts by computing the fitness values (as usual) and store the values in tuples(indexToIndividual, fitness),
        it then selects the top X (determined by numOfElites) individuals as elites (preserved) while handing the rest to the selection
        method.
        """
        terminate = False
        retention = 0.8 - elitesRatio #TODO: we should probably encapsulate this in a class such as params
        threshold = 0.001
        numOfElites = math.ceil(elitesRatio * self.popSize)
        # 1. computes the probability (or fitness)
        maxvalue = len(self.testValues)
        aggregatedFitnesses = []
        fitnesses = []
        tuples = []
        total = 0.0
        fitness = -1
        currentIdx = 0
        for ind in individuals:
            #given that we may have couple of entries, we will get the sum of fitness in this case
            fitness = sum(v for v in ind.getProbabilities().values())
            # saves this in the chromosome
            ind.fitness = fitness
            # if the diff between the best fitness and 1.0 is close enough (threshold), we can terminate
            if(maxvalue - fitness < threshold):
                terminate = True
            # saves this in a tuplie within the fitnesses array
            tuples.append((currentIdx, fitness))
            fitnesses.append(fitness)
            #we are creating the aggregated fitness so that when we roll a random number, we just have to compare if it is <= a value in fitnesses[]
            total += fitness
            #creates the range of aggregated fitness for selection later
            aggregatedFitnesses.append(total) 
            #updates the current individual offset
            currentIdx += 1
        #sorts the tuplies
        ranked = sorted(tuples, key=lambda tup:tup[1], reverse=True)

        elites = []
        #keeps the elites
        for i in range(0, numOfElites):
            offset = ranked[i][0]
            elites.append(individuals[offset].getClone())       

        #we want to send of everything for selection
        newPop = Ga.defaultMakeSelection(self.rand, self.popSize, individuals, aggregatedFitnesses, retention = retention)
        return newPop, fitnesses, terminate, elites
Example #2
0
 def rouletteWheelSelection(self, individuals: List[Chromosome], retention = 0.8) -> Tuple[List[Chromosome], List[float], bool]:
     """
     The probabilities from individuals are now based on the cases, to get the total fitness, we will sum all of the tup[1]
     """
     terminate = False
     aggregatedFitnesses = []
     fitnesses = []
     total = 0.0
     fitness = -1
     #computes the aggregated fitness
     for ind in individuals:
         probs = ind.getProbabilities()
         fitness = sum(v for v in probs.values())
         ind.fitness = fitness
         if(not terminate): #terminate should only be set to true if it's false, this prevents overwritting an otherwise true.
             terminate = self.__checkTerminateCondition(ind.fitness)
         #saves in the fitness array
         fitnesses.append(fitness)
         # updates the aggregated fitness
         total += fitness
         aggregatedFitnesses.append(total)
     return Ga.defaultMakeSelection(self.rand, self.popSize, individuals, aggregatedFitnesses, retention = retention), fitnesses, terminate
Example #3
0
def weightedSelectionFunc(
        individuals: List[Chromosome],
        retention=0.8) -> Tuple[List[Chromosome], List[float], bool]:
    """
    This selection method performs roulette wheel selection based on a weighted fitness value:
    prob1 * value of the first binary string + prob2 * value of the 2nd binary string + ...
    """
    terminate = False
    threshold = 0.001
    #computes the probability (fitness)
    aggregatedFitnesses = []
    fitnesses = []
    total = 0.0
    fitness = -1
    maxfitness = 2**registers - 1
    for ind in individuals:
        probabilities = list(ind.getProbabilities().values())
        # we need to iterate through all of the elements in the list and compute the fitness value, given that
        # this is a binary string problem, the values are arranged in 0, 1, 2,..., 2^numRegisters - 1 so it's straightforward
        # to compute this weighted probability
        for idx, prob in enumerate(probabilities):
            if (prob > 0.0):
                fitness += prob * idx
        ind.fitness = fitness
        # we can terminate when the weighted average fitness is >= 2^numRegisters - 1
        if (maxfitness - fitness < threshold):
            terminate = True
        fitnesses.append(fitness)
        total += fitness
        aggregatedFitnesses.append(total)
        fitness = 0.0
    return Ga.defaultMakeSelection(r,
                                   popSize,
                                   individuals,
                                   aggregatedFitnesses,
                                   retention=retention), fitnesses, terminate
Example #4
0
def elitismDefaultSelectionFunc(
    individuals: List[Chromosome],
    elitesRatio=0.1
) -> Tuple[List[Chromosome], List[float], bool, List[Chromosome]]:
    """
    This selection method performs elitism, here the nonElites ratio indicates that (by default), 90% of the individuals of
    the population are non-elites, or 10% of the individuals in the new population are elites.

    The algorithm starts by computing the fitness values (as usual) and store the values in tuples(indexToIndividual, fitness),
    it then selects the top X (determined by numOfElites) individuals as elites (preserved) while handing the rest to the selection
    method.
    """
    terminate = False
    retention = 0.8 - elitesRatio  #TODO: we should probably encapsulate this in a class such as params
    threshold = 0.001
    numOfElites = ceil(elitesRatio * popSize)
    # 1. computes the probability (or fitness)
    maxvalue = 2**registers - 1
    aggregatedFitnesses = []
    fitnesses = []
    tuples = []
    total = 0.0
    fitness = -1
    currentIdx = 0
    for ind in individuals:
        probabilities = list(ind.getProbabilities().values())
        largest = 0
        # gets the prob of the last non 0 prob entry in the list. This is only applicable for the max binary string problem
        # since the largest value is the one with all 1111...
        for i in range(maxvalue, -1, -1):
            if (probabilities[i] > 0.0):
                # i is the corresponding value translate from binary since:
                # for 5 registers: 11111 = 31 and the largest offset is 31 in the array
                largest = i
                break

        # the fitness value is the probability * value (state vector) for the state string that's closest to the max
        # value that can be represented by the qubits. For instance: given a 3 qubit problem, the max value is "111", so
        # if we obtained {000: 0.1, .... 100: 0.5, 101:0, 110:0, 111:0}, the fitness value is going to be int(100) * 0.5.
        fitness = probabilities[largest] * i

        # saves this in the chromosome
        ind.fitness = fitness

        # if the diff between the best fitness and 1.0 is close enough (threshold), we can terminate
        if (maxvalue - fitness < threshold):
            terminate = True

        # saves this in a tuplie within the fitnesses array
        tuples.append((currentIdx, fitness))
        fitnesses.append(fitness)
        #we are creating the aggregated fitness so that when we roll a random number, we just have to compare if it is <= a value in fitnesses[]
        total += fitness
        #creates the range of aggregated fitness for selection later
        aggregatedFitnesses.append(total)
        #updates the current individual offset
        currentIdx += 1

    #sorts the tuplies
    ranked = sorted(tuples, key=lambda tup: tup[1], reverse=True)

    elites = []
    #keeps the elites
    for i in range(0, numOfElites):
        offset = ranked[i][0]
        elites.append(individuals[offset].getClone())

    #we want to send of everything for selection
    newPop = Ga.defaultMakeSelection(r,
                                     popSize,
                                     individuals,
                                     aggregatedFitnesses,
                                     retention=retention)

    return newPop, fitnesses, terminate, elites