使用一个固定值标准化矢量

时间:2013-09-06 15:17:48

标签: c#

我有这个问题,我想保留一个值列表并将它们标准化,以便所有值的总和为1.

我找到this question,但有一点不同。我想要修复1个值。因为,有4个GUI滑块,我拖了一个。其他3应相应更新,以使总和为1。

// Let's keep 0.6 fixed and try to normalize the rest
List<float> categories = new List<float>() { 0.6f,0.3f,0.25f,0.25f };

// find the max value of the rest of the values that is not the fixed number
float maxval = categories.Where(s => s != 0.6f).Max();

if (maxval != 0) // check if not all other 
{
    // calculate the ratio
    float ratio = (1 - 0.6f) / maxval;

    foreach (float s in categories)
    {
        if (s != 0.6f)
        {
            s *= ratio;
        }
    }
}
else // all values are 0, so just add the rest value
{
    // do something else that is correct
}

不幸的是这个例子会返回:

{ 0.6f, 0.4f, 0.33f, 0.33f } => sum is 1.66f

还有一些我误解的事情。有人能给我一些关于如何将其余值归一化为余额(0.4f)的线索,以便所有值的总和为1?

2 个答案:

答案 0 :(得分:5)

你错误地计算了它。

如果你有一个4个元素,其中一个是固定的,总和需要为1,你就会这样:

ratio = (1-fixedElement) / sumOfAllOtherElements;

EachNonFixedElement *= ratio;

您正在使用最大值计算比率,但您需要使用所有非固定元素的总和来计算它。

答案 1 :(得分:0)

在其他问题中,这个循环没有达到预期效果:

foreach (float s in categories) {
    if (s != 0.6f) {
        s *= ratio;
    }
}

s是来自categories的其中一个值的本地副本。您修改副本,然后它超出范围,您的新值将消失。您从未修改过categories

C#foreach不能用于修改集合。

此外,为了避免累积大的舍入错误,您应该存储到新的集合而不是替换categories中的值,至少在拖动操作结束之前。