python - 两个列表中术语差异的最小总和
问题描述
假设我有两个这样的 python 列表:
[30、400、500]
[55、396、478]
我想找到元素之间的最小(绝对值)差异的总和。在这种情况下,这很容易:(55-30) + (400-396) + (500-478) = 51
但是当列表没有相同数量的元素时,我将如何有效地做到这一点。例如:
设置 1:
list1 = [30, 400, 500]
列表 2 = [412, 489]
或者即使是
设置 2
list1 = [30, 400, 500]
列表 2 = [24, 563]
最后,
设置 3
list1 = [30, 50]
list2 = [20, 31, 90]
对于第 1 组,答案是 (412-400) + (500-489) = 23
对于第 2 组,答案是 (30-24) + (563-500) = 69
对于第 3 组,答案是 (30-20) + (50-31) =29
我无法按元素进行比较。在集合 1 中,通过将 list1 的第二个元素与 list2 的第一个元素进行比较,将 list1 的第三个元素与 list2 的第二个元素进行比较,得到最小差之和。在集合 2 中,通过将 list1 的第一个元素与 list2 的第一个元素进行比较,将 list1 的第三个元素与 list2 的第二个元素进行比较,得到最小差之和。
任何帮助表示赞赏。
其他一些信息:
- 列表的长度永远不会超过另一个列表的 2 倍,但是对于 list1 是更大的列表还是 list2 是更大的列表没有限制。
- 列表将按排序顺序
- 较短列表中的所有元素必须至少使用一次
解决方案
为了确保得到正确的答案,我将使用二分加权匹配,其中每对之间的 abs-diff 是权重。这将避免基于排序的方法的所有陷阱,例如
list1=[30, 50], list2=[20, 31, 90], ans= 29
大多数直观算法会将 30 与 31 配对。(给出总和 41)
这是使用 scipy 的解决方案linear_sum_assignment
:
import numpy as np
from scipy.optimize import linear_sum_assignment
def min_diff_sum(list1, list2):
arr1 = np.asanyarray(list1)
arr2 = np.asanyarray(list2)
cost_matrix = np.abs(arr1-arr2[:, None])
pairs = linear_sum_assignment(cost_matrix)
return np.sum(cost_matrix[pairs])
这应该总是给出正确的结果。
In [45]: min_diff_sum([30, 400, 500], [412, 489])
Out[45]: 23
In [46]: min_diff_sum([30, 400, 500], [24, 563])
Out[46]: 69
推荐阅读
- python - 从 Python 发送 HTML 电子邮件
- visual-studio-2017 - vs 2017 网络标准项目黄色警告标志
- uml - 与贷款数据库(关联或聚合)的贷款关系?UML
- vba - 如何在 VBA 中选择一个切片器 = true 和剩余 = false
- java - 以编程方式更改读取数据/anr 文件的权限
- javascript - 无法更新此 React 组件的状态
- amazon-web-services - 您如何授予多个用户访问一个 EC2 实例的权限?
- nginx - 尽管匹配位置并显示正确的应用程序,nginx 将 url 更改为基本路径
- proxy - 如何在没有 CA 或 MITM 的情况下通过 HTTP 代理 HTTPS?
- c++ - 为什么警告会阻止我们编写优化程序?