0

我想标准化粒子列表中的权重。这些权重属于粒子对象。我尝试通过将它们除以权重之和来标准化它们。所有的重量都以双打形式声明。当程序从列表的开头开始除法时,值是正确的,但是在第二次或第三次除法之后不久,我得到了错误的结果..这导致运算后的权重总和不是 1,它应该。谁能帮我解决这个问题?也许与线程有关?提前谢谢..

// normalizing weights
double weightsum = 0;
double check = 0;
List<ParticleRobot> temporalparticleSet = new List<ParticleRobot>();

for (int i = 0; i < particleSet.Count; i++)
{
    weightsum = weightsum + this.particleSet[i].Weight;
}

Program.Weightsum = weightsum;

Console.WriteLine("Sum of unnormalized particleweights is " + weightsum);

foreach (ParticleRobot p in this.particleSet)
{
    Program.Weight = p.Weight;
    p.Weight = Program.Weight / Program.Weightsum;
    Console.WriteLine("Updated Particleweight is now : " + p.Weight);
}

// checking that they sum up to 1
for (int i = 0; i < particleSet.Count; i++)
{
    check = check + this.particleSet[i].Weight;
}

Console.WriteLine("Check: Sum of particles-weights is = " + check);
4

4 回答 4

0

可能不是线程问题。在任何数值分析书籍中阅读浮点数学。查看http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html。舍入误差、精度问题、取消问题都可能造成影响。

于 2011-12-15T02:28:55.097 回答
0

首先,什么是 temporalparticleSet?您实际上是要循环遍历它而不是 this.particleSet 吗?除此之外,我根本看不到代码有任何问题。我会修改:

Program.Weight = p.Weight;
p.Weight = Program.Weight / Program.Weightsum;

p.Weight = p.Weight / Program.Weight;

p.Weight 也是双倍的吗?可能是一些四舍五入的问题。您是否尝试过使用断点并单步执行?

于 2011-12-15T02:29:07.657 回答
0

我会担心 Program.Weight 会修改它分配的值或者不是相同的数据类型。

我会尝试更改以下几行:

        Program.Weight = p.Weight;
        p.Weight = Program.Weight / Program.Weightsum;

        p.Weight = p.Weight / Program.Weightsum;

还需要考虑舍入误差。

于 2011-12-15T02:33:24.453 回答
0

大量数字的累积可能会失去精度。这里有两种可以提供帮助的技术:

  1. 将权重按重量递增的顺序求和,从最轻的开始到最重的进行。如果数字可以是负数,则按数量级递增的顺序求和。
  2. 使用Kahan 求和算法来累加权重。这比(1)更容易,因为不需要先对数组进行排序。
  3. 如果总和与最小权重的比例很大,例如 10^16,则使用上述两种方法。
于 2011-12-16T22:15:13.237 回答