importar aleatorio, numpy como np, torch, torch.nn como nn, torch.nn.functional como F importar matplotlib.pyplot como plt desde clases de datos importar clase de datos desde escribir importar Tuple, Dict, Lista desde torch.utils.data importar conjunto de datos, cargador de datos intentar: desde tqdm.auto importar tqdm excepto Excepción: def tqdm(x, **kwargs): devolver x SEED = 7 semilla.aleatoria(SEMILLA); np.random.seed(SEMILLA); torch.manual_seed(SEED) if device.type == “cuda”: torch.backends.cudnn.benchmark = True @dataclass class WorldConfig: grid_size: int = 8 cell_px: int = 14 max_steps: int = 45 n_obstacles: int = 8 spawn_margin: int = 1 class GridWorldRGBNoPIL: ACTIONS = {0:(0,-1),1:(0,1),2:(-1,0),3:(1,0),4:(0,0)} ACTION_NAMES = {0:”ARRIBA”,1:”ABAJO”,2:”IZQUIERDA”,3:”DERECHA”,4:”QUEDAR”} def __init__(self, cfg: WorldConfig): self.cfg = cfg self.reset() def reset(self) -> Dict: g = self.cfg.grid_size self.steps = 0 def sample_empty(exclude=set()): while True: x = random.randint(self.cfg.spawn_margin, g-1-self.cfg.spawn_margin) y = random.randint(self.cfg.spawn_margin, g-1-self.cfg.spawn_margin) si (x,y) no está excluido: devolver (x,y) self.obstacles = set() ax, ay = sample_empty() gx, gy = sample_empty(exclude={(ax,ay)}) used = {(ax,ay),(gx,gy)} for _ in range(self.cfg.n_obstacles): buey, oy = sample_empty(exclude=used) self.obstacles.add((ox,oy)) used.add((ox,oy)) self.agent = (ax,ay) self.goal = (gx,gy) return {“image”: self._render_u8()} def _in_bounds(self, x, y): return 0 <= x < self.cfg.grid_size y 0 <= y < self.cfg.grid_size def _dist_to_goal(self, pos: Tupla[int,int]) -> flotante: x,y = pos; gx,gy = self.goal return abs(x-gx)+abs(y-gy) def _state_vector(self) -> np.ndarray: g = self.cfg.grid_size – 1 ax,ay = self.agent; gx,gy = self.goal return np.array([ax/g, ay/g, gx/g, gy/g]dtype=np.float32) def paso(self, acción: int): self.steps += 1 dx, dy = self.ACTIONS[int(action)]
x,y = self.agent nx, ny = x+dx, y+dy si self._in_bounds(nx,ny) y (nx,ny) no están en self.obstacles: self.agent = (nx,ny) done = (self.agent == self.goal) o (self.steps >= self.cfg.max_steps) d_prev = self._dist_to_goal((x,y)) d_now = self._dist_to_goal(self.agent) recompensa = 0.1*(d_prev – d_now) + (1.0 if self.agent == self.goal else 0.0) obs = {“image”: self._render_u8()} info = {“state”: self._state_vector()} return obs, float(reward), bool(hecho), info def _render_u8(self) -> np.ndarray: g, s = self.cfg.grid_size, self.cfg.cell_px H = W = g*s bg = np.array([245,245,245]np.uint8) línea de cuadrícula = np.array([220,220,220]np.uint8) obstáculo_c = np.array([220,70,70]np.uint8) objetivo_c = np.array([60,180,75]np.uint8) agente_c = np.array([65,105,225]np.uint8) img = np.empty((H,W,3), np.uint8); imagen[…] = bg img[::s,:,:] = imagen de cuadrícula[:,::s,:] = línea de cuadrícula def paint_cell(x,y,color): y0,y1 = y*s,(y+1)*s x0,x1 = x*s,(x+1)*s img[y0+1:y1-1, x0+1:x1-1] = color para (ox,oy) en self.obstacles: paint_cell(ox,oy, obstáculo_c) gx,gy = self.goal; paint_cell(gx,gy, goal_c) ax,ay = self.agent; paint_cell(ax,ay, agent_c) return img cfg = WorldConfig() env = GridWorldRGBNoPIL(cfg) plt.figure(figsize=(3,3)) plt.imshow(env.reset()[“image”]); plt.axis(“apagado”); plt.title(“Observación sin almohada”); plt.show() def to_tensor_img_u8(img_u8: np.ndarray) -> torch.Tensor: retorno torch.from_numpy(img_u8).permute(2,0,1).float() / 255.0
x,y = self.agent nx, ny = x+dx, y+dy si self._in_bounds(nx,ny) y (nx,ny) no están en self.obstacles: self.agent = (nx,ny) done = (self.agent == self.goal) o (self.steps >= self.cfg.max_steps) d_prev = self._dist_to_goal((x,y)) d_now = self._dist_to_goal(self.agent) recompensa = 0.1*(d_prev – d_now) + (1.0 if self.agent == self.goal else 0.0) obs = {“image”: self._render_u8()} info = {“state”: self._state_vector()} return obs, float(reward), bool(hecho), info def _render_u8(self) -> np.ndarray: g, s = self.cfg.grid_size, self.cfg.cell_px H = W = g*s bg = np.array([245,245,245]np.uint8) línea de cuadrícula = np.array([220,220,220]np.uint8) obstáculo_c = np.array([220,70,70]np.uint8) objetivo_c = np.array([60,180,75]np.uint8) agente_c = np.array([65,105,225]np.uint8) img = np.empty((H,W,3), np.uint8); imagen[…] = bg img[::s,:,:] = imagen de cuadrícula[:,::s,:] = línea de cuadrícula def paint_cell(x,y,color): y0,y1 = y*s,(y+1)*s x0,x1 = x*s,(x+1)*s img[y0+1:y1-1, x0+1:x1-1] = color para (ox,oy) en self.obstacles: paint_cell(ox,oy, obstáculo_c) gx,gy = self.goal; paint_cell(gx,gy, goal_c) ax,ay = self.agent; paint_cell(ax,ay, agent_c) return img cfg = WorldConfig() env = GridWorldRGBNoPIL(cfg) plt.figure(figsize=(3,3)) plt.imshow(env.reset()[“image”]); plt.axis(“apagado”); plt.title(“Observación sin almohada”); plt.show() def to_tensor_img_u8(img_u8: np.ndarray) -> torch.Tensor: retorno torch.from_numpy(img_u8).permute(2,0,1).float() / 255.0