我有一个问题,可以简化为以下问题陈述:
给定一系列双精度浮点数,每个数在范围[0, 1e7]之间,修改最后一个元素,使得这些数字的总和恰好等于目标数。这些双精度浮点数已经在epsilon(1e-7)内总和等于目标数,但它们不相等。
以下代码是有效的,但它是否保证对符合第一句中描述的所有输入都有效?
之前的问题是关于修改第一个元素的,但是修改最后一个元素可以将问题简化为已知总和和目标值,只需要回答是否
关于实际问题:我们在各种情况下多次遇到了这个问题,但是目前我们正在尝试减少线性规划求解器(Coin-OR CBC)中由于数值不稳定性而出现的浮点误差。例如,有6个变量都必须在 [0,X] 范围内,这些变量的和也必须为 X。由于数值不稳定性,求解器偶尔会返回略微负数和不完全等于 X 的值。我们已经解决了负数问题,现在只是尝试解决等于 X 的问题。(是的,我们可能违反了某些约束条件来更改结果,但确保这些数字加起来等于 X 是更重要的,而其他约束条件并不那么重要。)
给定一系列双精度浮点数,每个数在范围[0, 1e7]之间,修改最后一个元素,使得这些数字的总和恰好等于目标数。这些双精度浮点数已经在epsilon(1e-7)内总和等于目标数,但它们不相等。
以下代码是有效的,但它是否保证对符合第一句中描述的所有输入都有效?
public static double[] FixIt(double[] input, double targetDouble)
{
var result = new double[input.Length];
if (input.Length == 0) return result;
double sum = 0;
for (int i = 0; i < input.Length - 1; i++)
{
sum += input[i];
result[i] = input[i];
}
double remainder = targetDouble - sum;
result[result.Length - 1] = remainder;
return result;
}
var arr1 = Enumerable.Repeat(Math.PI / 13, 13).ToArray();
var arr2 = FixIt(arr1, Math.PI);
Debug.Print(Math.PI.ToString("R")); //3.1415926535897931
Debug.Print(arr1.Sum().ToString("R")); //3.1415926535897922
Debug.Print(arr2.Sum().ToString("R")); //3.1415926535897931
之前的问题是关于修改第一个元素的,但是修改最后一个元素可以将问题简化为已知总和和目标值,只需要回答是否
last = target-sum
意味着 sum+last == target
。(当然不包括 NaN,并且范围限制也意味着对 last
有一些限制,这可能有所帮助。)关于实际问题:我们在各种情况下多次遇到了这个问题,但是目前我们正在尝试减少线性规划求解器(Coin-OR CBC)中由于数值不稳定性而出现的浮点误差。例如,有6个变量都必须在 [0,X] 范围内,这些变量的和也必须为 X。由于数值不稳定性,求解器偶尔会返回略微负数和不完全等于 X 的值。我们已经解决了负数问题,现在只是尝试解决等于 X 的问题。(是的,我们可能违反了某些约束条件来更改结果,但确保这些数字加起来等于 X 是更重要的,而其他约束条件并不那么重要。)