class_docstr: A class that simulates a bandit
  
  Args:
      probs: A tensor of per-arm success probabilities
      max_steps: Max number os steps to simulate. This has to be specified because we pre-generate
          all the rewards at initialization (for speedup - generating random matrix once should be
          faster than generating random scalars in a loop)
class_docstr_tok: ["A","class","that","simulates","a","bandit","Args",":","probs",":","A","tensor","of","per-arm","success","probabilities","max_steps",":","Max","number","os","steps","to","simulate",".","This","has","to","be","specified","because","we","pre-generate","all","the","rewards","at","initialization","(","for","speedup","-","generating","random","matrix","once","should","be","faster","than","generating","random","scalars","in","a","loop",")"]
code: def __init__(
      self,
      max_steps: int,
      probs: torch.Tensor,
      arm_ids: Optional[List[str]] = None,
  ) -> None:
      """ """
      assert probs.max() <= 1.0
      assert probs.min() >= 0.0
      super().__init__(
          max_steps=max_steps, expected_rewards=probs, arm_ids=arm_ids
      )
      self.rewards = torch.bernoulli(
          probs.repeat(max_steps, 1)
      )  # pre-generate all rewards ahead of time
      assert self.rewards.shape == (max_steps, len(probs))
  
      self.best_action_value = probs.max().item()
  
imports: from abc import ABC, abstractmethod
  from functools import partial
  from multiprocessing import Pool
  from typing import Dict, List, Optional, Tuple, Type, Union
  import numpy
  import torch
  from reagent.mab.mab_algorithm import MABAlgo
  from torch import Tensor
label_desc: Use image node_id 1 to create a new BernoilliMAB object from inherited base classes: MAB with example: obj = BernoilliMAB(max_steps, probs, arm_ids)