两个列表之间的值差异

时间:2019-04-02 23:55:13

标签: python

我正在研究一个练习问题,想使用递归找到两个列表之间的最小差异。例如,如果我有一个列表X,其值分别为[79、85、10]和一个列表,Y,其值分别为[78、80、87、12],则视差为4。

我尝试遍历两个列表,无法弄清楚如何找到差异的最小和,而不是仅返回对。

我希望此函数返回成对的滑雪者和滑雪者,但不能返回代表两个给定列表之间最小差异的总和。

3 个答案:

答案 0 :(得分:1)

一种解决方案是使用NumPy在滑雪板列表中找到最接近的值(从Find nearest value in numpy array借用的NumPy函数)。然后遍历滑雪者并找到最接近的尺码。请记住,然后从列表中删除该大小。

import numpy as np

def find_nearest(array, value):
    array = np.asarray(array)
    idx = (np.abs(array-value)).argmin()
    return array[idx]

def pair(x, y):
    skier_skis = []
    skis_left = list(y)
    for skier in x:
        skier_skis.append((skier, find_nearest(skis_left, skier)))
        skis_left.remove(skier_skis[-1][1])
    return skier_skis

skiers = [6, 11, 13]
skis = [5, 7, 9, 14]
pair(skiers, skis)

返回[(6,5),(11,9),(13,14)]。

如果您的目标只是返回最小视差,请遍历skier_skis列表并求和。

编辑:正如@Rivers Shall指出的那样,这可能并不总是返回最佳解决方案。

答案 1 :(得分:1)

这里有不同的方法,一种是蛮力的:

from itertools import combinations


def best_match_brute(skiers, skis):
    all = [list(zip(skiers, c)) for c in combinations(skis, len(skiers))]
    all_with_disparity = [(sum([abs(x-y) for x, y in result]), result) for result in all]
    # assuming the best result is any one with the lowest disparity
    return sorted(all_with_disparity )[0]


def main():
    # making sure the collections are sorted to begin with
    skiers = sorted([6, 11, 13])
    skis = sorted([5, 7, 9, 14])

    # all skiers should be able to get skis
    assert len(skis) >= len(skiers)

    print(best_match_brute(skiers, skis))


if __name__ == '__main__':
    main()

如果您甚至坚持不使用诸如itertools.combinations之类的标准库函数,那么我想您也可以自制,但是我不明白这一点:

def combinations(xs, n):
    if n == 1:
        for x in xs:
            yield [x]
    else:
        while len(xs) >= n:
            x = xs[0]
            xs = xs[1:]
            for c in combinations(xs, n-1):
                yield [x] + c

答案 2 :(得分:0)

对不起,@ minterm发布的算法似乎是错误的。考虑skiers = [2, 12], skis = [0, 3]。 @minterm程序给出[(2, 3), (12, 0)]的最佳解是[(2,0), (12, 3)]。 @minterm使用的算法是一种贪婪算法,始终需要严格的证明来证明其正确性。

我认为这是maximum-weight matching problem。我们可以将skiersskis中的元素视为顶点,并且在每个元素skiers[i]skis[j]之间放置一条权重为abs(skiers[i], skis[j])的边。因此,示例类似于下图:

enter image description here