def coste_uniforme(problema):
    """Búsqueda en grafos de coste uniforme (uniform-cost search)."""
    raiz = crea_nodo_raiz(problema)
    frontera = [
        raiz,
    ]
    explorados = set()
    while True:
        if not frontera:
            return None
        nodo = frontera.pop(0)
        if problema.es_objetivo(nodo.estado):
            return nodo
        explorados.add(nodo.estado)
        if not nodo.acciones:
            continue
        for nombre_accion in nodo.acciones.keys():
            accion = Accion(nombre_accion)
            hijo = crea_nodo_hijo(problema, nodo, accion)
            estados_frontera = [nodo.estado for nodo in frontera]
            if (hijo.estado not in explorados
                    and hijo.estado not in estados_frontera):
                frontera.append(hijo)
            else:
                buscar = [
                    nodo for nodo in frontera if nodo.estado == hijo.estado
                ]
                if buscar:
                    if hijo.coste < buscar[0].coste:
                        indice = frontera.index(buscar[0])
                        frontera[indice] = hijo
            frontera.sort(key=lambda nodo: nodo.coste)
def profundidad(problema):
    """Búsqueda en grafos primero en profundidad (depth-first search)."""
    raiz = crea_nodo_raiz(problema)
    if problema.es_objetivo(raiz.estado):
        return raiz
    frontera = [
        raiz,
    ]
    explorados = set()
    while True:
        if not frontera:
            return None
        nodo = frontera.pop()
        explorados.add(nodo.estado)
        if not nodo.acciones:
            continue
        for nombre_accion in nodo.acciones.keys():
            accion = Accion(nombre_accion)
            hijo = crea_nodo_hijo(problema, nodo, accion)
            estados_frontera = [nodo.estado for nodo in frontera]
            if (hijo.estado not in explorados
                    and hijo.estado not in estados_frontera):
                es_objetivo = problema.es_objetivo(hijo.estado)
                if es_objetivo:
                    return hijo
                frontera.append(hijo)
Beispiel #3
0
def a_estrella_iterativa(problema, nodo=None, limite=0, explorados=None):
    """Búsqueda A* iterativa que buscará hasta un límite máximo."""
    if not nodo:
        nodo = crea_nodo_raiz(problema)
    if explorados is None:
        explorados = set()
    else:
        explorados.add(nodo.estado)
    if limite <= 0:
        limite = problema.infinito
    valor_nodo = min([
        nodo.valores[objetivo.nombre]
        for objetivo in problema.estados_objetivos
    ])
    if valor_nodo > limite:
        return None, valor_nodo
    if problema.es_objetivo(nodo.estado):
        return nodo, limite
    if not nodo.acciones:
        return None, limite
    minimo = problema.infinito
    for nombre_accion in nodo.acciones.keys():
        accion = Accion(nombre_accion)
        hijo = crea_nodo_hijo(problema, nodo, accion)
        if hijo.estado not in explorados:
            nod_hijo, lim_hijo = a_estrella_iterativa(problema, hijo, limite,
                                                      explorados)
            if nod_hijo:
                return nod_hijo, lim_hijo
            if lim_hijo < minimo:
                minimo = lim_hijo
    return None, minimo
def amplia_frontera(problema, nodo, objetivo, frontera, explorados):
    for nombre_accion in nodo.acciones.keys():
        accion = Accion(nombre_accion)
        hijo = crea_nodo_hijo(problema, nodo, accion)
        estados_frontera = [nodo.estado for nodo in frontera]
        estados_explorados = [nodo.estado for nodo in explorados]
        if (hijo.estado not in estados_explorados
                and hijo.estado not in estados_frontera):
            if objetivo == hijo.estado:
                return hijo
            frontera.append(hijo)
    return None
Beispiel #5
0
def sma_estrella(problema, maximo_nodos=10):
    """Búsqueda A* para memoria limitada (Simplified Memory-Bounded A*)."""
    raiz = crea_nodo_raiz(problema)
    frontera = [
        raiz,
    ]
    explorados = set()
    while True:
        if not frontera:
            return None
        nodo = sacar_siguiente(frontera,
                               'valor',
                               objetivos=problema.estados_objetivos)
        if problema.es_objetivo(nodo.estado):
            return nodo
        explorados.add(nodo.estado)
        if not nodo.acciones:
            continue
        for nombre_accion in nodo.acciones.keys():
            accion = Accion(nombre_accion)
            hijo = crea_nodo_hijo(problema, nodo, accion)
            estados_frontera = [nodo.estado for nodo in frontera]
            if hijo.estado in explorados or hijo.estado in estados_frontera:
                buscar = [
                    nodo for nodo in frontera if nodo.estado == hijo.estado
                ]
                if buscar:
                    valores_hijo = [
                        hijo.valores[objetivo.nombre]
                        for objetivo in problema.estados_objetivos
                    ]
                    valores_buscar = [
                        buscar[0].valores[objetivo.nombre]
                        for objetivo in problema.estados_objetivos
                    ]
                    minimo_hijo = min(valores_hijo)
                    minimo_buscar = min(valores_buscar)
                    if minimo_hijo < minimo_buscar:
                        indice = frontera.index(buscar[0])
                        frontera[indice] = hijo
            else:
                if len(frontera) > maximo_nodos:
                    ordenador = lambda x: [
                        x.valores[objetivo.nombre]
                        for objetivo in problema.estados_objetivos
                    ]
                    frontera = sorted(frontera, key=ordenador)
                    frontera.pop()
                frontera.append(hijo)
def __coste_recursivo(nodo, problema, limite, explorados, soluciones):
    """Función recursiva de la busqueda en profundidad iterativa con costes."""
    if limite <= 0:
        return None
    if problema.es_objetivo(nodo.estado):
        soluciones.append(nodo)
        return nodo
    explorados.add(nodo.estado)
    if not nodo.acciones:
        return None
    for nombre_accion in nodo.acciones.keys():
        accion = Accion(nombre_accion)
        hijo = crea_nodo_hijo(problema, nodo, accion)
        if hijo.estado not in explorados:
            coste = problema.coste_accion(nodo.estado, accion)
            __coste_recursivo(hijo, problema, limite - coste,
                              explorados.copy(), soluciones)
    return None
def __bpp_recursiva(nodo, problema, limite, explorados):
    """Función recursiva para realizar la búsqueda primero en profundidad."""
    if problema.es_objetivo(nodo.estado):
        return nodo
    if limite == 0:
        return None
    explorados.add(nodo.estado)
    if not nodo.acciones:
        return None
    for nombre_accion in nodo.acciones.keys():
        accion = Accion(nombre_accion)
        hijo = crea_nodo_hijo(problema, nodo, accion)
        if hijo.estado not in explorados:
            resultado = __bpp_recursiva(hijo, problema, limite - 1,
                                        explorados.copy())
            if resultado:
                return resultado
    return None
Beispiel #8
0
def a_estrella(problema):
    """Búsqueda A* (que se lee 'A estrella')."""
    raiz = crea_nodo_raiz(problema)
    frontera = [
        raiz,
    ]
    explorados = set()
    while True:
        if not frontera:
            return None
        nodo = sacar_siguiente(frontera,
                               'valor',
                               objetivos=problema.estados_objetivos)
        if problema.es_objetivo(nodo.estado):
            return nodo
        explorados.add(nodo.estado)
        if not nodo.acciones:
            continue
        for nombre_accion in nodo.acciones.keys():
            accion = Accion(nombre_accion)
            hijo = crea_nodo_hijo(problema, nodo, accion)
            estados_frontera = [nodo.estado for nodo in frontera]
            if hijo.estado in explorados or hijo.estado in estados_frontera:
                buscar = [
                    nodo for nodo in frontera if nodo.estado == hijo.estado
                ]
                if buscar:
                    valores_hijo = [
                        hijo.valores[objetivo.nombre]
                        for objetivo in problema.estados_objetivos
                    ]
                    valores_buscar = [
                        buscar[0].valores[objetivo.nombre]
                        for objetivo in problema.estados_objetivos
                    ]
                    minimo_hijo = min(valores_hijo)
                    minimo_buscar = min(valores_buscar)
                    if minimo_hijo < minimo_buscar:
                        indice = frontera.index(buscar[0])
                        frontera[indice] = hijo
            else:
                frontera.append(hijo)
Beispiel #9
0
def voraz(problema):
    """Búsqueda en grafos voraz (greedy search)."""
    raiz = crea_nodo_raiz(problema)
    frontera = [
        raiz,
    ]
    explorados = set()
    while True:
        if not frontera:
            return None
        nodo = sacar_siguiente(frontera,
                               'heuristica',
                               objetivos=problema.estados_objetivos)
        if problema.es_objetivo(nodo.estado):
            return nodo
        explorados.add(nodo.estado)
        if not nodo.acciones:
            continue
        for nombre_accion in nodo.acciones.keys():
            accion = Accion(nombre_accion)
            hijo = crea_nodo_hijo(problema, nodo, accion)
            estados_frontera = [nodo.estado for nodo in frontera]
            if hijo.estado in explorados or hijo.estado in estados_frontera:
                buscar = [
                    nodo for nodo in frontera if nodo.estado == hijo.estado
                ]
                if buscar:
                    heuristic_hijo = [
                        hijo.heuristicas[objetivo.nombre]
                        for objetivo in problema.estados_objetivos
                    ]
                    heuristic_buscar = [
                        buscar[0].heuristicas[objetivo.nombre]
                        for objetivo in problema.estados_objetivos
                    ]
                    minimo_hijo = min(heuristic_hijo)
                    minimo_buscar = min(heuristic_buscar)
                    if minimo_hijo < minimo_buscar:
                        indice = frontera.index(buscar[0])
                        frontera[indice] = hijo
            else:
                frontera.append(hijo)
Beispiel #10
0
def _brpm_recursiva(problema, nodo, limite, explorados):
    """Función recursiva para búsqueda recursiva primero el mejor."""
    explorados.add(nodo.estado)
    if limite <= 0:
        limite = problema.infinito
    if problema.es_objetivo(nodo.estado):
        return nodo, limite
    if not nodo.acciones:
        return None, limite
    for nombre_accion in nodo.acciones.keys():
        accion = Accion(nombre_accion)
        hijo = crea_nodo_hijo(problema, nodo, accion, False)
        if hijo.estado not in explorados:
            hijo.padre = nodo
            nodo.hijos.append(hijo)
            maximo = max([
                hijo.valores[objetivo.nombre]
                for objetivo in problema.estados_objetivos
            ])
            hijo.alfa = max(maximo, nodo.alfa)
    if not nodo.hijos:
        return None, problema.infinito
    while True:
        objetivos = problema.estados_objetivos
        mejor = nodo.hijo_mejor(problema, metrica='alfa')
        if mejor.alfa > limite:
            return None, mejor.alfa
        hijos = nodo.hijos.copy()
        nodo.hijos.remove(mejor)
        alfa = limite
        if nodo.hijos:
            alternativa = nodo.hijo_mejor(problema, metrica='alfa')
            alfa = min(limite, alternativa.alfa)
        nodo.hijos = hijos
        resultado, mejor.alfa = _brpm_recursiva(problema, mejor, alfa,
                                                explorados)
        if resultado:
            return resultado, mejor.alfa
            estado = nodo.estado.nombre
            coste_total = nodo.coste
            print(msg.format(estado, coste_total))
            if nodo.accion:
                accion = nodo.accion.nombre
                padre = nodo.padre.estado
                coste = problema_resolver.coste_accion(padre, nodo.accion)
                if accion:
                    msg = "<--- {0} [{1}] ---"
                    print(msg.format(accion, coste))
            nodo = nodo.padre


# %%
if __name__ == '__main__':
    accN = Accion('N')
    accS = Accion('S')
    accE = Accion('E')
    accO = Accion('O')
    accNE = Accion('NE')
    accNO = Accion('NO')
    accSE = Accion('SE')
    accSO = Accion('SO')

    lanoi = Estado('Lanoi', [accNE])
    nohoi = Estado('Nohoi', [accSO, accNO, accNE])
    ruun = Estado('Ruun', [accNO, accNE, accE, accSE])
    milos = Estado('Milos', [accO, accSO, accN])
    ghiido = Estado('Ghiido', [accN, accE, accSE])
    kuart = Estado('Kuart', [accO, accSO, accNE])
    boomon = Estado('Boomon', [accN, accSO])