Returns an integer that is equal to the margin of victory of the election profile, that is,
    the smallest number k such that changing k votes can change the winners.

    :ivar Profile profile: A Profile object that represents an election profile.

def MoVSimplifiedBucklin(profile):
    """
    Returns an integer that is equal to the margin of victory of the election profile, that is,
    the smallest number k such that changing k votes can change the winners.

    :ivar Profile profile: A Profile object that represents an election profile.
    """

    # Currently, we expect the profile to contain complete ordering over candidates.
    elecType = profile.getElecType()
    if elecType != "soc" and elecType != "csv" and elecType != "toc":
        print("ERROR: unsupported profile type")
        exit()

    # Initialization
    n = profile.numVoters
    m = profile.numCands
    half = math.floor(float(n) / 2)
    prefcounts = profile.getPreferenceCounts()
    len_prefcounts = len(prefcounts)
    rankmaps = profile.getRankMaps()
    values = zeros([len_prefcounts, m], dtype=int)
    if min(list(rankmaps[0].keys())) == 0:
        delta = 0
    else:
        delta = 1
    for i in range(len_prefcounts):
        for j in range(delta, m + delta):
            values[i][j - delta] = rankmaps[i][j]

    winners = MechanismSimplifiedBucklin().getWinners(profile)  # the winner list
    d = winners[0]  # the winner under the numerically tie-breaking rule
    alter = delete(range(delta, m + delta), d - delta)
    # Initialize MoV
    MoV = n * ones(m, dtype=int)
    for c in alter:
        for ell in range(1, int(math.floor(float(m) / 2)) + 2):
            numcond1 = sum(dot(array(prefcounts), logical_and(values[:, c - delta] > ell, values[:, d - delta] <= ell - 1)))
            numcond2 = sum(dot(array(prefcounts), logical_and(values[:, c - delta] > ell, values[:, d - delta] > ell - 1)))
            numcond3 = sum(dot(array(prefcounts), logical_and(values[:, c - delta] <= ell, values[:, d - delta] <= ell - 1)))
            diff_c = half - sum(dot(array(prefcounts), (values[:, c - delta] <= ell)))
            diff_d = half - sum(dot(array(prefcounts), (values[:, d - delta] <= ell - 1)))
            if diff_c < 0:
                if diff_d < 0 and numcond1 + numcond3 > abs(diff_d):
                    MoV[c - delta] = min(MoV[c - delta], abs(diff_d))
                continue
            # -------diff_c >= 0------------
            if diff_d >= 0:
                if numcond1 + numcond2 > diff_c >= 0:
                    MoV[c - delta] = min(MoV[c - delta], diff_c + 1)
            else:
                if numcond1 > diff_c and numcond1 > abs(diff_d):
                    MoV[c - delta] = min(MoV[c - delta], max(diff_c + 1, abs(diff_d)))
                elif diff_c >= numcond1 > abs(diff_d):
                    if numcond1 + numcond2 > diff_c:
                        MoV[c - delta] = min(MoV[c - delta], diff_c + 1)
                elif abs(diff_d) >= numcond1 > diff_c:
                    if numcond1 + numcond3 > abs(diff_d):
                        MoV[c - delta] = min(MoV[c - delta], abs(diff_d))
                else:  # numcond1 <= diff_c and numcond1 <= abs(diff_d)
                    if numcond1 + numcond2 > diff_c and numcond1 + numcond3 > abs(diff_d):
                        MoV[c - delta] = min(MoV[c - delta], numcond1 + abs(diff_c) + 1 + abs(diff_d))

    return min(MoV)