Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Диплом_Крохина_Н.[2.1].docx
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
4.12 Mб
Скачать

2.3 Разработка алгоритма программы

Для реализации представленной математической модели в среде программирования необходимо составить алгоритм программы. В данном случае целесообразно использовать операторы множественного выбора, так как необходимо реализовать два направления моделирования – расчет и построение.

Приложение состоит из 4 блоков. Алгоритм главной формы представлен на листе 1 графической части.

Блок «Файл» даёт возможность создать новый файл, сохранить графическое представление построенной модели для дальнейшего использования посредствам команды «Открыть».

Для выполнения расчётов необходимо выполнить построение графа. Блок «Построение» предполагает визуальное представление графа с соответствующим заполнением переменных по ходу построения. Алгоритм подпрограммы «Построение» представлен в соответствии с листом 2 графической части.

Для построения модели графа необходимо сначала выбрать объект – узел, ребро. При построении узлов определяются названия городов, которые будут включены в имитационную модель сети передачи данных. А при проектировании рёбер определяются интенсивности пропускной способности для каждого населённого пункта.

После выбора объекта выбирается режим построения – добавить, выделить, удалить.

Блок «Расчёт» определяет параметры графа в соответствии с формулами (1) – (6), кратчайший путь в графическом и текстовом виде, реализованный по алгоритму Дейкстры, а также отчёт расчётов.

Отчёт результатов обобщает данные полученные на предыдущих шагах алгоритма и определяет параметры модели в виде таблиц, в которых зависимости от выбранного параметра может быть отражена информация о следующих результатах расчётов:

- трафик городов;

- пропускная способность;

- время задержки пакетов в каналах между городами;

- интенсивность потока в каждом из узлов.

В алгоритме предусмотрено обращение в случае необходимости к справочной информации и руководству пользователя.

Также алгоритм спроектирован таким образом, что на любом этапе выполнения есть возможность прервать работу и выйти из проекта.

2.4 Реализация алгоритма программы на языке программирования

Алгоритм данной задачи реализован в среде объектно-ориентированного программирования Delphi.

Основные команды приложения лучше всего сделать доступными через пункты меню главного окна программы. Назначение пунктов меню можно пояснить в строке состояния главного окна. Нажатие на правую кнопку мыши сбрасывает выделение графа, кроме режима задания параметров узлов (в этом случае такая команда вызовет контекстное окно свойств для выбранной вершины).

Также необходимо обеспечить выполнение следующих команд.

Команды «Построение»приводит приложение в режим добавления узлов рёбер сети.

//Построение графа

ProcedureGrafficDraw;

var i, j, cur_reb_stac1, cur_reb_stac2 : integer;

X1, Y1: integer;

begin

Form1.Refresh;

form1.Canvas.Pen.Width:=3;

for i:= 1 to last_ver do

begin

if i = cur_ver then Form1.Canvas.Pen.Color := clRed

else Form1.Canvas.Pen.Color := clBlack;

Form1.Canvas.Ellipse(usel[i].X-rad_ver,usel[i].Y+rad_ver,usel[i].X+rad_ver,usel[i].Y-rad_ver);

Form1.Canvas.TextOut(usel[i].X,usel[i].Y-rad_ver,IntToStr(usel[i].Num));

Form1.Canvas.TextOut(usel[i].X+20,usel[i].Y-

rad_ver,usel[i].Name);

end;

for i:= 1 to last_ver do

for j:= 1 to last_ver do

begin X1:= (usel[j].X - rad_ver);

Y1:= (usel[j].Y - rad_ver);

ifkanal[i, j] > 0 then

begin

if (i=cur_reb_p1) and (j=cur_reb_p2) then

Form1.Canvas.Pen.Color := clRed

else if (propusk[i,j].Intens>propusk[i,j].Traf) then

Form1.Canvas.Pen.Color := clGreen

else

Form1.Canvas.Pen.Color := clBlue;

Form1.Canvas.MoveTo(usel[i].X,usel[i].Y);

Form1.Canvas.LineTo(usel[j].X,usel[j].Y);

Form1.Canvas.MoveTo(X1,Y1);

Form1.Canvas.LineTo(usel[j].X,usel[j].Y);

end;

end;

for i:= 1 to Count_p-1 do

begin Form1.Canvas.Pen.Color := clRed;

Form1.Canvas.MoveTo(usel[krat_put[i]].X,usel[krat_put[i]].Y);

Form1.Canvas.LineTo(usel[krat_put[i+1]].X,usel[krat_put[i+1]].Y);

end;

end;

Команда «Расчеты – Подсчет параметров»рассчитывает матрицу вероятностей переходов графа, проверяет каждую дугу на стационарность (в случае нестационарности, соответствующая дуга может быть выделена цветом и выдавать предупреждение о неверности заданного параметра), а также рассчитывает веса существующих ребер. Результат на экране можно не отображать.

withRadioGroup1, StringGrid1 do

caseItemIndexof 0:

begin //Трафикгородов

GroupBox1.Caption:='Трафикгородов';

Visible := true;

ColWidths[0] := 80;

RowHeights[0] := 40;

Cells[0,0] :='№ города';

Cells[0,1] :='Числопакетов';

for i := 1 to last_ver do

beginRowHeights[i] := 40;

ColWidths[i] := 60;

Width :=ColWidths[i]*last_ver+ColWidths[0]+30;

Height:=RowHeights[i] * 2;

Cells[i,0]:=IntToStr(usel[i].Num);

Cells[i,1]:=IntToStr(usel[i].Traf);

end;

end;

1: begin //Пропускнаяспособность

GroupBox1.Caption:='Пропускнаяспособность';

Visible := true;

for i := 1 to last_ver do

for j := 1 to last_ver do

begin Width:=ColWidths[i]*last_ver+ColWidths[0]+30;

Height:=RowHeights[j]*last_ver+RowHeights[0]+30;

Cells[i,0]:=IntToStr(usel[i].Num);

Cells[0,j]:=IntToStr(usel[j].Num);

Cells[i,j]:=IntToStr(propusk[i,j].Traf);

end;

end;

2: begin //Время задержки пакетов в каналах между городами

GroupBox1.Caption:='Время задержки пакетов в каналах между городами';

Visible := true;

for i := 1 to last_ver do

for j := 1 to last_ver do

beginColWidths[i] := 80;

RowHeights[i] := 40;

Width:=ColWidths[i]*last_ver+ColWidths[0]+30;

Height:=RowHeights[j]*last_ver+RowHeights[0]+30;

Cells[i,0]:=IntToStr(usel[i].Num);

Cells[0,j]:=IntToStr(usel[j].Num);

Cells[i,j]:=FloatToStr(propusk[i,j].Time);

end;

end;

3: begin //Интенсивность потока в каждом из узлов

GroupBox1.Caption:='Интенсивность потока в каждом из узлов';

Visible := true;

for i := 1 to last_ver do

for j := 1 to last_ver do

begin Width:=ColWidths[i]*last_ver+ColWidths[0]+30;

Height:=RowHeights[j]*last_ver+RowHeights[0]+30;

Cells[i,0]:=IntToStr(usel[i].Num);

Cells[0,j]:=IntToStr(usel[j].Num);

Cells[i,j]:=FloatToStr(propusk[i,j].Intens);

end;

end;

end;

Команда «Расчеты – Кратчайший путь». По данной команде программа вычисляет оптимальный путь между 0-й и последней вершиной при всех рассчитанных параметрах графа. Оптимальный путь целесообразно выделить на графе цветом.

//Кратчайший путь - алгоритм Дейкстры

procedure TForm1.N23Click(Sender: TObject);

vari,j,m,v : integer;

begin

cur_mode := 'puth';

Memo1.Clear;

if (ver_first< 1) or (ver_first> 21) then ver_first := 1;

//Расчет

fillchar(versina,sizeof(versina),0);

fillchar(Ras_Path,sizeof(Ras_Path), 10000); //бесконечность

Ras_Path[ver_first] := 0;//расстояние до начальной вершины

for i:=1 to 21 do

begin m:=100000;

for j:=1 to 21 do

if ( (Ras_Path[j] <= m) and (not versina[j]) ) then

begin m:=ras_Path[j];

v:=j;

end;

versina[v] := true;

for j:=1 to 21 do

if ((propusk[v,j].Traf<>0) and (not versina[j]) and

(ras_Path[v]+propusk[v,j].Traf<ras_Path[j])) then

Begin ras_Path[j]:=ras_Path[v]+propusk[v,j].Traf;

if ((ras_path[v]+propusk[v,j].Traf<ras_Path[j])

and (ras_Path[j]<>0)) then p[j]:=p[j]+p[v]+'/'+inttostr(j)

else p[j]:=p[v]+'/'+inttostr(j)+'';

end;

end;

//Вывод результата

for i := 1 to 21 do

begin

if i=ver_last then p[i]:=inttostr(ver_first)+p[i]+'!';

krat_put[i]:=0;

end;

//---отображение на экране

S:=''; Count_p:=0; for i:=1 to length(p[ver_last]) do

begin S:=S+copy(p[ver_last],i,1);

if (copy(p[ver_last],i,1)='/') or (copy(p[ver_last],i,1)='!') then

begin

Count_p:=Count_p+1;

krat_put[Count_p]:=strtoint(copy(S,1,length(S)-1));

S:='';

end;

end;

// Вывод перечень вершин пути

for i:=1 to Count_p-1 do

Memo1.Text := Memo1.Text + IntToStr(krat_put[i]) + '-';

Memo1.Text := Memo1.Text + IntToStr(krat_put[Count_p]);

ifCount_p<2 thenshowmessage('Между вершинами нет связи!');

// Выводпути

for i := 1 to Count_p do

Path := Path + ras_Path[krat_put[i]];

for i:= 1 to Count_p-1 do

begin Form1.Canvas.Pen.Color := clRed;

Form1.Canvas.MoveTo(usel[krat_put[i]].X,usel[krat_put[i]].Y);

Form1.Canvas.LineTo(usel[krat_put[i+1]].X,usel[krat_put[i+1]].Y);

end;

end;

Команда «Расчеты – Отчет». Выводит на экран модальное окно, содержащее в себе отчет по рассчитанным параметрам модели в текстовом виде (время задержки в каждой дуге, интенсивность прихода заявок в каждый узел, а также метки вершин).

//Подсчёт параметров

procedure TForm1.N20Click(Sender: TObject);

var i,j, cur_reb_stac1, cur_reb_stac2 : integer;

begin

for i:=1 to 21 do

for j:=1 to 21 do

usel[i].TrafOut := usel[i].TrafOut + propusk[i,j].Traf;

//расчётвероятностей

for i:=1 to 21 do

for j:=1 to 21 do

ifpropusk[i,j].Traf>0 then

propusk[i,j].Veroyatnost:=(propusk[i,j].Traf/usel[i].TrafOut);

//интенсивность канала и число пакетов поступающих в город

for i:=1 to 21 do

for j:=1 to 21 do

begin

propusk[i,j].Intens:=usel[i].Traf*propusk[i,j].Veroyatnost;

usel[j].Intens:=usel[j].Intens+propusk[i,j].Intens;

end;

//проверкастационарности сети

for i:=1 to last_ver do

For j:=1 to last_ver do

ifpropusk[i,j].Intens>propusk[i,j].Traf then

beginshowmessage('Необходимо увеличить пропускную способность канала между городами : '+usel[i].Name + ' и ' + usel[j].Name);

Form1.Canvas.Pen.Color := clGreen;

Form1.Canvas.MoveTo(usel[i].X,usel[i].Y);

Form1.Canvas.LineTo(usel[j].X,usel[j].Y);

end;

//расчет задержек в ребрах

for i:=1 to 21 do

for j:=1 to 21 do

if (propusk[i,j].Traf<> 0) then begin

ifpropusk[i,j].Traf - propusk[i,j].Intens = 0

thenpropusk[i,j].Traf := propusk[i,j].Traf + 1;

propusk[i,j].Time:=(1/(usel[j].Intens+usel[i].Traf))*

propusk[i,j].Intens/(propusk[i,j].Traf-propusk[i,j].Intens);

end;end;

Команда «Файл – Новый» осуществляет создание нового пустого документа модели сети передачи данных.

//Создание нового файла

procedure TForm1.N6Click(Sender: TObject);

var i, j: integer;

begin

for i:= 1 to 21 do

begin

usel[i].Num := 0;

usel[i].Name := '';

usel[i].X := 0;

usel[i].Y := 0;

usel[i].Traf := 0;

usel[i].Index:=0;

usel[i].Intens:=0;

usel[i].TrafOut:=0;

for j:= 1 to 21 do

kanal[i, j] := 0;

end;

last_ver := 0;

cur_ver := 0;

end;

Команда «Файл – Открыть» выводит форму для выбора файла, который необходимо открыть. Содержимое файла будет отражено в главном окне приложения в виде графа.

//Открытие файла

procedure TForm1.N7Click(Sender: TObject);

var F: TextFile;

i, j, count_ver: integer;

s: string;

begin

N6Click(Self);

Form1.OpenDialog1.FileName := filename;

Form1.OpenDialog1.InitialDir :=

extractfilepath(Application.ExeName);

Form1.OpenDialog1.Execute;

filename := Form1.OpenDialog1.FileName;

AssignFile(F, Form1.OpenDialog1.FileName);

{$I-}

Reset(F);

{$I+}

ifIOResult = 0 then begin ReadLn(F, s);

count_ver := StrToInt(s);

for i:=1 to count_ver do

beginReadLn(F, s); usel[i].Num := StrToInt(s);

ReadLn(F, usel[i].Name);

ReadLn(F, s); usel[i].X := StrToInt(s);

ReadLn(F, s); usel[i].Y := StrToInt(s);

ReadLn(F, s); usel[i].Traf := StrToInt(s);

end;

for i:= 1 to count_ver do

for j:= 1 to count_ver do

ReadLn(F, s); kanal[i, j] := StrToInt(s);

for i:= 1 to count_ver do

for j:= 1 to count_ver do

readLn(F, s); propusk[i, j].Traf := StrToInt(s);

CloseFile(F);

last_ver := count_ver;

end;

elseMessageDlg('File access error', mtWarning, [mbOk], 0);

end;

Команда «Файл – Сохранить» и «Файл – Сохранить как…»сохраняет файл с заданным в диалоге именем.

//Сохранение файла

procedure TForm1.N8Click(Sender: TObject);

var F: TextFile;

s: string;

begin Form1.saveDialog1.FileName := filename;

Form1.saveDialog1.InitialDir :=

extractfilepath(Application.ExeName);

Form1.saveDialog1.Execute;

filename := Form1.saveDialog1.FileName;

AssignFile(F, Form1.saveDialog1.FileName);

{$I-}

Rewrite(F);

{$I+}

writeln(f,memo1.text)

end;

Команда «Выход» производит закрытие всего приложения по средствам метода Application.terminate.

2.5 Описание процесса отладки программы и оценка результатов решения задач

Интегрированная среда разработки Delphi предоставляет программисту мощное средство поиска и устранение ошибок в программе – отладчик. Отладчик позволяет выполнять трассировку программы, наблюдать значения переменных, контролировать выводимые программой данные.

Отладкой программы называется процесс выявления и исправления ошибок.

Успешное завершение процесса компиляции не означает, что в программе нет ошибок. Убедиться, что программа работает правильно можно только в процессе ее работоспособности, которая называется тестированием.

Тестирование – это процесс исследования программного продукта с целью получения информации о качестве продукта.

Ошибки компьютерных программ делятся на синтаксические, логические и времени выполнения.

Ошибки времени выполнения, в Delphi они называются исключениями. Это ошибки, которые обычно возникают при первых запусках программы и во время тестирования.

Синтаксические ошибки, их так же называют ошибками времени компиляции, наиболее легко устранимы. это ошибки в написании структуры программного кода, а именно, в написании имен и ключевых слов, правила грамматики и.т.д..

Логические ошибки – это ошибки связаны с семантикой или значением исходного программного кода.

Легче всего устранить синтаксические ошибки, так как компилятор Delphi обнаруживает их и указывает на их местонахождение, а вот логическую ошибку обнаружить довольно трудно. К тому же для ее устранения часто приходится переписывать большой фрагмент кода.

Труднее всего обнаружить и устранить ошибки времени выполнения. Для предотвращения подобных ошибок необходимо тщательно протестировать программу, подавая на ее вход различные комбинации исходных данных, как правильные, так и ошибочные.

Существует несколько приемов отладки программы. Одним из которых является дамп данных (выгрузка, вывод данных на экран) и выполнение кода вручную. Они применяются на любых платформах и для всех языков программирования.

Наиболее простой прием отладки – дамп данных. Если программа не работает так, как ожидается, тогда можно добавить строки кода, выводящие промежуточные значения выбранных переменных на экран или в выходной файл. Такой вывод значения переменных называется дампом данных.

Другой стандартный прием – выполнение кода вручную. Выполнение вручную, или отслеживание кода, во многих случая оказывается незаменимы. Данный прием имеет весомые преимущества по сравнению с приемом дамп данных:

– во-первых, такой способ не требует применения компьютера – программу можно отлаживать где угодно; для этого достаточно иметь распечатку кода, карандаш и бумагу;

– во-вторых, отслеживая код вручную, логическую ошибку обнаружить можно намного быстрее, чем с помощью дампа данных.

Средства Delphi содержит встроенный отладчик, который значительно облегчает отслеживание программного кода и обнаружение ошибок. Чтобы отладчик можно было использовать, необходимо включить режим интегрированной отладки в меню Tools – DebuggerOptions, установить флажок опции Integratingdebugging, расположенный в нижней части вкладки LanguageExceptions диалогового окна DebuggerOptions, после чего щелкнуть на кнопку ОК. Отладчик предоставляет в распоряжение пользователя различные полуавтоматические способы обнаружения ошибок.

При разработке программного продукта встречались синтаксические ошибки, которые были предотвращены вручную.