class_docstr: Implements Hindsight Experience Replay as described in the following paper: https://arxiv.org/pdf/1707.01495.pdf
class_docstr_tok: ["Implements","Hindsight","Experience","Replay","as","described","in","the","following","paper",":","https",":","\/\/arxiv.org\/pdf\/1707.01495.pdf"]
code: def store_episode(self, episode: Episode, lock: bool = True) -> None:
      # generate hindsight transitions only when an episode is finished
      last_episode_transitions = copy.copy(episode.transitions)
  
      # cannot create a future hindsight goal in the last transition of an episode
      if (
          self.hindsight_goal_selection_method
          == HindsightGoalSelectionMethod.Future
      ):
          relevant_base_transitions = last_episode_transitions[:-1]
      else:
          relevant_base_transitions = last_episode_transitions
  
      # for each transition in the last episode, create a set of hindsight transitions
      for transition_index, transition in enumerate(
          relevant_base_transitions
      ):
          sampled_goals = self._sample_goals(
              last_episode_transitions, transition_index
          )
          for goal in sampled_goals:
              hindsight_transition = copy.copy(transition)
  
              if (
                  hindsight_transition.state["desired_goal"].shape
                  != goal.shape
              ):
                  raise ValueError(
                      (
                          "goal shape {goal_shape} already in transition is "
                          "different than the one sampled as a hindsight goal "
                          "{hindsight_goal_shape}."
                      ).format(
                          goal_shape=hindsight_transition.state[
                              "desired_goal"
                          ].shape,
                          hindsight_goal_shape=goal.shape,
                      )
                  )
  
              # update the goal in the transition
              hindsight_transition.state["desired_goal"] = goal
              hindsight_transition.next_state["desired_goal"] = goal
  
              # update the reward and terminal signal according to the goal
              (
                  hindsight_transition.reward,
                  hindsight_transition.game_over,
              ) = self.goals_space.get_reward_for_goal_and_state(
                  goal, hindsight_transition.next_state
              )
  
              hindsight_transition.n_step_discounted_rewards = None
              episode.insert(hindsight_transition)
  
      super().store_episode(episode)
  
imports: import copy
  from enum import Enum
  from typing import Tuple, List
  import numpy
  from rl_coach.core_types import Episode, Transition
  from rl_coach.memories.episodic.episodic_experience_replay import EpisodicExperienceReplayParameters, EpisodicExperienceReplay
  from rl_coach.memories.non_episodic.experience_replay import MemoryGranularity
  from rl_coach.spaces import GoalsSpace
label_desc: Use image node_id 4 for calling the EpisodicHindsightExperienceReplay obj's underlying member method code with example usage: obj.store_episode(episode, lock) without return types