LAB 09 Recorridos sobre grafos
Contents
!wget --no-cache -O init.py -q https://raw.githubusercontent.com/rramosp/20192.L3/master/init.py
import init; init.init(force_download=False); init.get_weblink()
import init
from local.lib.rlxmoocapi import submit, session
import inspect
student = session.Session(init.endpoint).login( course_id=init.course_id, 
                                                session_id="UDEA", 
                                                lab_id="lab_09" )
LAB 09 Recorridos sobre grafos¶
Ejercicio 1¶
completa al siguiente función para que dada una especificación de un laberinto como en las notas devuelva las coordenadas de la casilla T. Por ejemplo:
my_grid = [".....X",
           "XX...X",
           "...X..",
           ".XX..X",
           ".X...T"]
              
find_target(my_grid)
(4,5)
observa que en la coordenada resultante el primer elemento es la columna y el segundo la fila.
el resultado ha de ser del tipo tupla
sugerencia: usa la función np.argwhere
def find_target(grid):
    import numpy as np
    target = # tu codigo aqui
    return target
comprueba tu código
my_grid = [".....X",
        "XX...X",
        "...X..",
        ".XX..X",
        ".X...T"]
find_target(my_grid)
registra tu solución en línea¶
student.submit_task(globals(), task_id="task_01");
Ejercicio 2¶
completa la siguiente clase para que implemente una cola con prioridades de forma que:
- el método - putañada elemnetos asociados a una prioridad
- cada vez que se invoque el método - getdevuelva el elemento con la prioridad más baja y lo elimine de la cola.
- si la cola no tiene elementos el método - getha de devolver- None
- el método - emptyha de devolver- Truesi la cola no tiene elementos y- Falsesi tiene alguno
def PriorityQueue(*args, **kwargs):
    
    class PriorityQueue_class:
        
        def __init__(self):
            self.elements = []
        def empty(self):
            return ### tu codigo aqui
        def put(self, item, priority):
            ### tu codigo aqui
        def get(self):
            return ### tu codigo aqui
    return PriorityQueue_class(*args,**kwargs)
verifica tu código. el siguiente ejemplo debe de recuperar los elementos en el siguiente orden:
    c 
    a
    b 
    None
q = PriorityQueue()
q.put("a", 20)
q.put("b", 30)
q.put("c", 15)
print (q.get())
print (q.get())
print (q.get())
print (q.get())
registra tu solución en línea¶
student.submit_task(globals(), task_id="task_02");
Ejercicio 3¶
observa el algoritmo de búsqueda cost_search que devuelve dos estructuras:
- paths: un diccionario en el que, para cada posición, indica desde qué posición anterior se llegó con el menor coste desde la posición inicial (0,0).
- costs: un diccionario en el que, para cada posición, indica cual es el menor coste de los posibles caminos para llegar a dicha posición.
Definición: el coste de un camino es la longitud del mismo
Observa como, desde paths, se puede recuperar el camino de menor coste a cualquier posición empezando desde un target dado un caminando hacia atrás.
P.ej. desde al target (2,4) (esquina inferior derecha), se llega desde el (2,3), y a este desde el (2,2), y a este desde el (1,2), y a este desde el (0,2) y a este desde el (0,1) y a este desde el (0,0). Con lo que el camino completo desde el (0,0) es el siguiente:
(0,0), (0,1), (0,2), (1,2), (2,2), (2,3), (2,4)
con un coste de 6.
import pandas as pd
import numpy as np
EMPTY, WALL, TARGET, USED = ".","X","T","o"
c  = pd.Series({"EMPTY": ".", "WALL":"X", "TARGET":"T", "USED":"o"})
ci = pd.Series({".": 0, "X": 255, "T":100, "o":200})
def possible_moves(grid, y,x):
    moves = [ [y,x+1], [y-1,x], [y,x-1], [y+1,x]]
    moves = [(my,mx) for my,mx in moves if mx>=0 and mx<len(grid[0]) and \
                                           my>=0 and my<len(grid) and grid[my][mx]!=c.WALL]
    return moves
def cost_search(grid):
    
    start = (0,0)
    step_cost = 1
    frontier = PriorityQueue()
    frontier.put(start, 0)
    came_from   = {}
    cost_so_far = {}
    came_from[start]   = None
    cost_so_far[start] = 0
    while not frontier.empty():
        current = frontier.get()
        y,x = current
        if grid[y][x] == c.TARGET:
            break
        for next in possible_moves(grid,y,x):
            new_cost = cost_so_far[current] + step_cost
            if next not in cost_so_far or new_cost < cost_so_far[next]:
                cost_so_far[next] = new_cost
                priority = new_cost
                frontier.put(next, priority)
                came_from[next] = current
    return came_from, cost_so_far
Completa la función recover_path más abajo para que dado paths, costs y una tupla representando una posición target devuelva
- el camino especificado en - pathspara llegar a- target
- el coste del mismo 
por ejemplo, con los valores del ejemplo anterior:
> camino, coste = recover_path(path, cost, (2,4))
> print camino
> print coste
[(0, 0), (0, 1), (0, 2), (1, 2), (2, 2), (2, 3), (2, 4)]
6
my_grid = ["....X",
           "XX.XX",
           ".X..T"]
path, cost = cost_search(my_grid)
path
cost
Completa esta función ” recover_path “¶
def recover_path(path, cost, target):
    # tu codigo aqui
    camino = ...
    coste  = ...
    return camino, coste
prueba tu código
camino, coste = recover_path(path, cost, (2,4))
print (camino)
print (coste)
registra tu solución en línea¶
student.submit_task(globals(), task_id="task_03");