我有这个问题,我想保留一个值列表并将它们标准化,以便所有值的总和为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?
答案 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
中的值,至少在拖动操作结束之前。