对阵列变化范围进行微小更改

时间:2014-01-12 21:16:45

标签: arrays algorithm

考虑让数组填充元素a0,a1,a2,....,a(n-1)。 考虑一下这个数组已经排序了;描述问题会更容易。

现在,数组的范围被定义为最大元素 - 最小元素。 假设此范围是某个值x。 现在我遇到的问题是,我想以这样一种方式改变元素,使得范围小于/等于某个目标值y

我还有一个额外的约束,我想改变每个元素的最小数量。考虑具有值a(i)的元素z。如果我按r金额更改,则费用为r^2

因此,更新此阵列以使范围小于或等于目标范围y以最小化成本的有效算法是什么。

一个例子:

Array = [ 0, 3, 19, 20, 23 ] Target range is 17.

我会创建新数组[ 3, 3, 19, 20, 20 ]。费用为(3)^2 + (3)^2 = 18

这是最低成本。

如果要添加/删除某些元素a(i),则必须一次添加/删除该数量q。您不能从某个元素中删除3个1单位,但必须删除一个3个单位的数量。

2 个答案:

答案 0 :(得分:1)

我认为你可以从数组中构建两个堆 - 一个最小堆,一个最大堆。现在,您将采用堆叠的顶部元素并查看它们下方的元素并比较差异。如果差异大于您的需求,那么您将获得更大的差异,您将只需要所需的尺寸并增加成本。

现在,如果你必须完全改变并且没有实现目标,那么你需要重复这一步。但是,如果您再次从同一个堆中进行选择,则必须记住在该步骤中添加从堆中取出的元素的成本以及之前从已处理堆中取出的那些成本。

这会产生O(N * logN)算法,我不确定它是否可以更快地完成。

示例:

数组[2,5,10,12],我想要差异4。 第一个堆有2个顶部,第二个堆12个,2个远离5个,12个远离10个,所以我采用最小堆,两个必须改为3.所以现在我们有了新的情况: [5,10,12] 12是远离10的2,我们接受它,减去2并获得新的情况: [5,10] 现在我们可以选择任何堆,两者的差异都是相同的(相同的数字:-))。我们只需要改变1,所以我们从10中减去1得到正确的结果。现在,因为我们将5改为6,所以我们还必须将最初12的数字再次更改为9,以便产生成本:

[2 - 改为5,5 - 未改变,10 - 改为9,12 - 改为9]。

答案 1 :(得分:1)

这是一种线性时间算法,可以最小化分段二次目标函数。可能它可以简化。

设范围为[x,x + y],其中x是变量。对于x的不同选择,由2n个临界值a0-y,a1-y,...,a(n-1)-y,a0,最多有2n + 1种可能性,其中点位于该范围内。 a1,...,a(n-1)。一个线性时间合并按排序顺序生成临界值。对于范围包含至少一个点的临界值之间的2n-1个区间[w,z]中的每一个,我们可以构造并最小化由每个点aj小于w得到一个项的和的二次函数(x - aj)^ 2并且每个点aj大于z + y产生项(x + y-aj)^ 2。全局最小值取决于aj(对于第一种类型的术语)或aj-y(对于第二种类型的术语)的均值;还必须检查间隔的端点。天真地,这给出了二次时间算法。

要降低线性时间,只需逐步更新平均值计算之前的总和即可。每个关键值都有一个相关的事件,指示负责它的点是进入还是离开间隔,这意味着该点的术语应该进入或离开总和。