- •«Разработка программного комплекса решения математической задачи численными методами»
- •1.Описание программы
- •1.3.2. Структура программы
- •1.4. Используемые технические средства
- •1.4.1. При разработке
- •1.4.2. Минимальные требования
- •1.5. Вызов и загрузка
- •2.3. Описание задачи
- •2.4. Входные данные
- •3.4. Входные и выходные данные.
- •3.4.1. Входные данные.
- •3.4.2. Выходные данные.
- •3.5. Сообщения
- •4.Описание контрольного примера
- •6.Блок-схема программы
- •Библиографический список
4.Описание контрольного примера
4.1 Назначение программы
Программа предназначена для решения системы линейных уравнений методом Гаусса. Программа имеет некоторые ограничения, которые необходимо учитывать пользователю при вводе тех или иных параметров. В любом случае параметры проверяются перед расчетом.
4.2. Целью проведения испытаний
Проверить правильность нахождения решения системы линейных уравнений методом Гаусса.
4.3 Требования, подлежащие проверке
- Правильность нахождения решения системы линейных уравнений;
- Верность выдаваемых сообщений об ошибке или предупредительных сообщений при наличии данных, некорректно введенных пользователем.
4.4. Технические программные средства, используемые при вводе
Технические средства: компьютер типа IBM PC, монитор, мышь и клавиатура.
Программные средства: операционная система Microsoft Windows XP Professional и тестируемая программа.
4.5. Порядок проведения тестирования
- Вести значения, соответствующие проверяемым требованиям;
- Отследить результаты работы программы;
- Сравнить полученные значения с ожидаемыми результатами.
4.6. Используемые методы тестирования
4.6.1.Проверка правильности решения системы линейных уравнений
Построим таблицу для ввода исходных данных 2х3:
Введем коэффициенты:
2 4 6
-4 2 7
3) Ожидаемое решение:
x1 = -0,8;
x2 = 1,9.
Рассчитаем:
4.6.2. Проверка поведения программы при заведомо неправильных входных
данных
Ошибки
Пользователь не ввел в ячейку (2,2) коэффициент при переменной
Пользователь ввел в ячейку (1,2) данные, которые нельзя преобразовать в число:
3. Введена система линейно зависимых уравнений:
4. Файл со справкой отсутствует в одной папке с программой:
5.Текст программы
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <Math.h>
#include <ShellAPI.h>
#include <stdio.h>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
double opredelitel(double **Matr1, int size);
int proverka_zapoln (void);
void na_shag_vverh (double **M, int row); // перемещение строк при возникновении стуации деления на ноль
int metod_Gaussa(void);
int perepoln_pri_umnosh(double x1, double x2);
int perepoln_pri_slosh(double x1, double x2);
void pogreshnost(void);
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
StringGrid1->ColCount = 3;
StringGrid1->RowCount = 2;
StringGrid1->Cells[2][0] = "b";
StringGrid1->Cells[1][0] = "x1";
StringGrid1->Cells[0][1] = "y1";
StringGrid2->Cells[0][0] = "x1";
Button1->Caption = "Добавить строку и столбец";
Button2->Caption = "Решить систему";
Button3->Caption = "Удалить строку и столбец";
Button4->Caption = "Справка";
Label1->Caption = "Погрешность = 10";
Label1->Visible = false;
Edit1->Visible = false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
//добавление строки и столбца
if (StringGrid1->RowCount > 9)
return;
if (StringGrid1->DefaultRowHeight > 30)
{
int razmer;
if (Form1->Height * 1.3 > Form1->Width)
razmer = Form1->Width;
else
razmer = Form1->Height * 1.3;
StringGrid1->Height = 0.2 * razmer;
StringGrid1->Width = 0.9 * razmer;
StringGrid1->ColCount += 1;
StringGrid1->RowCount += 1;
StringGrid1->DefaultRowHeight = (StringGrid1->Height - StringGrid1->RowCount - 1)/StringGrid1->RowCount;
StringGrid1->DefaultColWidth = (StringGrid1->Width - StringGrid1->ColCount - 1)/StringGrid1->ColCount;
StringGrid1->Width = StringGrid1->DefaultColWidth * StringGrid1->ColCount + (StringGrid1->ColCount + 3);
StringGrid1->Height = StringGrid1->DefaultRowHeight * StringGrid1->RowCount + (StringGrid1->ColCount + 3);
StringGrid1->Font->Size = floor(StringGrid1->DefaultColWidth / 14);
StringGrid2->Font->Size = StringGrid1->Font->Size;
StringGrid2->DefaultRowHeight = StringGrid1->DefaultRowHeight;
StringGrid2->DefaultColWidth = StringGrid1->DefaultColWidth;
StringGrid2->Width = StringGrid1->Width - StringGrid1->DefaultColWidth * 2;
StringGrid2->Height = StringGrid2->DefaultRowHeight * 2 + 3;
StringGrid2->ColCount += 1;
StringGrid1->Cells[StringGrid1->ColCount - 1][0] = StringGrid1->Cells[StringGrid1->ColCount - 2][0];
StringGrid1->Cells[StringGrid1->ColCount - 2][0] = "x" + IntToStr(StringGrid1->ColCount - 2);
StringGrid1->Cells[0][StringGrid1->RowCount - 1] = "y" + IntToStr(StringGrid1->RowCount - 1);
StringGrid2->Cells[StringGrid1->ColCount - 3][0] = StringGrid1->Cells[StringGrid1->ColCount - 2][0];
for (int i = 1; i < StringGrid1->ColCount; i++)
{
StringGrid1->Cells[StringGrid1->ColCount - 1][i] = StringGrid1->Cells[StringGrid1->ColCount - 2][i];
StringGrid1->Cells[StringGrid1->ColCount - 2][i] = "";
}
}
else
{
StringGrid1->ColCount += 1;
StringGrid1->RowCount += 1;
StringGrid1->Cells[StringGrid1->ColCount - 1][0] = StringGrid1->Cells[StringGrid1->ColCount - 2][0];
StringGrid1->Cells[StringGrid1->ColCount - 2][0] = "x" + IntToStr(StringGrid1->ColCount - 2);
StringGrid1->Cells[0][StringGrid1->RowCount - 1] = "y" + IntToStr(StringGrid1->RowCount - 1);
StringGrid2->ColCount += 1;
StringGrid2->Cells[StringGrid1->ColCount - 3][0] = StringGrid1->Cells[StringGrid1->ColCount - 2][0];
for (int i = 1; i < StringGrid1->ColCount; i++)
{
StringGrid1->Cells[StringGrid1->ColCount - 1][i] = StringGrid1->Cells[StringGrid1->ColCount - 2][i];
StringGrid1->Cells[StringGrid1->ColCount - 2][i] = "";
}
if ((StringGrid2->DefaultColWidth + 1) * StringGrid2->ColCount + 3 <= StringGrid1->Width)
{
StringGrid2->Width = (StringGrid2->DefaultColWidth + 1) * StringGrid2->ColCount + 5;
}
else
{
StringGrid2->Width = StringGrid1->Width;
StringGrid2->Height = StringGrid2->DefaultRowHeight * 2 + 20;
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
//удаление строки и столбца
if (StringGrid1->ColCount > 3)
{
if (StringGrid1->DefaultColWidth * (StringGrid1->ColCount - 1) + StringGrid1->ColCount < StringGrid1->Width)
{
int razmer;
if (Form1->Height * 1.3 > Form1->Width)
razmer = Form1->Width;
else
razmer = Form1->Height * 1.3;
StringGrid1->Height = 0.2 * razmer;
StringGrid1->Width = 0.9 * razmer;
for (int i = 0; i < StringGrid1->RowCount - 1; i++)
{
StringGrid1->Cells[StringGrid1->ColCount - 2][i] = StringGrid1->Cells[StringGrid1->ColCount - 1][i];
}
StringGrid1->ColCount--;
StringGrid1->RowCount--;
StringGrid2->ColCount--;
StringGrid1->DefaultRowHeight = (StringGrid1->Height - StringGrid1->RowCount - 1)/StringGrid1->RowCount;
StringGrid1->DefaultColWidth = (StringGrid1->Width - StringGrid1->ColCount - 1)/StringGrid1->ColCount;
StringGrid1->Width = StringGrid1->DefaultColWidth * StringGrid1->ColCount + (StringGrid1->ColCount + 3);
StringGrid1->Height = StringGrid1->DefaultRowHeight * StringGrid1->RowCount + (StringGrid1->ColCount + 3);
StringGrid1->Font->Size = floor(StringGrid1->DefaultColWidth / 14);
StringGrid2->Font->Size = StringGrid1->Font->Size;
StringGrid2->DefaultRowHeight = StringGrid1->DefaultRowHeight;
StringGrid2->DefaultColWidth = StringGrid1->DefaultColWidth;
StringGrid2->Width = StringGrid1->Width - StringGrid1->DefaultColWidth * 2;
StringGrid2->Height = StringGrid2->DefaultRowHeight * 2 + 3;
}
else
{
for (int i = 0; i < StringGrid1->RowCount - 1; i++)
{
StringGrid1->Cells[StringGrid1->ColCount - 2][i] = StringGrid1->Cells[StringGrid1->ColCount - 1][i];
}
StringGrid1->ColCount--;
StringGrid1->RowCount--;
StringGrid2->ColCount--;
if ((StringGrid2->DefaultColWidth + 1) * StringGrid2->ColCount + 3 < StringGrid1->Width)
{
StringGrid2->Width = (StringGrid2->DefaultColWidth + 1) * StringGrid2->ColCount + 5;
}
else
{
StringGrid2->Width = StringGrid1->Width;
StringGrid2->Height = StringGrid2->DefaultRowHeight * 2 + 20;
}
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
double op = 1;
int a = proverka_zapoln();
if (a == 1)
{
return;
}
double **M;
int n = StringGrid1->ColCount - 2;
M = new double* [n];
for (int i = 0; i < n; i++)
{
M[i] = new double [n];
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
M[i][j] = StringGrid1->Cells[j+1][i+1].ToDouble();
}
}
if (n > 1)
op = opredelitel(M, n);
if (op)
{
metod_Gaussa();
pogreshnost();
}
else
Application->MessageBoxA("Это система содержит линейно зависимые уравнения","Ошибка",0);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
int razmer;
if (Form1->Height * 1.3 > Form1->Width)
razmer = Form1->Width;
else
razmer = Form1->Height * 1.3;
if (StringGrid1->Top == 0.14 * razmer)
return;
StringGrid1->Top = 0.24 * razmer;
StringGrid2->Top = 0.47 * razmer;
Button1->Top = 0.06 * razmer;
Button2->Top = 0.06 * razmer;
Button3->Top = 0.14 * razmer;
Button4->Top = 0.06 * razmer;
Label1->Top = 0.16 * razmer;
Edit1->Top = 0.14 * razmer;
StringGrid1->Left = 0.05 * razmer;
StringGrid2->Left = 0.05 * razmer;
Button1->Left = 0.05 * razmer;
Button2->Left = 0.4 * razmer;
Button3->Left = 0.05 * razmer;
Button4->Left = 0.82 * razmer;
Label1->Left = 0.4 * razmer;
Edit1->Left = 0.57 * razmer;
StringGrid1->Width = 0.9 * razmer;
StringGrid1->Height = 0.2 * razmer;
if ((StringGrid1->Height - StringGrid1->RowCount)/StringGrid1->RowCount > 30)
{
StringGrid1->DefaultRowHeight = (StringGrid1->Height - StringGrid1->RowCount)/StringGrid1->RowCount;
StringGrid1->DefaultColWidth = (StringGrid1->Width - StringGrid1->ColCount)/StringGrid1->ColCount;
StringGrid1->Width = StringGrid1->DefaultColWidth * StringGrid1->ColCount + (StringGrid1->ColCount + 3);
StringGrid1->Height = StringGrid1->DefaultRowHeight * StringGrid1->RowCount + (StringGrid1->ColCount + 3);
StringGrid1->Font->Size = floor(StringGrid1->DefaultColWidth * 1 / 14);
StringGrid2->Font->Size = StringGrid1->Font->Size;
StringGrid2->DefaultRowHeight = StringGrid1->DefaultRowHeight;
StringGrid2->DefaultColWidth = StringGrid1->DefaultColWidth;
StringGrid2->Width = StringGrid1->Width - StringGrid1->DefaultColWidth * 2;
StringGrid2->Height = StringGrid2->DefaultRowHeight * 2 + 3;
}
else
{
StringGrid1->DefaultColWidth = 116;
StringGrid2->DefaultColWidth = 116;
StringGrid1->DefaultRowHeight = 30;
StringGrid1->DefaultRowHeight = 30;
StringGrid2->Font->Size = StringGrid1->Font->Size;
StringGrid1->Font->Size = floor(StringGrid1->DefaultColWidth * 1 / 14);
StringGrid2->Font->Size = StringGrid1->Font->Size;
if ((StringGrid2->DefaultColWidth + 1) * StringGrid2->ColCount + 3 <= StringGrid1->Width)
{
StringGrid2->Width = (StringGrid2->DefaultColWidth + 1) * StringGrid2->ColCount + 5;
StringGrid2->Height = StringGrid2->DefaultRowHeight * 2 + 5;
}
else
{
StringGrid2->Width = StringGrid1->Width;
StringGrid2->Height = StringGrid2->DefaultRowHeight * 2 + 20;
}
}
Button1->Height = 0.06 * razmer;
Button1->Width = 0.3 * razmer;
Button1->Font->Size = 0.017 * razmer;
Button2->Height = 0.06 * razmer;
Button2->Font->Size = 0.017 * razmer;
Button2->Width = 0.37 * razmer;
Button3->Height = 0.06 * razmer;
Button3->Font->Size = 0.017 * razmer;
Button3->Width = 0.3 * razmer;
Button4->Height = 0.06 * razmer;
Button4->Font->Size = 0.017 * razmer;
Button4->Width = 0.12 * razmer;
Label1->Font->Size = 0.017 * razmer;
Edit1->Height = 0.04 * razmer;
Edit1->Font->Size = 0.017 * razmer;
Edit1->Width = 0.06 * razmer;
}
//---------------------------------------------------------------------------
int metod_Gaussa (void)
{
int size = Form1->StringGrid1->RowCount - 1;
double **M;
M = new double* [size];
for (int i = 0; i < size; i++)
{
M[i] = new double[size + 1];
}
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size + 1; j++)
{
M[i][j] = Form1->StringGrid1->Cells[j + 1][i + 1].ToDouble();
}
}
for (int i = 0; i < size; i++)
{
for (int p = i; p < size + 1; p++)
{
if (M[i][i] == 0)
{
na_shag_vverh(M, i);
}
else
break;
if (p == size)
return 1;
}
for (int j = 0; j < size; j++)
{
for (int k = size; k > i - 1; k--)
{
M[i][k] /= M[i][i];
}
if (i != j)
{
if (M[j][i] != 0)
{
for (int k = i; k < size + 1; k++)
{
M[i][k] *= M[j][i];
}
for (int k = i; k < size + 1; k++)
{
M[j][k] -= M[i][k];
}
}
for (int k = size; k > i - 1; k--)
{
M[i][k] /= M[i][i];
}
}
}
}
for (int i = 0; i < size; i++)
{
Form1->StringGrid2->Cells[i][1] = M[i][size];
}
return 0;
}
//----------------------------------------------------------------------------
int proverka_zapoln(void)
{
// Проверка заполненности всех ячеек
for (int i = 0; i < Form1->StringGrid1->ColCount - 1; i++)
{
for (int j = 0; j < Form1->StringGrid1->ColCount - 2; j++)
{
if (Form1->StringGrid1->Cells[i + 1][j + 1] == "")
{
Application->MessageBoxA("Не все ячейки заполнены","Ошибка",0);
return 1;
}
try
{
Form1->StringGrid1->Cells[i + 1][j + 1].ToDouble();
}
catch(EConvertError&)
{
Application->MessageBoxA("Не во всех ячейках числовые данные","Ошибка",0);
return 1;
}
catch(...)
{
}
}
}
return 0;
}
//---------------------------------------------------------------------------
double opredelitel(double **Matr1, int size)
{
double znach, znach1, **Matr, element;
int error;
if (size == 2)
{
error = perepoln_pri_umnosh(Matr1[0][0], Matr1[1][1]);
if (error == 1)
return 3 * pow(10, 308);
error = perepoln_pri_umnosh(Matr1[1][0], Matr1[0][1]);
if (error == 1)
return 3 * pow(10, 308);
error = perepoln_pri_slosh(Matr1[0][0]*Matr1[1][1], -Matr1[1][0]*Matr1[0][1]);
if (error == 1)
return 3 * pow(10, 308);
znach = Matr1[0][0]*Matr1[1][1] - Matr1[1][0]*Matr1[0][1];
}
else
{
znach = 0;
Matr = new double* [size - 1];
for (int i = 0; i < size - 1; i++)
{
Matr[i] = new double [size - 1];
}
for (int i = 0; i < size; i++)
{
element = Matr1[i][0];
if (i%2 == 1)
element *= -1;
for (int j = 0, j1 = 0; j < size - 1; j++, j1++)
{
if (j1 == i)
j1++;
if (j1 > size)
break;
for (int k = 0; k < size - 1; k++)
{
Matr[j][k] = Matr1[j1][k + 1];
}
}
znach1 = opredelitel(Matr,size - 1);
if (znach1 == 3 * pow(10, 308))
return 3 * pow(10, 308);
error = perepoln_pri_umnosh(znach1, element);
if (error == 1)
return 3 * pow(10, 308);
znach1 *= element;
error = perepoln_pri_slosh(znach, znach1);
if (error == 1)
return 3 * pow(10, 308);
znach += znach1;
}
}
return znach;
}
//----------------------------------------------------------------------------
void na_shag_vverh (double **M, int row)
{
int size = Form1->StringGrid1->RowCount;
double *str = new double[size];
for (int i = 0; i < size; i++)
{
str[i] = M[row][i];
}
for (int i = row; i < size - 2; i++)
{
for (int j = 0; j < size; j++)
{
M[i][j] = M[i + 1][j];
}
}
for (int i = 0; i < size; i++)
{
M[size - 2][i] = str[i];
}
delete str;
return;
}
//----------------------------------------------------------------------------
int perepoln_pri_umnosh(double x1, double x2)
{
try
{
x1 * x2;
}
catch (EOverflow&)
{
Application->MessageBoxA("Программа не может продолжить выполнение программы, так как аппаратура не настоько мощна","Ошибка",0);
return 1;
}
return 0;
}
//---------------------------------------------------------------------------
int perepoln_pri_slosh(double x1, double x2)
{
try
{
x1 * x2;
}
catch (EOverflow&)
{
Application->MessageBoxA("Программа не может продолжить выполнение программы, так как аппаратура не настоько мощна","Ошибка",0);
return 1;
}
return 0;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
FILE* stream;
stream = fopen("Gauss_help.mht","rt");
if (!stream)
{
Application->MessageBoxA("Не найден файл со справкой","Ошибка",0);
return;
}
ShellExecute(Handle,NULL,"Gauss_help.mht",NULL,NULL,SW_RESTORE);
}
//---------------------------------------------------------------------------
void pogreshnost(void)
{
double max = 0, promegut, b;
for (int i = 1; i < Form1->StringGrid1->RowCount; i++)
{
promegut = 0;
for (int j = 1; j < Form1->StringGrid1->RowCount; j++)
{
promegut += Form1->StringGrid1->Cells[j][i].ToDouble() * Form1->StringGrid2->Cells[j-1][1].ToDouble();
}
if (promegut < 0)
promegut *= -1;
b = Form1->StringGrid1->Cells[Form1->StringGrid1->RowCount][i].ToDouble();
if (b < 0)
b *= -1;
promegut = promegut - b;
if (promegut < 0)
promegut *= -1;
if (promegut > max)
max = promegut;
}
if (max)
Form1->Edit1->Text = floor(log10(max));
else
Form1->Edit1->Text = "-oo";
Form1->Label1->Visible = true;
Form1->Edit1->Visible = true;
}