code: def get_neighbours(y):
          r
          onBits     = np.where( y == 1. )[0]
          offBits    = np.where( y == 0. )[0]
          neighbours = [y.copy()]
  
          for on in onBits:
              z     = y.copy()
              z[on] = 0.
              neighbours.append(z)
  
          for off in offBits:
              z      = y.copy()
              z[off] = 1.
              neighbours.append(z)
  
          # np.random.shuffle(neighbours)
  
          return neighbours
docs: r"""
          Returns a neigbourhood $N$ of $y$ consisting of elements that 
          share $|y| - 1$ bits with $y$, i.e 
          $$
                      N(y) = \{ x : x^T \cdot y  = |y| - 1  \}
          $$