Todos os desafios
Médio 0 resolvidos 0% de aceitação

Atualizações de Q-learning

Aplique a atualização do Q-learning a um fluxo de experiências e veja as recompensas voltarem para estados anteriores.

O que você vai aprender

  • Atualizar valores de ação a partir da experiência
  • Usar fatores de desconto e estados terminais
  • Ver as recompensas voltarem para estados anteriores

Problema

Ver original (inglês)

O Q-learning aprende apenas pela experiência o quão boa é cada ação em cada estado, Q(s, a). Depois de executar a ação a no estado s, receber reward e chegar ao estado s':

  • target = reward, se o episódio terminou (done = 1)
  • target = reward + gamma × máximo sobre a' de Q(s', a'), caso contrário
  • Q(s, a) ← Q(s, a) + alpha × (target - Q(s, a))

Comece com todos os valores Q em 0 e aplique as transições em ordem.

Implemente q_learning(num_states, num_actions, transitions, alpha, gamma).

Entrada

num_states, num_actions: O tamanho da tabela.

transitions: Uma linha [state, action, reward, next_state, done] por passo.

alpha: A taxa de aprendizado.

gamma: O fator de desconto.

Saída

Retorne a tabela Q como uma matriz com uma linha por estado e uma coluna por ação.

Restrições

1 ≤ num_states, num_actions ≤ 100, 0 ≤ número de transições ≤ 10.000

-100 ≤ reward ≤ 100, done é 0 ou 1

0 < alpha ≤ 1, 0 ≤ gamma ≤ 1

Exemplos

Exemplo 1
Entrada:
alpha = 0.5
gamma = 0.9
num_states = 2
num_actions = 2
transitions = [
    [0, 1, 0, 1, 0],
    [1, 0, 10, 0, 1]
]

Saída esperada:
expected = [
    [0.0, 0.0],
    [5.0, 0.0]
]
Entrada:
double alpha = 0.5;
double gamma = 0.9;
long long num_states = 2;
long long num_actions = 2;
std::vector<std::vector<long long>> transitions = {
    {0, 1, 0, 1, 0},
    {1, 0, 10, 0, 1}
};

Saída esperada:
std::vector<std::vector<double>> expected = {
    {0.0, 0.0},
    {5.0, 0.0}
};
Entrada:
double alpha = 0.5;
double gamma = 0.9;
long num_states = 2;
long num_actions = 2;
long[][] transitions = new long[][] {
    new long[] {0, 1, 0, 1, 0},
    new long[] {1, 0, 10, 0, 1}
};

Saída esperada:
double[][] expected = new double[][] {
    new double[] {0.0, 0.0},
    new double[] {5.0, 0.0}
};

Explicação

O primeiro passo ainda não encontra recompensa: target = 0 + 0.9 × max(Q[1]) = 0, então Q[0][1] continua 0. O segundo passo termina o episódio com recompensa 10: Q[1][0] = 0 + 0.5 × (10 - 0) = 5.

Exemplo 2
Entrada:
alpha = 0.5
gamma = 0.9
num_states = 2
num_actions = 2
transitions = [
    [1, 0, 10, 0, 1],
    [0, 1, 0, 1, 0]
]

Saída esperada:
expected = [
    [0.0, 2.25],
    [5.0, 0.0]
]
Entrada:
double alpha = 0.5;
double gamma = 0.9;
long long num_states = 2;
long long num_actions = 2;
std::vector<std::vector<long long>> transitions = {
    {1, 0, 10, 0, 1},
    {0, 1, 0, 1, 0}
};

Saída esperada:
std::vector<std::vector<double>> expected = {
    {0.0, 2.25},
    {5.0, 0.0}
};
Entrada:
double alpha = 0.5;
double gamma = 0.9;
long num_states = 2;
long num_actions = 2;
long[][] transitions = new long[][] {
    new long[] {1, 0, 10, 0, 1},
    new long[] {0, 1, 0, 1, 0}
};

Saída esperada:
double[][] expected = new double[][] {
    new double[] {0.0, 2.25},
    new double[] {5.0, 0.0}
};

Explicação

Os mesmos passos na ordem inversa. Q[1][0] vira 5 primeiro, então o passo a partir do estado 0 o enxerga: target = 0 + 0.9 × 5 = 4.5 e Q[0][1] = 0.5 × 4.5 = 2.25. A recompensa voltou um estado.

Referências

Este desafio foi adaptado para o CodeUtility. Siga o enunciado e as restrições acima.

Aprenda com outros

Soluções da comunidade

Ainda não há soluções publicadas. Resolva este desafio para compartilhar a primeira.