Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛАБ_ВМ_2010.doc
Скачиваний:
1
Добавлен:
01.03.2025
Размер:
3 Мб
Скачать
☆

Лабораторные работы 4, 5

ИССЛЕДОВАНИЕ МЕТОДОВ РЕШЕНИЙ СИСТЕМ ЛИНЕЙНЫХ АЛГЕБРАИЧЕСКИХ УРАВНЕНИЙ (СЛАУ)

Задание. 1. Выполнить тестирование по схеме с единственным делением заданной по варианту СЛАУ 3-го порядка.

2. Для СЛАУ с произвольно задаваемыми параметрами выполнить тестирование по схеме с выбором по столбцу ведущего коэффициента.

3. Получить зависимости временных затрат и усредненной точности решения системы от порядка (размера) системы. Исследовать влияние типа представления коэффициентов (float, double, long double) на точность решения системы.

  1. Для проектирования приложения логично использовать три формы согласно пунктам задания.

  2. Создайте новый проект командой Файл/Новый/Приложение.

  3. Сохраните файлы модуля и проекта командой Файл/Сохранить все под именами LR4_1 и PR_LR4. Командой Файл/Новый/Форма добавьте к проекту две формы, сохранив их модули под именами LR4_2 и LR4_3. Теперь перейдем к проектированию приложения. В результате проектирования получим формы, представленные на рис.4.1, 4.2, 4.3. В свойство Caption форм впишите соответствующие заголовки.

  4. Начните проектирование с первой формы (рис.4.1). (Для перехода с одной формы на другую используйте быструю кнопку Вид формы, для перехода с модуля на модуль - Вид модуля, а с формы на модуль – Переключатель Форма/Модуль.) Перенесите на форму 3 кнопки (страница Стандарт) с надписями соответственно: Button1 –ТЕСТИРУЕМАЯ СЛАУ 3-ГО ПОРЯДКА, Button2- РЕШЕНИЕ, Button3 –ТЕСТИРОВАНИЕ СЛАУ n – ПОРЯДКА. Для размещения системы перенесите на форму компонент StringGrid1 (страница Дополнительно). Установите следующие значения свойств компонента StringGrid1: ColCount – 8, DefaultColWidth -40, FixedCols – 0, FixedRows – 0, Font – черный, обычный, размер 8, RowCount – 3. Для вывода на экран результатов тестирования перенесите на форму компонент StringGrid2 и три метки: LabeledEdit1, LabeledEdit2 и LabeledEdit3 (страница Дополнительно). Установите следующие значения свойств компонента StringGrid2: ColCount – 2, DefaultColWidth -48, FixedCols – 1, FixedRows – 0, Font – черный, обычный, размер 8, RowCount – 3. Для всех трех меток свойству LabelPosition присвойте значение lpLeft (из выпадающего списка), а свойству Font – обычный, размер 8. Раскрывая свойство EditLabel, для всех трех меток установите подсвойство Font – черный, жирный, размер 8, а в подсвойстве Caption впишите соответственно невязка, кол-во умн+дел, кол-во сл+выч.

рис.4.1

  1. Для выполнения п.1 задания файл LR4_1.cpp может быть таким:

#include <vcl.h>

#pragma hdrstop

#include "LR4_1.h"

#include "LR4_2.h"

#include <math.h>

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma link "CSPIN"

#pragma resource "*.dfm"

TForm1 *Form1;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

}

//---------------------------------------------------------------------------

const int n=3;

const float a[][4]={{3.05,2.64,2.23,67.17},{4.14,3.61,3.14,91.43},

{5.63,5.03,4.52,125.40}};

float x[3];

void __fastcall TForm1::Button1Click(TObject *Sender)

{AnsiString s;

for(int j=0;j<3;j++){

if(j<2)s=" + ";

else s="";

for(int i=0;i<3;i++){

StringGrid1->Cells[2*j][i]=FloatToStrF(a[i][j],ffFixed,5,2)

+" * ";

StringGrid1->Cells[2*j+1][i]=" x["+IntToStr(j)+"]"+s;}

for(int i=0;i<3;i++){

StringGrid1->Cells[6][i]=" = ";

StringGrid1->Cells[7][i]=FloatToStrF(a[i][3],ffFixed,5,2);}}

}

//---------------------------------------------------------------------------

void __fastcall gauss(float& nev,int& mul,int& ad)

{ int i,j,k,l;

float a1[3][4],c,b,s;

//копирование исходной матрицы во вспомогательную матрицу

for(i=0;i<n;i++)

for(j=0;j<n+1;j++) a1[i][j]=a[i][j];

//решение СЛАУ

mul=ad=0;

for(i=0;i<n-1;i++){

c=a1[i][i];

for(j=i;j<n+1;j++) {a1[i][j]/=c; mul++;}

for(k=i+1;k<n;k++){

b=a1[k][i];

for(l=i;l<n+1;l++)

{a1[k][l]-=b*a1[i][l]; ad++; mul++;}}}

x[n-1]=a1[n-1][n]/a1[n-1][n-1]; mul++;

for(k=n-2;k>=0;k--){

s=0;

for(j=k+1;j<n;j++)

{s+=a1[k][j]*x[j]; ad++; mul++;}

x[k]=a1[k][n]-s; ad++;}

//вычисление невязки

c=0;

for(int i=0;i<n;i++){

b=0;

for(int j=0;j<n;j++) b+=a[i][j]*x[j];

c+=pow(b-a[i][n],2);}

nev=sqrt(c)/n;

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)

{int mul,ad;

float nev;

gauss(nev,mul,ad);

for(int i=0;i<3;i++){

StringGrid2->Cells[0][i]=" x["+IntToStr(i)+"] = ";

StringGrid2->Cells[1][i]=FloatToStrF(x[i],ffFixed,7,5);}

LabeledEdit1->Text=FloatToStrF(nev,ffExponent,4,2);

LabeledEdit2->Text=IntToStr(mul);

LabeledEdit3->Text=IntToStr(ad);

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button3Click(TObject *Sender)

{

Form2->Show();

Form2->StringGrid1->Cells[0][0]=" n";

Form2->StringGrid1->Cells[1][0]=" k";

Form2->StringGrid1->Cells[2][0]=" mul";

Form2->StringGrid1->Cells[3][0]=" ad";

Form2->StringGrid1->Cells[4][0]=" nev_f";

Form2->StringGrid1->Cells[5][0]=" nev_d";

Form2->StringGrid1->Cells[6][0]=" nev_ld";

}

//---------------------------------------------------------------------------

  1. Перенесите на 2-ю форму (рис.4.2) 11 меток Label (страница Стандарт), в свойство Caption (надпись) которых в порядке их номеров впишите значения порядок СЛАУ, мин, макс, шаг, кол-во СЛАУ, диапазон коэфф-тов, макс, мин, диапазон правых частей, макс, мин; 3 кнопки Button (страница Стандарт), с надписями решение, график, сброс. Во всех компонентах на форме шрифт имеет размер 8. Для задания параметров СЛАУ перенесите на форму 8 компонентов ввода целых чисел – CSpinEdit (страница Примеры). Свойства MaxValue, MinValue, Value установите соответственно: CSpinEdit1 (порядок СЛАУ, мин) – 100,1,3; CSpinEdit2 (порядок СЛАУ, макс) – 1000,2,10; CSpinEdit3 (порядок СЛАУ, шаг) – 100,1,1; CSpinEdit4 (кол-во СЛАУ) – 100,1,1; CSpinEdit5 (диапазон коэфф-тов, макс) – 10,0,5; CSpinEdit6 (диапазон коэфф-тов, мин) – 0,-10,-5; CSpinEdit7 (диапазон правых частей, макс) – 100,1,20; CSpinEdit8 (диапазон правых частей, мин) – 0,-100,-20. Для вывода результатов решения СЛАУ в таблицу перенесите на форму компонент StringGrid1 (страница Дополнительно). Установите следующие значения свойств компонента StringGrid1: ColCount – 7, DefaultColWidth -48, FixedCols – 0, FixedRows – 1, Font – черный, обычный, размер 8, RowCount – 100. Для отображения процесса решения СЛАУ перенесите в нижнюю часть формы компонент ProgressBar1 (страница Win32).

рис.4.2

  1. Для выполнения п.1 задания файл LR4_2.cpp может быть таким:

#include <vcl.h>

#pragma hdrstop

#include "LR4_2.h"

#include "LR4_3.h"

#include "LR4_1.h"

#include <math.h>

#include <time.h>

#include <stdlib.h>

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma link "CSPIN"

#pragma resource "*.dfm"

TForm2 *Form2;

//---------------------------------------------------------------------------

__fastcall TForm2::TForm2(TComponent* Owner)

: TForm(Owner)

{

}

//---------------------------------------------------------------------------

template<class T>

void __fastcall gauss_1(float**b,int n,T& nev,int& mul,int& ad)

{ T c,z,d,s;

int max;

T* x=new T[n];

T** a=new T*[n];

for(int i=0;i<n;i++) a[i]=new T[n+1];

for(int i=0;i<n;i++)

for(int j=0;j<n+1;j++)

a[i][j]=b[i][j];

mul=ad=0;

for(int i=0;i<n-1;i++){

max=i;

for(int k=i+1;k<n;k++)

if(fabs(a[k][i])>fabs(a[max][i])) max=k;

for(int j=i;j<n+1;j++)

{z=a[i][j]; a[i][j]=a[max][j]; a[max][j]=z;}

c=a[i][i];

for(int j=i;j<n+1;j++) {a[i][j]/=c; mul++;}

for(int k=i+1;k<n;k++){

d=a[k][i];

for(int l=i;l<n+1;l++)

{a[k][l]-=d*a[i][l]; mul++; ad++;}}}

x[n-1]=a[n-1][n]/a[n-1][n-1]; mul++;

for(int k=n-2;k>=0;k--){

s=0;

for(int j=k+1;j<n;j++) {s+=a[k][j]*x[j]; mul++; ad++;}

x[k]=a[k][n]-s; ad++;}

//вычисление невязки

c=0;

for(int i=0;i<n;i++){

d=0;

for(int j=0;j<n;j++) d+=b[i][j]*x[j];

c+=pow(d-b[i][n],2);}

nev=sqrt(c)/n;

for(int i=0;i<n;i++) delete[]a[i];

delete[]a; a=0;

delete[]x; x=0;

}

//---------------------------------------------------------------------------

int pk=1;

//---------------------------------------------------------------------------

void __fastcall TForm2::Button1Click(TObject *Sender)

{

Form3->Series1->Clear();

Form3->Series2->Clear();

Form3->Series3->Clear();

Form3->Series4->Clear();

Form3->Series5->Clear();

int count=0, current=0;

for(int n=CSpinEdit1->Value; n<=CSpinEdit2->Value;

n+=CSpinEdit3->Value)

count+=n; count*=CSpinEdit4->Value;

float**b,w,z;

int mul,smul,ad,sad;

float nev_f,snev_f;

double nev_d,snev_d;

long double nev_ld,snev_ld;

int k=CSpinEdit4->Value;

for(int n=CSpinEdit1->Value;

n<=CSpinEdit2->Value;n+=CSpinEdit3->Value){

b=new float*[n];

for(int i=0;i<n;i++)

b[i]=new float[n+1];

smul=0; sad=0; snev_f=0; snev_d=0; snev_ld=0;

for(int kc=0;kc<k;kc++){

srand(time(NULL));

for(int i=0;i<n;i++){

w=rand()%(CSpinEdit7->Value-CSpinEdit8->Value+1)+CSpinEdit8->Value

+(float)random(CSpinEdit7->Value-CSpinEdit8->Value+1)

/(CSpinEdit7->Value-CSpinEdit8->Value)-0.5;

if(w>CSpinEdit7->Value)w=CSpinEdit7->Value;

if(w<CSpinEdit8->Value)w=CSpinEdit8->Value;

b[i][n]=w;

for(int j=0;j<n;j++){

z=rand()%(CSpinEdit5->Value-CSpinEdit6->Value+1)+CSpinEdit6->Value

+(float)random(CSpinEdit5->Value-CSpinEdit6->Value+1)

/(CSpinEdit5->Value-CSpinEdit6->Value)-0.5;

if(z>CSpinEdit5->Value)z=CSpinEdit5->Value;

if(z<CSpinEdit6->Value)z=CSpinEdit6->Value;

b[i][j]=z; }}

gauss_1(b,n,nev_f,mul,ad);

snev_f+=nev_f; smul+=mul; sad+=ad;

gauss_1(b,n,nev_d,mul,ad);

snev_d+=nev_d;

gauss_1(b,n,nev_ld,mul,ad);

snev_ld+=nev_ld;

current+=n;

ProgressBar1->Position=100*current/count; }

StringGrid1->Cells[0][pk]=IntToStr(n);

StringGrid1->Cells[1][pk]=IntToStr(k);

StringGrid1->Cells[2][pk]=IntToStr(smul);

StringGrid1->Cells[3][pk]=IntToStr(sad);

StringGrid1->Cells[4][pk]=FloatToStrF(snev_f/k,ffExponent,5,4);

StringGrid1->Cells[5][pk]=FloatToStrF(snev_d/k,ffExponent,5,4);

StringGrid1->Cells[6][pk]=FloatToStrF(snev_ld/k,ffExponent,5,4);

Form3->Series1->AddXY(n,smul,"",clBlack);

Form3->Series2->AddXY(n,sad,"",clBlack);

Form3->Series3->AddXY(n,snev_f/k*1.0e6,"",clBlack);

Form3->Series4->AddXY(n,snev_d/k*1.0e15,"",clBlack);

Form3->Series5->AddXY(n,snev_ld/k*1.0e18,"",clBlack);

pk++;

for(int i=0;i<n;i++)delete[] b[i];

delete[]b; b=0; }

}

//---------------------------------------------------------------------------

void __fastcall TForm2::Button2Click(TObject *Sender)

{

for(int i=1;i<StringGrid1->RowCount;i++)

for(int j=0;j<StringGrid1->ColCount;j++)

StringGrid1->Cells[j][i]="";

ProgressBar1->Position=0;

Form3->Series1->Clear();

Form3->Series2->Clear();

Form3->Series3->Clear();

Form3->Series4->Clear();

Form3->Series5->Clear();

pk=1;

}

//---------------------------------------------------------------------------

void __fastcall TForm2::Button3Click(TObject *Sender)

{

Form3->Show();

}

//---------------------------------------------------

  1. Для графического представления результатов исследования решения СЛАУ методом Гаусса с выбором ведущего коэффициента по столбцу на форму 3 перенесите (рис.4.3) компоненты Chart1 и Chart2 (страница Additional). Зададим свойства компонента Chart1. Щелкните правой кнопкой мыши на компоненте Chart1 и в появившемся меню выберите Edit Chart…. На экране появится окно Редактора Диаграмм (Editing Chart1) с открытой страницей Chart, которая имеет несколько закладок. В данный момент открыта закладка Series. Щелкните на кнопке Add… - добавить серию. В появившемся окне выберите тип графика – Line и выключите индикатор 3D. Кнопкой Title… вызовите Change Series Title, где дайте заголовок первому графику – кол-во умн+дел. Действуя подобным образом, добавьте Series 2 и дайте заголовок второму графику – кол-во сл+выч. На вкладке Legend в группе кнопок Position нажмите кнопку Top. Цвет фона Back Color.. установите белый. На закладке Panel, нажав кнопку Panel Color…, выберите белый цвет. Перейдите на закладку Titles. В окне редактирования, которое в данный момент соответствует Title – заголовку графика, сотрите TChart и напишите (шрифт Font… - черный, жирный, размер 8) ЗАВИСИМОСТЬ ВРЕМ ЗАТРАТ ОТ ПОРЯДКА СЛАУ. Цвет фона Back Color.. установите белый. В выпадающем списке от окна редактирования Title перейдите в окно редактирования Foot и напишите тем же шрифтом n – ПОРЯДОК СЛАУ. В группе кнопок Alignment нажмите кнопку Right. Цвет фона Back Color.. также установите белый. Перейдите со страницы Chart на страницу Series. Здесь на закладке Format задайте параметры линий графиков. Требуемый график (кол-во умн+дел, кол-во сл+выч) выбирается из выпадающего списка. Для графика кол-во сл+выч в группе Line нажмите кнопку Border… и в группе кнопок Style включите кнопку Dot, а остальные значения параметров графиков оставьте заданными по умолчанию. Нажмите кнопку Close и выйдите из режима редактирования компонента Chart1.

рис.4.3

  1. Изложенную последовательность действий используйте и для компонента Chart2. Отличия: 3 графика – невязка (float)*1.0e6 (толщина линии Width – 2), невязка (double)*1.0e15 (толщина линии Width – 1, стиль Style – solid), невязка (long double)*1.0e18 (толщина линии Width – 1, стиль Style – Dot). Кроме того, на этой форме следует разместить 2 кнопки Button (страница Стандарт), с надписями таблица, конец. Кнопка таблица нужна для возврата на вторую форму, а кнопка конец – для перехода от выполнения приложения к его редактированию.

  2. Файл LR4_3.cpp имеет вид:

#include <vcl.h>

#pragma hdrstop

#include "LR4_3.h"

#include "LR4_2.h"

#include "LR4_1.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm3 *Form3;

//---------------------------------------------------------------------------

__fastcall TForm3::TForm3(TComponent* Owner)

: TForm(Owner)

{

}

//---------------------------------------------------------------------------

void __fastcall TForm3::Button1Click(TObject *Sender)

{

Form2->Show();

}

//--------------------------------------------------------------------------

void __fastcall TForm3::Button2Click(TObject *Sender)

{

Close();

Form2->Close();

Form1->Close();

}

//---------------------------------------------------------------------------

рис.4.4

рис.4.5

рис.4.6

  1. Для построения графиков зависимостей невязок, которые для разных типов коэффициентов СЛАУ отличаются друг от друга на несколько порядков, необходимо все невязки сблизить при помощи множителей. Величины множителей устанавливаются при решении СЛАУ. Запустим приложение на выполнение, нажав быстрые кнопки Сохранить все и Запуск. После щелчков на кнопках первой формы - ТЕСТИРУЕМАЯ СЛАУ 3-ГО ПОРЯДКА, РЕШЕНИЕ, ТЕСТИРОВАНИЕ СЛАУ n – ПОРЯДКА, и щелчка на кнопке РЕШЕНИЕ второй формы получим результаты выполнения задания (рис.4.4, рис.4.5).

рис.4.7

рис.4.8

  1. Полученные результаты позволяют внести множители в соответствующие операторы:

Form3->Series3->AddXY(n,snev_f/k*1.0e6,"",clBlack);

Form3->Series4->AddXY(n,snev_d/k*1.0e15,"",clBlack);

Form3->Series5->AddXY(n,snev_ld/k*1.0e18,"",clBlack);

После этого графики зависимостей могут иметь вид (рис.4.6).

  1. Последовательно нажимая кнопки решение, графики, таблица, сброс, решение, ….., убедитесь, что зависимости невязок от порядка системы случайны. Чтобы установить вид функциональных зависимостей, необходимо увеличить количество обрабатываемых СЛАУ заданного порядка для получения средних значений. Представление о характере зависимостей и вычислительных затратах при этом дают графики на рис.4.7 и на рис.4.8, полученные при 10 и 100 СЛАУ задаваемого порядка от 10 до 100 с шагом 10. Очевидно, что временные затраты для установления вида функциональных зависимостей значительны.

  2. Щелчком на кнопке конец перейдите из режима выполнения в режим проектирования приложения.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]