def unaRonda(politica, grid=Grid.grid_estandar()): # Comenzamos en posiciones random para comprobar su # valor posiblesEstadosIniciales = list(grid.acciones.keys()) inicial = np.random.choice(len(posiblesEstadosIniciales)) grid.set_estado(posiblesEstadosIniciales[inicial]) s = grid.estado_actual() print(s) s_r = [(s, 0)] while not grid.game_over(): a = politica[s] r = grid.mover(a) s = grid.estado_actual() s_r.append((s, r)) G = 0 s_retornos = [] primeraVez = False for s, r in reversed(s_r): """ El primer elemento se corresponde con el último estado, que por definición siempre será 0 """ if not primeraVez: primeraVez = True else: s_retornos.append((s, G)) G = r + GAMMA * G return reversed(s_retornos)
def accionRandom(a,grid = Grid.grid_estandar(), eps=EPS): p = np.random.random() if p < (1.0 - eps): return a else: return np.random.choice(grid.posiblesAccionesBasicas())
def jugar(politica, grid=Grid.grid_estandar()): s = (2, 0) # No starter method grid.set_estado(s) acciones_recompensas = [(s, 0)] while not grid.game_over(): a = politica[s] a = accionRandom(a, grid) r = grid.mover(a) s = grid.estado_actual() acciones_recompensas.append((s, r)) return acciones_recompensas
def convertirS_X(s, grid=Grid.grid_estandar()): arriba = 0 abajo = 0 derecha = 0 izquierda = 0 # Si es terminal no miraremosa ningún lado if grid.es_terminal(s): return np.array([0, 0, 0, 0]) # Comprobamos si encima hay un estado terminal sArriba = (s[0] - 1, s[1]) if sArriba in grid.recompensas: arriba = grid.recompensas[ sArriba] # Seteamos el valor que nos de el estado terminal elif sArriba not in grid.acciones: arriba = -1 # Se sale del mapa | obstáculo # Comprobamos si a la derecha hay un estado terminal sDerecha = (s[0], s[1] + 1) if sDerecha in grid.recompensas: derecha = grid.recompensas[sDerecha] elif sDerecha not in grid.acciones: derecha = -1 # Se sale del mapa | obstáculo # Comprobamos si abajo hay un estado terminal sAbajo = (s[0] + 1, s[1]) if sAbajo in grid.recompensas: abajo = grid.recompensas[sAbajo] elif sAbajo not in grid.acciones: abajo = -1 # Se sale del mapa | obstáculo # Comprobamos si a la izquierda hay un estado terminal sIzquierda = (s[0], s[1] - 1) if sIzquierda in grid.recompensas: izquierda = grid.recompensas[sIzquierda] elif sIzquierda not in grid.acciones: izquierda = -1 # Se sale del mapa | obstáculo return np.array([arriba, derecha, abajo, izquierda])
MaxA = a return MaxV,MaxA def accionRandom(a,grid = Grid.grid_estandar(), eps=EPS): p = np.random.random() if p < (1.0 - eps): return a else: return np.random.choice(grid.posiblesAccionesBasicas()) if __name__ == "__main__": grid = Grid.grid_negativo(-0.1) todos_estados = grid.todos_estados() Q = {} alpha_personal = {} for s in todos_estados: Q[s] = {} alpha_personal[s] = {} for a in grid.posiblesAccionesBasicas(): Q[s][a] = 0 alpha_personal[s][a] = 1.0 t = 1.0
print("----------------") if __name__ == "__main__": """ Dada una política, encontramos los valores V(s). Vamos a hacer esto tanto para una "política aletoria random" como para una "política fija (determinista)" NOTA: ♦ La aleatoriedad proviene de dos lugares ♦ p(a|s) -> Decide que acción tomar dado un estado ♦ p(s',r|s,a) -> El estado al que llegaremos y la recompensa que obtendremos dado un estado y una acción ♦ De momento p(a|s) tendra una distribución uniforme (todos la misma probabilidad) ☺ ¿Cómo cambiaría el código si p(s',r|s,a) no fuese determinista? """ grid = Grid.grid_estandar() # Los estados serán posiciones (i,j) estados = grid.todos_estados() """ Acciones Randoms con distribuciones uniformes """ # Iniciamos V(s) = 0 V = {} for s in estados: V[s] = 0 gamma = 0.99 # Factor de descuento # Repetir hasta converger while True:
def MaxQ(Q_s): MaxV = float('-inf') MaxA = None for k, v in Q_s.items(): if v > MaxV: MaxV = v MaxA = k return (MaxV, MaxA) if __name__ == "__main__": grid = Grid.grid_negativo(penalizacion=-0.2) Q, politica, historialRetornos = iniciarValores(grid) print("Recompensas") mostrar_valores(grid.recompensas, grid) print("\nPolítica Inicial") mostrar_politica(politica, grid) print("\nValores Iniciales") V = {} for s in politica: V[s] = MaxQ(Q[s])[0] mostrar_valores(V, grid) episodios = 10000