示例#1
0
def mutation(n, individual: Individual):
    randx = random.randint(0, n - 3)
    randy = random.randint(0, n - 1)

    # deepcopy para evitar cambiar las referencias al original
    auxInd = deepcopy(individual)
    auxValue = abs(individual.getIndividual()[randx][randy]) - 1
    auxInd.individual[randx][randy] = auxValue

    return auxInd
示例#2
0
def generateNeighbourhood(n, individual: Individual, refFitness):

    Neighbourhood = list()
    eval = (-math.inf, -math.inf)
    index = None

    for i in range(len(individual.getIndividual())):
        for j in range(len(individual.getIndividual()[i])):

            #deepcopy para evitar cambiar las referencias al original
            auxInd = deepcopy(individual)  #Copiamos el original
            auxValue = abs(individual.getIndividual()[i]
                           [j]) - 1  #Cambiamos el valor que genera un vecino
            auxInd.individual[i][
                j] = auxValue  #Guadamos el cambio en el vecino

            #Añadimos el vecino
            Neighbourhood.append(auxInd)  #Añadimos el vecino a la lista

            #Conforme calculamos los vecinos, los vamos evaluando
            auxeval = None
            auxeval = fitness(n, auxInd.getIndividual())  #Evaluamos el vecino
            ''' SE PUEDE COMENTAR PARA QUITAR ESTA CONDICION'''
            #Si el individuo generado tiene mejor coste que refFitness, lo devolvemos, no seguimos
            if auxeval[1] > refFitness[1]:
                eval = auxeval
                index = (i *
                         n) + j  #para calcular el indice del mejor individuo
                return (Neighbourhood, index, eval)
            ''''''

            if auxeval[1] > eval[1]:
                eval = auxeval
                index = (i *
                         n) + j  #para calcular el indice del mejor individuo
            elif auxeval[1] == eval[1] and auxeval[0] > auxeval[0]:
                eval = auxeval
                index = (i * n) + j

    #Si ninguna configuración tiene solución, como eval es -inf, se devolverá la primera encontrada,
    # y se buscará otra configuración en le algoritmo alterando el individuo evaluado
    return (Neighbourhood, index, eval)
示例#3
0
def generatePopulation(n, popSize):
    '''
    n           tamaño de problema
    popSize     tamaño de la población
    '''

    population = list()
    for i in range(popSize):
        population.append(Individual(n, None))

    return population
示例#4
0
def crossover1(parent1: Individual, parent2: Individual):
    # Creamos los dos individuos Hijo
    c1 = [[int for _ in range(len(parent1.getIndividual()[0]))]
          for _ in range(len(parent1.getIndividual()))]
    c2 = [[int for _ in range(len(parent1.getIndividual()[0]))]
          for _ in range(len(parent1.getIndividual()))]

    #Tamaño del individuo
    indSize = len(parent1.getIndividual()) * len(parent1.getIndividual()[0])

    #Máscara:
    mask = [[random.randint(0, 1) for _ in range(indSize)]
            for _ in range(indSize - 2)]

    # Cruce
    for i in range(len(parent1.getIndividual())):
        for j in range(len(parent1.getIndividual()[0])):
            if (mask[i][j]):
                c1[i][j] = parent2.getIndividual()[i][j]
                c2[i][j] = parent1.getIndividual()[i][j]
            else:
                c1[i][j] = parent1.getIndividual()[i][j]
                c2[i][j] = parent2.getIndividual()[i][j]

    c1 = Individual(None, c1)
    c2 = Individual(None, c2)

    return c1, c2
示例#5
0
def crossover2(parent1: Individual, parent2: Individual):
    # Creamos los dos individuos Hijo
    c1 = [[int for _ in range(len(parent1.getIndividual()[0]))]
          for _ in range(len(parent1.getIndividual()))]
    c2 = [[int for _ in range(len(parent1.getIndividual()[0]))]
          for _ in range(len(parent1.getIndividual()))]

    #Tamaño del individuo
    indSize = len(parent1.getIndividual()) * len(parent1.getIndividual()[0])

    #Obtener punto de cruce

    crossoverPoint = random.randint(0, indSize - 1)

    # Cruce
    for i in range(len(parent1.getIndividual())):
        for j in range(len(parent1.getIndividual()[0])):
            if (i * len(parent1.getIndividual()[0]) + j > crossoverPoint):
                c1[i][j] = parent2.getIndividual()[i][j]
                c2[i][j] = parent1.getIndividual()[i][j]
            else:
                c1[i][j] = parent1.getIndividual()[i][j]
                c2[i][j] = parent2.getIndividual()[i][j]

    c1 = Individual(None, c1)
    c2 = Individual(None, c2)

    return c1, c2
示例#6
0
def crossover3(parent1: Individual, parent2: Individual):
    #Creamos los dos individuos Hijo
    c1 = [[int for _ in range(len(parent1.getIndividual()[0]))]
          for _ in range(len(parent1.getIndividual()))]
    c2 = [[int for _ in range(len(parent1.getIndividual()[0]))]
          for _ in range(len(parent1.getIndividual()))]

    #Tamaño de un individuo
    indSize = len(parent1.getIndividual()) * len(parent1.getIndividual()[0])

    #Obtener los puntos de cruce
    crossoverPoints = list()
    crossoverPoints.append(random.randint(0, indSize - 1))
    x = None
    while (x == crossoverPoints[0] or x == None):
        x = random.randint(0, indSize - 1)
    crossoverPoints.append(x)
    crossoverPoints.sort()

    #Cruce
    for i in range(len(parent1.getIndividual())):
        for j in range(len(parent1.getIndividual()[0])):
            if (i * len(parent1.getIndividual()[0]) + j >= crossoverPoints[0]):
                if (i * len(parent1.getIndividual()[0]) + j <=
                        crossoverPoints[1]):
                    c1[i][j] = parent2.getIndividual()[i][j]
                    c2[i][j] = parent1.getIndividual()[i][j]
                else:
                    c1[i][j] = parent1.getIndividual()[i][j]
                    c2[i][j] = parent2.getIndividual()[i][j]
            else:
                c1[i][j] = parent1.getIndividual()[i][j]
                c2[i][j] = parent2.getIndividual()[i][j]

    c1 = Individual(None, c1)
    c2 = Individual(None, c2)

    return c1, c2
示例#7
0
def HillClimbing(n, seed, it):
    '''
    n:     tamaño del problema
    seed:  semilla aleatoria
    it:     número de iteraciones
    '''

    random.seed(seed)

    #El mejor individuo encontrado
    bestIndividual = None
    bestFitness = (-math.inf, -math.inf)

    #Inicializamos otras variables necesarias
    iteration = 0
    bestNeighbIndex = None
    actualFitness = None

    #Generamos una configuración aleatoria de muros
    actualIndividual = Individual(n, None)
    actualFitness = fitness(n, actualIndividual.getIndividual())
    print("Individuo inicial: ")
    actualIndividual.__str__()

    #Iteramos
    while iteration < it:

        #Introducimos no determinismo, generando individuos aleatorios con probabilidad 0.x (variable)
        if (random.random() < 0.2):
            #print("Aleatorio")

            bestNeighb = Individual(n, None)
            randomNeighbFit = fitness(n, bestNeighb.getIndividual())
            newFitness = randomNeighbFit

        else:
            #Generamos los vecinos (solo hasta que encontremos el mejor,
            # o todos si no hay ninguno mejor que el actual)
            result = generateNeighbourhood(n, actualIndividual, actualFitness)
            neighbourhood = result[0]  #Vecinos
            bestNeighbIndex = result[1]  #El mejor encontrado
            bestNeighb = neighbourhood[bestNeighbIndex]
            newFitness = result[2]  #Fitness del mejor encontrado

            #Si no obtenemos solución de los vecinos, alteramos el actual
            if bestNeighbIndex == None:
                print("Sin solucion en el vecindario")
                actualIndividual = mutation(n, bestIndividual)

        #print("IT: " + iteration.__str__() + " ACTUAL [N.Exp: " + actualFitness[0].__str__() + ", Coste: " + actualFitness[1].__str__() + "] [N.Exp: " + newFitness[0].__str__() + ", Coste: " + newFitness[1].__str__() + "]")

        iteration += 1

        if (newFitness[1] > actualFitness[1]
                or (newFitness[1] == actualFitness[1]
                    and newFitness[0] > actualFitness[0])):
            actualIndividual = bestNeighb
            actualFitness = newFitness  #De esta manera no tenemos que reevaluar el fitness del actual, solamente si lo alteramos abajo

        elif (
                newFitness[1] != -1
                or (newFitness[1] == -1 and actualFitness[1] == -1)
        ):  #APLICAMOS ILS, PERO SIN TENER EN CUENTA INDIVIDUOS SIN SOLUCIÓN ALEATORIOS
            #print("Alteración individuo")   #Alteramos el mejor individuo en vez de el actual
            actualIndividual = mutation(n, actualIndividual)
            actualFitness = fitness(n, actualIndividual.getIndividual())

        #Actualizamos el mejor individuo hasta ahora
        if (actualFitness[1] > bestFitness[1]):
            bestFitness = actualFitness
            bestIndividual = actualIndividual
            print("IT: " + iteration.__str__() + ", Mejor Solución [N.Exp: " +
                  bestFitness[0].__str__() + ", Coste: " +
                  bestFitness[1].__str__() + "]")

    print("Mejor Individuo: ")
    bestIndividual.__str__()
    print("Nodos Expandidos: " + bestFitness[0].__str__() +
          " Coste de la solución: " + bestFitness[1].__str__())
    return bestFitness