Hoppa till innehållet
AI-grafen
D· AI-utvecklarereinforcement-learning· ca 45 min· grundläggande — ändras sällan· verifierad 2026-09-20

Rutnätsvärlden: din första RL-agent

Kunna implementera en agent som lär sig hitta till målet i ett rutnät.

Förkunskaper

Intuition

Rutnätsvärlden är RL:s motsvarighet till «Hej världen». Ett litet rutnät, en agent, ett mål.

. . . M      M = mål (+1)
. # . X      X = fälla (−1)
A . . .      # = vägg

De fyra begreppen finns alla här, i sin enklaste form:

BegreppI rutnätet
Tillståndvilken ruta agenten står i
Handlingupp, ner, vänster, höger
Belöning+1 i mål, −1 i fällan, annars ett litet minus per steg
Episodfrån start tills agenten når mål eller fälla

Agenten vet ingenting i början. Den provar sig fram, får poäng, och kommer långsamt ihåg vilka rutor som är värda att gå till.

Det lilla minuset per steg är viktigare än det låter: utan det spelar det ingen roll hur lång vägen är, och agenten kan lära sig att vandra runt i evighet innan den går i mål.

Kod

import random

BREDD, HOJD = 4, 3
VAGGAR = {(1, 1)}
MAL, FALLA = (0, 3), (1, 3)
HANDLINGAR = ["upp", "ner", "vanster", "hoger"]
DELTA = {"upp": (-1, 0), "ner": (1, 0), "vanster": (0, -1), "hoger": (0, 1)}

def flytta(pos, handling):
    dr, dk = DELTA[handling]
    ny = (pos[0] + dr, pos[1] + dk)
    if not (0 <= ny[0] < HOJD and 0 <= ny[1] < BREDD) or ny in VAGGAR:
        return pos                       # gå in i en vägg → stå kvar
    return ny

def belon(pos):
    if pos == MAL:
        return 1.0, True
    if pos == FALLA:
        return -1.0, True
    return -0.04, False                  # litet minus per steg → korta vägar lönar sig

Q = {(r, k, h): 0.0 for r in range(HOJD) for k in range(BREDD) for h in HANDLINGAR}

def basta(pos):
    return max(HANDLINGAR, key=lambda h: Q[(pos[0], pos[1], h)])

rng = random.Random(0)
for episod in range(2000):
    eps = max(0.05, 1.0 - episod / 1000)          # utforska mycket först, sedan mindre
    pos, steg = (2, 0), 0
    while steg < 100:
        h = rng.choice(HANDLINGAR) if rng.random() < eps else basta(pos)
        ny = flytta(pos, h)
        r, klar = belon(ny)
        basta_nasta = 0.0 if klar else max(Q[(ny[0], ny[1], a)] for a in HANDLINGAR)
        Q[(pos[0], pos[1], h)] += 0.1 * (r + 0.95 * basta_nasta - Q[(pos[0], pos[1], h)])
        pos, steg = ny, steg + 1
        if klar:
            break

ETIKETT = {MAL: " MAL ", FALLA: "FALLA", **{v: "  #  " for v in VAGGAR}}
for r in range(HOJD):
    print(" ".join(ETIKETT.get((r, k), f"{basta((r, k)):^5.5}") for k in range(BREDD)))
# hoger hoger hoger  MAL
# upp     #   upp   FALLA
# upp   hoger upp   vanst

Pilarna pekar mot målet och bort från fällan — utan att någon har sagt var de ligger. Agenten har bara provat, fått poäng, och kommit ihåg.

Interaktivt

Fyra experiment som ändrar vad agenten lär sig. Kör grundversionen först, titta på pilarna, och ändra sedan en sak i taget.

ÄndringVad som händer
Ta bort straffet per steg (-0.04 → 0.0)pilarna slutar peka raka vägen; alla vägar är lika bra
Höj straffet till -0.5agenten går rakt i fällan — att dö snabbt blir bättre än att gå långt
Sätt eps = 0.0agenten fastnar i den första väg den hittade, ofta en dålig
Sätt 0.95 → 0.5agenten blir närsynt och ser inte mål som ligger långt bort

Den andra raden är den mest lärorika. Belöningen är inte en önskan — den är en definition. Straffar du varje steg för hårt har du faktiskt bett agenten att avsluta fort, och fällan avslutar fort.

Det är samma fenomen som gör belöningsdesign svårt i verkliga system, och det syns tydligast här i rutnätet där du kan se hela lösningen på en gång.

Behärskning innebär

  • Beskriver tillstånd, handling och belöning i ett rutnät
  • Implementerar rörelse med väggar
  • Förklarar hur belöningen styr vad agenten lär sig

Logga in för att göra övningarna och bygga upp din behärskning.

Källor

Alla källor och licenser