Пример #1
0
def mejorVecino(posicionPG, sol, numVecinos, porcModificacion,
                datos):  #,modificar):
    c = 0  #contador de vecinos
    bound = datos["bounds"]

    size = len(posicionPG)
    porcModificacion = porcModificacion / 100.0
    n = size * porcModificacion  #numero de cambios a cada vecino dependiendo del tamanio de la solucion
    n = int(n)

    ff = evaluar(sol, datos)
    fmin = ff
    smin = copy.copy(sol)

    for c in range(numVecinos):
        d = 0  #contador de cambios en cada vecino
        s1 = copy.copy(sol)
        while (d < n):
            x = random.randrange(size)  #numero de dato
            ndato = posicionPG[x]

            if isinstance(s1[ndato], list):
                sdato = random.sample(bound[ndato], len(bound[ndato]))
            else:
                sdato = random.choice(bound[ndato])
            s1[ndato] = sdato
            d = d + 1
        ff1 = evaluar(s1, datos)
        if (c == 0 or ff1 < fmin):
            fmin = ff1
            smin = copy.copy(s1)
        c = c + 1
    return fmin, smin
def descensoColinaSimple(sol, datos, posProblema, iteraciones, porcentaje):
    bound = datos["bounds"]
    fact = evaluar(sol, datos)
    i = 0
    s1 = copy.copy(sol)
    sol2 = s1
    n = len(posProblema)
    n = porcentaje * n
    n = int(n)

    while i < iteraciones:
        d = 0
        while (d < n):
            ndato = posProblema[random.randrange(len(posProblema))]
            #Se van a modificar los dias
            if isinstance(s1[ndato], list):
                sdato = random.sample(bound[ndato], len(bound[ndato]))
            else:
                sdato = random.choice(bound[ndato])
            s1[ndato] = sdato

            d = d + 1
        if evaluar(s1, datos) < fact:
            sol2 = s1
            i = iteraciones
        i = i + 1
    return sol2
Пример #3
0
def algoritmoGenetico(datos, numGeneraciones, tamPoblacion, Pcruza,
                      probabilidadMutacion, porMutacion, porSeleccion):
    t1 = time()
    #GENERAR POBLACION INICIAL
    listaPoblacion = generaPoblacion(tamPoblacion, datos)
    sMax = evaluar(minimoP(listaPoblacion, datos),
                   datos)  # factibilidad mínima inicial
    contador = 0

    #Para romper ciclo en caso de estancamiento
    #out = 0
    #cambiosMinimos = 0
    #cambiosGeneraciones = 0
    #rangoCambios = 50 #(rango mínimo de cambios), si no se cumple se sale del ciclo. Entra cuando hay tres cambios positivos o negativos
    #anterior = 0
    #GENERACIONES
    while (contador <
           numGeneraciones):  # and cambiosMinimos != 1 and out < 3):

        #Seleccion (por Torneo)
        listaPadres = generaPadres(porSeleccion, tamPoblacion, listaPoblacion,
                                   datos)

        #Cruzamiento
        #N puntos Lineal (al azar)
        listaPoblacion = cruzarHijos(Pcruza, listaPadres, datos)

        #Mutacion
        listaNueva = []
        for elem in listaPoblacion:
            listaNueva.append(
                mutar(probabilidadMutacion, porMutacion, elem, datos))

        listaPoblacion = listaNueva
        fact = evaluar(minimoP(listaPoblacion, datos), datos)
        print "factibilidad: ", fact, " iteración: ", contador

        #VERIFICAR que no haya estancamiento en el algoritmo
        #if contador > 0:
        #    cambiosGeneraciones = cambiosGeneraciones + abs(anterior - fact) #Ir sumando los cambios de 5 generaciones
        #    if contador % 5 == 0:#Hacerlo cada ciertas iteraciones (cada 5 generaciones)
        #        if cambiosGeneraciones != 0:
        #            if abs(cambiosGeneraciones) < rangoCambios: # Si no hay mucho cambio en 5 generaciones salirse del ciclo porque ya no tiene caso buscar mas soluciones
        #                cambiosMinimos = 1
        #            cambiosGeneraciones = 0 # Se reinicia el contador para volver a calcular otras 5 generaciones
        #            out = 0
        #        else:
        #            out = out+1 #es igual a 5 ciclos que no tienen cambios
        #anterior = fact
        contador = contador + 1
    listMinimo = minimoP(listaPoblacion, datos)

    t2 = time()
    tiempo = t2 - t1
    return tiempo, evaluar(listMinimo,
                           datos), listMinimo, sMax  #[tiempo,final,listMinimo]
def poblacionInicial(n, datos):
    contador = 0
    solBest, datosFijosBest, datosPrioritariosBest = solucion(datos)
    while contador < n - 1:
        sBest, datosFIJOS, datosPRIORITARIOS = solucion(datos)
        if evaluar(sBest, datos) < evaluar(solBest, datos):
            solBest = sBest
            datosFijosBest = datosFIJOS
            datosPrioritariosBest = datosPRIORITARIOS
        contador = contador + 1
    return solBest, datosFijosBest, datosPrioritariosBest
Пример #5
0
def busquedaTabu(datos,iteraciones,tamMemoria,vecinos,porcMod):
    t1 = time()                     #Para contabilizar el tiempo
    sol     = solucion(datos)       #Solución inicial S0
    tempS = evaluar(sol,datos)      #Factibilidad de la solución inicial
    c    = 0                        #Contador de iteraciones
    sBest = sol                     #Se asigna como sBest a la solución inicial
    #PARA Verificar si no hay cambios y romper el ciclo tabú
    #cambiosCiclos = 0
    #anterior = 0
    #out  = 15 # parametro para verificar cada ciertas iteraciones si ya se estanco el algoritmo en una solucion
    #noHayCambios = 0

    tabuList = []
    while (c <= iteraciones): #and noHayCambios != 1):
        candidateList = []
        sVecinos = SNeighborhood(sol,vecinos,porcMod,datos)
        for sCand in sVecinos:
            if sCand not in tabuList:
                candidateList.append(sCand)
        sCandidate = mejorCandidato(candidateList,datos)
        sol = sCandidate
        if (evaluar(sCandidate,datos) < evaluar(sBest,datos)):
            tabuList.append(sCandidate)
            sBest = sCandidate
            if len(tabuList) > tamMemoria:
                fin = len(tabuList)
                inicio = fin-tamMemoria
                tabuList = tabuList[inicio:fin]
        fact = evaluar(sBest,datos)
        print "factibilidad: ",fact, " iteración: ",c

# Salirse si no hay cambios en un determinado número de iteraciones         
#        if c > 0:
#            cambiosCiclos = cambiosCiclos + abs(anterior - fact) #Ir sumando los cambios de 5 generaciones
#            if c % out == 0:#Hacerlo cada ciertas iteraciones (cada 15 )
#                if cambiosCiclos != 0:
#                    if abs(cambiosCiclos) == 0: # Si no hay mucho cambio en 5 generaciones salirse del ciclo porque ya no tiene caso buscar mas soluciones
#                        noHayCambios = 1
#                    cambiosCiclos = 0 # Se reinicia el contador para volver a calcular otras 5 generaciones
#        anterior = fact

        c = c+1
    t2 = time()
    tiempo = t2 - t1
    return tiempo,fact,sBest,tempS
    
#################################################################################
#############################################################################################    
Пример #6
0
def busquedaArmonica(datos, iteraciones, HMS, HMCR, BW, PAR):
    t1 = time()
    HM = generaPoblacion(HMS, datos)
    tempS = evaluar(minimoP(HM, datos), datos)
    c = 0  # contador de iteraciones

    #Para romper ciclo en caso de estancamiento
    #noHayCambios = 0
    #anterior = 0
    #cambiosCiclos = 0
    #out  = 15 # parametro para decidir si ya se estanco el algoritmo en una solucion

    while (c <= iteraciones):  # and noHayCambios != 1):
        obtenerMemoria = random.random()
        if (obtenerMemoria < (HMCR / 100.00)):
            elem = getRandomHM(HM)
            #modificar la armonía en un porcentaje
            copia = elem[:]
            modificar(PAR, BW, copia, datos)
        else:
            copia = solucion(datos)
        #ESCOJER LA PEOR DE LA MEMORIA ARMÓNICA PARA SUSTITUIRLA CON EL NUEVO SI ES MEJOR
        [indice, maximo] = peorS(HM, datos)
        nuevo = evaluar(copia, datos)
        if nuevo < maximo:
            HM[indice] = copia

        vecMin = minimoP(HM, datos)
        fact = evaluar(vecMin, datos)
        print "fact: ", fact, " iteración: ", c

        #VERIFICAR que no haya estancamiento en el algoritmo
        #if c > 0:
        #    cambiosCiclos = cambiosCiclos + abs(anterior - fact) #Ir sumando los cambios de 5 generaciones
        #    if c % out == 0:#Hacerlo cada ciertas iteraciones (cada 15 )
        #        if cambiosCiclos != 0:
        #            if abs(cambiosCiclos) == 0: # Si no hay mucho cambio en 5 generaciones salirse del ciclo porque ya no tiene caso buscar mas soluciones
        #                noHayCambios = 1
        #            cambiosCiclos = 0 # Se reinicia el contador para volver a calcular otras 5 generaciones
        #anterior = fact
        c = c + 1

    t2 = time()
    tiempo = t2 - t1
    return tiempo, fact, vecMin, tempS
def peorS(lista, datos):
    maxLista = []
    for i in range(len(lista)):
        maxLista.append(evaluar(lista[i], datos))
    maximo = max(maxLista)
    for i in range(len(lista)):
        if (maxLista[i] == maximo):
            indice = i
    return [indice, maximo]
def minimoP(lista, datos):
    minLista = []
    for i in range(len(lista)):
        minLista.append(evaluar(lista[i], datos))
    minimo = min(minLista)
    for i in range(len(lista)):
        if (minLista[i] == minimo):
            indice = i
    return lista[indice]
Пример #9
0
def mejorVecino(solucion, numVecinos, porcModificacion, datos): 
    c = 0             #contador de vecinos
    bound = datos["bounds"]
    mBound = datos["metabounds"]

    size = len(bound)
    n = size*porcModificacion    #numero de cambios a cada vecino dependiendo del tamanio de la solucion
    ff= evaluar(solucion, datos)
    fmin = ff
    smin = copy.copy(solucion)
    posiciones = posicion(mBound)
    for c in range(numVecinos):
        d = 0 #contador de cambios en cada vecino
        s1=copy.copy(solucion)
        while (d <= n):
            d = d + 1
            ndato = random.randrange(size) #numero de dato
            pos = busquedaBin(posiciones.values(),ndato) 
            lenlgs = len(mBound[pos]["lgs"])
            lgs = mBound[pos]["lgs"]
            
            sdato = random.choice(bound[posiciones[pos]]) #Se escoge el espacio t de manera aleatoria.
            s1[posiciones[pos]] = sdato
            
            if mBound[pos]["gpid"]:
                sdato = random.choice(bound[posiciones[pos]+1]) #Se escoge el espacio practica de manera aleatoria.                
                s1[posiciones[pos]+1]
            for j in range(lenlgs):
                if(lgs[j]["hidx"] != -1):
                    sdato = random.choice(bound[posiciones[pos]+lgs[j]["hidx"]]) #Se escoge la hora de manera aleatoria.
                    s1[posiciones[pos]+lgs[j]["hidx"]] = sdato
            
                if(lgs[j]["pidx"] != -1):
                    p = bound[posiciones[pos]+lgs[j]["pidx"]]
                    sdato = random.sample(p,len(p))
                    s1[posiciones[pos]+lgs[j]["pidx"]] = sdato
        ff1 = evaluar(s1,datos)
        if (c == 0 or ff1 < fmin):
            fmin = ff1
            smin = copy.copy(s1)
        c = c + 1
    return fmin,smin
Пример #10
0
def recocidoSimulado(datos,iteraciones,tempI,tempMin,vecinos,cambiosPorc,reduccion):
    # PARAMETROS
    t1 = time()			
    e = 2.7182818284            #numero de Euler
    sol     = solucion(datos)   #Solución inicial S0
    S     = evaluar(sol,datos)  #factibilidad de la solucion inicial
    c    = 0                    #contador de iteraciones
    tempS = S                   #para retornar la factibilidad de la solución inicial
    #PARA romper ciclo cuando se repitan valores en cierta cantidad de iteraciones
    #out  = 15                   # parametro para verificar cada ciertas iteraciones si ya se estanco el algoritmo en una solucion
    #cambiosCiclos = 0
    #anterior = 0
    #noHayCambios = 0
    
    while (c <= iteraciones and tempI >= tempMin):# and noHayCambios != 1):
        Sprima,solAux = mejorVecino(sol,vecinos,cambiosPorc, datos)
        delta = Sprima-S   
        if (delta <= 0):
            S = Sprima
            sol = solAux
        else:
             exp      = -delta/tempI
             n     = e**exp
             a   = random.uniform(0,1)
             if(a <= n):
                 S = Sprima
                 sol = solAux
        tempI   = tempI*reduccion

        print "factibilidad: ",S, " iteración: ",c

#PARA verificar que no se quede estancado el algoritmo y romper el ciclo
#        if c > 0:
#            cambiosCiclos = cambiosCiclos + abs(anterior - S) #Ir sumando los cambios de 5 generaciones
#            if c % out == 0:#Hacerlo cada ciertas iteraciones (cada 15 )
#                if cambiosCiclos != 0:
#                    if abs(cambiosCiclos) == 0: # Si no hay mucho cambio en 5 generaciones salirse del ciclo porque ya no tiene caso buscar mas soluciones
#                        noHayCambios = 1
#                    cambiosCiclos = 0 # Se reinicia el contador para volver a calcular otras 5 generaciones
#        anterior = S
        c   = c + 1
        
    t2 = time()
    tiempo = t2 - t1
    return tiempo,S,sol,tempS
def mejorCandidato(lista, datos):
    fEvalAux = 0
    solAux = []
    c = 0
    best = []
    for sol in lista:
        fEval = evaluar(sol, datos)
        if (c < 1):
            fEvalAux = fEval
            solAux = sol
        else:
            if fEvalAux > fEval:
                best = sol
                fEvalAux = fEval
                solAux = best
            else:
                best = solAux
        c = c + 1
    return best
def busquedaArmonica(sol, datos, posicion, iteraciones, HMS, HMCR, BW, PAR):
    HM = generaPoblacion(HMS, sol)
    #HM.append(sol)

    #out  = 15 # parametro para decidir si ya se estancó el algoritmo en una solucion
    c = 0  # contador de iteraciones
    #noHayCambios = 0
    #anterior = 0
    #cambiosCiclos = 0
    while (c <= iteraciones):  # and noHayCambios != 1):
        obtenerMemoria = random.random()
        if (obtenerMemoria < (HMCR / 100.00)):
            elem = getRandomHM(HM)
            #modificar la armonía en un porcentaje
            copia = elem[:]
            modificar(PAR, BW, copia, datos, posicion)
        else:
            copia = solucion(datos)
        #ESCOJER LA PEOR DE LA MEMORIA ARMÓNICA PARA SUSTITUIRLA CON EL NUEVO SI ES MEJOR
        [indice, maximo] = peorS(HM, datos)
        nuevo = evaluar(copia, datos)
        if nuevo < maximo:
            HM[indice] = copia

        vecMin = minimoP(HM, datos)

        #PARA romper ciclo en caso de que se quede estancado
        #fact = evaluar(vecMin,datos)
        #if c > 0:
        #    cambiosCiclos = cambiosCiclos + abs(anterior - fact) #Ir sumando los cambios de 5 generaciones
        #    if c % out == 0:#Hacerlo cada ciertas iteraciones (cada 15 )
        #        if cambiosCiclos != 0:
        #            if abs(cambiosCiclos) == 0: # Si no hay mucho cambio en 5 generaciones salirse del ciclo porque ya no tiene caso buscar mas soluciones
        #                noHayCambios = 1
        #            cambiosCiclos = 0 # Se reinicia el contador para volver a calcular otras 5 generaciones
        #anterior = fact
        c = c + 1

    return vecMin
Пример #13
0
def recocidoSimulado(sol, posicion, datos, iteraciones, tempI, tempMin,
                     vecinos, cambiosPorc, reduccion):

    S = evaluar(sol, datos)  #factibilidad de la solucion inicial
    c = 0  # contador de iteraciones
    contadorPositivo = 0
    while (c <= iteraciones and tempI >= tempMin):  # and noHayCambios != 1):
        Sprima, solAux = mejorVecino(posicion, sol, vecinos, cambiosPorc,
                                     datos)
        delta = Sprima - S
        if (delta <= 0):
            S = Sprima
            sol = solAux
            contadorPositivo = 0
        else:
            n = math.exp(-delta / tempI)
            a = random.random()
            contadorPositivo = contadorPositivo + 1
            if (a <= n):
                S = Sprima
                sol = solAux
        tempI = tempI * reduccion
        c = c + 1
    return sol
def hiperheuristica(datos, iteraciones, tamMemoria, vecinos, porcMod):
    t1 = time()
    #Se puede iniciar con la mejor solucion de 100 elementos aleatorios
    sBest, datosFIJOS, datosPRIORITARIOS = poblacionInicial(
        100, datos)  #Solución inicial S0
    #se puede iniciar con un solo elemento aleatorio
    #sBest,datosFIJOS,datosPRIORITARIOS = solucion(datos) #Solución inicial S0

    #sFinal = sBest                          #la solución incial
    datosPrioritarios = 0  #para ir contabilizando los datos prioritarios restantes
    #evalúa las colisiones de cada restricción y devuelve sus valores y las posiciones de colisiones
    posicion, listaFactibilidad = seleccionar(sBest, datos)
    c = 0  # contador de iteraciones
    tabuList = []
    valorAuxRepeticiones = 0
    contadorRepeticiones = 0

    #5 % de valores repetidos para que se modifique a otro método
    #noRepetir = 20
    #noRepetir = iteraciones*(noRepetir/100.0)
    #noRepetir = int(noRepetir)

    while (c < iteraciones):  # and noHayCambios != 1):
        candidateList = []
        #Genera vecinos sin tomar en cuenta los datos fijos
        sVecinos = SNeighborhood(sBest, vecinos, porcMod, datos, datosFIJOS)

        for sCand in sVecinos:
            if sCand not in tabuList:
                candidateList.append(sCand)
        sCandidate = mejorCandidato(candidateList, datos)

        #En esta parte se identifican los problemas en la solución
        posProblema, posProb2, metaH, fact, datosPrioritarios = verificarProblema(
            sCandidate, datos, listaFactibilidad, datosPRIORITARIOS,
            datosPrioritarios)
        #Para verificar que ya se hayan satisfecho los datos prioritarios para convertirlos en fijos
        if (datosPrioritarios == 1):
            datosFIJOS = datosFIJOS + list(datosPRIORITARIOS)
            datosPRIORITARIOS = []
            datosPrioritarios = -1

        datosFIJOS = set(datosFIJOS)
        posProblema = list(set(posProblema) - datosFIJOS)
        datosFIJOS = list(datosFIJOS)

        listaFactibilidad = fact

        #clases de teoria y practica no deben ser a la misma
        #hora, el mismo día (MODIFICAR DIA)
        if metaH == "local1":
            solNueva = descensoColinaSimple(sCandidate, datos, posProblema, 30,
                                            40)
            #print "falta"

        #Las clases no deben impartirse fuera del horario de clases
        if metaH == "local2":
            solNueva = descensoColinaSimple(sCandidate, datos, posProblema, 30,
                                            40)
            #print "falta"

        #Un profesor no puede estar en dos lugares distintos a la
        #misma hora, el mismo día (MODIFICAR HORA)
        if metaH == "local3":
            solNueva = descensoColina(sCandidate, datos, posProblema, 80, 40)
            #print "falta"

        #Dos o mas profesores o grupos no pueden estar en el mismo lugar
        #a la misma hora, el mismo día a menos que sea multiasignacion
        if metaH == "local4":

            datosFIJOS = set(datosFIJOS)
            posProb2 = list(set(posProb2) - datosFIJOS)
            datosFIJOS = list(datosFIJOS)
            solNueva = recocidoSimuladoModificado(sCandidate, datos,
                                                  posProblema)
            solNueva = recocidoSimuladoModificado(solNueva, datos, posProb2)

        #Un mismo grupo no puede tener asignada otra clase, ya sea en el mismo
        # o diferente lugar a la misma hora, el mismo día. a menos que sean
        #clases de diferentes especialidades de ese grupo (MODIFICAR HORA)
        if metaH == "local5":
            #el algoritmo armónica necesita otros parámetros para mejorar la solución
            solNueva = sbusquedaArmonica(sCandidate, datos, posProblema)
            #solNueva = descensoColina(sCandidate,datos,posProblema,100,2)

        #Si un profesor da clases a la 8, no puede dar clases a la 1 (MODIFICAR HORA)
        if metaH == "local6":
            solNueva = descensoColinaSimple(sCandidate, datos, posProblema, 30,
                                            40)

        #Un grupo no puede tomar clases obligatorias a la misma hora en la que un alumno de recursamiento toma clases junto a otro grupo
        #(MODIFICAR HORA)
        if metaH == "local7":
            solNueva = descensoColinaSimple(sCandidate, datos, posProblema, 30,
                                            40)

        #Un grupo debe tener dos horas libres al día (MODIFICAR HORA)
        if metaH == "local8":
            solNueva = descensoColinaSimple(sCandidate, datos, posProblema, 30,
                                            40)

        #Un espacio solo puede permitir 9 horas al día
        if metaH == "local9":
            solNueva = descensoColinaSimple(sCandidate, datos, posProblema, 50,
                                            40)

        #Heuristica 1 (restricción débil)
        if metaH == "local10":
            solNueva = descensoColina(sCandidate, datos, posProblema, 30, 40)

        #Heurística 2 (restricción débil)
        if metaH == "local11":
            solNueva = descensoColina(sCandidate, datos, posProblema, 30, 40)

        if (evaluar(solNueva, datos) < evaluar(sBest, datos)):
            sBest = solNueva
            if len(tabuList) > tamMemoria:
                tabuList.pop(0)
            tabuList.append(solNueva)

        fact = evaluar(sBest, datos)

        print "factibilidad: ", fact, " iteración: ", c
        #PARA ROMPER CICLO cuando se estanca
        #if c > 0:
        #    cambiosCiclos = cambiosCiclos + abs(anterior - fact) #Ir sumando los cambios de 5 generaciones
        #    if c % out == 0:#Hacerlo cada ciertas iteraciones (cada 15 )
        #        if cambiosCiclos != 0:
        #            if abs(cambiosCiclos) == 0: # Si no hay mucho cambio en 5 generaciones salirse del ciclo porque ya no tiene caso buscar mas soluciones
        #                noHayCambios = 1
        #            cambiosCiclos = 0 # Se reinicia el contador para volver a calcular otras 5 generaciones
        #sol = sBest
        #anterior = fact
        #if(valorAuxRepeticiones == fact):
        #    contadorRepeticiones = contadorRepeticiones + 1
        #else:
        #    contadorRepeticiones = 0
        #if contadorRepeticiones >= noRepetir:
        #    solucion2,datosFIJOS,datosPRIORITARIOS = solucion(datos)
        #    datosPrioritarios = 0
        #    contadorRepeticiones = 0
        #    if evaluar(solucion2,datos) < evaluar(sBest,datos):
        #        sFinal = solucion2
        #    sBest = solucion2
        #valorAuxRepeticiones = fact
        #if evaluar(sBest,datos) < evaluar(sFinal,datos):
        #    sFinal = sBest

        c = c + 1

    t2 = time()
    tiempo = t2 - t1
    #fact = evaluar(sFinal,datos)
    return tiempo, fact, sBest  #,tempS