- •Введение
- •Общая часть
- •Общие сведения об организации
- •Цель разработки программного продукта
- •Анализ предметной области программного продукта
- •Анализ методов разработки программного продукта
- •1.5 Анализ средств программирования программного продукта
- •2.2 Описание математической модели реализации задачи
- •2.3 Разработка алгоритма программы
- •2.4 Реализация алгоритма программы на языке программирования
- •2.6 Руководство пользователя
- •3.2 Организация оплаты труда работников увц фгоу спо «кит»
- •3.3 Организация ремонтов свт
- •4.2 Расчет суммы амортизационных отчислений
- •4.3 Расчет стоимости программного продукта
- •5.2 Техника безопасности на участке увц фгоу спо «кит»
- •5.3 Эргономикарабочего места оператора эвм
- •Заключение
- •Список используемых источников
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, после чего щелкнуть на кнопку ОК. Отладчик предоставляет в распоряжение пользователя различные полуавтоматические способы обнаружения ошибок.
При разработке программного продукта встречались синтаксические ошибки, которые были предотвращены вручную.
