Курсовая Разработка программного комплекса решения математической задачи численными методами
Работа добавлена на сайт bukvasha.net: 2015-10-25Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
от 25%
договор
Федеральное агентство по образованию
Государственное образовательное учреждение
высшего профессионального образования
"Липецкий государственный технический университет"
Кафедра автоматизированных систем управления
Курсовая работа
по программированию
«Разработка программного комплекса решения математической задачи численными методами»
Студент: ____________ Писаренко И.М.
подпись, дата
Группа: АИ-09-1
|
______________ ____________ Ведищев В.В.
учёная степень, звание подпись, дата
Липецк – 2010 г.
АННОТАЦИЯ
С. 36. Ил. 4. Библиогр.: 8 назв.
В отчёте представлено описание использованного метода решения системы линейных уравнений (метода Гаусса), описание разработанной программы, описание применения, руководство программиста, описание контрольного примера, текст программы.
ОГЛАВЛЕНИЕ
1. ОПИСАНИЕ ПРОГРАММЫ 5
1.1.ОБЩИЕ СВЕДЕНИЯ 5
1.2 ФУНКЦИОНАЛЬНОЕ НАЗНАЧЕНИЕ 5
1.3. ОПИСАНИЕ ЛОГИЧЕСКОЙ СТРУКТУРЫ 6
1.4. ИСПОЛЬЗУЕМЫЕ ТЕХНИЧЕСКИЕ СРЕДСТВА 8
1.5.ВЫЗОВ И ЗАГРУЗКА 8
1.6. ВХОДНЫЕ ДАННЫЕ 8
1.7. ВЫХОДНЫЕ ДАННЫЕ 8
2. ОПИСАНИЕ ПРИМЕНЕНИЯ 9
2.1. НАЗНАЧЕНИЕ ПРОГРАММЫ 9
2.2. УСЛОВИЯ ПРИМЕНЕНИЯ 9
2.3. ОПИСАНИЕ ЗАДАЧИ 9
2.4 ВХОДНЫЕ И ВЫХОДНЫЕ ДАННЫЕ 11
3. РУКОВОДСТВО ПРОГРАММИСТА
11
3.1. НАЗНАЧЕНИЕ И УСЛОВИЯ ПРИМЕНЕНИЯ ПРОГРАММЫ 11
3.2. ХАРАКТЕРИСТИКА ПРОГРАММЫ 12
3.3. ОБРАЩЕНИЕ К ПРОГРАММЕ 12
3.4. ВХОДНЫЕ И ВЫХОДНЫЕ ДАННЫЕ 12
3.5. СООБЩЕНИЯ 13
4. ОПИСАНИЕ КОНТРОЛЬНОГО ПРИМЕРА 15
4.1. ОБЪЕКТ ИСПЫТАНИЙ 15
4.2. ЦЕЛЬ ИСПЫТАНИЙ 15
4.3. ТРЕБОВАНИЯ К ПРОГРАММЕ 15
4.3.1. КОРРЕКТНЫЕ ВХОДНЫЕ ДАННЫЕ 16
4.3.2. ОШИБОЧНЫЕ ВХОДНЫЕ ДАННЫЕ 18
5. ТЕКСТ ПРОГРАММЫ 19
ЗАКЛЮЧЕНИЕ 35
БИБЛИОГРАФИЧЕСКИЙ СПИСОК 36
1. ОПИСАНИЕ ПРОГРАММЫ
1.1.ОБЩИЕ СВЕДЕНИЯ
Обозначение и наименование программы: решение системы линейных уравнений методом Гаусса; имя программы – Gauss.exe.
Программное обеспечение, необходимое для функционирования программы: операционная система MS Windows XP или MS Windows Vista.
Используемый язык программирования: С.
1.2 ФУНКЦИОНАЛЬНОЕ НАЗНАЧЕНИЕ
Классы решаемых задач: системы линейных алгебраических уравнений.
Назначение программы: решение систем линейных алгебраических уравнений методом Гаусса.
1.3. ОПИСАНИЕ ЛОГИЧЕСКОЙ СТРУКТУРЫ
1.4. ИСПОЛЬЗУЕМЫЕ ТЕХНИЧЕСКИЕ СРЕДСТВА
Компьютер IBM PC совместимый.
1.5.ВЫЗОВ И ЗАГРУЗКА
Запуск программы осуществляется указанием имени программного модуля (Gauss.exe) командной строке. Установка программы не требуется.
1.6. ВХОДНЫЕ ДАННЫЕ
Входными данными являются навигационные символы "h", "q", "s" в нижнем регистре при английской раскладке клавиатуры; размер расширенной матрицы, записанный в виде двух целых положительных чисел (в записи должны содержаться только цифры от 0 до 9), не превосходящих 2147483648, разделённых символом "*" (количество строк в расширенной матрице должно быть на единицу меньше количества столбцов); элементы расширенной матрицы записанные в виде целых или вещественных чисел (в записи должны содержаться только цифры от 0 до 9, в вещественных числах целая часть от дробной должна отделяться с помощью символа ",", при вводе отрицательных чисел следует использовать символ "-").
1.7. ВЫХОДНЫЕ ДАННЫЕ
Выходными данными являются пошаговое решение системы линейных алгебраических уравнений, сообщения о возможных ошибках, полученный ответ, выведенные на консоль. Формат выходных данных: символьная информация, целые и вещественные числа в арифметическом виде; в вещественных числах целая часть от дробной отделяется символом ",".
2. ОПИСАНИЕ ПРИМЕНЕНИЯ
2.1. НАЗНАЧЕНИЕ ПРОГРАММЫ
Программа предназначена для решения систем линейных алгебраических уравнений в которых число уравнений совпадает с числом неизвестных. Ограничение на количество неизвестных определяется размером оперативной памяти. Модуль элемента расширенной матрицы не должен превышать 1073741823. Вещественные числа выводятся с точностью до 5-ти знаков после запятой.
2.2. УСЛОВИЯ ПРИМЕНЕНИЯ
Операционная система MS Windows XP или MS Windows Vista, процессор с частотой 1 ГГц, 256 Мб ОЗУ, 20 КБ свободного места на жёстком диске, видеокарта без ограничений, клавиатура.
Входная информация вводится с клавиатуры, выходная информация выводится на консоль.
2.3. ОПИСАНИЕ ЗАДАЧИ
В разделе «Численные методы линейной алгебры» рассматриваются численные методы решения систем линейных алгебраических уравнений (СЛАУ) и численные методы решения задач на собственные значения и собственные векторы матриц.
Среди численных методов алгебры существуют прямые методы, в которых решение получается за конечное фиксированное число операций и итерационные методы, в которых результат достигается в процессе последовательных приближений.
Из прямых методов решения СЛАУ рассмотрим методы Гаусса.
В методе Гаусса матрица СЛАУ с помощью равносильных преобразований преобразуется в верхнюю треугольную матрицу, получающуюся в результате прямого хода. В обратном ходе определяются неизвестные.
На первом шаге алгоритма Гаусса выберем диагональный элемент a11 (если он равен 0, то первую строку переставляем с какой-либо нижележащей строкой) и объявляем его ведущим, а соответствующую строку и столбец, на пересечении которых он стоит - ведущими. Обнулим элементы a21, ..., an1 ведущего столбца. Для этого сформируем числа (–a21/a11);...;(-an1/a11). Умножая ведущую строку на число (–a21/a11), складывая со второй строкой и ставя результат на место второй строки, получим вместо элемента a21 нуль, а вместо элементов aj1 j от 2 до n, b2 – соответственно элементы a12j = a2j + a1j * (-a21/a11), j от 2 до n, b12 = b2 + b1 * (-a21/a11) и т.д. Умножая ведущую строку на число (‑an1/a11), складывая с n-ой строкой и ставя результат на место n-ой строки, получим вместо элемента an1 нуль, а остальные элементы будут иметь вид: a1nj = anj + a1j * (-an1/a11), b1n = bn + b1 * (-an1/a11).
Повторяя аналогичные действия для остальных строк, получим матрицу треугольного вида, что и завершит прямой ход метода Гаусса.
В обратном ходе алгоритма Гаусса из последнего уравнения сразу определяется xn, из предпоследнего – xn-1 и т.д. Из первого уравнения определяется x1.При обработке результатов также необходимо учитывать следующее:
- если элементы какой-либо строки матрицы системы в результате преобразований стали равными нулю, а правая часть не равна нулю, то СЛАУ несовместна, поскольку не выполняются условия теоремы Кронекера-Капелли;
- если элементы какой-либо строки матрицы системы и правая часть в результате преобразований стали равными нулю, то СЛАУ совместна, но имеет бесконечное множество решений.
2.4 ВХОДНЫЕ И ВЫХОДНЫЕ ДАННЫЕ
Входными данными являются навигационные символы "h" (вызов справки), "q" (выход из программы или возврат в предыдущий пункт меню), "s" (начало ввода необходимы числовых данных или переход в другой раздел меню) в нижнем регистре при английской раскладке клавиатуры; размер расширенной матрицы, записанный в виде двух целых положительных чисел (в записи должны содержаться только цифры от 0 до 9), не превосходящих 2147483648, разделённых символом "*" (количество строк в расширенной матрице должно быть на единицу меньше количества столбцов); элементы расширенной матрицы записанные в виде целых или вещественных чисел (в записи должны содержаться только цифры от 0 до 9, в вещественных числах целая часть от дробной должна отделяться с помощью символа ",", при вводе отрицательных чисел следует использовать символ "-").
Выходными данными являются пошаговое решение системы линейных алгебраических уравнений, сообщения о возможных ошибках, полученный ответ, выведенные на консоль. Формат выходных данных: символьная информация, целые и вещественные числа в арифметическом виде; в вещественных числах целая часть от дробной отделяется символом ",".
3. РУКОВОДСТВО ПРОГРАММИСТА
3.1. НАЗНАЧЕНИЕ И УСЛОВИЯ ПРИМЕНЕНИЯ ПРОГРАММЫ
Программа представляет собой набор функций, написанных на языке программирования С, решающих задачи: выделения оперативной памяти под хранение матриц, очистки оперативной памяти, заполнения матриц, вывод матриц на консоль; формирования заголовков разделов меню, вывода ошибок и предупреждений, частичной очистки консоли; поиска решения системы линейных алгебраических уравнений, проверки правильности ввода данных, реализации прямого и обратного ходов метода Гаусса (см. п.1), обмена местами строк; вывода справочной информации.
Для функционирования программы необходимы следующие периферийные устройства: клавиатура и монитор. Необходимый объём оперативной памяти 1,6 МБ.
3.2. ХАРАКТЕРИСТИКА ПРОГРАММЫ
Программа предназначена для решения систем линейных алгебраических уравнений в которых число уравнений совпадает с числом неизвестных. Ограничение на количество неизвестных определяется размером оперативной памяти. Модуль элемента расширенной матрицы не должен превышать 1073741823. Вещественные числа выводятся с точностью до 5-ти знаков после запятой.
Временные характеристики: менее секунды. Средство контроля правильности выполнения: ручное.
3.3. ОБРАЩЕНИЕ К ПРОГРАММЕ
Вызов программы осуществляется указанием её имени (Gauss.exe) в командной строке.
3.4. ВХОДНЫЕ И ВЫХОДНЫЕ ДАННЫЕ
Входными данными являются навигационные символы "h" (вызов справки), "q" (выход из программы или возврат в предыдущий пункт меню), "s" (начало ввода необходимы числовых данных или переход в другой раздел меню) в нижнем регистре при английской раскладке клавиатуры; размер расширенной матрицы, записанный в виде двух целых положительных чисел (в записи должны содержаться только цифры от 0 до 9), не превосходящих 2147483648, разделённых символом "*" (количество строк в расширенной матрице должно быть на единицу меньше количества столбцов); элементы расширенной матрицы записанные в виде целых или вещественных чисел (в записи должны содержаться только цифры от 0 до 9, в вещественных числах целая часть от дробной должна отделяться с помощью символа ",", при вводе отрицательных чисел следует использовать символ "-").
Выходными данными являются пошаговое решение системы линейных алгебраических уравнений, сообщения о возможных ошибках, полученный ответ, выведенные на консоль. Формат выходных данных: символьная информация, целые и вещественные числа в арифметическом виде; в вещественных числах целая часть от дробной отделяется символом ",".
3.5. СООБЩЕНИЯ
Для навигации в этом разделе меню вы можете использовать только клавиши "s", "h" и "q" в нижнем регистре (убедитесь, что не активирован Caps Lock). Раскладка клавиатуры должна быть английской.
Сообщение выдаётся при навигации символами, не относящимися к навигационным, либо при вводе требуемых символов в верхнем регистре. Появление сообщения так же возможно при нажатии пользователем на клавишу, содержащую необходимый символ, но не при английской раскладке клавиатуры.
Данная программа предназначена только для решения систем, в которых количество неизвестных равно количеству уравнений.
Сообщение выдаётся при вводе пользователем некорректных размеров расширенной матрицы (количество строк в расширенной матрице должно быть на единицу меньше количества столбцов).
Не удалось выделить память под матрицу указанного размера! Нажмите "h", если хотите получить справочную информацию об ошибке или любую другую клавишу для возврата в главное меню.
Сообщение выдаётся, если не удалось выделить память под матрицу указанного пользователем размера. Размер матрицы ограничен размером оперативно памяти. После появления такой ошибки рекомендуется перезапустить программу.
ОШИБКА: Не удалось выделить память под хранение результата! Нажмите любую клавишу...
Сообщение выдаётся, если не удалось выделить память под массив для хранения найденных в ходе решения значений. Размер массива ограничен размером оперативной памяти.
ОШИБКА: Вы не ввели два целых числа! Нажмите любую клавишу...
ОШИБКА: Вы должны ввести только два целых положительных числа, разделённых символом "*"! Нажмите любую клавишу...
Сообщения выдаются при некорректном вводе размеров расширенной матрице (ввод отрицательных чисел, символов, не являющихся цифрами).
ОШИБКА: Слишком большое число! Нажмите любую клавишу...
Сообщение выдаётся при вводе в качестве одного из размеров расширенной матрицы числа, превосходящего 2147483647.
ОШИБКА: Неверно введено вещественное число! (Отсутствует целая или дробная часть.). Нажмите любую клавишу...
ОШИБКА: В записи одного из чисел содержится недопустимый символ! Нажмите любую клавишу...
Сообщения выдаются при некорректном вводе элементов расширенной матрицы.
ОШИБКА: Одно из чисел слишком велико по модулю! Нажмите любую клавишу...
Сообщение выдаётся при вводе в качестве элемента расширенной матрицы числа, превосходящего 1073741823.
4. ОПИСАНИЕ КОНТРОЛЬНОГО ПРИМЕРА
4.1. ОБЪЕКТ ИСПЫТАНИЙ
Программа для решения систем линейных уравнений методом Гаусса (Gauss.exe).
4.2. ЦЕЛЬ ИСПЫТАНИЙ
Проверка правильности работы программы.
4.3. ТРЕБОВАНИЯ К ПРОГРАММЕ
При запуске программы пользователь попадает в главное меню, где ему предлагается выбрать одно из трёх возможных действий: решить систему линейных уравнений методом Гаусса, перейти в справочный раздел, выйти их программы.
Рисунок 1. Главное меню.
Выбрав пункт меню "Решить СЛУ методом Гаусса" пользователь перенаправляется в раздел "Решение СЛУ методом Гаусса", где ему необходимо ввести размер расширенной матрицы и значения её элементов. (При необходимости пользователь может получить справочную информацию по вводу.)
4.3.1. КОРРЕКТНЫЕ ВХОДНЫЕ ДАННЫЕ
Рисунок 2. Ввод входных данных
После окончания ввода на консоль выводится ход решения и ответ.
Рисунок 3. Вывод решения и ответа
4.3.2. ОШИБОЧНЫЕ ВХОДНЫЕ ДАННЫЕ
При вводе ошибочных входных данных, например, отрицательного числа в качестве одного из размеров расширенной матрицы, должно быть выдано сообщение об ошибке.
Рисунок 4. Вывод сообщения об ошибке при некорректных входных данных
5. ТЕКСТ ПРОГРАММЫ
help.h:
int GaussMethod();
int MemoryMatrix();
int StartHelp();
interface.h:
int Header(char *Content, char *Type, int MaxLength);
int Alert(char *Content);
int Error(char *Content);
int DelLastSymbols(int NumSymbols);
solution.h:
int FindSolution();
int SizeFormatCheck(unsigned int *NumRow, unsigned int *NumCol, char String[]);
int DigitCheck(char *Symbol);
int ElementsCheck(float *Element, char String[]);
int Gauss(float **Matrix, int NumRow, int NumCol);
int ChangeStrings(float **Matrix, int NumRow, int NumCol, int NowI);
int ReverseGauss(float **Matrix, int NumRow, int NumCol, float *Result);
matrix.h:
float** CreateMatrix(unsigned int NumRow, unsigned int NumCol);
void DelMatrix(float **Matrix, int NumRow);
int FullMatrix(float **Matrix, int NumRow, int NumCol);
int PrintMatrix(float **Matrix, int NumRow, int NumCol);
help.cpp:
#include <stdio.h>
#include "interface.h"
#include "help.h"
int GaussMethod(){
Header("Решение СЛУ методом Гаусса", "-", 42);
printf("\n\n");
printf("Метод Гаусса — классический метод решения системы линейных уравнений. Это метод\nпоследовательного исключения переменных, когда с помощью элементарных\nпреобразований система уравнений приводится к равносильной системе ступенчатого\n(или треугольного) вида, из которого последовательно, начиная с последних\n(по номеру) переменных, находятся все остальные переменные.\n\n");
printf("A11X1 + ... + A1nXn = B1\n");
printf("........................\n");
printf("Am1X1 + ... + AmnXn = Bm\n");
printf("\nВ данной системе линейных уравнений набор строк и столбцов из коэффициентов Aij\nсоставляют основную матрицу, элементы Bi - столбец свободных членов.\nРасширенная матрица состоит из основной матрицы и столбца свободных членов.\nВ этом примере расширенная матрица будет выглядеть следующим образом:\n\n");
printf("A11 ... A1n B1\n");
printf("..............\n");
printf("Am1 ... Amn Bm\n");
return 0;
}
int MemoryMatrix(){
Header("Выделение памяти под матрицу", "-", 42);
printf("\n\n");
printf("Для решения СЛУ методом Гаусса вам необходимо ввести размер матрицы\nв формате m*n, после чего программа должна выделить память для хранения самой\nматрицы. В связи с этим максимальный размер матрицы ограничен объёмом\nоперативной памяти вашего компьютера. Появление в процессе работы с программой\nошибки\"Не удалось выделить память под матрицу\", означает, что превышен\nмаксимальный размер матрицы.\nПосле появления такой ошибки рекомендуется перезапустить программу.");
return 0;
}
int StartHelp(){
Header("Общая информация", "-", 42);
printf("\n\n");
printf("Данная программа предназначена для решения систем линейных уравнеий методом\nГаусса (приведение матрицы к треугольному виду). Решение уравнения состоит из\nдвух этапов: ввод данных (I), вывод результатов каждого шага решения и ответа\n(II). В качестве входных данных вам необходимо будет ввести размер расширенной\nматрицы, затем её саму. Размер расширенной матрице следует вводить в формате\nm*n, где m - количество строк, n - количество столбцов (то есть, если вы хотите\nввести матрицу с 3-мя строками 4-мя столбцами, формат ввода будет 3*4; важно\nпомнить, что количество строк должно быть на единицу меньше количества\nстолбцов). Элементы матрицы могут быть как целыми, так и вещественными,\nчислами. При вводе вещественных чисел целую часть от дробной следует отделять\nс помощью запятой. Все вещественные числа выводятся на экран с точностью до\n5-ти знаков после запятой.\n");
return 0;
}
interface.cpp:
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "interface.h"
int Header(char *Content, char *Type, int MaxLength){
printf("\t\t");
int ContLength = strlen(Content);
if (ContLength > MaxLength) {
printf("%s", Type);
for (int i = 0; i < MaxLength - 3; i++) {printf("%c", Content[i]);}
printf("...%s", Type);
} else {
int i, N = (MaxLength - ContLength) /2;
for (i = 0; i < N; i++) {printf("%s", Type);}
printf("%s", Content);
for (i = 0; i < MaxLength - ContLength - N; i++) {printf("%s", Type);}
}
return 0;
}
int Alert(char *Content){
system("cls");
system("color 4F");
Header("Предупреждение", "*", 42);
printf("\n\n%s\n\nНажмите любую клавишу...", Content);
return 0;
}
int Error(char *Content){
system("color 4F");
printf ("%s", Content);
getch();
system("color F0");
return 0;
}
int DelLastSymbols(int NumSymbols){
for (int i = 0; i < NumSymbols; i++) {printf("\b \b");}
return 0;
}
solution.cpp:
#include <conio.h>
#include <malloc.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "interface.h"
#include "matrix.h"
#include "help.h"
#include "solution.h"
int FindSolution(){
char Action = 'h';
while (Action != 's') {
system("cls");
system("color F0");
Header("Меню >> Решение СЛУ методом Гаусса >> I", "=", 42);
printf("\n\nДля решения СЛУ методом Гаусса вам необходимо ввести размер расширенной матрицы\nв формате m*n, затем построчно ввести саму матрицу. При вводе вещественных\nчисел целую часть от дробной следует отделять с помощью запятой.");
printf("\nДля начала работы нажмите \"s\", для вызова справки нажмите \"h\"; вернуться в\nглавное меню - \"q\".");
Action = getch();
if (Action != 'h' && Action != 's' && Action != 'q') {
Alert("Для навигации в этом разделе меню вы можете использовать только\nклавиши \"s\", \"h\" и \"q\" в нижнем регистре (убедитесь, что не активирован\nCaps Lock). Раскладка клавиатуры должна быть английской.");
getch();
continue;
}
if (Action == 'q') {break;}
if (Action == 'h') {
system("cls");
system("color 70");
Header("Справка", "=", 42);
printf("\n\n");
GaussMethod();
printf("\n\nДля возврата нажмите любую клавишу...");
getch();
}
if (Action == 's') {
unsigned int NumRow, NumCol;
char Size[255];
for (;;) {
printf("\n\nВведите размер расширенной матрицы в формате m*n (m - количество строк,\nn - количество столбцов; количество строк должно быть на единицу меньше\nколичества столбцов):\n");
scanf("%s", Size);
if (SizeFormatCheck(&NumRow, &NumCol, Size)) {break;}
}
if (NumRow != NumCol - 1) {
Alert("Данная программа предназначена только для решения систем, в которых количество\nнеизвестных равно количеству уравнений.");
getch();
return 0;
}
system("color F7");
printf("\nИдёт выделение памяти под хранение матрицы. (Процесс может занять некоторое\nвремя...)");
float **Matrix = CreateMatrix(NumRow, NumCol);
if (Matrix == NULL) {
Alert("Не удалось выделить память под матрицу указанного размера!\n\nНажмите \"h\", если хотите получить справочную информацию об ошибке или любую\nдругую клавишу для возврата в главное меню.");
DelLastSymbols(26);
Action = getch();
if (Action == 'h') {
system("cls");
system("color 70");
Header("Справка", "=", 42);
printf("\n\n");
MemoryMatrix();
printf("\n\nДля возврата нажмите любую клавишу...");
getch();
}
return 0;
}
system("color F0");
printf("\n\nПамять выделена.\n");
FullMatrix(Matrix, NumRow, NumCol);
system("cls");
system("color F0");
Header("Меню >> Решение СЛУ методом Гаусса >> II", "=", 42);
Gauss(Matrix, NumRow, NumCol);
float *Result = (float*)malloc(sizeof(float)*(NumCol - 1));
switch(ReverseGauss(Matrix, NumRow, NumCol, Result)) {
case 0:
printf("\n\nОтвет:\n");
for (int i = 0; i < NumCol - 1; i++) {
if (abs(Result[i]) < 1e-5) {printf("X%d = %10.5f\n", i + 1, 0.0);} else {printf("X%d = %10.5f\n", i + 1, Result[i]);}
}
printf("\nПримечание: в ответах возможна потеря точности.\n\nДля возврата в главное меню нажмите любую клавишу...");
getch();
break;
case 1: printf("\n\nТак как в результате преобразований все элементы одной из строк\nматрицы стали равны 0, а свободный член соответствующей строки\nнет, то система не совместна.\n\nОтвет: система линейный уравнений не совместна."); getch(); break;
case 2: printf("\n\nТак как в результате преобразований все элементы одной из строк\nматрицы стали равны 0 (в том числе и свободный член\nсоответствующей строки), то система имеет бесконечное множество решений.\n\n\n\nОтвет: система линейный уравнений имеет бесконечное множество решений"); getch(); break;
case 3: Error("\n\nОШИБКА: Не удалось выделить память под хранение результата!\nНажмите любую клавишу..."); break;
}
DelMatrix(Matrix, NumRow);
}
}
return 0;
}
int SizeFormatCheck(unsigned int *NumRow, unsigned int *NumCol, char String[]){
int StrLength = strlen(String) - 1;
int NumSymbols = 0;
int Degree = 1;
int NowNumber = 0;
int Length = 0;
for (int i = StrLength; i > -1; i--) {
if (((i == StrLength || i == 0) && String[i] == '*') || (i == 0 && NumSymbols == 0)) {
return(Error("\nОШИБКА: Вы не ввели два целых числа!\nНажмите любую клавишу..."));
}
if (String[i] == '*') {
NumSymbols++;
*NumCol = NowNumber;
NowNumber = 0;
Length = 0;
Degree = 1;
continue;
}
if (!DigitCheck(&String[i]) || NumSymbols > 1) {
return(Error("\nОШИБКА: Вы должны ввести только два целых положительных числа, разделённых\nсимволом \"*\"!\nНажмите любую клавишу..."));
}
if (Length == 9 && ((int)String[i] - 48 > 2 || NowNumber > 147483647)) {
return(Error("\nОШИБКА: Слишком большое число!\nНажмите любую клавишу..."));
}
NowNumber += ((int)String[i] - 48)*Degree;
Degree *= 10;
Length++;
}
*NumRow = NowNumber;
return 1;
}
int DigitCheck(char *Symbol){
char Permissible[] = "0123456789";
for (int i = 0; i < 10; i++) {
if (Symbol[0] == Permissible[i]) {return 1;}
}
return 0;
}
int ElementsCheck(float *Element, char String[]){
int StrLength = strlen(String);
int NumSymbols = 0;
int Degree = 10;
float Number = 0;
float Sign = 1.0;
for (int i = 0; i < StrLength; i++) {
if (String[i] == ',' && (i == 0 || i == StrLength - 1)) {
return(Error("\n\nОШИБКА: Неверно введено вещественное число! (Отсутствует целая или дробная\nчасть.)\nНажмите любую клавишу..."));
}
if (String[i] == ',') {
NumSymbols++;
continue;
}
if (i == 0 && String[0] == '-') {
Sign = -1.0;
continue;
}
if (NumSymbols > 1 || !DigitCheck(&String[i])) {
return(Error("\n\nОШИБКА: В записи одного из чисел содержится недопустимый символ!\nНажмите любую клавишу..."));
}
if (NumSymbols == 0) {
Number = Number*10 + ((int)String[i] - 48);
} else {
Number += ((float)String[i] - 48)/Degree;
Degree *= 10;
}
if (NumSymbols == 0 && String[i] != ',' && abs(Number) > 1073741823) {
return(Error("\n\nОШИБКА: Одно из чисел слишком велико по модулю!\nНажмите любую клавишу..."));
}
}
*Element = Sign*Number;
return 1;
}
int Gauss(float **Matrix, int NumRow, int NumCol) {
printf("\n\nШаг 0 (исходная матрица):\n\n");
PrintMatrix(Matrix, NumRow, NumCol);
float Multiplier;
for (int i = 0; i < NumCol - 1; i++) {
printf("\n\nШаг %d:\n\n", i+1);
if (!ChangeStrings(Matrix, NumRow, NumCol, i)) {
printf("В матрице, полученной на предыдущем шаге, элементы %d-го столбца,\nначиная с %d-ой строки равны 0. Переходим к следующему шагу.", i + 1,i + 1);
continue;
}
for (int j = i + 1; j < NumRow; j++) {
Multiplier = -1*Matrix[j][i]/Matrix[i][i];
for (int k = i; k < NumCol; k++) {
Matrix[j][k] = Matrix[j][k] + Multiplier*Matrix[i][k];
}
}
PrintMatrix(Matrix, NumRow, NumCol);
}
return 0;
}
int ChangeStrings(float **Matrix, int NumRow, int NumCol, int NowI) {
if (Matrix[NowI][NowI] != 0) {return 1;}
float Element;
for (int i = NowI; i < NumRow; i++) {
if (Matrix[i][NowI] != 0) {
for (int j = NowI; j < NumCol; j++) {
Element = Matrix[i][j];
Matrix[i][j] = Matrix[NowI][j];
Matrix[NowI][j] = Element;
}
printf("В матрице, полученной на предыдущем шаге, меняем местами строки %d и %d: \n\n", NowI + 1, i + 1);
return 1;
}
}
return 0;
}
int ReverseGauss(float **Matrix, int NumRow, int NumCol, float *Result) {
int NumNil, i, j;
for (i = 0; i < NumCol - 1; i++) {
NumNil = 0;
for (j = 0; j < NumCol - 1; j++) {
if (abs(Matrix[i][j]) < 1e-5) {NumNil++;}
}
if (NumNil == NumCol - 1 && abs(Matrix[i][NumCol - 1]) > 1e-5) {return 1;}
if (NumNil == NumCol - 1 && abs(Matrix[i][NumCol - 1]) < 1e-5) {return 2;}
}
if (Result == NULL) {return 3;}
float Summ;
for (i = NumCol - 2; i > -1; i--) {
Summ = Matrix[i][NumCol - 1];
for (j = NumCol - 2; j > i; j--) {
Summ -= Result[j]*Matrix[i][j];
}
Result[i] = Summ/Matrix[i][i];
}
return 0;
}
matrix.cpp:
#include <locale.h>
#include <malloc.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "matrix.h"
#include "solution.h"
float** CreateMatrix(unsigned int NumRow, unsigned int NumCol) {
float **Pointer;
Pointer = (float**) malloc(sizeof(float*) * NumRow);
if (Pointer == NULL) {return 0;}
for (unsigned int i = 0; i < NumRow; i++) {
Pointer[i] = (float*) malloc(sizeof(float) * NumCol);
if (Pointer[i] == NULL) {return 0;}
}
return(Pointer);
}
void DelMatrix(float **Matrix, int NumRow) {
for (int i = 0; i < NumRow; i++) {
free(Matrix[i]);
}
free(Matrix);
return;
}
int FullMatrix(float **Matrix, int NumRow, int NumCol) {
char Number[255];
int i = 0, NumErrors;
while (i < NumRow) {
NumErrors = 0;
printf("\nВведите %d-ую строку матрицы, отделяя числа друг от друга пробелами (дробную\nчасть от целой следует отделять с помощью запятой):\n", i+1);
for (int j = 0; j < NumCol; j++) {
scanf("%s", Number);
if (!ElementsCheck(&Matrix[i][j], Number)) {NumErrors++;}
}
if (NumErrors == 0) {i++;}
}
return 0;
}
int PrintMatrix(float **Matrix, int NumRow, int NumCol) {
for (int i = 0; i < NumRow; i++) {
for (int j = 0; j < NumCol; j++) {
if (abs(Matrix[i][j]) < 1e-5) {printf("%10.5f", 0.0);} else {printf("%10.5f", Matrix[i][j]);}
}
printf("\n\n");
}
return 0;
}
main.cpp:
#include <conio.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include "interface.h"
#include "help.h"
#include "matrix.h"
#include "solution.h"
int main(){
setlocale(LC_ALL, "Russian");
system("color F0");
char Action = '\t';
char Head[255];
while (Action != 'q') {
system("cls");
system("color F0");
Header("Меню", "=", 42);
printf("\n\nВыберите действие:\n Решить СЛУ методом Гаусса (s)\n Перейти в раздел \"Справка\" (h)\n Выйти из программы (q)\n");
Action = getch();
if (Action != 'q' && Action != 'h' && Action != 's') {
Alert("Для навигации в этом разделе меню вы можете использовать только\nклавиши \"s\", \"h\" и \"q\". Раскладка клавиатуры должна быть английской.");
getch();
continue;
}
if (Action == 's') {
system("cls");
FindSolution();
continue;
}
if (Action == 'h') {
system("cls");
system("color 70");
Header("Меню >> Справка", "=", 42);
printf("\n\n");
StartHelp();
printf("\n");
GaussMethod();
printf("\n");
MemoryMatrix();
printf("\n\nДля возврата в меню нажмите любую клавишу...");
getch();
}
}
return 0;
}
ЗАКЛЮЧЕНИЕ
В ходе выполнения курсовой работы были изучены принципы разработки программного комплекса решения математической задачи численными методами на примере решения системы линейных уравнений методом Гаусса.
БИБЛИОГРАФИЧЕСКИЙ СПИСОК
1. Ильин В. А., Позняк Э. Г. Линейная алгебра.- М.: ФИЗМАТЛИТ, 2005.- 280 с.
2. Керниган Б., Ритчи Д. Язык программирования C.- М.: Вильямс, 2009.- 304 с
3. ГОСТ 19.402-78 Описание программы.
4. ГОСТ 19.502-78 Описание применения. Требования к содержанию и оформлению.
5. ГОСТ 19.504-79 Руководство программиста. Требования к содержанию и оформлению.
6. ГОСТ 19.401-78 Текст программы. Требования к содержанию и оформлению.
7. ГОСТ Р 7.0.5 - 2008. БИБЛИОГРАФИЧЕСКАЯ ССЫЛКА. Общие требования и правила составления.
8. СТАНДАРТЫ Липецкого государственного технического университета по оформлению и нормоконтролю учебных отчётов, работ, проектов /Составитель В.С. Зайцев. — Липецк, 2002. 32 с.