Volver a los desafíos
Intermedio 0 resueltos 0% de aceptación

Iteración de valores

Calcula cuánto vale cada estado de un proceso de decisión de Markov aplicando repetidamente la actualización de optimalidad de Bellman.

Lo que aprenderás

  • Aplicar la actualización de optimalidad de Bellman
  • Calcular valores de estado barrido a barrido
  • Modelar decisiones como estados, acciones y recompensas

Problema

Ver original (inglés)

La iteración de valores resuelve un proceso de decisión de Markov: encuentra V(s), la mejor recompensa total descontada que se puede obtener empezando en el estado s.

Aquí las transiciones son deterministas. En el estado s, la acción a da la recompensa rewards[s][a] y lleva al estado next_states[s][a], donde -1 significa que el episodio termina. Empieza con V(s) = 0 para cada estado y repite iterations veces, calculando cada valor nuevo a partir del barrido anterior:

V_new(s) = máximo sobre a de ( rewards[s][a] + gamma × V(next_states[s][a]) )

donde el término gamma × V es 0 cuando el siguiente estado es -1.

Implementa value_iteration(next_states, rewards, gamma, iterations).

Entrada

next_states: Para cada estado, el siguiente estado de cada una de sus acciones (-1 termina el episodio). Los estados pueden tener distinto número de acciones.

rewards: La recompensa de cada acción, con la misma forma que next_states.

gamma: El factor de descuento.

iterations: El número de barridos.

Salida

Devuelve V tras el último barrido, un valor por estado.

Restricciones

1 ≤ estados ≤ 200, 1 ≤ acciones por estado ≤ 10, 0 ≤ iterations ≤ 1.000

-100 ≤ cada recompensa ≤ 100, 0 ≤ gamma ≤ 1

Ejemplos

Ejemplo 1
Entrada:
gamma = 0.9
rewards = [
    [0.0, 0.0],
    [0.0, 0.0],
    [10.0]
]
iterations = 3
next_states = [
    [0, 1],
    [0, 2],
    [-1]
]

Salida esperada:
expected = [8.1, 9.0, 10.0]
Entrada:
double gamma = 0.9;
std::vector<std::vector<double>> rewards = {
    {0.0, 0.0},
    {0.0, 0.0},
    {10.0}
};
long long iterations = 3;
std::vector<std::vector<long long>> next_states = {
    {0, 1},
    {0, 2},
    {-1}
};

Salida esperada:
std::vector<double> expected = {8.1, 9.0, 10.0};
Entrada:
double gamma = 0.9;
double[][] rewards = new double[][] {
    new double[] {0.0, 0.0},
    new double[] {0.0, 0.0},
    new double[] {10.0}
};
long iterations = 3;
long[][] next_states = new long[][] {
    new long[] {0, 1},
    new long[] {0, 2},
    new long[] {-1}
};

Salida esperada:
double[] expected = new double[] {8.1, 9.0, 10.0};

Explicación

Barrido 1: solo el estado 2 puede obtener una recompensa, V = [0, 0, 10]. Barrido 2: el estado 1 va a la derecha hasta él, 0.9 × 10 = 9, V = [0, 9, 10]. Barrido 3: el estado 0 obtiene 0.9 × 9 = 8.1. Resultado: [8.1, 9, 10].

Ejemplo 2
Entrada:
gamma = 0.0
rewards = [
    [1.0, 2.0],
    [3.0, 0.0]
]
iterations = 5
next_states = [
    [1, 0],
    [0, 1]
]

Salida esperada:
expected = [2.0, 3.0]
Entrada:
double gamma = 0.0;
std::vector<std::vector<double>> rewards = {
    {1.0, 2.0},
    {3.0, 0.0}
};
long long iterations = 5;
std::vector<std::vector<long long>> next_states = {
    {1, 0},
    {0, 1}
};

Salida esperada:
std::vector<double> expected = {2.0, 3.0};
Entrada:
double gamma = 0.0;
double[][] rewards = new double[][] {
    new double[] {1.0, 2.0},
    new double[] {3.0, 0.0}
};
long iterations = 5;
long[][] next_states = new long[][] {
    new long[] {1, 0},
    new long[] {0, 1}
};

Salida esperada:
double[] expected = new double[] {2.0, 3.0};

Explicación

Con gamma = 0 el futuro no cuenta, así que el valor de cada estado es simplemente su mejor recompensa inmediata: [2, 3].

Cómo abordarlo

Inténtalo primero por tu cuenta y luego abre las pistas una a una.

Pista 1

Cada barrido usa solo los valores del barrido anterior, no las actualizaciones hechas antes en el mismo paso.

Pista 2

Para cada estado, compara todas las acciones combinando la recompensa inmediata con el valor descontado del siguiente estado.

Pista 3

Maneja con cuidado las acciones terminales: aportan solo su recompensa inmediata cuando falta el siguiente estado.

Complejidad esperada

O(iterations * total_actions) tiempo, O(states) espacio extra

Referencias

Este reto está adaptado para CodeUtility. Sigue el enunciado y las restricciones indicadas arriba.

Aprende de otros

Soluciones de la comunidad

Aún no hay soluciones publicadas. Resuelve este reto para compartir la primera.