Returns an integer that represents the winning candidate given an election profile.
    The winner has the largest score.
    Tie-breaking rule: numerically increasing order

    :ivar Profile profile: A Profile object that represents an election profile.
    :ivar list<int> scoringVector: A list of integers (or floats) that give the scores assigned to
        each position in a ranking from first to last.

def MoVScoring(profile, scoringVector):
    """
    Returns an integer that represents the winning candidate given an election profile.
    The winner has the largest score.
    Tie-breaking rule: numerically increasing order

    :ivar Profile profile: A Profile object that represents an election profile.
    :ivar list<int> scoringVector: A list of integers (or floats) that give the scores assigned to
        each position in a ranking from first to last.
    """
    # 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()

    winners = MechanismPosScoring(scoringVector).getWinners(profile)
    if len(winners) > 1:
        return 1
    n = profile.numVoters
    m = profile.numCands
    if len(scoringVector) != m:
        print("ERROR: the length of the scoring vector is not correct!")
        exit()

    # Construct the score matrix--values
    prefcounts = array(profile.getPreferenceCounts())
    rankmaps = profile.getRankMaps()
    len_prefcounts = len(prefcounts)
    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] = scoringVector[rankmaps[i][j] - 1]

    # Compute the scores of all the candidates
    score = dot(array(prefcounts), values)
    # Compute the winner of the original profile

    d = argmax(score, axis=0) + delta
    # print("d=",d)
    alter = delete(range(delta, m + delta), d - delta)
    # Initialize
    MoV = n * ones(m, dtype=int)
    # for c in [3]:
    for c in alter:
        # The difference vector of d and c
        difference = values[:, c - delta] - values[:, d - delta]
        # print("dif=", difference)
        index = argsort(difference, axis=0, kind='mergesort')
        # The vector that each element is the gain in the difference
        # between d and c if the pattern of the vote changed to [c > others > d]
        change = scoringVector[0] - difference

        # The total_difference between score(d) and score(c)
        total_difference = score[d - delta] - score[c - delta]
        # print("total-dif=", total_difference)
        for i in range(len_prefcounts):
            # The number of votes of the first i kinds of patterns
            temp_sum = sum(prefcounts[index][0:i])
            # print("temp_sum=", temp_sum)

            # The aggregate gain (of the first i kinds of patterns)
            # in the difference between d and c if changed to [c > others > d]
            lower_bound = dot(prefcounts[index][0:i], change[index][0:i])
            # print("lower_bound=", lower_bound)

            # The aggregate gain (of the first i+1 kinds of patterns)
            # in the difference between d and c if changed to [c > others > d]
            upper_bound = dot(prefcounts[index][0:i + 1], change[index][0:i + 1])
            # print("upper_bound=", upper_bound)
            # if lower_bound < total_difference <= upper_bound:
            if lower_bound <= total_difference < upper_bound:
                # MoV[c - delta] = temp_sum + math.floor(float(total_difference - lower_bound)/change[index][i]) + 1
                # Update on Apr 13 2019
                MoV[c - delta] = temp_sum + math.ceil(float(total_difference - lower_bound) / change[index][i])
                break
    # print("MoV=", MoV)
    return min(MoV)