docstr: sample actions via epsilon-greedy
  Args:
      obs (np.ndarray):                (n_agents, obs_shape)
      available_actions (np.ndarray):  (n_agents, n_actions)
  Returns:
      actions (np.ndarray):            (n_agents, )
docstr_tok: ["sample","actions","via","epsilon-greedy","Args",":","obs","(","np.ndarray",")",":","(","n_agents",",","obs_shape",")","available_actions","(","np.ndarray",")",":","(","n_agents",",","n_actions",")","Returns",":","actions","(","np.ndarray",")",":","(","n_agents",",",")"]
code: def sample(self, obs, available_actions):
      """sample actions via epsilon-greedy
      Args:
          obs (np.ndarray):                (n_agents, obs_shape)
          available_actions (np.ndarray):  (n_agents, n_actions)
      Returns:
          actions (np.ndarray):            (n_agents, )
      """
      epsilon = np.random.random()
      if epsilon > self.exploration:
          actions = self.predict(obs, available_actions)
      else:
          actions = AvailableActionsSampler(available_actions).sample()
      self.exploration = max(
          self.min_exploration,
          self.exploration - self.exploration_decay,
      )
      return actions
  
file_path: PARL/examples/QMIX/qmix_agent.py
imports: import paddle
  import parl
  import numpy
  from utils import AvailableActionsSampler
  import os
label_desc: Use image node_id 5 for calling the QMixAgent obj's underlying member method code with example usage: obj.sample(obs, available_actions) and returns: actions