📜  用最好的直线表示给定的一组点

📅  最后修改于: 2021-10-23 08:32:39             🧑  作者: Mango

找到 m 和 c 的值,使得一条直线 y = mx + c,最能代表给定点集 (x _1   , y _1   ), (X _2   , y _2   ), (X _3   , y _3   ), ……。, (X _n   , y _n   ),给定 n >=2。

例子:

输入:n = 5 x _1 = 1, x _2 = 2, x _3 = 3, x _4 = 4, x _5 = 5 年_1 = 14, y _2 = 27, y _3 = 40, y _4 = 55, y _5 = 68 输出: m = 13.6 c = 0 如果我们取任何一对数 ( x _i , y _i ) 从给定的数据中,m 和 c 的这些值应该使其最适合直线方程 y = mx + c。取 x _1 = 1 和 y _1 = 14,然后使用输出中的 m 和 c 的值,并将其放入以下等式中,y = mx + c,LHS:y = 14,RHS:mx + c = 13.6 x 1 + 0 = 13.6 所以,它们大致相等。现在,取 x _3 = 3 和 y _3 = 40,LHS:y = 40,RHS:mx + c = 13.6 x 3 + 0 = 40.8 因此,它们也大致相等,对于所有其他值依此类推。输入:n = 6 x _1 = 1, x _2 = 2, x _3 = 3, x _4 = 4, x _5 = 5, x _6 = 6 年_1 = 1200, y _2 = 900, y _3 = 600, y _4 = 200, y _5 = 110, y _6 = 50 输出:m = -243.42 c = 1361.97

方法

为了最好地拟合直线方程中的一组点,我们需要找到两个变量 m 和 c 的值。现在,由于有 2 个未知变量,并且取决于 n 的值,因此可能有两种情况——

情况 1 – 当 n = 2 时:将有两个方程和两个未知变量需要查找,因此将有唯一解。
情况 2 – 当 n > 2 时:在这种情况下,可能存在也可能不存在满足所有 n 个方程的 m 和 c 的值,但是我们可以找到 m 和 c 的最佳可能值,它们可以拟合一条直线给定的点。

所以,如果我们有 n 对不同的 x 和 y,那么,我们可以形成 n no。来自它们的直线方程,如下

F _1 = mx _1 + c, f _2 = mx _2 + c, f _3 = mx _3 + c, …………………………….., … …………………………, F _n = mx _n + c, 其中, f _i , 是将 x 放入后得到的值_i在等式 mx + c 中。

那么,由于理想情况下 f _i   应该和 y 一样_i   ,但我们仍然可以找到 f _i   最接近 y _i   在所有情况下,如果我们取一个新的量,U = ?(y _i   – F _i   ) ^2   ,并使这个数量对于从 1 到 n 的所有 i 值最小。

注: (y _i   – F _i   ) ^2   用于代替 (y _i   – F _i   ),因为我们要考虑两种情况,当 f _i   或者当你_i   更大,我们希望它们的差异最小,所以如果我们不平方这个项,那么f的情况_i
更大,y 的情况_i   更大会在一定程度上相互抵消,这不是我们想要的。所以,我们需要对这个词进行平方。

现在,要使 U 最小,它必须满足以下两个等式 –

\frac{\partial U}{\partial m} = 0 和\frac{\partial U}{\partial c} = 0。

求解上述两个方程,我们得到两个方程,如下:

?y = nc + m?x, ?xy = c?x + m?x ^2 , 可以重新排列为 – m = (n * ?xy – ?x?y) / (n * ?x ^2 – (?X) ^2 ), 和 c = (?y – m?x) / n,

因此,这就是获得这两种情况下 m 和 c 值的方式,我们可以用最好的直线表示给定的一组点。

下面的代码实现了上面给出的算法——

C++
// C++ Program to find m and c for a straight line given,
// x and y
#include 
#include 
using namespace std;
 
// function to calculate m and c that best fit points
// represented by x[] and y[]
void bestApproximate(int x[], int y[], int n)
{
    float m, c, sum_x = 0, sum_y = 0, sum_xy = 0, sum_x2 = 0;
    for (int i = 0; i < n; i++) {
        sum_x += x[i];
        sum_y += y[i];
        sum_xy += x[i] * y[i];
        sum_x2 += pow(x[i], 2);
    }
 
    m = (n * sum_xy - sum_x * sum_y) / (n * sum_x2 - pow(sum_x, 2));
    c = (sum_y - m * sum_x) / n;
 
    cout << "m =" << m;
    cout << "\nc =" << c;
}
 
// Driver main function
int main()
{
    int x[] = { 1, 2, 3, 4, 5 };
    int y[] = { 14, 27, 40, 55, 68 };
    int n = sizeof(x) / sizeof(x[0]);
    bestApproximate(x, y, n);
    return 0;
}


C
// C Program to find m and c for a straight line given,
// x and y
#include 
 
// function to calculate m and c that best fit points
// represented by x[] and y[]
void bestApproximate(int x[], int y[], int n)
{
    int i, j;
    float m, c, sum_x = 0, sum_y = 0, sum_xy = 0, sum_x2 = 0;
    for (i = 0; i < n; i++) {
        sum_x += x[i];
        sum_y += y[i];
        sum_xy += x[i] * y[i];
        sum_x2 += (x[i] * x[i]);
    }
 
    m = (n * sum_xy - sum_x * sum_y) / (n * sum_x2 - (sum_x * sum_x));
    c = (sum_y - m * sum_x) / n;
 
    printf("m =% f", m);
    printf("\nc =% f", c);
}
 
// Driver main function
int main()
{
    int x[] = { 1, 2, 3, 4, 5 };
    int y[] = { 14, 27, 40, 55, 68 };
    int n = sizeof(x) / sizeof(x[0]);
    bestApproximate(x, y, n);
    return 0;
}


Java
// Java Program to find m and c for a straight line given,
// x and y
import java.io.*;
import static java.lang.Math.pow;
 
public class A {
    // function to calculate m and c that best fit points
    // represented by x[] and y[]
    static void bestApproximate(int x[], int y[])
    {
        int n = x.length;
        double m, c, sum_x = 0, sum_y = 0,
                     sum_xy = 0, sum_x2 = 0;
        for (int i = 0; i < n; i++) {
            sum_x += x[i];
            sum_y += y[i];
            sum_xy += x[i] * y[i];
            sum_x2 += pow(x[i], 2);
        }
 
        m = (n * sum_xy - sum_x * sum_y) / (n * sum_x2 - pow(sum_x, 2));
        c = (sum_y - m * sum_x) / n;
 
        System.out.println("m = " + m);
        System.out.println("c = " + c);
    }
 
    // Driver main function
    public static void main(String args[])
    {
        int x[] = { 1, 2, 3, 4, 5 };
        int y[] = { 14, 27, 40, 55, 68 };
        bestApproximate(x, y);
    }
}


Python3
# python Program to find m and c for
# a straight line given, x and y
 
# function to calculate m and c that
# best fit points represented by x[]
# and y[]
def bestApproximate(x, y, n):
     
    sum_x = 0
    sum_y = 0
    sum_xy = 0
    sum_x2 = 0
     
    for i in range (0, n):
        sum_x += x[i]
        sum_y += y[i]
        sum_xy += x[i] * y[i]
        sum_x2 += pow(x[i], 2)
 
    m = (float)((n * sum_xy - sum_x * sum_y)
            / (n * sum_x2 - pow(sum_x, 2)));
             
    c = (float)(sum_y - m * sum_x) / n;
     
    print("m = ", m);
    print("c = ", c);
     
     
# Driver main function
x = [1, 2, 3, 4, 5 ]
y = [ 14, 27, 40, 55, 68]
n = len(x)
 
bestApproximate(x, y, n)
     
# This code is contributed by Sam007.


C#
// C# Program to find m and c for a
// straight line given, x and y
using System;
 
class GFG {
 
    // function to calculate m and c that
    // best fit points represented by x[] and y[]
    static void bestApproximate(int[] x, int[] y)
    {
        int n = x.Length;
        double m, c, sum_x = 0, sum_y = 0,
                     sum_xy = 0, sum_x2 = 0;
 
        for (int i = 0; i < n; i++) {
            sum_x += x[i];
            sum_y += y[i];
            sum_xy += x[i] * y[i];
            sum_x2 += Math.Pow(x[i], 2);
        }
 
        m = (n * sum_xy - sum_x * sum_y) / (n * sum_x2 - Math.Pow(sum_x, 2));
 
        c = (sum_y - m * sum_x) / n;
 
        Console.WriteLine("m = " + m);
        Console.WriteLine("c = " + c);
    }
 
    // Driver main function
    public static void Main()
    {
        int[] x = { 1, 2, 3, 4, 5 };
        int[] y = { 14, 27, 40, 55, 68 };
 
        // Function calling
        bestApproximate(x, y);
    }
}
 
// This code is contributed by Sam007


PHP


Javascript


输出:

m=13.6
c=0.0

上面代码分析——
辅助空间:O(1)
时间复杂度:O(n)。我们有一个循环迭代 n 次,并且每次执行常数 no。的计算。

参考-
1- BS Grewal 的高等工程数学。

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程