Программирование >>  Немодифицирующие последовательные алгоритмы 

1 ... 64 65 66 [ 67 ] 68 69 70 ... 78


Существует другая версия алгоритма, принимающая дополнительный параметр, чтобы можно было указать операцию, отличную от вычитания. Например, после выполпепия

int а[4] = {2, 20, 150, 700}, Ь[4], *iEnd;

iEnd = adjacent difference(а, a+4, b, divides<int>());

МЫ получим b = {2, 15, 5, 4}, так как 30/2 = 15, 150/30 = 5 и 700/150 = 4.

7.5. Прикладная профамма: метод наименьших квадратов

Теперь мы применим алгоритмы accumulate и innerjproduct для решения известной практической задачи. Предположим, что имеется набор из п пар чисел (х, у), где каждая пара соответствует точке на плоскости ху, и мы хотим найти прямую линию, которая является достаточно разумным приближением зависимости, представленной этими точками, как показано на рисунке 7.1.

118.6 118.5 118.4 118.3 118.2 118.1 118.0

-Линия регрессии у = а + Ьх

20.4 20.5 20.6 20.7 20.8 20.9 21.0 21.1 х

Рисунок 7.1. Восемь точек и вычисленная линия регрессии

Количество точек произвольно, но не может быть меньше 2. Расположение точек должно быть таким, чтобы получающаяся линия не оказалась вертикальной; в частности недопустимо, если все точки имеют одну и ту же координату х.

Координаты п точек будут находиться во входном файле, имя которого вводится пользователем. Например, восемь точек, изображенных в виде крестиков на рисунке 7.1, находятся в следующем файле data.txt:

20.5 118.1

20.6 118.25 20.65 118.2



прикладная программа; метод наименьших квадратов 207

20.75 118.4

20.8 118.4 20.85 118.5

20.9 118.45 21.0 118.5

Получающаяся линия, называемая линией регрессии, будет представлена уравнением

у = а + Ьх

где коэффициенты avib вычислены таким образом, что сумма - У(г)У (где y(J) = а + Ьх)

квадратов отклонений будет иметь наименьшее из возможных значений. Метод наименьших квадратов обязан своим происхождением Гауссу, по этому методу неизвестные коэффициенты ааЬ могут быть найдены путем решения следующей системы линейных уравнений:

an + i X X = S у, aLx. + ЬЪх = Ё л- у

Программирование решения этой задачи с помощью STL представляется удобным, потому что:

алгоритм accumulate позволит просто вычислить значения X х и S у;,

алгоритм inner product позволит просто вычислить X и X х. у:,

последовательные контейнеры позволяют хранить переменное количество значений хиу.

Что касается последнего пункта: на самом деле нет необходимости хранить все эти числа, обычно это и не делалось в раннюю эпоху компьютерных вычислений, когда память компьютеров была ограничена. Мы предположим, что располагаем достаточным количеством памяти для хранения всех чисел; более того, это позволит нам выводить не только искомые коэффициенты а и но и список отклонений

г/i - y(i)

где, как уже упоминалось, y(i) = а + Ьх.. Если бы мы не сохраняли все значения, нам пришлось бы дважды читать входной файл. Используя тип vector<double> для хранения значений л: и г/, получаем следующую программу:

leastsq.cpp: Метод наименьших квадратов, ♦include <iostream>



ttinclude <fstream>

ttinclude <iomanip>

ttinclude <vector>

ttinclude <numeric>

ttinclude <string>

using namespace std;

typedef vector<double> array;

int ReadPoints(ifstream &file, array &x, array &y) { double xl, yl;

while (file >> xl yl)

{ x.push baclc(xl); y.push baclc(yl);

return X.size();

int CpmputeCoeff(const array &x, const array &y,

double &a, double &b) { double sx=0, sx2=0, sy=0, sxy=0;

sx = accumulate (x.begin 0 , x.endO, sx) ;

sy = accumulate (y. begin 0 , y.endO, sy) ;

sx2 = inner product (x.beginO , x.endO, X.begin0, sx2);

sxy = inner product (x.begin 0 , x.endO, y.beginO, sxy);

int n = X.size();

double D = n * sx2 - sx * sx;

if (D != 0)

{ a = (sy * sx2 - sx * sxy)/D;

b = (n * sxy - sx * sy)/D;

return 1; } else return 0;

void ShowComputedPoints(const array &x, const array &y,

double a, double b) { cout \n X yGiven yComputed\n\n

setiosflags(ios::fixed); int n = X.size(); for (int i=0; i<n; i++)

cout setw(lO) setprecision(2) x[i] setw(lO) y[i]

setw(lO) a + b * x[i] endl;

int mainO

{ array X, y;



1 ... 64 65 66 [ 67 ] 68 69 70 ... 78

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика