'Sample the most probable alignments from the entire alignment
space
First, determine the best alignment according to IBM Model 2.
With this initial alignment, use hill climbing to determine the
best alignment according to a higher IBM Model. Add this
alignment and its neighbors to the sample set. Repeat this
process with other initial alignments obtained by pegging an
alignment point.
Hill climbing may be stuck in a local maxima, hence the pegging
and trying out of different alignments.
:param sentence_pair: Source and target language sentence pair
to generate a sample of alignments from
:type sentence_pair: AlignedSent
:return: A set of best alignments represented by their ``AlignmentInfo``
and the best alignment of the set for convenience
:rtype: set(AlignmentInfo), AlignmentInfo'

def sample(self, sentence_pair):

    sampled_alignments = set()
    l = len(sentence_pair.mots)
    m = len(sentence_pair.words)
    initial_alignment = self.best_model2_alignment(sentence_pair)
    potential_alignment = self.hillclimb(initial_alignment)
    sampled_alignments.update(self.neighboring(potential_alignment))
    best_alignment = potential_alignment
    for j in range(1, (m + 1)):
        for i in range(0, (l + 1)):
            initial_alignment = self.best_model2_alignment(sentence_pair, j, i)
            potential_alignment = self.hillclimb(initial_alignment, j)
            neighbors = self.neighboring(potential_alignment, j)
            sampled_alignments.update(neighbors)
            if (potential_alignment.score > best_alignment.score):
                best_alignment = potential_alignment
    return (sampled_alignments, best_alignment)
