49560 (609159), страница 4
Текст из файла (страница 4)
Свойство антисимметрии при перестановке двух строк (или двух столбцов). При перестановке местами двух строк (или двух столбцов) определитель сохраняет свою абсолютную величину, но меняет знак на противоположный.
Для определителя второго порядка это свойство проверяется элементарно (из правила (1.10) сразу вытекает, что определители
отличаются лишь знаком).
Пусть n > 2, рассмотрим теперь определитель n‑го порядка (1.11) и предположим, что в этом определителе меняются местами две строки с номерами i1 и i2. Записывая формулу Лапласа разложения по этим двум строкам, будет иметь
. (1.35)
При перестановке местами строк с номерами i1 и i2 каждый определитель второго порядка в силу доказанного выше меняет знак на противоположный, а все остальные величины, стоящие под знаком суммы в (1.35), совсем не зависят от элементов строк с номерами i1 и i2 и сохраняют свое значение. Тем самым свойство 2° доказано.
Линейное свойство определителя. Будем говорить, что некоторая строка ( ) является линейной комбинацией строк (
), (
),…, (
) с коэффициентами
, если
для всех j = 1, 2,…, n.
Линейное свойство определителя можно сформулировать так: если в определителе n‑го порядка ∆ некоторая i‑я строка ( ) является линейной комбинацией двух строк (
) и (
) с коэффициентами λ и µ, то
, где
– определитель, у которого i‑я строка равна (
), а все остальные строки те же, что и у ∆, а ∆2 – определитель, у которого i‑я строка равна (
), а все
остальные строки те же, что и у ∆.
Для доказательства разложим каждый из трех определителей по i‑й строке и заметим, что у всех трех определителей все миноры
элементов i‑й строки одинаковы. Но отсюда следует, что формула
сразу вытекает из равенств
(j = 1, 2,…, n).
Конечно, линейное свойство справедливо и для случая, когда i‑я строка является линейной комбинацией не двух, а нескольких строк. Кроме того, линейное свойство справедливо и для столбцов определителя.
Доказанные три свойства являются основными свойствами определителя, вскрывающими его природу.
Следующие пять свойств являются логическими следствиями трех основных свойств.
Следствие 1. Определитель с двумя одинаковыми строками (или столбцами) равен нулю. В самом деле, при перестановке двух одинаковых строк, с одной стороны, определитель ∆ не изменится, а с другой стороны, в силу свойства 2° изменит знак на противоположный. Таким образом, , т.е. 2∆=0 или ∆ = 0.
Следствие 2. Умножение всех элементов некоторой строки (или некоторого столбца) определителя на число λ равносильно умножению определителя на это число λ.
Иными словами, общий множитель всех элементов некоторой строки (или некоторого столбца) определителя можно вынести за знак этого определителя. (Это свойство вытекает из свойства 3° при μ = 0.)
Следствие 3. Если все элементы некоторой строки (или некоторого столбца) определителя равны нулю, то и сам определитель равен нулю. (Это свойство вытекает из предыдущего при λ = 0.)
Следствие 4. Если элементы двух строк (или двух столбцов) определителя пропорциональны, то определитель равен нулю. (В самом деле, в силу следствия 2 множитель пропорциональности можно вынести за знак определителя, после чего останется определитель с двумя одинаковыми строками, который равен нулю согласно следствию 1).
Следствие 5. Если к элементам некоторой строки (или некоторого столбца) определителя прибавить соответствующие элементы другой строки (другого столбца), умноженные на произвольный множитель λ, то величина определителя не изменится. (В самом деле, полученный в результате указанного прибавления определитель можно в силу свойства 3° разбить на сумму двух определителей, первый из которых совпадает с исходным, а второй равен нулю в силу пропорциональности двух строк (или столбцов) и следствия 4.)
Следствие 5, как и линейное свойство, допускает более общую формулировку, которую приведем для строк: если к элементам некоторой строки определителя прибавить соответствующие элементы строки, являющейся линейной комбинацией нескольких других строк этого определителя (с какими угодно коэффициентами), то величина определителя не изменится.
Следствие 5 широко применяется при конкретном вычислении определителей (соответствующие примеры будут приведены в следующем пункте).
Прежде чем сформулировать еще одно свойство определителя, введем полезное понятие алгебраического дополнения данного элемента определителя.
Алгебраическим дополнением данного элемента определителя n‑го порядка (1.11) назовем число, равное
и обозначаемое символом
.
Таким образом, алгебраическое дополнение данного элемента может отличаться от минора этого элемента только знаком.
С помощью понятия алгебраического дополнения теоремы 1.1 и 1.2 можно переформулировать так: сумма произведений элементов любой строки (любого столбца) определителя на соответствующие алгебраические дополнения этой строки (этого столбца) равна этому определителю.
Соответствующие формулы разложения определителя по i‑й строке и по j‑му столбцу можно переписать так:
(1.13')
(1.21')
Свойство алгебраических дополнений соседних строк (или столбцов). Сумма произведений элементов какой-либо строки (или какого-либо столбца) определителя на соответствующие алгебраические дополнения элементов любой другой строки (любого другого столбца) равна нулю.
Доказательство проведем для строк (для столбцов оно проводится аналогично). Записывая подробно формулу (1.13')
(1.36)
видно, что поскольку алгебраические дополнения не зависят от элементов i – й строки
, то равенство (1.36) является тождеством относительно
и сохраняется при замене чисел
любыми другими n числами. Заменив
соответствующими элементами любой (отличной от i‑й) k‑й строки
, мы получим слева в (1.36) определитель с двумя одинаковыми строками, равный нулю согласно следствию 1. Таким образом,
(для любых несовпадающих i и k).
2. Описание алгоритма генерации матриц
2.1 Описание алгоритма программы генерации квадратных матриц
Исследовав теоретическую часть по проблеме генерации матриц, приступаем к практическому применению полученных знаний. Но прежде, чем приступать к написанию кода программы, генерирующей квадратные матрицы по введенному пользователем определителю, размерности матрицы и диапазона элементов матрицы, составим алгоритм для решения данной задачи.
Алгоритм.
-
Ввести определитель, размерность и диапазон значений генерируемой матрицы.
-
Если введенный определитель является простым числом, выходящим за рамки введенного диапазона, и размерность меньше двух, то выдать сообщение об ошибке и перейти к пункту 1, иначе, при корректном вводе, перейти к пункту 3.
-
Организовать функцию разложения определителя на простые множители. Полученные множители записать в вспомогательный массив.
-
Если размерность вспомогательного массива меньше размерности строки генерируемой матрицы, то массив дополняется единицами до тех пор, пока размерность вспомогательного массива не будет равна размерности строки генерируемой матрицы. Если размерность вспомогательного массива больше размерности строки генерируемой матрицы, то получившийся в результате разности размерностей массива и матрицы хвост перемножается с первыми элементами вспомогательного массива.
-
Организовать цикл для генерации матрицы, в которой получившийся массив в пункте 4 располагается на главной диагонали, и одна из областей, находящихся выше или ниже главной диагонали, заполняется случайными числами, принадлежащими введенному диапазону, а другая заполняется нулями.
-
Дальше берется первая строка, умноженная на определенные коэффициенты, получившейся матрицы и складывается с остальными строками.
-
Вывести получившуюся матрицу на экран.
2.2 Написание программы, реализующей алгоритм генерации матриц
Преодоление проблем, возникших при написании программы
При написании кода программы, реализующей алгоритм генерации матриц, столкнулись с рядом трудностей.
Во-первых, необходимо было реализовать проверку вводимых данных, чтобы вводимый определитель удовлетворял диапазону элементов матрицы, т.е. введенный определитель, если является простым числом, то должен входить во введенный диапазон, и размерность матрицы должна быть больше двух. Для преодоления первой проблемы был разработан следующий алгоритм, реализация которого будет приведена ниже.
-
Инициализировать функцию простого числа.
-
Инициализировать функцию проверки определителя и размерности.
-
Если определитель выходит за рамки диапазона и является простым числом или размерность матрицы меньше двух, то выдаем сообщение об ошибке.
-
Иначе при успешной проверки переходим к дальнейшим преобразованиям для генерации матрицы.
Второй проблемой явилось выход элементов матрицы из введенного диапазона, при сложении первой строки, умноженной на определенные коэффициенты, матрицы с остальными строками. Для преодоления данной проблемы были применены следующие операции. Для генерации случайных чисел, введенный диапазон был уменьшен в четыре раза, а коэффициенты берутся из диапазона [-3, 3].
Описание и пояснение некоторых частей программы
В данном пункте будут приведены некоторые части программы, реализующей алгоритм генерации матриц, с пояснениями.
-
Функция простого числа типа int
int prost (int det)
{
int d, i, flag=1;
d=det;
if((d % 2==0 && d!=0 && d!=2) || d<0)
flag=0;
else
for (i=3; i if (d % i==0) flag=0; return flag; } Данная функция определяет, является ли число простым. Если функция получила простое число, то она возвращает единицу, в противном случае ноль. Входные данные – число типа int. Выходные данные – число типа int. Функция проверки определителя и размерности матрицы. int prov_data (int det, int a, int b, int n) { int flag; if (detb || n<2) { if (prost(det)==1 || n<2) flag= -1; } else if (det==0) flag= 0; else if (det==1) flag= 1; else if (det>1 || (deta)) flag= 2; return flag; } Если введенный определитель является простым числом, выходящим из введенного диапазона, и размерность меньше двух, то функция возвращает -1. Иначе если определитель равен нулю, то функция возвращает ноль. Иначе если определитель равен единице, то функция возвращает единицу, иначе если определитель больше двух или меньше нуля, то функция возвращает два. Входные данные – четыре числа типа int. Выходные данные – число типа int (-1, 0, 1 или 2). Функция разложения числа на простые множители. void faktor (int *mas_fakt, int det, int n) { int i, j=0, d, r; int *mass1,*mass2; mass1=(int*) malloc (n*sizeof(int)); mass2=(int*) malloc (n*sizeof(int)); if (det<0) d=-1*det; else if (det>=0) d=det; for (i=2; i<=d/2+1; i++) {while (d % i==0) { d/=i; *(mas_fakt+j)=i; j++; } } if (j { while (j<=n) { *(mas_fakt+j)=1; j++; } } else if (j>n) { r=i=0; while (i { if (i *(mass1+i)=*(mas_fakt+i); else if (i>=n) { *(mass2+r)=*(mas_fakt+i); r++; } i++; } for (i=0; i {j=*(mass2+i); *(mass1+i)=*(mass1+i)*j;} for (i=0; i *(mas_fakt+i)=*(mass1+i); } if (det<0) {r=*(mas_fakt+0);*(mas_fakt+0)=-1*r;} free(mass1); free(mass2); } В данной функции инициализируется цикл для разложения числа, массив mas_fakt заполняется значениями, полученными в результате разложения определителя на простые множители. Если размерность массива mas_fakt меньше размерности строки равной n генерируемой матрицы matr, дописываем единицами. Если размерность массива mas_fakt больше n, то используются два вспомогательных массива mass1 и mass2, где в массив mass1 записываются элементы 1, …, n из массива mas_fakt, а в массив mass2 все остальные. Потом элементы из массива mass1 умножаются на элементы из массива mass2. В итоге массив mas_fakt заполняется элементами массива mass1. Входные данные – числа типа int. Выходные данные – массив (mas_fakt) типа int. Функция, генерации квадратной матрицы. void gen_matric (int *matr, int *mas_fakt, int n, int a, int b) { int i, j,*vsp_mas, k=1, k1; vsp_mas=(int*) malloc (n*sizeof(int)); for (i=0; i for (j=0; j { if (i==j) { *(matr+i*n+j)=*(mas_fakt+j); } else if (i { if (a>=-10 && b<=10) *(matr+i*n+j)=random (b-a)+a; if (a10) *(matr+i*n+j)=random (b/4‑a/4)+a/4; } else *(matr+i*n+j)=0; } for (i=0; i *(vsp_mas+i)=*(matr+0*n+i); for (i=0; i { if (a10) { k=random(7) – 3; if (k1==k) { if (k-3) k-=1; else if (k>=-3 && k<3) k+=1; } } for (j=0; j { if (i>0) *(matr+i*n+j)=*(matr+i*n+j)+*(vsp_mas+j)*k; else if (i==0) *(matr+i*n+j)=*(matr+i*n+j); } k1=k; } free (vsp_mas); } Сначала инициализируется цикл для генерации треугольной матрицы, в которой массив mas_fakt располагается на главной диагонали, и одна из областей, находящаяся выше главной диагонали, заполняется случайными числами, принадлежащими введенному диапазону, а другая заполняется нулями. Потом инициализируется цикл для сложения первой строки, получившейся матрицы matr и умноженной на определенные коэффициенты, с остальными строками. Входные данные – числа типа int. Выходные данные – матрица (matr) типа int. #include #include #include #include #include #include void gen_matric_0 (int *matr, int n, int a, int b); void gen_matric_1 (int *matr, int n); void gen_matric (int *matr, int *mas_fakt, int n, int a, int b); int prov_data (int det, int a, int b, int n); void print_matric (int *matr, int n); void faktor (int *mas_fakt, int det, int n); int prost (int det); void main() { clrscr(); randomize(); FILE *fp; int *matr, mas[4], det, k,*mas_fakt; int n, i, j, l, l1, a, b; int flag; fp=fopen («inf.txt», «r»); fseek (fp, 0L, SEEK_END); l=ftell(fp); fseek (fp, 0L, SEEK_SET); printf («Входные данные:\n»); i=0; while (l!=ftell(fp)) { fscanf (fp, «%d»,&k); l1=ftell(fp); mas[i]=k; printf («%d:», mas[i]); i++; fseek (fp, l1, SEEK_SET); } fclose(fp); det=mas[0]; n=mas[1]; a=mas[2]; b=mas[3]; matr=(int*) malloc (n*n*sizeof(int)); mas_fakt=(int*) malloc (n*sizeof(int)); faktor (mas_fakt, det, kol, n); flag=prov_data (det, a, b, n); if (flag==-1) printf («\nПроверьте правильность ввода данных!\nРазмерность должна быть > или равно 2.\n Определитель должен входить в диапазон, \n если является простым числом, \n или раскладываться на простые множители принадлежащие данному диапазону!!!»);»); else if (flag!=-1) { printf («\nМатрица:\n»); if (flag==0) gen_matric_0 (matr, n, a, b); else if (flag==1) { gen_matric_1 (matr, n); print_matric (matr, n); printf («\n или\n\n»); gen_matric (matr, mas_fakt, n, a, b); } else if (flag==2) gen_matric (matr, mas_fakt, n, a, b); print_matric (matr, n); } free (mas_fakt); free(matr); free(kol); getch(); } int prov_data (int det, int a, int b, int n) { int flag; if (detb) { if (prost(det)==1 || n<2) flag= -1; } else if (det==0) flag= 0; else if (det==1) flag= 1; else if (det>1 || (deta)) flag= 2; return flag; } void gen_matric_0 (int *matr, int n, int a, int b) { int *mass; int nomer_str, i, j, k, l, ras; mass=(int*) malloc (n*sizeof(int)); ras=n; nomer_str=0; if (n==2) k=1; else if (n>2) k=2; for (l=0; l mass[l]=a+random (b-a); for (i=0; i for (j=0, l=0; j { if (i==nomer_str) { *(matr+i*n+j)=mass[l]; l++; } else if (i==k) { *(matr+i*n+j)=mass[l]; l++; } else *(matr+i*n+j)=random (b-a)+a; } free(mass); } void gen_matric_1 (int *matr, int n) { int i, j; for (i=0; i for (j=0; j { if (i==j) *(matr+i*n+j)=1; else if (i!=j) *(matr+i*n+j)=0; } } void gen_matric (int *matr, int *mas_fakt, int n, int a, int b) { int i, j,*vsp_mas, k=1, k1; vsp_mas=(int*) malloc (n*sizeof(int)); for (i=0; i for (j=0; j { if (i==j) { *(matr+i*n+j)=*(mas_fakt+j); } else if (i { if (a>=-10 && b<=10) *(matr+i*n+j)=random (b-a)+a; if (a10) *(matr+i*n+j)=random (b/4‑a/4)+a/4; } else *(matr+i*n+j)=0; } for (i=0; i *(vsp_mas+i)=*(matr+0*n+i); for (i=0; i { if (a10) { k=random(7) – 3; if (k1==k) { if (k-3) k-=1; else if (k>=-3 && k<3) k+=1; } } for (j=0; j { if (i>0) *(matr+i*n+j)=*(matr+i*n+j)+*(vsp_mas+j)*k; else if (i==0) *(matr+i*n+j)=*(matr+i*n+j); } k1=k; } free (vsp_mas); } void print_matric (int *matr, int n) { int i, j; for (i=0; i { for (j=0; j { printf («%5d»,*(matr+i*n+j)); } printf («\n»); } } void faktor (int *mas_fakt, int det, int n) { int i, j=0, d, r; int *mass1,*mass2; mass1=(int*) malloc (n*sizeof(int)); mass2=(int*) malloc (n*sizeof(int)); if (det<0) d=-1*det; else if (det>=0) d=det; for (i=2; i<=d; i++) { while (d % i==0) { d/=i; *(mas_fakt+j)=i; j++; } } if (j { while (j<=n) { *(mas_fakt+j)=1; j++; } } else if (j>n) { r=i=0; while (i { if (i *(mass1+i)=*(mas_fakt+i); else if (i>=n) { *(mass2+r)=*(mas_fakt+i); r++; } i++; } for (i=0; i { j=*(mass2+i); *(mass1+i)=*(mass1+i)*j; } for (i=0; i *(mas_fakt+i)=*(mass1+i); } if (det<0) {r=*(mas_fakt+0);*(mas_fakt+0)=-1*r;} free(mass1); free(mass2); } int prost (int det) { int d, i, flag=1; d=det; if((d % 2==0 && d!=0 && d!=2) || d<0) flag=0; else for (i=3; i if (d % i==0) flag=0; return flag; В заключение данной курсовой работы хотелось бы кратко сказать о проделанной работе, о проблемах, с которыми столкнулся при выполнении поставленной цели, и о перспективах развития и улучшения данного программного продукта. Целью данной курсовой работы было составить алгоритм генерации матриц по введенному определителю, размерности и диапазона элементов матрицы. Чтобы выполнить поставленную цель, необходимо было решить три задачи: Поиск литературы по предмету данной курсовой работы. Составление алгоритма для выполнения поставленной цели. Написание программы, реализующей составленный алгоритм. При решении третьей задачи столкнулся с трудностью проверки корректности ввода данных. Необходимо было проверять, чтобы вводимый определитель удовлетворял диапазону элементов матрицы, т.е. введенный определитель, если является простым числом, то должен входить во введенный диапазон, и размерность матрицы должна быть больше двух. Основными источниками, помогавшими выполнить поставленную цель, явились: Книги по линейной алгебре, в которых содержался материал по теории матриц. Книги по информатике и программированию. Результатом данной курсовой работы стал алгоритм генерации матриц и написанная на его основе программа. Данная программа предназначена для работы с целыми числами. Одной из перспектив развития данного алгоритма является его улучшение для работы с действительными и комплексными числами, а программы – написание ее для работы со всеми числами: целыми, вещественными, комплексными. Чтобы более полно использовать возможности алгоритма, его лучше реализовывать на тех языках программирования, у которых типы данных имеют достаточно большие диапазоны. Надеюсь, что данная программа из области исследования при выполнении курсовой работы, при условии ее усовершенствования, выйдет в свет как полностью готовый к использованию программный продукт и будет востребован не только в целях методических разработок. Ланкастер П. Теория матриц / Ланкастер П. – М.: Наука, 1982. – 272 с. Линейная алгебра / Ильин В.А., Позняк Э.Г. – М.: Наука, 1978. – 304 с. Кострикин А.И. Введение в алгебру / Кострикин А.И. – М.: Физико-математическая литература, 2001. – 368 с. Писанецки С. Технология разряженных матриц / Писанецки С. – М.: Мир, 1988. – 410 с. Гантмахер Ф.Р. Теория матриц / Гантмахер Ф.Р. – М.: Наука, 1988. – 552 с. Подбельский В.В. Язык С++ / Подбельский В.В. – М.: Финансы и статистика, 2003. – 560 с. Кетков Ю.Л., Кетков А.Ю. Практика программирования: Бейсик, Си, Паскаль. Самоучитель. / Кетков Ю.Л., Кетков А.Ю. – СПб.: БХВ – Петербург, 2002. – 480 с. Мальцев А.И. Основы линейной алгебры / Мальцев А.И. – М.: Наука, 1970. – 400 с. Крячков А.В., Сухинина И.В., Томшин В.К. Программирование на С и С++ / Крячков А.В., Сухинина И.В., Томшин В.К. – М.: Горячая линия – Телеком, 2000. – 344 с. Приложение Таблица тестов. В таблице приведены результаты некоторых тестов программы. номер теста входные данные выходные данные 1 0 2 -100 100 2 -10 3 -50 50 3 -1 3 -24 50 4 50 2 -100 100 5 113 4 -100 100 Проверьте правильность ввода данных! Размерность должна быть > или равно 2. Определитель должен входить в диапазон, если является простым числом, или раскладываться на простые множители принадлежащие данному диапазону!!! 6 1 3 -24 50
Листинг программы, реализующей алгоритм генерации матриц
Заключение
Список литературы