Advertisement
kartikkukreja

Segmented Least Squares

Oct 21st, 2013
214
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.97 KB | None | 0 0
  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <stack>
  4. #include <limits>
  5. #define MAXN 1000
  6. #define INF numeric_limits<double>::infinity()
  7. using namespace std;
  8.  
  9. struct Point {
  10.     int x, y;
  11.     bool operator < (const Point& that) const {
  12.         return x < that.x;
  13.     }
  14. } points[MAXN + 1];
  15.  
  16. // Used for computing E[i][j] which is the square error of a segment
  17. // that is best fit to the points {points[i], points[i+1], ..., points[j]}
  18.  
  19. // cumulative_x[i] is sum(points[j].x) for 1 <= j <= i
  20. // cumulative_y[i] is sum(points[j].y) for 1 <= j <= i
  21. // cumulative_xy[i] is sum(points[j].x * points[j].y) for 1 <= j <= i
  22. // cumulative_xSqr[i] is sum(points[j].x * points[j].x) for 1 <= j <= i
  23.  
  24. // slope[i][j] is the slope of the segment that is best fit to
  25. // the points {points[i], points[i+1], ..., points[j]}
  26.  
  27. // intercept[i][j] is the y-intercept of the segment that is best fit to
  28. // the points {points[i], points[i+1], ..., points[j]}
  29.  
  30. // E[i][j] is the square error of the segment that is best fit to
  31. // the points {points[i], points[i+1], ..., points[j]}
  32.  
  33. long long cumulative_x[MAXN + 1], cumulative_y[MAXN + 1], cumulative_xy[MAXN + 1], cumulative_xSqr[MAXN + 1];
  34. double slope[MAXN + 1][MAXN + 1], intercept[MAXN + 1][MAXN + 1], E[MAXN + 1][MAXN + 1];
  35.  
  36. // OPT[i] is the optimal solution (minimum cost) for the points {points[1], points[2], ..., points[i]}
  37. double OPT[MAXN + 1];
  38.  
  39. // [opt_segment[i], i] is the last segment in the optimal solution
  40. // for the points {points[1], points[2], ..., points[i]}
  41. int opt_segment[MAXN + 1];
  42.  
  43. int main()  {
  44.     int N, i, j, k, interval;
  45.     long long x_sum, y_sum, xy_sum, xsqr_sum, num, denom;
  46.     double tmp, mn, C;
  47.    
  48.     printf("Enter the number of points : ");
  49.     scanf("%d", &N);
  50.     printf("Enter %d points :\n", N);
  51.     for (i = 1; i <= N; i++)
  52.         scanf("%d %d", &points[i].x, &points[i].y);
  53.     printf("Enter the cost of creating a new segment : ");
  54.     scanf("%lf", &C);
  55.    
  56.     // sort the points in non-decreasing order of x coordinate
  57.     sort (points + 1, points + N + 1);
  58.    
  59.     // precompute the error terms
  60.     cumulative_x[0] = cumulative_y[0] = cumulative_xy[0] = cumulative_xSqr[0] = 0;
  61.     for (j = 1; j <= N; j++)    {
  62.         cumulative_x[j] = cumulative_x[j-1] + points[j].x;
  63.         cumulative_y[j] = cumulative_y[j-1] + points[j].y;
  64.         cumulative_xy[j] = cumulative_xy[j-1] + points[j].x * points[j].y;
  65.         cumulative_xSqr[j] = cumulative_xSqr[j-1] + points[j].x * points[j].x;
  66.        
  67.         for (i = 1; i <= j; i++)    {
  68.             interval = j - i + 1;
  69.             x_sum = cumulative_x[j] - cumulative_x[i-1];
  70.             y_sum = cumulative_y[j] - cumulative_y[i-1];
  71.             xy_sum = cumulative_xy[j] - cumulative_xy[i-1];
  72.             xsqr_sum = cumulative_xSqr[j] - cumulative_xSqr[i-1];
  73.            
  74.             num = interval * xy_sum - x_sum * y_sum;
  75.             if (num == 0)
  76.                 slope[i][j] = 0.0;
  77.             else {
  78.                 denom = interval * xsqr_sum - x_sum * x_sum;
  79.                 slope[i][j] = (denom == 0) ? INF : (num / double(denom));              
  80.             }
  81.                     intercept[i][j] = (y_sum - slope[i][j] * x_sum) / double(interval);
  82.            
  83.                 for (k = i, E[i][j] = 0.0; k <= j; k++) {
  84.                         tmp = points[k].y - slope[i][j] * points[k].x - intercept[i][j];
  85.                         E[i][j] += tmp * tmp;
  86.                     }
  87.         }
  88.     }
  89.    
  90.     // find the cost of the optimal solution
  91.     OPT[0] = opt_segment[0] = 0;
  92.     for (j = 1; j <= N; j++)    {
  93.         for (i = 1, mn = INF, k = 0; i <= j; i++)   {
  94.             tmp = E[i][j] + OPT[i-1];
  95.             if (tmp < mn)   {
  96.                 mn = tmp;
  97.                 k = i;
  98.             }
  99.         }
  100.         OPT[j] = mn + C;
  101.         opt_segment[j] = k;
  102.     }
  103.    
  104.     printf("\nCost of the optimal solution : %lf\n", OPT[N]);
  105.    
  106.     // find the optimal solution
  107.     stack <int> segments;
  108.     for (i = N, j = opt_segment[N]; i > 0; i = j-1, j = opt_segment[i]) {
  109.         segments.push(i);
  110.         segments.push(j);
  111.     }
  112.    
  113.     printf("\nAn optimal solution :\n");
  114.     while (!segments.empty())   {
  115.         i = segments.top(); segments.pop();
  116.         j = segments.top(); segments.pop();
  117.         printf("Segment (y = %lf * x + %lf) from points %d to %d with square error %lf.\n",
  118.                 slope[i][j], intercept[i][j], i, j, E[i][j]);
  119.     }
  120.    
  121.     return 0;
  122. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement