平衡一组数字的最佳解决方案

时间:2017-08-20 06:56:31

标签: javascript java c# python algorithm

所以我正在为一个侧面项目写作并尝试优化:

给定一组n个数(例如[4,10,15,25,3]),我们希望在给定的容差范围内使每个数字大致相同(即如果我们想要精确,那么它应该是11.4)在上面的例子中)。

我们可以添加/删除一个并添加到另一个。例如,我们可以从[3]和+5到[1],这将给我们[9,10,10,25,3]。

我所拥有的约束是我们想要最少数量的"转移"在每个数字之间(例如,如果我们从[3]做-3.6,那么它算作一个"转移")。

没有关于性能的讨论(大多数我可以看到它最多只有一组50个数字)但是真的希望将传输保持在最低限度。

我们可以假设容差为+/- 1,但可以动态改变。

2 个答案:

答案 0 :(得分:0)

在代码中,getMinMax函数足够简单,返回最小/最大值,索引和距离(减法的绝对值)

// the principle of the balance is to even the most different numbers in the set (min and max)

const balance = (threshold, arr) => {
    const toBalance = Object.assign([], arr);
    let mm = getMinMax(toBalance);

    while (mm.distance > threshold){
        toBalance[mm.maxIdx] -= mm.distance / 2;
        toBalance[mm.minIdx] += mm.distance / 2;
        mm = getMinMax(toBalance);
    }

    return toBalance;
}

测试它

const numbers = [4, 10, 15, 25, 3];
const threshold = 0;
const output = balance(threshold, numbers);
console.log(output);
// prints an array with four numbers of 11.4 (with some precision error)

答案 1 :(得分:0)

算法的目标是确保列表中的每个数字在给定的容差范围内大致相同。因此,如果容差为零,则所有数字必须等于列表中所有值的平均值(在整个算法中将保持不变)。考虑到容差,列表中的所有数字都必须属于包含间隔[average - 0.5*TOLERANCE, average + 0.5*TOLERANCE]

算法的主要迭代包括检索最大值和最小值,并从最大值到最小值“转移”,使得最远的值(这可能是最小值)或最大值落在所需的时间间隔内。此过程将迭代,直到最大值和最小值彼此相距不超过TOLERANCE个单位。

算法的伪代码如下所示:

target = average of the values in the list

while dist(max, min) > TOLERANCE
    x = maximum of dist(max, target) and dist(min, target)
    transfer (x - 0.5*TOLERANCE) units from maximum into minimum

dist(a, b)可以简单地定义为abs(a - b)

此算法平均运行时间约为O(n^2),需要的时间超过n次,其中n是值的数量。

这种算法所需的迭代次数不到一半,这种简单的次优方法只能平均每次迭代中的最小值和最大值。