问题描述
Please use dynamic programming method to solve segmented least squre propblem and analyze time complexity of your designed solution.
翻译
请使用动态编程方法解决分段最小二乘法问题,并分析所设计方案的时间复杂性。
高考线性回归曲线,要求给n个点,将点分x组,然后给一个参数k
经过相关计算求的误差最小?
思路
计算公式
步骤:计算完dp
代码:不知道对错
套公式呗,出这题不寄了吗还学呢
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string>
#include <algorithm>
#include <stdlib.h>
using namespace std;
const int N = 1e3 + 10;
double x[N];
double y[N];
double mem[N];
double E[N][N];
double errorCalculation(double x[], double y[], int l, int r)//计算误差的起始点和终止点
{
double sum = 0; double a, b;
double sumX = 0, sumY = 0,sumMuli=0;
double sumX2 = 0;
int n = r - l + 1;//多少个点
for (int i = l; i <= r; i++)
{
sumX += x[i];
sumX2 += x[i] * x[i];
sumY += y[i];
sumMuli += x[i] * y[i];
}
a = (n * sumMuli - sumX * sumY) / (sumX2 * n - sumX * sumX);
b = (sumY - a * sumY) / n;
double res = 0;
for (int i = l; i <= r; i++)
res += (y[i] - a * x[i] - b) * (y[i] - a * x[i] - b);
return res;
}
double Opt(double x[], double y[], int k,int n)
{
mem[0] = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= i; j++)
E[i][j] = errorCalculation(x, y, i, j);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= i; j++)
mem[i] = min(E[i][j] + k + mem[j - 1], mem[i]);//包含这个点和不包含这个点两种情况
return mem[n];
}
void solution(double x[], double y[], int k, int n)//输出划分方式
{
if (n == 0)
;
else
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= i; j++)
{
E[i][j] = errorCalculation(x, y, i, j);
if (E[i][j] + k + mem[j - 1] < mem[i])
{
cout << i << " ";
solution(x, y, k, n - 1);
}
}
}
}
}
int main(double x[], double y[], int k, int n)
{
int n;
cout << "Please enter the n of Points:" << endl;
cin >> n;
int k;
cout << "Please enter the factor k:" << endl;
cin >> k;
for (int i = 1; i <= n; i++)
{
cin >> x[i] >> y[i];
}
int res=Opt(x, y, k, n);
cout << "The minest erro is " << res << endl;
return 0;
}
测试案例
没找着
运行结果
不知道
时间复杂度分析
O(n^3)
速记
速寄
mem[i] = min(E[i][j] + k + mem[j - 1], mem[i]);//包含这个点和不包含这个点两种情况
伪代码: