Показать полную графическую версию : [решено] Помогите с программой для Turbo Pascal (умножение матриц)
dasha131
01-10-2010, 13:45
ПОмогите пожалуйста составить программу для вычисения произведения матриц A,B,C каждая из которых имеет размерность nxn
ВОт составленная мною часть проги, где вводятся сами матрицы, проверьте пожалуйста
program ABC;
var
matrA: array[1..500,1..500] of integer;
matrB: array[1..500,1..500] of integer;
matrC: array[1..500,1..500] of integer;
i: integer;
j: integer;
begin
for i:=1 to n do
for j:=1 to n do
begin
read matrA[i,j];
end;
begin
read matrB[i,j];
end;
begin
read matrC[i,j];
end;
в принципе правильно, вот только нет ввода n и вместо оператора read лучше использовать readln imho, неплохо бы было выводить приглашение на ввод данных. размерность матриц лучше задавать через константу
const
R=500;
var
matrA: array[1..R,1..R] of integer;
ввод матриц я бы организовал процедурой
p. s. используйте тег CODE
dasha131
01-10-2010, 14:02
program ABC;
var
const
R=500;
matr1,matr2,matr3,matr4: array[1..R,1..R] of real;
i,j,m,n,p,s,g: integer;
S:real;
Begin
read (g) {размерность матрицы gxg}
for i:=1 to g do
for j:=1 to g do
begin
read(matr1[i,j]);
end;
for m:=1 to g do
for n:=1 to g do
begin
read(matr2[m,n]);
end;
for p:=1 to g do
for s:=1 to g do
begin
read(matr3[p,s]);
end;
D[i,j] := D[i,j] + (A[i,j]*B[j,i])*C[j,i];
Вот формула
Значит матрицы мною заданны, как теперь задать их перемножение?
dasha131
01-10-2010, 18:19
Сами матрицы точно правильно введутся?!
D[i,j] := D[i,j] + (A[i,j]*B[j,i])*C[j,i];
Вот формула »
судя по формуле это не перемножение матриц, а просто алгоритм вычисления значения элемента матрицы D на основании соответствующих элементов предыдущих 3 матриц, тогда просто это надо выполнить в цикле
dasha131
02-10-2010, 04:57
Это не данная формула)) Значит моя ошибка(
МОжет поможете дальше с программой?
блок const не надо смешивать с блоком var.
program ABC;
const
R=500;
var
matr1,matr2,matr3,matr4: array[1..R,1..R] of real;
i,j,m,n,p,s,g: integer;
S:real;
Begin
read (g) {размерность матрицы gxg}
for i:=1 to g do
for j:=1 to g do
begin
read(matr1[i,j]);
end;
for m:=1 to g do
for n:=1 to g do
begin
read(matr2[m,n]);
end;
for p:=1 to g do
for s:=1 to g do
begin
read(matr3[p,s]);
end;
»
Решение простое, "в лоб" можно конечно улучшить, но работать будет без проблем.
Может поможете дальше с программой? »
Посмотри здесь (http://www.webmath.ru/web/prog5_1.php)
И вид общей формулы тут (http://ru.wikipedia.org/wiki/Умножение_матриц)
Результирующую матрицу получать в 2 этапа. Сначала 1*2, затем получившее*3;
Процедуры и функции проходили? Они бы сейчас очень пригодились.
dasha131
02-10-2010, 15:51
1.program AB;
2.const NMax = 10;{можно увеличить}
3.type Matrix = array [1..NMax, 1..NMax] of Real;
4.procedure MulMatrix(var a, b, c: Matrix; n: Integer);
5.var i, j, k: Integer;
6. s: Real;
7.begin
8. for i := 1 to n do
9. for j := 1 to n do
10. begin
11. s := 0;
12. for k := 1 to n do
13. s := s + a[i, k]*b[k, j];
14. c[i, j] := s
15. end
16.end;
17.var a, b, c: Matrix;
18. i, j, n: Integer;
19.begin
20. WriteLn('Введите порядок матрицы');
21. Write('n = '); ReadLn(n);
22. WriteLn('Введите первую матрицу');
23. for i := 1 to n do
24. for j := 1 to n do
25. Read(a[i, j]);
26. WriteLn('Введите вторую матрицу');
27. for i := 1 to n do
28. for j := 1 to n do
29. Read(b[i, j]);
30. MulMatrix(a, b, c, n);
31. for i := 1 to n do
32. begin
33. for j := 1 to n do
34. Write(c[i, j]:0:6, ' ');
35. WriteLn
36. end;
37. ReadLn
38.end.
Благодарю за помощь) А можно по подробнее разобрать цикл с 4-15строчки, почему вконце 14 и 15й строчек не ставится ";" ? Почему так записали 31-33ю строчки, почему begin между? И еще непонятно значение строчек 35,37...
Почему так записали 31-33ю строчки, почему begin между? »
это вывод матрицы, внешний цикл выбирает номер строки, а в его теле внутренний выводит значение элементов, а пустой writeln переводит каретку (чтоб красиво было :) )
И еще непонятно значение строчек 35,37 »
37 строка просто задержка, чтобы программа после выполнения сразу не закрывалась
почему вконце 14 и 15й строчек не ставится ";" ? »
код тестировали? imho просто ошибка, забыли поставить
разобрать цикл с 4-15строчки »
это реализация математического метода умножения матриц
dasha131
04-10-2010, 07:30
код тестировали? imho просто ошибка, забыли поставить »
ВОт это то самое и интересное, все тестировалось, и работало прекрасно без ";" ну и как это объяснить?
А чтобы перемножать три матрицы, нужно новый цикл писать "MulMatrix(var c, d, e: Matrix; n: Integer)" ??
dasha131
04-10-2010, 07:54
Вот готово, замечания будут?
program ABC;
const NMax = 10;
type Matrix = array [1..NMax, 1..NMax] of Real;
procedure 1MulMatrix(var a, b, c: Matrix; n: Integer);
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 2MulMatrix(var c, d, e: Matrix; n: Integer);
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 + c[i, k]*d[k, j];
e[i, j] := s
end
end;
var a, b, c,d,e: Matrix;
i, j, n: Integer;
begin
WriteLn('vvedite poradok matrix');
Write('n = '); ReadLn(n);
WriteLn('vvedite pervyu');
for i := 1 to n do
for j := 1 to n do
Read(a[i, j]);
WriteLn('vvedite vtoryu');
for i := 1 to n do
for j := 1 to n do
Read(b[i, j]);
WriteLn('vvedite tretu');
for i := 1 to n do
for j := 1 to n do
Read(d[i, j]);
MulMatrix(a, b, c, n);
MulMatrix(c, d, e, n);
for i := 1 to n do
begin
for j := 1 to n do
Write(e[i, j]:0:6, ' ');
WriteLn
end;
ReadLn
end.
Вот готово, замечания будут? »
Будут :)
program ABC;
const NMax = 10;
type Matrix = array [1..NMax, 1..NMax] of Real;
procedure MulMatrix(var M1, M2, M3: Matrix; n: Integer);
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 + M1[i, k]*M2[k, j];
M3[i, j] := s
end
end;
procedure VvodM(var M1:Matrix; n:integer);
var
i,j:integer;
begin
for i := 1 to n do
for j := 1 to n do
Read(M1[i, j]);
end;
procedure VivodM(var M1:Matrix; n:integer);
var
i,j:integer;
begin
for i := 1 to n do
begin
for j := 1 to n do
Write(M1[i, j]:0:6, ' ');
WriteLn;
end;
end;
var a, b, c,d,e: Matrix;
i, j, n: Integer;
begin
WriteLn('vvedite poradok matrix');
Write('n = '); ReadLn(n);
WriteLn('vvedite pervyu');
VvodM(a, n);
WriteLn('vvedite vtoryu');
VvodM(b, n);
WriteLn('vvedite tretu');
VvodM(c, n);
MulMatrix(a, b, d, n);
MulMatrix(c, d, e, n);
VivodM(e,n);
ReadLn;
end.
Как вариант, можно кусочек переписать иначе, через функцию:
finction MulMatrix(var M1, M2; n: Integer):Matrix;
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 + M1[i, k]*M2[k, j];
result[i, j] := s
end
end;
соотв. в основном теле программы будет:
d:=MulMatrix(a,b,n);
e:=MulMatrix(c,d,n);
Общие комментарии:
Вообще не стОит путать локальные(внутри процедур и функций) и глобальные(общие для всей программы) переменные.
Поэтому я переименовал в процедурах a, b, c, e и т.д. в более условные и единые M1, M2, M3.
i, j, k счетчики, с ними все ясно.
Массивы a, b, c - основные.
d, e производные от умножения.
Бывшие процедуры 1MulMatrix, 2MulMatrix нигде не вызывались, соотв. заменены на вызываемую MulMatrix с разными передаваемыми ей аргументами.
Конечный Readln; по большому счету не нужен. Он служит для паузы во время отладки. При финальной компиляции программы эту строчку желательно закоментировать.
dasha131
13-10-2010, 14:55
Спасибо, да действительно объединение двух процедур перемножения в одну очень кстати, и процедура ввода весьма удобна, а вот процедура вывода кажется мне лишней=)
dasha131
13-10-2010, 15:18
Проверила все в ручную на примере перемножения матриц размерностью 3х3 в первой программа все вычисляется верно, а во второй где процедуры объединены неверно, почему так??
dasha131, приведи код программы пожалуйста. В которой процедуры объединены и работают не верно.
dasha131
14-10-2010, 12:50
Вот же он.
Выше вами приведенный
Да вот кстати обьясните пожалуйста почему в моём варианте кода выбор параметра в процедуре по ссылке лучше чем по значению???
dasha131
15-10-2010, 18:01
lxa85, приведи код программы пожалуйста »
Я имею веду ваш код!
Странно, вроде бы ошибки быть не должно.
Давай сравнивать входные наборы и полученные результаты.
Да вот кстати обьясните пожалуйста почему в моём варианте кода выбор параметра в процедуре по ссылке лучше чем по значению?? »
Ты имеешь в виду в чем отличие записи
procedure VvodM(var M1:Matrix; n:integer); от
procedure VvodM(M1:Matrix; n:integer);
При вызове процедуры (функции) выделяется память, в нее записываются передаваемые данные и служебная информация.
Передавать ссылку на массив проще, нежели сам массив. Это быстрее, экономичнее в плане ресурсов и времени.
Если этого не делать, а передавать в процедуру весь массив, то при большой "вложенности" процедур с пересылками полного массива данных, может возникнуть переполнение доступной памяти. Если передавать ссылки, этого не произойдет. Однако следует быть внимательным к тому, что на что и когда ссылается.
Для наглядности предложу вариант с книжной библиотекой. Если понадобилась информация, нас адресуют к нужному стеллажу. Перетаскивать к себе домой 6 рядов книг, чтобы прочесть эпиграф к произведению - нецелесообразно. Можно конечно, но не нужно :)
dasha131
15-10-2010, 18:26
Понятно обьяснили, спасибо!=)
dasha131
15-10-2010, 18:45
результат получается числа но не те
ввожу матрицы, пеемножение которых было проверенно мной в ручную
размерность=3
3 2 1 0 4 7 7 4 0
4 0 5 8 2 1 8 2 1
7 0 2 6 5 0 9 1 1
правильный ответ
529 153 44
790 230 69
829 173 87
ответ выдаваемый программой
274 311 273
248 288 289
240 268 284
Попробовала убрать вызов второй процедуры и вывисти результат перемножения AB, результат сошолся с тем который был получен в ручную
22 21 23
30 41 28
12 38 49
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.