如何找到最能描述一组点的线?

时间:2019-05-27 20:59:30

标签: c++ algorithm oop numerical-methods numerical-analysis

因此,我遇到了这个问题(不用做功课,不用担心),如果有必要,我必须找到最能描述一组要点的直线。我想出了一种算法,该算法:

  1. 计算每对点之间的斜率,并获得平均值

  2. 使用在步骤1中找到的平均值,通过遍历所有点(y = mx + b,找到b)来找到y轴的平均截距

  3. 我们检查之前发现的平均值的所有在+ -5范围内的m,b值,然后得出线与点的距离之和最小的对

    >
  4. 我们按照步骤3的结果进行任意多次迭代,然后检查+ -0.5的半径,然后检查+ -0.05的半径。

如果您可以提供帮助,我有两个主要问题/担忧:

  • 在某种意义上,有没有办法使该算法更有效/更准确?如果可以的话?

  • 由于我是OOP / C ++的新手,您能否快速了解一下我的代码中是否有错误/错误调用?

非常感谢您的光临!

#include <iostream>
#include <string>
using namespace std;
class Point {
private:
    double x;
    double y;
public:
    Point() //default
    {
        x = 0;
        y = 0;
    }
    Point(double xAxis, double yAxis)
    {
        x = xAxis;
        y = yAxis;
    }
    double getX()
    {
        return x;
    }
    double getY()
    {
        return y;
    }
    void setX(double tx)
    {
        x = tx;
    }
    void setY(double ty)
    {
        y = ty;
    }
    double calcSlope(Point p2)
    {
        return (p2.getY() - y) / (p2.getX() - x);
    }
};
class Line {
private:
    double m;
    double b;
public:
    Line()
    {
        m = b = 0;
    }
    Line(double slope, double remain)
    {
        m = slope;
        b = remain;
    }
    Line(Point p1, Point p2)
    {
        m = (p1.getY() - p2.getY()) / (p1.getX() - p2.getX());
        b = p1.getY() - p1.getX() * m;
    }
    double getSlope()
    {
        return m;
    }
    double getB()
    {
        return b;
    }
    void setSlope(double slope)
    {
        m = slope;
    }
    void setB(double bb)
    {
        b = bb;
    }
    double dist(Point p)
    {
        double d = (double)abs(m*p.getX() - p.getY() + b) / sqrt(1 + m * m);
        return d;
    }
    void avgLine(Point pArr[], int size)
    {
        double sum = 0;
        for (int i = 0; i < size; i++)
        {
            for (int j = i+1; j < size; j++)
            {
                sum += pArr[i].calcSlope(pArr[j]);
            }
        }
        sum /= ((size)*(size - 1) / 2);
        double sumB = 0;
        for (int i = 0; i < size; i++)
        {
            sumB += pArr[i].getY() - sum * pArr[i].getX();
        }
        sumB /= size;
        m = sum;
        b = sumB;
    }
    double sumDist(Point pArr[], int size)
    {
        double sum = 0;
        for (int i = 0; i < size; i++)
        {
            sum += this->dist(pArr[i]);
        }
        return sum;
    }
};
int main()
{
    int accuracy, size;
    double x, y, min, tmp;
    cout << "Please choose number of points:" << endl;
    cin >> size;
    Point *pArr;
    pArr = new Point[size];
    cout << "Please choose accuracy 0 < d < 5, accuracy is 10^(-d)" << endl;
    cin >> accuracy;
    for (int i = 0; i < size; i++)
    {
        cout << "X value:" << endl;
        cin >> x;
        cout << "Y value:" << endl;
        cin >> y;
        pArr[i].setX(x);
        pArr[i].setY(y);
    }
    Line avgL;
    avgL.avgLine(pArr, size);
    Line minL = avgL, tmpLine;
    min = minL.sumDist(pArr, size);
    for (int i = 1; i >= pow(10, -accuracy); i /= 10)
    {
        for (double startM = avgL.getSlope() - 5 * i; startM <= avgL.getSlope() + 5 * i; startM += i)
        {
            for (double startB = avgL.getB() - 5 * i; startB <= avgL.getB() + 5 * i; startB += i)
            {
                tmpLine.setSlope(startM);
                tmpLine.setB(startB);
                tmp = tmpLine.sumDist(pArr, size);
                if (tmp < min)
                {
                    tmp = min;
                    minL = tmpLine;
                }
            }
        }
        avgL = minL;
    }
    cout << "The line is: y = " << minL.getSlope() << "x + " << minL.getB() << endl;
}

0 个答案:

没有答案