1. Заголовок темы должен быть информативным. В противном случае тема удаляется ... 2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения. 3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали! 4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора). 5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM! 6. Одна тема - один вопрос (задача) 7.Проверяйте программы перед тем, как разместить их на форуме!!! 8.Спрашивайте и отвечайте четко и по существу!!!
Застопорился на простом – ввод и вывод матрицы – когда составлял одну программу. Хочу сделать так чтобы матрица красиво выводилась, но после ввода значений в вектор B, в нем выводятся одни нули. То есть матрица A выводиться правильно, а в векторе B одни нули. Где допустил ошибку не могу найти. Помогите разобраться. Вот код ввода и вывода:
program vv;
uses crt; const c=10; type mat=array [1..c, 1..c] of real; vec=array [1..c] of real; var A: mat; B: vec; n: integer;
{Процедура ввода матрицы} procedure Matr_Vvod(n:integer; var A:mat; B:vec); var i, j: integer; begin writeln('Вводите коэфф-ты матpицы A по стpокам нажимая ENTER:'); for i:=1 to n do for j:=1 to n do begin write ('A[',i,',',j,']='); read(A[i,j]); end; writeln; writeln('Введите вектоp В свободных членов нажимая ENTER:'); for i:=1 to n do begin write ('B[',i,']='); read(B[i]); end; end;
{Процедура вывода матрицы} procedure Matr_Vivod(n: integer; var A:mat; B:vec); var i, j: integer; begin writeln('Исходная матpица:'); for i:=1 to n do begin for j:=1 to n do write (A[i, j]:5:3,' ':2); {Вывод матрицы с отступами} write (B[i]:5:3,' ':2); {Вывод вектора с отступами} writeln; end; end;
procedure Matr_Vvod(n:integer; var A:mat; var B:vec);
Хорошо! Но при таком вводе вот эта программа работает неправильно:
program Zeyd; {Вычисление СЛАУ методом Зейделя}
uses crt; const c=10; type mat=array [1..c, 1..c] of real; vec=array [1..c] of real; var A: mat; B: vec; i,l,m,n: integer; e: real;
{Процедура ввода матрицы} procedure Matr_Vvod(n:integer; var A:mat; var B:vec); var i, j: integer; begin writeln('Вводите коэфф-ты матpицы A по стpокам нажимая ENTER:'); for i:=1 to n do for j:=1 to n do begin write ('A[',i,',',j,']='); read(A[i,j]); end; writeln; writeln('Введите вектоp В свободных членов нажимая ENTER:'); for i:=1 to n do begin write ('B[',i,']='); read (B[i]); end; end;
{Процедура вывода матрицы} procedure Matr_Vivod(n: integer; var A:mat; var B:vec); var i, j: integer; begin writeln('Исходная матpица:'); for i:=1 to n do begin for j:=1 to n do write (A[i, j]:5:3,' ':2); {Вывод матрицы с отступами} write (B[i]:5:3,' ':2); {Вывод вектора с отступами} writeln; end; end;
{Процедура вычисления СЛАУ методом Зейделя} procedure Seid(var n,m,l:integer; var A:mat; var B:vec; e:real); var i,j,k,k1,n1:integer; s:real; begin for k:=1 to m do begin l:=k; for i:=1 to n do begin s:=A[i, n+1]; for j:=1 to n do s:=s - a[i,j] * B[j]; s:=s / a[i,i]; B[i]:=B[i] + s; if abs(s) > e then l:=0; end; if l<>0 then exit; end; end;
begin clrscr;
writeln('Вычислить СЛАУ методом Зейделя.'); writeln; writeln('Введите колич-во неизвестных величин "n" и нажмите ENTER:'); readln(n); writeln; writeln('Введите максимально допустимое кол-во интераций "m":'); readln(m); writeln; writeln('Задайте погрешность решений "e":'); readln(e); writeln;
Seid(n,m,l,A,B,e); {Вычисление СЛАУ методом Зейделя}
if l<>0 then begin writeln('ОТВЕТ:'); for i:=1 to n do writeln('X', i,' = ',B[i]:3:4); writeln; writeln(l:2,' интерации(я).'); end else writeln('Интерации все.');
readkey;
end.
Если решить систему уравнений методом Зейделя: 10x1+x2+x3=12; 2x1+10x2+x3=13; 2x1+2x2+10x3=14;
То должен получиться след. примерный ответ: x1=0.9992; x2=1.0054; x3= 0.9991; После 5 итераций с погрешностью решений 1, а выходит следующее: x1=0.0062; x2=-0.0024; x3=-0.0008; Что очень далеко до правильного ответа. :(
Ну, ответ кроется в некорректном использовании переменных A и B в теле программы и внутри Seid. В теле программы: A - матрица коэффициетов B - вектор свободных членов В Seid: A - расширенная матрица коэффициентов B - вектор решений (т.е. X)
Для нахождения таких ошибок есть пошаговый отладчик. Запусти его и следи за изменением интересующих переменных.
Ну, ответ кроется в некорректном использовании переменных A и B в теле программы и внутри Seid. В теле программы:
Цитата(Федосеев Павел @ 14.04.2013 23:34)
Ну, ответ кроется в некорректном использовании переменных A и B в теле программы и внутри Seid. В теле программы: A - матрица коэффициетов B - вектор свободных членов В Seid: A - расширенная матрица коэффициентов B - вектор решений (т.е. X)
Блин, что-то я запутался! При чем если изменить ввод и вывод матрицы матрицы так чтобы ее можно было вводить в строчку (например, a[1.4]=12, a[2.4]=13, a[3.4]=14, т.е. без ввода векторов отдельно), то программа работает правильная, но такой ввод неудобен.
Код:
program Zeyd; {Вычисление СЛАУ методом Зейделя}
uses crt; const c=10; type mat=array [1..c, 1..c] of real; vec=array [1..c] of real; var A: mat; X: vec; i,l,m,n: integer; e: real;
{Процедура ввода матрицы} procedure Matr_Vvod(n:integer; var A:mat; var X:vec); var i, j: integer; begin writeln('Вводите коэфф-ты матpицы A по стpокам нажимая ENTER:'); for i:=1 to n do begin X[i]:=0; for j:=1 to n+1 do begin write ('a[',i,',',j,']='); {Ввод матрицы} read(a[i,j]); end; end; end;
{Процедура вывода матрицы} procedure Matr_Vivod(n: integer; var A:mat; var X:vec); var i, j: integer; begin writeln('Исходная матpица:'); for i:=1 to n do begin for j:=1 to n+1 do write (A[i, j]:5:3,' ':2); {Вывод матрицы с отступами} writeln; end; end;
{Процедура вычисления СЛАУ методом Зейделя} procedure Seid(var n,m,l:integer; var A:mat; var X:vec; e:real); var i,j,k,k1,n1:integer; s:real; begin for k:=1 to m do begin l:=k; for i:=1 to n do begin s:=A[i, n+1]; for j:=1 to n do s:=s - A[i,j] * X[j]; s:=s / A[i,i]; X[i]:=X[i] + s; if abs(s) > e then l:=0; end; if l<>0 then exit; end; end;
begin clrscr;
writeln('Вычислить СЛАУ методом Зейделя.'); writeln; writeln('Введите колич-во неизвестных величин "n" и нажмите ENTER:'); readln(n); writeln; writeln('Введите максимально допустимое кол-во интераций "m":'); readln(m); writeln; writeln('Задайте погрешность решений "e":'); readln(e); writeln;
Seid(n,m,l,A,X,e); {Вычисление СЛАУ методом Зейделя}
if l<>0 then begin writeln('ОТВЕТ:'); for i:=1 to n do writeln('X', i,' = ',X[i]:3:4); writeln; writeln(l:2,' интерации(я).'); end else writeln('Интерации все.');
И после этого программа начала правильно находить два корня из трех. Третий корень выводит на единицу больше чем нужно. Например, имеем след. систему уравнений: x1+4x2+2x3=3; 2x1+7x2+3x3=4; 8x2+x3=-5. Итераций: 4. Точность: 1. Выводиться: x1=1; x2=-1; x3=4. А должно быть: x1=1; x2=-1; x3=3. И так практически во всех урав-ях. Третий «икс» выводиться на 1 больше. Помогите определить, что не так? Полный код:
program Zeyd; {Вычисление СЛАУ методом Зейделя}
uses crt; const c=10; type mat=array [1..c, 1..c] of real; vec=array [1..c] of real; var A: mat; B, X: vec; i,l,m,n: integer; e: real;
{Процедура ввода матрицы} procedure Matr_Vvod(n:integer; var A:mat; var B, X:vec); var i, j: integer; begin writeln('Вводите коэфф-ты матpицы A по стpокам нажимая ENTER:'); for i:=1 to n do for j:=1 to n do begin write ('A[',i,',',j,']='); read(A[i,j]); end; writeln; writeln('Введите вектоp В свободных членов нажимая ENTER:'); for i:=1 to n do begin write ('B[',i,']='); read (B[i]); end; end;
{Процедура вывода матрицы} procedure Matr_Vivod(n: integer; var A:mat; var B, X:vec); var i, j: integer; begin writeln('Исходная матpица:'); for i:=1 to n do begin for j:=1 to n do write (A[i, j]:5:3,' ':2); {Вывод матрицы с отступами} write (B[i]:5:3,' ':2); {Вывод вектора с отступами} writeln; end; end;
{Процедура вычисления СЛАУ методом Зейделя} procedure Seid(var n,m,l:integer; var A:mat; var B, X:vec; var e:real); var i,j,k,k1,n1:integer; s:real; begin for k:=1 to m do begin l:=k; for i:=1 to n do begin s:=A[i, n] +B[i]; for j:=1 to n do s:=s - A[i,j] * X[j]; s:=s / A[i,i]; X[i]:=X[i] + s; if abs(s) > e then l:=0; end; if l<>0 then exit; end; end;
begin clrscr;
writeln('Вычислить СЛАУ методом Зейделя.'); writeln; writeln('Введите колич-во неизвестных величин "n" и нажмите ENTER:'); readln(n); writeln; writeln('Введите максимально допустимое кол-во интераций "m":'); readln(m); writeln; writeln('Задайте погрешность решений "e":'); readln(e); writeln;
Seid(n,m,l,A,B,X,e); {Вычисление СЛАУ методом Зейделя}
if l<>0 then begin writeln('ОТВЕТ:'); for i:=1 to n do writeln('X', i,' = ',X[i]:3:4); writeln; writeln(l:2,' интерации(я).'); end else writeln('Интерации все.');