展开过于接近的数组值

时间:2015-11-16 14:55:27

标签: algorithm vba optimization

我有一个数组中的值列表(从低到高排序),我打算显示这些值分布在一行上,但由于某些值接近,这些点最终会重叠。由于确切的值并不重要,小的调整无关紧要,我正在尝试制作一些代码,这些代码可以传播任何值的集群,使得它们比其他任何值都更接近.5。

例如,假设我们有这个数组:

my_values = { 0.2, 1.3, 2.0, 2.1, 2.5, 3.6, 5.2 }

2.0,2.1和2.5太靠近了,所以我需要移动它们,因此它们不会比.5更接近但是尽可能接近实际值。因此,最佳解决方案将是:

my_values = { 0.2, 1.1, 1.6, 2.1, 2.6, 3.6, 5.2 }

到目前为止,这是我的代码,它只是对解决方案的蹩脚尝试(我的代码中列表中的实际项目是具有get / set函数的对象,但原理是相同的):

...
last_dot = -999 'Low enough
For Each dot In my_values
    If dot.getPos <= last_dot + 0.5 Then
        dot.setPos last_dot + 0.5
    End If
    last_dot = dot.getPos
Next dot

有些事情我不确定如何解决: 我喜欢将它们上下传播,所以任何一个cluser的中心都不会被移动。到目前为止,我所做的每一个动作都只是提高了值,并且群集的最后一个值比其他值更加偏移,最好是向上移动的任何值都应该向下移动另一个值。保持任何值的最大调整尽可能低。所以在上面的列表中,当2.0向下移动到1.6时,它太接近1.3,所以必须移动到1.1,但在我的代码中我不知道在检查1.3项时。 (不确定我是否解释过,所以任何人都可以理解= /)

任何有用的帮助!

1 个答案:

答案 0 :(得分:2)

整个阵列的迭代放松:

输入:

 { 0.2, 1.3, 2.0, 2.1, 2.5, 3.6, 5.2 }

功能:

    for (int j = 0; j < 100; j++)// 100 is extreme, maybe 20 is enough for short anomalies
    {
        for (int i = 0; i < t.Length - 1; i++)
        {
            if (t[i] > t[i + 1] - 0.5)
            {
                t[i] -= (t[i] - (t[i + 1] - 0.5)) * 0.1;
            }
        }
        for (int i = t.Length - 1; i >= 1; i--)
        {
            if (t[i] < t[i - 1] + 0.5)
            {
                t[i] -= (t[i] - (t[i - 1] + 0.5)) * 0.1;
            }
        }
    }

结果:

0,2
1,00031552491128
1,61163875308098
2,1160023905259
2,66
3,6
5,2

警告:当只需要改变一些元素时,O(n)效率不高。

编辑:将代码更正为A.S.H.评论

新输出:

0,2
1,21857842635286
1,71823144559425
2,21771136663457
2,71733660405361
3,6
5,2

因此它看起来更加对称,现在更接近点2.05,这是点太近的点的中点。