如何规范化 float 集合,使所有元素的总和为 X

How to normalize a float collection such that the sum of all elements is X

如果这个问题措辞不当或者解决方案很简单,请原谅我。我似乎找不到使用我熟悉的术语搜索的现有答案。

我有一个非负浮点数数组,我想对它们进行归一化 - 我能做的就这些。我的问题是,我希望集合中所有元素的总和为特定数量。

我可以设想实现此目标的丑陋方法,但我只知道有一种 "right" 方法可以实现。目的是创建一个总宽度必须固定的复合条形图。集合中的每个数据点都分配了一种颜色,该颜色应占总条形图宽度的 N%。我受限于图表显示方式。

如果需要代码,最好使用 C# 示例。

// normalize data        
var ratio = 100.0 / widths.Max();
var normalizedList = widths.Select(o => o * ratio).ToList();
// magic happens here such that the sum of all elements is N
// and the relative scale of each sibling element is preserved

非常感谢您的帮助,


补充信息: 该图是复合(分段)条形图。 float 集合的每个元素对应一个段。 http://oi62.tinypic.com/2vskt8m.jpg

元素之和为N法则的必要性与作图方法有关,本人权限有限。

为了达到我想要的宽度(由这个 float 集合驱动的图形视觉效果),所有元素的总和必须是一个特定的数字,因此要进行归一化。但是,元素的数量和它们的值都会发生变化,我不清楚如何以任何其他方式对此进行补偿。出于许多无关的原因,以任何其他方式缩放图形视觉效果以避免这种混乱是不可取的。

可能有更完善的方法来解决这个问题,但是:

  • 基于 1 对整个集合进行归一化
  • 计算归一化集合的总和作为Sum。
  • 将每一项乘以 (DesiredSum / Sum)

我没试过,只是 运行 我脑海中的几个基本示例,但它应该涵盖它。

我相信数学方程会是

s= s0 + s1 + s2 + ...

a= size / s

a * s = a* (s0 + s1 + s2 + ...)

a * s = a*s0 + a*s1 + a*s2 + ...

所以这应该可以解决问题

        var total = widths.Sum();
        var size=100;
        var ratio = size/total; //a in the equation
        var normalizedList = widths.Select(o => o * ratio).ToList();

        var normalSum = normalizedList.Sum(); //should be equal to size

我认为你的比例有点不对。你需要的是你想要的总数除以所有元素的总和。例如

int desiredTotal = 300; 

float[] widths = new float[] { 35f, 63f, 12f };

float ratio = desiredTotal / widths.Sum();
var normalizedList = widths.Select(o => o * ratio).ToList();

foreach (var item in normalizedList)
{
    Console.WriteLine(item);
}

Console.WriteLine(normalizedList.Sum());

/* Which prints:
95.45454
171.8182
32.72727
300
*/