Как это словарное понимание отличается от этого цикла for? - PullRequest
1 голос
/ 18 мая 2019

Я пытался реализовать алгоритм как с пониманием словаря, так и с циклом for, оба из которых, как я полагал, были установлены для достижения одинаковых результатов.

словарное понимание

for i in range(num_iter):
    new_state_values = {s: get_new_state_value(mdp, state_values, s, gamma) for s in mdp.get_all_states()}

дляцикл

for i in range(num_iter):
    for s in mdp.get_all_states():
        new_state_values[s] = get_new_state_value(mdp, state_values, s, gamma)

, поскольку мой алгоритм работает, они достигают очень разных результатов.Может кто-нибудь указать мне, где разница в этих двух?

Подробности

полный алгоритм ниже

# parameters
gamma = 0.9  # discount for MDP
num_iter = 100  # maximum iterations, excluding initialization
min_difference = 0.001  # stop VI if new values are this close to old values (or closer)

# initialize V(s)
state_values = {s: 0 for s in mdp.get_all_states()}

for i in range(num_iter):
    new_state_values = {s: get_new_state_value(mdp, state_values, s, gamma) for s in mdp.get_all_states()}

    # Compute difference
    diff = max(abs(new_state_values[s] - state_values[s]) for s in mdp.get_all_states())
    state_values = new_state_values

    if diff < min_difference:
        print("Terminated")
        break

версия 'for-loop' работает дляпочти никаких итераций, в то время как понимание словаря выполняется для многих других итераций.

update : приведенный выше код работает и сходится (и, я полагаю, является наиболее питоническим, imo).Принятый ответ дает хорошее представление о различных методах.

1 Ответ

3 голосов
/ 18 мая 2019

Версия без понимания накапливает значения, не отбрасывая значения из предыдущих запусков внешнего цикла.Если вы хотите, чтобы он был эквивалентным, вам нужно изменить:

for i in range(num_iter):
    for s in mdp.get_all_states():
        new_state_values[s] = get_new_state_value(mdp, state_values, s, gamma)

на:

for i in range(num_iter):
    new_state_values = {}  # NEW!!!
    for s in mdp.get_all_states():
        new_state_values[s] = get_new_state_value(mdp, state_values, s, gamma)

, чтобы повторно инициализировать new_state_values в чистую dict.

В вашем полном коде решение для непонимания оставит и state_values, и new_state_values в качестве псевдонимов того же dict (поэтому state_values изменится, когда вы его использовали), усугубляя проблему;dict понимание исправляет это путем создания нового dict без изменения state_values по мере его создания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...