【问题标题】:Algorithm for scaling one list of ranges to another将一个范围列表缩放到另一个范围的算法
【发布时间】:2014-03-14 00:05:56
【问题描述】:

我有一个恒定的基本列表,如下所示:

[50, 100, 150, 200, 500, 1000]

该列表定义了范围:0 到 50、50 到 100,一直到 1000 到无穷大。

我想编写一个函数,用于将任何数字列表转换为与上述兼容的列表。 “兼容”是指它只有该列表中的数字,但数字尽可能接近原始值。因此,对于[111, 255, 950] 的示例输入,我会得到[100, 200, 1000]。到目前为止,我有一个像这样工作的天真的代码:

for each i in input
{
    calculate proximity to each number in base list
    get the closest number
    remove that number from the base list
    return the number
}

这适用于大多数情况,但当输入比例失控时就会崩溃。当我有一个像[1000, 2000, 3000] 这样的输入时,第一个数字从基本列表中获取最后一个数字,然后 2000 和 3000 分别获得 500 和 200(因为已经采用了 1000 和 500)。这会产生一个向后列表[1000, 500, 200]

我该如何防范呢?

【问题讨论】:

  • 有效地找到最接近的值 - 很容易。这样做可以使每个数字最多使用一次 - 有点困难。
  • [1000, 500, 200] 有什么问题?差异的总和与 [200, 500, 1000] 相同,所以我看不出它是如何次优的。请定义您要优化的度量
  • 如果我们按降序对输入进行排序并遵循您的流程会怎样。像 [3000,2000,1000] - 很明显你已经从你的基地的最后一个开始比较以获得更快的速度。
  • @NiklasB。问题是数字定义了范围,而我在向后列表中得到了负范围。
  • 好的,所以你想要非递减订单。您希望最小化什么措施?

标签: algorithm list language-agnostic numbers


【解决方案1】:

方法 1

这可以通过使用Hungarian algorithm 在 O(n^3) 时间内解决,其中 n 为 max(len(list),len(input))。

首先建立一个矩阵,给出将每个输入分配给列表中每个数字的成本。

matrix[i,j] = abs(input[i]-list[j])

然后使用匈牙利算法找到输入与列表中数字匹配的最小成本。

如果列表中的数字多于输入,则添加一些额外的虚拟输入,它们与列表中的任何数字匹配的成本为零。

方法2

如果第一种方法太慢,那么您可以使用动态规划来计算最佳拟合。

这个想法是计算一个函数 A(a,b),它给出第一个 a 输入与列表中前 b 个数字的最佳匹配。

A(a,b) = min( A(a-1,b-1)+matrix[a,b], A(a,b-1) )

这应该给出一个 O(n^2) 的解决方案,但需要更多的努力才能读回解决方案。

【讨论】:

  • 我认为对于 DP,必须对列表进行排序
  • 这个算法会节省空间吗?它似乎需要 min O(n*m)。
  • @Mani 您可以在 O (n) 中实现它,因为您完全需要两行 DP 表。运行时间是二次方的,但不确定是否值得努力
猜你喜欢
  • 2021-01-16
  • 1970-01-01
  • 2021-07-14
  • 1970-01-01
  • 1970-01-01
  • 2015-07-22
  • 1970-01-01
  • 2020-03-03
  • 1970-01-01
相关资源
最近更新 更多