Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.77/104: Рейтинг темы: голосов - 104, средняя оценка - 4.77
0 / 0 / 0
Регистрация: 23.03.2016
Сообщений: 15
1

Решение СЛАУ методом Якоби

05.06.2017, 01:27. Показов 19997. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Пытаюсь реализовать метод решения системы линейных уравнений методом Якоби.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
#include "stdafx.h"
#include "conio.h"
#include "iostream"
using namespace std;
double eps = 1;
const int n=3;
double a[n][n], c[n], xx[n];
double E[n][n], D[n][n];
void enterA() , enterX0(), enterC();
void inversion(double **A, int N);
void out();void returnB();
double **D1 = new double *[n];
double returnDA(int I,int J);
double B[n][n];double returnG(int I);
double g[n];
double returnBx(int I);
double xXx[n];
 
int main()
{
    double norm;
    setlocale(LC_ALL, "Russian");
    for (int i = 0; i < n; i++)
    D1[i] = new double[n];
    enterA();
    enterC();
    enterX0();
    out();
    returnB();
    
 
    
    for (int i = 0;i < n;i++)
    {
        xXx[i] = xx[i];
    }
    double Bx[n];
    do
    {
        for (int i = 0;i < n;i++)
        {
            Bx[i] = returnBx(i);
        }
        for (int i = 0;i < n;i++)
        {
            xXx[i] = Bx[i] - g[i];
        }
        norm = xXx[0] - xx[0];
        for (int i = 0;i < n;i++)
        {
            xx[i] = xXx[i];
        }
    } while (norm > eps);
    cout << "Корни:" << endl;
    for (int i = 0;i < n;i++)
    {
        cout <<xXx[i]<<" "<<endl;
    }
        
    getch();
 
}
 
void enterA()
{
 
    cout << "Введите коэффициенты: "<<endl;
    for (int i = 0;i <= (n - 1);i++)
    {
        for (int j = 0;j <= (n - 1);j++)
        {
            cout << "Введите a[" << i << "][" << j << "]: ";
            cin >> a[i][j];
            cout << endl;
        }   
    }
}
 
void enterC()
{
    cout << "Введите свободные члены: " << endl;
    for (int i = 0;i <= (n - 1);i++)
    {
        cout << "Введите c[" << i << "]: ";
        cin >> c[i];
    }cout << endl;
}
 
void enterX0()
{
    cout << "Введите начальные приближения: " << endl;
    for (int i = 0;i <= (n - 1);i++)
    {
        cout << "Введите хх[" << i << "]: ";
        cin >> xx[i];
    }cout << endl;
}
 
void out()
{
    cout << "Введенные коэффициенты представляют следующую матрицу:" << endl;
    for (int i = 0;i <= (n - 1);i++)
    {
        for (int j = 0;j <= (n - 1);j++)
        {
            cout << a[i][j] << " ";
        }
        cout << endl;
    }
 
    cout << "Столбец свободных членов:" << endl;
    for (int i = 0;i < n;i++)
    {
        cout << c[i] << endl;
    }
 
    cout << "Столбец начальных приближений:" << endl;
    for (int i = 0;i < n;i++)
    {
        cout << xx[i] << endl;
    }
 
 
    for (int i = 0;i < n;i++)
    {
        for (int j = 0;j < n;j++)
        {
            E[i][j] = 1;
        }
    }
    for (int i = 0;i < n;i++)
    {
        for (int j = 0;j < n;j++)
        {
            if (j == i) D[i][j] = a[i][j];
            else D[i][j] = 0;
        }
    }
 
    cout << "Матрица единиц:" << endl;
 
    for (int i = 0;i < n;i++)
    {
        for (int j = 0;j < n;j++)
        {
            cout << E[i][j] << " ";
        }cout << endl;
    }
 
    cout << "Матрица D:" << endl;
 
    for (int i = 0;i < n;i++)
    {
        for (int j = 0;j < n;j++)
        {
            cout << D[i][j] << " ";
        }cout << endl;
    }
 
    
 
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
        {
            D1[i][j] = D[i][j];
        }
 
    inversion(D1, n);
 
    cout << "Матрица D^-1:" << endl;
 
    for (int i = 0;i < n;i++)
    {
        for (int j = 0;j < n;j++)
        {
            cout << D1[i][j] << " ";
        }cout << endl;
    }
}
 
void inversion(double **A, int N)
{
    double temp;
 
    double **E = new double *[N];
 
    for (int i = 0; i < N; i++)
        E[i] = new double[N];
 
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
        {
            E[i][j] = 0.0;
 
            if (i == j)
                E[i][j] = 1.0;
        }
 
    for (int k = 0; k < N; k++)
    {
        temp = A[k][k];
 
        for (int j = 0; j < N; j++)
        {
            A[k][j] /= temp;
            E[k][j] /= temp;
        }
 
        for (int i = k + 1; i < N; i++)
        {
            temp = A[i][k];
 
            for (int j = 0; j < N; j++)
            {
                A[i][j] -= A[k][j] * temp;
                E[i][j] -= E[k][j] * temp;
            }
        }
    }
 
    for (int k = N - 1; k > 0; k--)
    {
        for (int i = k - 1; i >= 0; i--)
        {
            temp = A[i][k];
 
            for (int j = 0; j < N; j++)
            {
                A[i][j] -= A[k][j] * temp;
                E[i][j] -= E[k][j] * temp;
            }
        }
    }
 
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            A[i][j] = E[i][j];
 
    for (int i = 0; i < N; i++)
        delete[] E[i];
 
    delete[] E;
}
 
void returnB()
{
    double D1A[n][n];
        for (int i = 0;i < n;i++)
        {
            for (int j = 0;j < n;j++)
            {
                D1A[i][j] = returnDA(i,j);
            }
        }
        cout << "D1A:" << endl;
        for (int i = 0;i < n;i++)
        {
            for (int j = 0;j < n;j++)
            {
                cout << D1A[i][j] << " ";
            }cout << endl;
        }
        
        for (int i = 0;i < n;i++)
        {
            for (int j = 0;j < n;j++)
            {
                B[i][j] = E[i][j] - D1A[i][j];
            }
        }
        cout << "Матрица B:" << endl;
        for (int i = 0;i < n;i++)
        {
            for (int j = 0;j < n;j++)
            {
                cout << B[i][j] << " ";
            }cout << endl;
        }
 
        for (int i = 0;i < n;i++)
        {
            g[i] = returnG(i);
        }
        cout << "Матрица G" << endl;
        for (int i = 0;i < n;i++)
        {
        
                cout << g[i] << " ";
            
        }
 
}
 
double returnDA(int I,int J)
{
    double da=0;
    
    for (int i = 0;i < n;i++)
    {
        da += D1[I][i] * a[i][J];
    }
 
    return da;
}
 
double returnG(int I)
{
    double G=0;
 
    for (int i = 0;i < n;i++)
    {
        G += D1[I][i] * c[i];
    }
    return G;
}
 
double returnBx(int I)
{
    double Bx = 0;
 
    for (int i = 0;i < n;i++)
    {
        Bx += B[I][i] * xx[i];
    }
    return Bx;
}


Может кому-то этот код не будет резать глаза, и получится посмотреть что делаю не так. Все делал по порядку на основе формул из википедии, последовательно получал все необходимые матрицы-множители, все вроде правильно находилось. И вот я сделал на основе всех полученных множителей подсчет корней, и полученные как-то совсем не сходятся с проверкой по онлайн калькулятору СЛАУ.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.06.2017, 01:27
Ответы с готовыми решениями:

Решение СЛАУ методом Якоби
Решить СЛАУ методом Якоби. Вывести значения решения, график зависимости нормы невязки от номера...

Программа на решение СЛАУ методом Якоби
Вывести значение решения и количество итераций

Решение СЛАУ методом вращений (Якоби)
помогите, может у когото имеется приложение (на языке Pascal или C++), Решение СЛАУ методом...

Решение СЛАУ методом Якоби - Необработанное исключение (ошибка)
Здравствуйте, стояла задача решения СЛАУ, методом Якоби. Что-то набросал, что то скопировал, но...

5
с++
1282 / 523 / 225
Регистрация: 15.07.2015
Сообщений: 2,562
05.06.2017, 09:24 2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <math.h>
const double eps = 0.001; ///< желаемая точность 
 
..........................
 
/// N - размерность матрицы; A[N][N] - матрица коэффициентов, F[N] - столбец свободных членов,
/// X[N] - начальное приближение, ответ записывается также в X[N];
void Jacobi (int N, double** A, double* F, double* X)
{
    double* TempX = new double[N];
    double norm; // норма, определяемая как наибольшая разность компонент столбца иксов соседних итераций.
 
    do {
        for (int i = 0; i < N; i++) {
            TempX[i] = F[i];
            for (int g = 0; g < N; g++) {
                if (i != g)
                    TempX[i] -= A[i][g] * X[g];
            }
            TempX[i] /= A[i][i];
        }
        norm = fabs(X[0] - TempX[0]);
        for (int h = 0; h < N; h++) {
            if (fabs(X[h] - TempX[h]) > norm)
                norm = fabs(X[h] - TempX[h]);
            X[h] = TempX[h];
        }
    } while (norm > eps);
    delete[] TempX;
}
1
0 / 0 / 0
Регистрация: 23.03.2016
Сообщений: 15
05.06.2017, 09:29  [ТС] 3
я пробовал брать этот код, но как-то не получается им пользоваться, я немного не догоняю объявление массивов через new double*[N]
0
с++
1282 / 523 / 225
Регистрация: 15.07.2015
Сообщений: 2,562
05.06.2017, 09:39 4
Лучший ответ Сообщение было отмечено klimkin3teers как решение

Решение

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const unsigned int DIM1 = 3;
const unsigned int DIM2 = 5;
 
//создание двумерного динамического масива
int **ary= new int * [DIM1];
 
 for (int i = 0; i < DIM1; i++) { 
        ary[i] = new int [DIM2]; 
    }
 
// работа с массивом
    for (int i = 0; i < DIM1; i++) {
        for (int j = 0; j < DIM2; j++) {
            ary[i][j] =  i +10;
        }
    }
 
вывод
for (int i = 0; i < DIM1; i++) {
        for (int j = 0; j < DIM2; j++) {
            cout << setw(4) << ary[i][j];
        }
        cout << endl;
    }
 
// уничтожение
    for (int i = 0; i < DIM1; i++) {
        delete [] ary[i];
    }
    delete [] ary;
Добавлено через 2 минуты
так же можно с double и другими числовыми типами
1
0 / 0 / 0
Регистрация: 23.03.2016
Сообщений: 15
05.06.2017, 12:12  [ТС] 5
спасибо, дошло)

Добавлено через 16 секунд
а вот все таки не правильно работает код из вкипедии, ну видимо я что-то не так делаю, while зацикливается, а все корни в каждом цикле неправильные, мой изначальный код тоже зацикливался, но корни находил несколько больше похожие на действительные.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include "stdafx.h"
#include <math.h>
#include <iomanip>
#include "iostream"
using namespace std;
const double eps = 0.1; ///< желаемая точность 
void Jacobi(int N, double** A, double* F, double* X);
 
int main()
{
    setlocale(LC_ALL, "Russian");
    const unsigned int DIM1 = 3;
    const unsigned int DIM2 = 3;
 
    //создание двумерного динамического масива
    double **a = new double *[DIM1];
 
    for (int i = 0; i < DIM1; i++) {
        a[i] = new double[DIM2];
    }
 
    double * c = new double[DIM1];
    double * x = new double[DIM1];
 
    // работа с массивом
    for (int i = 0; i < DIM1; i++) {
        for (int j = 0; j < DIM2; j++) {
            cout << "Введите a[" << i << "][" << j << "]: ";
            cin >> a[i][j];cout << endl;
        }
    }
 
    for (int j = 0; j < DIM2; j++) {
        cout << "Введите c[" << j << "][" << j << "]: ";
        cin >> c[j];cout << endl;
    }
 
    for (int j = 0; j < DIM2; j++) {
        cout << "Введите x[" << j << "][" << j << "]: ";
        cin >> x[j];cout << endl;
    }
    Jacobi(DIM1, a, c, x);
    //вывод
    //for (int i = 0; i < DIM1; i++) {
    for (int j = 0; j < DIM2; j++) {
        cout << setw(4) << x[j];
    }
    cout << endl;
    //}
    system("pause");
 
    // уничтожение
    for (int i = 0; i < DIM1; i++) {
        delete[] a[i];
    }
    delete[] a;
    return 0;
}
 
/// N - размерность матрицы; A[N][N] - матрица коэффициентов, F[N] - столбец свободных членов,
/// X[N] - начальное приближение, ответ записывается также в X[N];
void Jacobi(int N, double** A, double* F, double* X)
{
    double* TempX = new double[N];
    double norm; // норма, определяемая как наибольшая разность компонент столбца иксов соседних итераций.
 
    do {
        for (int i = 0; i < N; i++) {
            TempX[i] = F[i];
            for (int g = 0; g < N; g++) {
                if (i != g)
                    TempX[i] -= A[i][g] * X[g];
            }
            TempX[i] /= A[i][i];
        }
        norm = fabs(X[0] - TempX[0]);
        for (int h = 0; h < N; h++) {
            if (fabs(X[h] - TempX[h]) > norm)
                norm = fabs(X[h] - TempX[h]);
            X[h] = TempX[h];
        }for (int i = 0;i < 3;i++)
    {
        cout << X[i]<<" ";
        }cout << endl;
    } while (norm > eps);
 
    
 
    delete[] TempX;
}
0
с++
1282 / 523 / 225
Регистрация: 15.07.2015
Сообщений: 2,562
05.06.2017, 12:34 6
пример в интернете нашол может он подойдет
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include <iostream>
#include <cmath>
using namespace std;
// приведение матрицы коэффициентов к виду с ненулевой диагональю и соответствующее изменение вектора правых частей
// возвращает true - если приведение - успешно
bool getDiagonal( double **coefficients, double *rightPart, int currColumn, int numberOfEquation ) {
    bool result = false;
    int i, row = currColumn;
    double tempItem;
 
    // для матрицы 1x1 ответом является ненулевость ее единственного элемента
    if ( currColumn == numberOfEquation - 1 ) {
        result = coefficients[currColumn][currColumn] != 0;
    }
    else {
        // пока не найдена перестановка приводящая матрицу к виду с ненулевой диагональю и пока мы можем еще просматривать строки ищем перестановку
        while ( !result && row < numberOfEquation ) {
            // если текущий элемент на диагонали нулевой ищем в столбце дальше ненулевой
            if ( coefficients[row][currColumn] != 0 ) {
                // если элемент ненулевой и не лежит на диагонали меняем местами сотвествующие строки в матрице и элементы в векторе прваых частей
                if ( row != currColumn ) {
                    for ( i = 0; i < numberOfEquation; i++ ) {
                        tempItem = coefficients[currColumn][i];
                        coefficients[currColumn][i] = coefficients[row][i];
                        coefficients[row][i] = tempItem;
                    }               
                    tempItem = rightPart[currColumn];
                    rightPart[currColumn] = rightPart[row];
                    rightPart[row] = tempItem;                  
                }
                // рекурсивный вызов фактически для подматрицы с размерностью на 1 меньше
                result = getDiagonal( coefficients, rightPart, currColumn + 1, numberOfEquation );
                if ( result ) {
                    break;
                }
            }
            row ++;
        }
    }
 
    return result;
}
 
// было ли найдено решение, если да - итог в параметре solution
int iteration( double **coefficients, double *rightPart, int numberOfEquation, double *solution, double precision ) {
    bool result;
    int i, j, k, step = 1;
    double temp;
    double* tempSolution;
 
    tempSolution = new double[numberOfEquation];
    
    // приведение матрицы коэффициентов к виду с ненулевой диагональю и соответствующее изменение вектора правых частей
    result = getDiagonal( coefficients, rightPart, 0, numberOfEquation );   
 
    // если приведение успешно - работаем дальше
    if ( result ) {
        double fault = precision + 1;
 
        // преобразуем матрицу и правую часть для дальнейшего решения
        for ( i = 0; i < numberOfEquation; i ++ ) {
            for ( j = 0; j < numberOfEquation; j ++ ) {
                if ( i != j ) {
                    coefficients[i][j] = - coefficients[i][j] / coefficients[i][i];
                }
            }
            rightPart[i] = rightPart[i] / coefficients[i][i];
            coefficients[i][i] = 0;
        }
 
        // первое приближение решения - преобразованный вектор правых частей
        for ( i = 0; i < numberOfEquation; i ++ ) {
            solution[i] = rightPart[i];
        }
 
        // пока не найдено решение с допустимй погрешнстью или пока не исчерпан лимит шагов... если все расходится например
        while ( fault > precision && step <= 1000 ) {
 
            // поиск новой итерации с ее "самоиспользованием" при расчетах            
            for ( j = 0; j < numberOfEquation; j ++ ) {
                tempSolution[j] = 0;
            }
            for ( i = 0; i < numberOfEquation; i ++ ) {
                for ( j = 0; j < numberOfEquation; j ++ ) {
                    tempSolution[i] = tempSolution[i] + coefficients[i][j] * solution[j]; 
                }
                tempSolution[i] = tempSolution[i] + rightPart[i];
            }
 
            // расчет погрешности
            fault = 0.0;
            for ( j = 0; j < numberOfEquation; j ++ ) {
                fault = fault + (solution[j] - tempSolution[j])*(solution[j] - tempSolution[j]);
            }
            fault = sqrt( fault );
 
            // сохранение полученной новой итерации
            for ( j = 0; j < numberOfEquation; j ++ ) {
                solution[j] = tempSolution[j];
            }
            step++;
        }
    }
    else {
        result = 1001;
    }
    
 
    return step;
}
 
 
int main() {
    int i, j;
    int size;
    double **coefficients, *rightPart, *solution, precision;
 
    cout << "Simple iteration method.\nEnter system dimension: ";
    cin >> size;
 
    coefficients = new double*[size];
    for ( i = 0; i < size; i++ ) {
        coefficients[i] = new double[size];
    }
    rightPart = new double[size];
    solution = new double[size];
 
    for ( i = 0; i < size; i ++ ){
        cout << "Enter " << i + 1 << " row: ";
        for ( j = 0; j < size; j ++ ){
            cin >> coefficients[i][j];
        }
    }
 
    cout << "Enter right part: ";
    for ( j = 0; j < size; j ++ ){
        cin >> rightPart[j];
    }
 
    cout << "Enter precision: ";
        cin >> precision;
 
    int steps = iteration( coefficients, rightPart, size, solution, precision );
    if ( steps > 1000 ) {
        cout << "Solution for this matrix of coefficients not exist or not found";
    }
    else {
        cout << "Solution is:\n";
        for ( j = 0; j < size; j ++ ){
            cout << solution[j] << "\n";
        }
        cout << "Number of step: " << steps;
    }
 
    cout << "\nPress "Enter" to continue..." << endl; 
return 0;
}
1
05.06.2017, 12:34
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.06.2017, 12:34
Помогаю со студенческими работами здесь

Решение СЛАУ методом Жордана
Решить СЛАУ методом Жордана, Вычислить интегральнок выражение методом Симпсона

Решение СЛАУ методом отражений
Добрый вечер :) Было две темы &quot;Решение СЛАУ методом отражений&quot;, но нет реализации) У меня есть...

Решение СЛАУ методом отражений
Всем привет. Задали писать курсач. Нужно реализовать метод отражения. Предусмотреть ввод числа...

Решение СЛАУ методом вращения
Доброго времени суток, товарищи. Имеется задание: дано интегральное уравнение: U(x) + I (...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru