예제 #1
0
def BFS(lab: Labyrinth):
    """
    Fa una busqueda per nivells de forma iterativa
    Precondicions: Necessita un laberynth d'entrada vàlid (amb posició d'entrada, sortida i almenys un camí vàlid)
    Postcondicions: Un trail amb un camí dels més curts possibles (pot trobar 2 camins amb la mateixa longitud que
    siguin vàlids, en aquest cas retornarà el primer que trobi a la hora de processar-los)
    """
    print('Starting BFS')

    #Posteriorment afegirem a trails la posició d'inici, per aixó l'afegim aquí
    ja_buscats = [lab.getStartCell()]

    # Donat que en el BFS busquem tots els camins possibles fins que trobem el més curt,
    # necessitem varis trails. La iniciem amb la posició de sortida per a no fer saltar la verificacio de
    # camins possibles

    trails = [[lab.getStartCell()]]
    while True:     #Comencem la iteració
        # En el cas que la longitud de trails sigui 0, implicaria que no hi hauria cap camí possible.
        # també detectaria un error a la hora de llegir el laberint si no conté una start cell
        if trails.__len__() == 0:
            print("Error al buscar un camí, es possible que no hi hagi solució?")
            break
        else:
            #comprova cada trail
            for j in trails:
                pos_val = j[j.__len__() - 1] #agafem la ultima posició de cada taril per a obtenir els seus children
                children = pos_val.getChildren() #d'aquesta manera independentment de la llargada sempre tenim els
                                                 #children de la ultima posició
                if children.__len__() == 0: #si detectem que aquell camí no te cap children, implica que s'ha acabat
                                            #per tant eliminem el camí de trails
                    trails.remove(j)
                else:
                    #per cada children que tingui el camí actual volem crear un camí nou (afegint k al final)
                    # Per tant primer filtem per veure si aquest children ja ha estat buscat, sino el conté, copiem el
                    # el trail i li afegim el children k al final i l'afegim a trails. Llavors mirem si aquest children
                    # es la posició final, si ho és retornem el trail (que ja te la posició k inclosa). De no ser aixi
                    # afegim la posició com a ja buscada
                    for k in children:
                        if not ja_buscats.__contains__(k):
                            prov = j.copy()
                            prov.append(k)
                            trails.append(prov) #'aqui'
                            if k == lab.getEndCell():
                                prov_f =trails[trails.__len__()-1] #hem afegit abans 'aqui' a trails al final de tot
                                return prov_f
                            ja_buscats.append(k)
                    #borrem el trail j degut a que no te cap dels childrens i es inutil guardar-lo ja que els camins
                    # derivats d'aquest trail j ja han estat afegits ('aqui').
                    trails.remove(j)


    # para la salida obtenemos getchildren() donde obtenemos los hijos del nodo

    return trails
예제 #2
0
def DFS(lab: Labyrinth):
    """Fa una busqueda en profunditat (escull una rama i va fins al final), la solució esta implementada de forma recursiva
    Precondicions:  Necessita un laberynth d'entrada vàlid (amb posició d'entrada, sortida i almenys un camí vàlid)
    Postcondicions: Un trail amb un camí vàlid (que va des de l'entrada fins a la sortida)
    """
    print('Starting DFS')
    trail = []
    ja_cercats = []

    start = lab.getStartCell()


    def busqueda(ultima_pos):
        """S'encarrega de buscar el camí, li ha d'entrar una posició del fill de la ultima posició del trail
            Busca si existeixen fills de la ultima posició, comprova que no s'hagin consultat abans
            i si no ha passat per alla abans o no es una posició sense sortida escull un. Si detecta que cap
            fill es viable, marca la última posició com a ja_buscda, per a vetar que intenti passar per alla
            de nou
            Precondicions: Una posició vàlida (format (1,2) per exemple)
            Postcondicions: Un trail vàlid
        """
        children = ultima_pos.getChildren()     #obtenim els children de la posició d'entrada
        trail.append(ultima_pos)    #afegim la posició d'entrada al trail

        a_eliminar = []     #degut a que eliminarem posicions de childrem, creem aquest array per a guardar
                            #les posicions que eliminarem

        # recorrem totes les posicions de children per a guardar a a_eliminar les que siguin punts morts
        # o per les que ja esta passant el trail (que ens porten a un punt mort)
        # si detecta que un dels children es la posició final, l'afegeix al trail i retorna el trail
        for a in children:
            if (ja_cercats.__contains__(a)) or (trail.__contains__(a)):
                a_eliminar.append(a)
            elif a == lab.getEndCell():
                trail.append(a)
                return trail

        # Elimina tots els children que abans hem marcat per a eliminar
        # evita que al for de children no revisi la ultima posició si es fa algun remove
        for c in a_eliminar:
            children.remove(c)

        # Detecta si el cami es viable (te alguna posició per on seguir) no fills => children.len == 0
        # Si el cami no es viable, afegeix la ultima posició com a punt mort i aixi no tornará a passar pel mateix lloc
        # que portaria a la fucio a arribar al mateix punt mort. Elimiminem el pas actual i l'anterior de trail
        # i iniciem la busqueda des de la posició anterior a la que ens ha portat aqui.
        if children.__len__() == 0:
            ja_cercats.append(ultima_pos)
            trail.remove(ultima_pos)    #eliminem la posició que ens porta a un punt mort del trail.
            trail.pop(trail.__len__()-1)#Degut a com esta implementat la funció, tambe hem de eliminar
                                        #de trail la posició anterior a la que ens ha portat al punt mort
                                        #ja que sinó es trobaria en un bucle infinit.
            busqueda(trail[trail.__len__()-1])
        else:
            # si el cami es viable (children != 0) buscarem a partir de la posició children[0] ja que sempre
            # existira aquesta posició
            busqueda(children[0])

    busqueda(start) #iniciem la iteració des de la posició start (aixó nomes pasará la primera vegada)


    return trail