class_docstr: Abstract base class for all IBM models
class_docstr_tok: ["Abstract","base","class","for","all","IBM","models"]
docstr: Starting from the alignment in ``alignment_info``, look at
  neighboring alignments iteratively for the best one
  
  There is no guarantee that the best alignment in the alignment
  space will be found, because the algorithm might be stuck in a
  local maximum.
  
  :param j_pegged: If specified, the search will be constrained to
      alignments where ``j_pegged`` remains unchanged
  :type j_pegged: int
  
  :return: The best alignment found from hill climbing
  :rtype: AlignmentInfo
docstr_tok: ["Starting","from","the","alignment","in","``","alignment_info","``",",","look","at","neighboring","alignments","iteratively","for","the","best","one","There","is","no","guarantee","that","the","best","alignment","in","the","alignment","space","will","be","found",",","because","the","algorithm","might","be","stuck","in","a","local","maximum",".",":","param","j_pegged",":","If","specified",",","the","search","will","be","constrained","to","alignments","where","``","j_pegged","``","remains","unchanged",":","type","j_pegged",":","int",":","return",":","The","best","alignment","found","from","hill","climbing",":","rtype",":","AlignmentInfo"]
code: def hillclimb(self, alignment_info, j_pegged=None):
      """
      Starting from the alignment in ``alignment_info``, look at
      neighboring alignments iteratively for the best one
  
      There is no guarantee that the best alignment in the alignment
      space will be found, because the algorithm might be stuck in a
      local maximum.
  
      :param j_pegged: If specified, the search will be constrained to
          alignments where ``j_pegged`` remains unchanged
      :type j_pegged: int
  
      :return: The best alignment found from hill climbing
      :rtype: AlignmentInfo
      """
      alignment = alignment_info  # alias with shorter name
      max_probability = self.prob_t_a_given_s(alignment)
  
      while True:
          old_alignment = alignment
          for neighbor_alignment in self.neighboring(
              alignment, j_pegged
          ):
              neighbor_probability = self.prob_t_a_given_s(
                  neighbor_alignment
              )
  
              if neighbor_probability > max_probability:
                  alignment = neighbor_alignment
                  max_probability = neighbor_probability
  
          if alignment == old_alignment:
              # Until there are no better alignments
              break
  
      alignment.score = max_probability
      return alignment
  
imports: from bisect import insort_left
  from collections import defaultdict
  from copy import deepcopy
  from math import ceil
label_desc: Use image node_id 7 for calling the IBMModel obj's underlying member method code with example usage: obj.hillclimb(alignment_info, j_pegged) and returns: alignment