Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果未知变量发生变化,是否有解决单个未知变量的通用方法?_C#_Algorithm_Symbolic Math - Fatal编程技术网

C# 如果未知变量发生变化,是否有解决单个未知变量的通用方法?

C# 如果未知变量发生变化,是否有解决单个未知变量的通用方法?,c#,algorithm,symbolic-math,C#,Algorithm,Symbolic Math,我有一个简单的代数关系,使用三个变量。我可以保证我知道三个变量中的两个,并且需要解第三个,但我不一定知道我会知道哪两个变量。我正在寻找一个单一的方法或算法,可以处理没有大量条件的任何情况。这可能是不可能的,但我希望在更一般的意义上实现它,而不是根据其他变量在每个关系中编写代码。 例如,如果这是关系: 3x - 5y + z = 5 我不想编写以下代码: function(int x, int y) { return 5 - 3x + 5y; } function(int x, int z

我有一个简单的代数关系,使用三个变量。我可以保证我知道三个变量中的两个,并且需要解第三个,但我不一定知道我会知道哪两个变量。我正在寻找一个单一的方法或算法,可以处理没有大量条件的任何情况。这可能是不可能的,但我希望在更一般的意义上实现它,而不是根据其他变量在每个关系中编写代码。 例如,如果这是关系:

3x - 5y + z = 5
我不想编写以下代码:

function(int x, int y)
{
  return 5 - 3x + 5y;
}

function(int x, int z)
{
  return (5 - z - 3x)/(-5);
}

等等。有没有一种标准的方法来处理这样的编程问题?可能使用矩阵、参数化等?

我不确定您在寻找什么,因为问题已标记,但您的示例代码生成的是数值解,而不是符号解

如果您想为更一般的情况找到数值解,那么请定义一个函数

f(x, y, z) = 3x - 5y + z - 5
并将其馈送给常规,以查找将生成根的未知参数的值。大多数根查找实现允许您在沿着问题的未锁定维度搜索根之前,将特定函数参数锁定为固定值。

没有解决此类问题的标准方法

在一般情况下,符号数学是由专门构建的库解决的问题,math.NET有一个您可能感兴趣的符号库:

具有讽刺意味的是,一个更难的问题,一个线性方程组,可以很容易地通过计算逆矩阵由计算机解决您可以用这种方式设置提供的等式,但是.NET中没有内置的通用矩阵类。

在您的特定情况下,您可以使用以下内容:

public int SolveForVar(int? x, int? y, int? z)
{
    int unknownCount = 0;
    int currentSum = 0;

    if (x.HasValue)
       currentSum += 3 * x.Value;
    else
       unknownCount++;

    if (y.HasValue)
       currentSum += -5 * y.Value;
    else
       unknownCount++;

    if (z.HasValue)
       currentSum += z.Value;
    else
       unknownCount++;

    if (unknownCount > 1)
       throw new ArgumentException("Too Many Unknowns");

    return 5 - currentSum;
}

int correctY = SolveForVar(10, null, 3);

显然,这种方法对于较大的变量计数来说非常笨拙,如果需要大量的动态数或复杂的运算,则不起作用,但它可以在一定程度上进行推广。

是的,这里有一个函数:

private double? ValueSolved (int? x, int? y, int? z)
    {
      if (y.HasValue && z.HasValue && !x.HasValue
         return (5 + (5 * y.Value) - z.Value) / 3;

      if (x.HasValue && z.HasValue && !y.HasValue
        return (5 - z.Value - (3 * x.Value)) / -5;

      if (x.HasValue && y.HasValue && !z.HasValue
        return 5 - (3 * x.Value) + (5 * y.Value);

      return null;
     }

如果你把自己限制在上面所示的线性函数中,你可以像这样推广这个函数

3x - 5y + z = 5
将成为

a[0]*x[0] + a[1]*x[1] + a[2]*x[2] = c
使用
a={3,-5,1}
c=5

也就是说,您需要一个常数因子的列表(或数组)
list a和变量列表
列表x加上右侧的常数
双c

public double Solve(IList<double> a, IList<double?> x, double c)
{
    int unknowns = 0;
    int unkonwnIndex = 0; // Initialization required because the compiler is not smart
                          // enough to infer that unknownIndex will be initialized when
                          // our code reaches the return statement.
    double sum = 0.0;

    if (a.Count != x.Count) {
       throw new ArgumentException("a[] and x[] must have same length");
    }
    for (int i = 0; i < a.Count; i++) {
        if (x[i].HasValue) {
           sum += a[i] * x[i].Value;
        } else {
           unknowns++;
           unknownIndex = i;
        }
    }
    if (unknowns != 1) {
       throw new ArgumentException("Exactly one unknown expected");
    }
    return (c - sum) / a[unknownIndex];
}
如示例所示,解决方案包括从常数中减去除未知项之外的所有项之和,然后除以未知项的因子。因此,我的解决方案记住未知的索引


假设你有方程,你可以用这样的幂来概括

a[0]*x[0]^p[0] + a[1]*x[1]^p[1] + a[2]*x[2]^p[2] = c
您需要一个附加参数
IList p
,结果变为

return Math.Pow((c - sum) / a[unknownIndex], 1.0 / p[unknownIndex]);
as
x^(1/n)
等于
n根(x)


如果对幂使用双精度,甚至可以表示如下函数

         5
7*x^3 + --- + 4*sqrt(z) = 11
        y^2

a = { 7, 5, 4 },  p = { 3, -2, 0.5 },  c = 11
因为

          1
x^(-n) = ---
         x^n


但是,您将无法找到真正的非线性多项式的根,如
x^2-5x=7
。上面显示的算法只有在未知项在等式中只出现一次时才有效。

这是显而易见的方法。我认为这个问题需要更一般的东西。是的,我可以像你上面所说的那样强行解决它,但我认为可能有一种更一般(算法或分析)的方法来解决这样的问题。
+1
可以正确概括我的想法。我不认为使用列表作为参数。是否使用列表或数组取决于所需的灵活性。由于两者都实现了
IList
,我将参数更改为
IList
,我想这只是一个基本的线性方程根查找器,但它可以根据需要推广到更高的维度,并且不需要基于先前未知知识的任何条件分支。我想我会实施这个,谢谢!我认为最后一个
if
和下面的
return
语句不应该在
for
循环中。@NikonthThird:你当然是对的。不知道他们是怎么到那里的。
          1
x^(-n) = ---
         x^n
nth-root(x) = x^(1/n)