docs: def _run_mplp(self, no_iterations):
          """
          Updates messages until either Mplp converges or if doesn't converges; halts after no_iterations.
  
          Parameters
          --------
          no_iterations:  integer
                          Number of maximum iterations that we want MPLP to run.
          """
          for niter in range(no_iterations):
              # We take the clusters in the order they were added in the model and update messages for all factors whose
              # scope is greater than 1
              for factor in self.model.get_factors():
                  if len(factor.scope()) > 1:
                      self._update_message(self.cluster_set[frozenset(factor.scope())])
              # Find an integral solution by locally maximizing the single node beliefs
              self._local_decode()
              # If mplp converges to a global/local optima, we break.
              if self._is_converged(self.dual_threshold, self.integrality_gap_threshold) and niter >= 16:
                  break