![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Sanchez-2 |
|
|||
|
Unregistered |
Напишите, пжлст, как организовать решение Системы линейных уравнений Методом Зейделя. Ну например в 7 строк.
|
|||
|
||||
| Borik |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 11 Регистрация: 28.4.2004 Репутация: нет Всего: нет |
Листинг на делфи (все что могу сделать):
реализованы 2 метода: Гаусса и Зейделя. Метод Зейделя, основанный на том, что матрица В, полученная из матрицы А путем выделения переменных, обладает таким свойством, что при циклическом подставлении результатов расчета корней, корни уточняются. В итоге получается, что методом Зейделя можно считать системы уравнений с заданной точностью. Private Function Summ(N1, N2 As Integer) Dim J As Integer Summ = 0 For J = N1 To N2 Summ = Summ + Mas(N1 - 1, J) * X(J) Next J End Function Private Sub Gauss(N As Integer) Dim I, J, K As Integer On Error GoTo Errsee For K = 1 To N - 1 For I = K + 1 To N L(I, K) = Mas(I, K) / Mas(K, K) Mas(0, I) = Mas(0, I) - L(I, K) * Mas(0, K) Mas(I, K) = 0 For J = K + 1 To N Mas(I, J) = Mas(I, J) - L(I, K) * Mas(K, J) Next J Next I Next K For I = 1 To N L(I, I) = 1 Next I X(N) = Mas(0, N) / Mas(N, N) For I = N - 1 To 1 Step -1 X(I) = (1 / Mas(I, I)) * (Mas(0, I) - Summ(I + 1, N)) Next I Exit Sub Errsee: MsgBox "Ошибка вычислений", vbOKOnly, "Ошибка" End Sub Public Sub Lab1C2(N As Integer) Dim I, J, K As Integer LoadMas Gauss (N) Form1.Text45.Text = X(1) Form1.Text46.Text = X(2) Form1.Text47.Text = X(3) Form1.Text48.Text = X(4) Form1.Text49.Text = X(5) Form1.Text50.Text = X(6) If Form1.Text49.Text = "-1,#IND" Then Form1.Text49.Text = "Ошибка" End If If Form1.Text50.Text = "-1,#IND" Then Form1.Text50.Text = "Ошибка" End If For I = 0 To 6 For J = 0 To 6 Mas(I, J) = Mas(I, J) Next J Next I For I = 0 To 6 For J = 0 To 6 L(I, J) = L(I, J) Next J Next I End Sub Public Sub SeeU(N As Integer) Dim I, J As Integer Dim tmpStr As String * 6 Form1.Text1.Text = "" For I = 1 To N For J = 1 To N tmpStr = Round(Mas(I, J), 5) Form1.Text1.Text = Form1.Text1.Text + tmpStr + vbTab Next J Form1.Text1.Text = Form1.Text1.Text & vbCrLf Next I End Sub Public Sub SeeL(N As Integer) Dim I, J As Integer Dim tmpStr As String * 6 Form1.Text2.Text = "" For I = 1 To N For J = 1 To N tmpStr = Round(L(I, J), 5) Form1.Text2.Text = Form1.Text2.Text + tmpStr + vbTab Next J Form1.Text2.Text = Form1.Text2.Text & vbCrLf Next I End Sub Public Function DetA(N As Integer) As Double Dim I As Integer Lab1C2 (N) DetA = 1 For I = 1 To N DetA = DetA * Mas(I, I) Next I End Function Public Sub LU(N As Integer) Dim Rez(6, 6) As Double Dim I, J, K As Integer SeeU (N) SeeL (N) For I = 1 To N For J = 1 To N For K = 1 To N Rez(I, J) = Rez(I, J) + L(I, K) * Mas(K, J) Next K Next J Next I Dim tmpStr As String * 6 Form1.Text51.Text = "" For I = 1 To N For J = 1 To N tmpStr = Round(Rez(I, J), 4) Form1.Text51.Text = Form1.Text51.Text + tmpStr + vbTab Next J Form1.Text51.Text = Form1.Text51.Text & vbCrLf Next I End Sub Private Sub LoadMas() Mas(0, 1) = Form1.Text39.Text Mas(0, 2) = Form1.Text40.Text Mas(0, 3) = Form1.Text41.Text Mas(0, 4) = Form1.Text42.Text Mas(0, 5) = Form1.Text43.Text Mas(0, 6) = Form1.Text44.Text Mas(1, 1) = Form1.Text3.Text Mas(1, 2) = Form1.Text4.Text Mas(1, 3) = Form1.Text5.Text Mas(1, 4) = Form1.Text6.Text Mas(1, 5) = Form1.Text7.Text Mas(1, 6) = Form1.Text8.Text Mas(2, 1) = Form1.Text9.Text Mas(2, 2) = Form1.Text10.Text Mas(2, 3) = Form1.Text11.Text Mas(2, 4) = Form1.Text12.Text Mas(2, 5) = Form1.Text13.Text Mas(2, 6) = Form1.Text14.Text Mas(3, 1) = Form1.Text15.Text Mas(3, 2) = Form1.Text16.Text Mas(3, 3) = Form1.Text17.Text Mas(3, 4) = Form1.Text18.Text Mas(3, 5) = Form1.Text19.Text Mas(3, 6) = Form1.Text20.Text Mas(4, 1) = Form1.Text21.Text Mas(4, 2) = Form1.Text22.Text Mas(4, 3) = Form1.Text23.Text Mas(4, 4) = Form1.Text24.Text Mas(4, 5) = Form1.Text25.Text Mas(4, 6) = Form1.Text26.Text Mas(5, 1) = Form1.Text27.Text Mas(5, 2) = Form1.Text28.Text Mas(5, 3) = Form1.Text29.Text Mas(5, 4) = Form1.Text30.Text Mas(5, 5) = Form1.Text31.Text Mas(5, 6) = Form1.Text32.Text Mas(6, 1) = Form1.Text33.Text Mas(6, 2) = Form1.Text34.Text Mas(6, 3) = Form1.Text35.Text Mas(6, 4) = Form1.Text36.Text Mas(6, 5) = Form1.Text37.Text Mas(6, 6) = Form1.Text38.Text End Sub Public Sub Zeidel(N As Integer) Dim Bas(6, 7) As Double Dim Xmas(6) As Double Dim tmpX(6) As Double Dim I, J, K As Integer Dim E, Q As Double LoadMas E = Form1.Text52.Text For I = 1 To N For J = 1 To N On Error Resume Next Bas(I, J) = -1 * Mas(I, J) / Mas(I, I) Next J Next I For I = 1 To N Bas(I, I) = 0 Next I For I = 1 To N Bas(I, 7) = Mas(0, I) / Mas(I, I) Next I Q = Norma(Bas, N) If Q >= 1 Then MsgBox "Расчет невозможен", vbOKOnly, "Ошибка" Exit Sub End If Dim tmpStr As String * 6 Form1.Text51.Text = "" For I = 1 To N For J = 1 To N tmpStr = Round(Bas(I, J), 5) Form1.Text51.Text = Form1.Text51.Text + tmpStr + vbTab Next J tmpStr = Round(Bas(I, 7), 5) Form1.Text51.Text = Form1.Text51.Text + tmpStr + vbTab Form1.Text51.Text = Form1.Text51.Text & vbCrLf Next I For K = 1 To 50 For I = 1 To N Xmas(I) = 0 For J = 1 To I - 1 Xmas(I) = Xmas(I) + Bas(I, J) * Xmas(J) Next J For J = I + 1 To N Xmas(I) = Xmas(I) + Bas(I, J) * tmpX(J) Next J Xmas(I) = Xmas(I) + Bas(I, 7) Next I If Abs(Xmas(1) - tmpX(1)) < (((1 - Q) * E) / Q) Then Exit For End If For J = 1 To 6 tmpX(J) = Xmas(J) Next J Next K MsgBox K, vbOKOnly, "Количество итераций" Form1.Text45.Text = Xmas(1) Form1.Text46.Text = Xmas(2) Form1.Text47.Text = Xmas(3) Form1.Text48.Text = Xmas(4) Form1.Text49.Text = Xmas(5) Form1.Text50.Text = Xmas(6) If Form1.Text49.Text = "-1,#IND" Then Form1.Text49.Text = "Ошибка" End If If Form1.Text50.Text = "-1,#IND" Then Form1.Text50.Text = "Ошибка" End If End Sub Private Function Norma(Mas() As Double, N As Integer) As Double Dim Max, Q As Double Dim K, I As Integer Q = 0 For K = 1 To N Max = Q Q = 0 For I = 1 To N Q = Q + Abs(Mas(K, I)) If Q > Max Then Max = Q Next I Next K Norma = Max End Function Public Sub TransMas(N As Integer) Dim AMas(6, 6) As Double Dim I, K, J, M As Integer For M = 1 To N LoadMas For I = 1 To 6 Mas(0, I) = 0 Next I Mas(0, M) = 1 Gauss (N) For I = 1 To 6 AMas(I, M) = X(I) Next I Next M Dim tmpStr As String * 6 Form1.Text2.Text = "" For I = 1 To N For J = 1 To N tmpStr = Round(AMas(I, J), 5) Form1.Text2.Text = Form1.Text2.Text + tmpStr + vbTab Next J Form1.Text2.Text = Form1.Text2.Text & vbCrLf Next I LoadMas Dim Rez(6, 6) As Double For I = 1 To N For J = 1 To N For K = 1 To N Rez(I, J) = Rez(I, J) + AMas(I, K) * Mas(K, J) Next K Next J Next I Form1.Text51.Text = "" For I = 1 To N For J = 1 To N tmpStr = Round(Rez(I, J), 4) Form1.Text51.Text = Form1.Text51.Text + tmpStr + vbTab Next J Form1.Text51.Text = Form1.Text51.Text & vbCrLf Next I End Sub Добавлено @ 01:58 ..... а вот еще лаба на паскале. может поможет! Листинг программы: program vm_2; uses crt; const n=4; type vector=array [1..n] of real; mas=array [1..n] of vector; const a0:mas=((10,-1,0,2),(10,1,2,0),(2,-1,1,2),(3,-2,1,1)); b0:vector=(11,13,4,3); b1:vector=(0,0,0,0); var a:mas; b,x,b11,bb:vector; j:integer; function max_a(k:integer; var u:mas): Integer; var maxm: Integer; max: real; i: integer; begin max:= -maxint; for i:= k to n do begin if abs(u[i, k]) > max then begin max:= u[i, k]; maxm:= i; end; end; max_a:= maxm; end; procedure change_string(k, m: Integer; var u: mas); var c: real; i: integer; begin for i:= 1 to n do begin c:= u[k, i]; u[k, i]:= u[m, i]; u[m, i]:= c; end; end; {умножение матриц} procedure multiply(a,b:mas; var c:mas); var i,j,k:integer; s:real; begin for i:=1 to n do for j:=1 to n do begin s:=0; for k:=1 to n do s:=s+a[i,k]*b[k,j]; c[i,j]:=s; end; end; {метод Гаусса} procedure gauss; var c,i,j,k,m:integer; d,max,s:real; l,u:mas; begin a:=a0; u:=a0; {прямой ход} for k:=1 to n-1 do for i:=k+1 to n do begin if a[k, k] = 0 then begin m:= max_a(k, u); change_string(k, m, u); end; if u[k,k]=0 then begin max:=abs(u[k,k]); m:=k; for c:=k+1 to n do begin if abs(u[c,k])>max then begin max:=abs(u[c,k]); m:=c end end; b11:=u[k]; u[k]:=u[m]; u[m]:=b11; d:=bb[k]; bb[k]:=bb[m]; bb[m]:=d; end; l[i,k]:=u[i,k]/u[k,k]; b[i]:=b[i]-l[i,k]*b[k]; for j:=1 to n do u[i,j]:=u[i,j]-l[i,k]*u[k,j]; end; {обратный ход} for k:=n downto 1 do begin s:=0; for j:=k+1 to n do s:=s+u[k,j]*x[j]; x[k]:=(b[k]-s)/u[k,k]; end; end; {решение системы линейных алгебраических уравнений} procedure sistema; var i,j,k,m:integer; s:real; l,u,a1:mas; begin clrscr; a:=a0; b:=b0; u:=a; textcolor(1); writeln(' Решение системы линейных алгебраических уравнений:'); for i:=1 to n do for j:=1 to n do if i=j then l[i,j]:=1 else l[i,j]:=0; textcolor(10); write(' Матрица A:'); writeln(' Матрица b:'); for i:=1 to n do begin textcolor(9); for j:=1 to n do write(a[i,j]:9:3); write(' '); write(b[i]:7:3); writeln; end; writeln; for k:=1 to n-1 do for i:=k+1 to n do begin if u[k, k] = 0 then begin m:= max_a(k, u); change_string(k, m, u); end; l[i,k]:=u[i,k]/u[k,k]; b[i]:=b[i]-l[i,k]*b[k]; for j:=1 to n do u[i,j]:=u[i,j]-l[i,k]*u[k,j]; end; multiply(l,u,a1); textcolor(10); write(' Матрица L:'); writeln; textcolor(9); for i:=1 to n do begin for j:=1 to n do write(l[i,j]:9:3); writeln; end; writeln; textcolor(10); write(' Матрица U:'); writeln; textcolor(9); for i:=1 to n do begin for j:=1 to n do write(u[i,j]:9:3); writeln; end; textcolor(10); writeln; write(' Проверка L*U=A'); writeln; textcolor(9); for i:=1 to n do begin for j:=1 to n do write(a1[i,j]:9:3); writeln; end; readln; clrscr; textcolor(10); writeln('Корни данной системы:'); textcolor(9); for i:=1 to n do x[n]:=b[n]/u[n,n]; writeln('x',n,'=',x[n]:4:3); k:=n-1; while k>=1 do begin s:=0; for j:=k+1 to n do s:=s+u[k,j]*x[j]; x[k]:=(b[k]-s)/u[k,k]; writeln('x',k,'=',x[k]:4:3,' '); dec(k); end; s:=1; writeln; textcolor(10); for k:=1 to n do s:=s*u[k,k]*(-1); writeln('Определитель матрицы = ',s:7:2); writeln; end; {обратная матрица} procedure obrmatr; var i,j,k:integer; m,mo:real; c,e:mas; s,so:vector; begin for i:=1 to n do begin b:=b1; b[i]:=1; gauss; for j:=1 to n do c[j,i]:=x[j]; end; multiply(c,a,e); textcolor(10); write(' Обратная матрица:'); textcolor(9); writeln; for i:=1 to n do begin for j:=1 to n do write(c[i,j]:7:3); writeln; end; textcolor(10); writeln; writeln(' Единичная матрица:'); textcolor(9); for i:=1 to n do begin for j:=1 to n do write(e[i,j]:7:3); writeln; end; m:=0; mo:=0; for i:=1 to n do begin s[i]:=0; so[i]:=0; for j:=1 to n do begin s[i]:=s[i]+abs(a[i,j]); so[i]:=so[i]+abs(c[i,j]); end; if m<s[i] then m:=s[i]; if mo<so[i] then mo:=so[i]; end; writeln; textcolor(10); writeln('Норма обратной матрицы =',mo:7:3); mo:=m*mo; write('Число обусловленности =',mo:7:3); if (mo>=1) and (mo<=10) then writeln(' (cистема хорошо обусловлена)') else writeln(' Система плохо обусловлена'); end; {Метод Зейделя} procedure zeidel; var s,x:vector; b:mas; i,j,k,l:integer; q,lam,sum,xr,e,ke:real; begin readln; clrscr; textcolor(10); writeln(' Матрица B:'); textcolor(9); for i:=1 to n do begin s[i]:=0; for j:=1 to n do begin if i=j then b[i,j]:=0 else b[i,j]:=-a0[i,j]/a[i,i]; s[i]:=s[i]+abs(b[i,j]); write(b[i,j]:9:3); end; write(s[i]:5:1); if q<s[i] then q:=s[i]; writeln; end; if q>=1 then exit else writeln; textcolor(10);writeln(' Норма матрицы В =',q:7:3); writeln; readln; clrscr; e:=0.01; for l:=1 to 3 do begin k:=0; sum:=0; e:=e*0.1; for i:=1 to n do x[i]:=0; repeat lam:=0; inc(k); for i:=1 to n do begin sum:=0; xr:=x[i]; if i=3 then ke:=ln(abs(x[2])/(e*(1-q)))/ln(1/q); for j:=1 to n do if i<>j then sum:=sum+a[i,j]*x[j]; x[i]:=(b0[i]-sum)/a[i,i]; if lam<abs(x[i]-xr) then lam:=abs(x[i]-xr); end; until lam<e*(1-q)/q; textcolor(10); writeln; writeln('Точность = ',e:7:7); writeln('Количество итераций = ',k); writeln('Априорная оценка = ',ke:6:2); textcolor(9); for i:=1 to n do writeln('x',i,'=',x[i]:10:8); end; end; {основная программа} begin textcolor(11); sistema; obrmatr; zeidel; readkey; end. Результаты: Решение системы линейных алгебраических уравнений: Матрица A: Матрица b: 10.000 -1.000 0.000 2.000 11.000 10.000 1.000 2.000 0.000 11.000 2.000 -1.000 1.000 2.000 4.000 3.000 -2.000 1.000 1.000 3.000 Матрица L: 1.000 0.000 0.000 0.000 1.000 1.000 0.000 0.000 0.200 -0.400 1.000 0.000 0.300 -0.850 1.500 1.000 Матрица U: 10.000 -1.000 0.000 2.000 0.000 2.000 2.000 -2.000 0.000 0.000 1.800 0.800 -0.000 0.000 0.000 -2.500 Проверка L*U=A 10.000 -1.000 0.000 2.000 10.000 1.000 2.000 0.000 2.000 -1.000 1.000 2.000 3.000 -2.000 1.000 1.000 Корни данной системы: x4=1.000 x3=1.000 x2=1.000 x1=1.000 Определитель матрицы = -90.00 Обратная матрица: 0.078 0.033 -0.089 0.022 -0.022 0.133 0.311 -0.578 -0.378 0.267 0.289 0.178 0.100 -0.100 0.600 -0.400 Единичная матрица: 1.000 0.000 0.000 0.000 0.000 1.000 0.000 0.000 -0.000 0.000 1.000 -0.000 0.000 -0.000 0.000 1.000 Норма обратной матрицы = 1.200 Число обусловленности = 15.600 Система плохо обусловлена Матрица B: 0.000 0.100 0.000 -0.200 0.3 -10.000 0.000 -2.000 0.000 12.0 -2.000 1.000 0.000 -2.000 5.0 -3.000 2.000 -1.000 0.000 6.0 Вывод: В ходе данной лабораторной работы я научился решать системы линейных алгебраических уравнений двумя способами: методом Гаусса и методом Зейделя. Были проверены равенства А=L*U, A-1*A=E, вычислен определитель и число обусловленностей. Действительно было доказано, что в методе Зейделя количество итераций не превышает априорной оценки. Метод Гаусса отличается от метода Зейделя том, что в первом вычисляются корни до ошибки вычислений, а во втором вычисляются корни с точностью до ε, которая задается. Таким образом метод Зейделя наиболее удобен в использовании, так как можно найти корни с наиболее высокой точностью. |
|||
|
||||
| Sanchez-2 |
|
|||
|
Unregistered |
Мда, товарищ...
А на Си как-нибудь??? |
|||
|
||||
| Darked |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 536 Регистрация: 26.2.2004 Где: Южный Урал Репутация: нет Всего: нет |
Ну посидеть немного со справочником по делфи или паскаля, а там и в С перевести можно.
-------------------- Veni, Vidi, Vici !!! |
|||
|
||||
| Abrekos |
|
|||
|
Unregistered |
Написано на Билдере. Матрица и вектор св. членов заносится в компонент StringGrid. Размерность системы произвольная (переменная razm).
void __fastcall TForm1::BitBtn2Click(TObject *Sender) { int i,k; float b[100][100]; float d[100]; float x0[100]; float diag[100]; //Решение системы //Проверка на правильность заполнения форм данных for(i=0;i<razm;i++) { for(k=0;k<razm;k++) { a[i][k]=StrToFloat(StringGrid1->Cells[k+1][i+1]); if(k==i) { diag[i]=a[i][k]; //Проверка на нулевые диагональные элементы if(diag[i]<0.00000000001){Form2->Show(); Abort();} } } y[i]=StrToFloat(StringGrid2->Cells[1][i+1]); } //Выражаем систему в виде x=Bx+d for(i=0;i<razm;i++) { d[i]=y[i]/diag[i]; //Вектор d for(k=0;k<razm;k++) { b[i][k]=-a[i][k]/diag[i]; //Матрица B } } for(i=0;i<razm;i++){b[i][i]=0;} //Замена исходных матриц на новые for(i=0;i<razm;i++) { for(k=0;k<razm;k++) { StringGrid1->Cells[k+1][i+1]=FloatToStr(b[i][k]); } StringGrid2->Cells[1][i+1]=FloatToStr(d[i]); } for(i=0;i<razm;i++){x0[i]=0;} for(i=0;i<razm;i++){x[i]=0;}//Начальные знач. х //Итерационый процесс double s0; //вспомогательная сумма double e=0; //невязка int n=0; do { for(i=0;i<razm;i++) {s0=0; for(k=0;k<razm;k++) { s0=s0+(b[i][k]*x0[k]); } x[i]=s0+d[i]; e=e+fabs(x[i]-x0[i]); x0[i]=x[i]; } n=n++; }while(n<20); //Кол-во итераций Label5->Caption="X="; StringGrid1->Visible=false; StringGrid2->Visible=false; StringGrid3->Visible=true; Label1->Visible=false; Label2->Visible=false; for(k=0;k<razm;k++) { StringGrid3->Cells[1][k+1]=FloatToStr(x[k]); } BitBtn2->Caption="Готово"; } |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |