- •6 Охрана труда и окружающей среды 79 Введение
- •1 Постановка задачи
- •2 Анализ предметной области
- •2.2 Передача информации по каналам связи
- •2.3 Помехоустойчивые коды
- •2.3.1 Способы борьбы с ошибками
- •2.3.2 Коды обнаружения и исправления ошибок
- •2.4 Классификация конечных абстрактных автоматов
- •2.4.1 Автомат Мили
- •2.4.2 Автомат Мура
- •2.5 Сверточное кодирование
- •2.5.1 Представление сверточного кодера
- •2.5.2 Представление связи
- •2.5.3 Реакция кодера на импульсное возмущение
- •2.5.4 Полиномиальное представление
- •2.5.5 Представление состояния и диаграмма состояний
- •2.5.6 Древовидные диаграммы
- •2.5.7 Решетчатая диаграмма
- •2.6 Декодирование по методу максимального правдоподобия
- •2.6.1 Алгоритм сверточного декодирования Витерби
- •2.6.2 Пример сверточного декодирования Витерби
- •2.6.4 Память путей и синхронизация
- •3 Разработка программного обеспечения системы кодирования сверточным кодом
- •3.1 Описание программы
- •3.2 Описание блок схем алгоритмов программы
- •3.3 Обоснование выбора языка программирования
- •3.4 Тестирование программы
- •3.5 Быстродействие программы
- •5. Оценка экономической эффективности разработки и внедрения программного продукта
- •1 Расчет трудоемкости разработки пп
- •6 Охрана труда и окружающей среды
- •6 Канал (длинноволновый инфракрасный или тепловой):
- •7 Канал (средний, или коротковолновый инфракрасный):
- •8 Канал (панхроматический — 4,3,2):
- •Библиографический список
- •Приложение б (информационное)
- •Приложение в (справочное)
- •Эффективности разработки и внедрения программного продукта»
Библиографический список
Никитин Г. И. Сверточные коды: Учебное пособие.— СПбГУАП. СПб.,: Сов. радио, 2001. — 80 с.
Назаров М.В. , Кувшинов Б.И. , Попов О.В. Теория передачи сигналов. М.: Связь, 1970г.
Блейхут Р. Теория и практика кодов, контролирующих ошибки - Theory and Practice of Error Control Codes.— М.: Мир, 1986. — 576 с.
Берлекэмп Элвин Алгебраическая теория кодирования. /Пер. с англ. под ред. С. Д. Бермана. — М.: Мир, 1971. — 463 с.
Классификация абстрактных автоматов [Электронный ресурс] / Свободная энциклопедия — Режим доступа: http://ru.wikipedia.org/wiki/Классификация_абстрактных_автоматов
Бернард Скляр Цифровая связь. Теоретические основы и практическое применение. Изд. 2-е, испр.: Пер. с англ. – М.: Издательский дом «Вильямс», 2003. – 1104 с.
Витерби А.Д., Омура Дж.К. Принципы цифровой связи и кодирования/Пер. с англ. под ред. К.Ш. Зигангирова. — М.: Радио и связь, 1982. — 536 с.
Алгоритм свёрточного декодирования Витерби [Электронный ресурс] / Свободная энциклопедия — Режим доступа: http://ru.wikipedia.org/wiki/Алгоритм_свёрточного_декодирования_Витерби
Расстояние Хэмминга [Электронный ресурс] / Свободная энциклопедия — Режим доступа: http://ru.wikipedia.org/wiki/Расстояние_Хэмминга
Культин Н.Б. Delphi 6. Программирование на Object pascal. БХВ-Петербург, 2001 г. — 528с.
ГОСТ 19.701-90 Единая система программной документации. Схемы алгоритмов, программ, данных и систем. Условные обозначения и правила выполнения. / А.А. Мкртумян, А.Л. Щерс, А.Н. Сироткин./ М.: Государственный стандарт союза ССР, 1992.
Барышев А.Ф. Маркетинг:Учеб.для сред.проф.образования/ А. Ф. Барышев. – 2-е изд.,стер. – М.: Издательский центр «Академия»; Мастерство, 2002. – 207 с.
Гаврипин Ю.Ф. Маркетинг. Челябинск: ЧГТУ. 1995.
Методические указания к выполнению дипломного проекта «Расчет экономической эффективности создания и использования программного продукта» по дисциплинам «Основы менеджмента и маркетинга», «Менеджмент» / Сост. Г.А. Раздобреева, Е.В. Коваль, Т.В. Кулешова, С.В. Ключко – Севастополь: Изд-во СевНТУ, 2009. – 32 с.
НПАОП 0.00 – 1.31 – 99 Правила ОТ при эксплуатации ЭВМ. Введ. 1.09.99 – К., 1999. – 107 с.
Приложение А
(информационное)
Текст программы
unit Viterbi_Unit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, Grids, ExtCtrls, TeeProcs, TeEngine, Chart,
Series,DateUtils, idGlobal ;
type
{**
* сокращенные названия для типов
*}
pint = ^integer;
int = integer;
{**
* узел сети используемый при декодировании
*}
TNodeDataPtr = ^TNodeData;
TNodeData = record
val : string; // содержимое вершины
way : int; // метрика длины пути
minWayBelong : bool; // принадлежит минимальному пути
parent : TNodeDataPtr; // указатель на родителя
end;
{**
* уровень сети используемой при декодировании
*}
TListElemPtr =^TListElem;
TListElem = record
nodes : array [0..15] of TNodeDataPtr; // узлы текущего уровня
code : string; // декодируемый код
pnext : TListElemPtr; // указатель на следующий уровень
pprev : TListElemPtr; // указатель на предыдущий уровень
end;
{**
* форма
*}
TmyForm = class(TForm)
step1Btn: TButton;
step2Btn: TButton;
step3Btn: TButton;
allStepsBtn: TButton;
GroupBox2: TGroupBox;
inputData: TRichEdit;
step0Data: TRichEdit;
step1Data: TRichEdit;
step2Data: TRichEdit;
step3Data: TRichEdit;
step4Data: TRichEdit;
Label1: TLabel;
step1Label: TLabel;
Label3: TLabel;
Label4: TLabel;
step2Label: TLabel;
Label6: TLabel;
step0Label: TLabel;
Label8: TLabel;
errorMultiplicityBox: TComboBox;
errorProbabilityBox: TComboBox;
leftTreePaintPosition: TScrollBar;
Label2: TLabel;
Label5: TLabel;
Label7: TLabel;
Label9: TLabel;
allBitsLabel: TLabel;
errorBitsLabel: TLabel;
trueBitsLabel: TLabel;
coderCharts: TChart;
speedTestBtn: TButton;
coderSeries: TLineSeries;
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
decoderCharts: TChart;
decoderSeries: TLineSeries;
procedure step1BtnClick(Sender: TObject);
procedure step2BtnClick(Sender: TObject);
procedure step3BtnClick(Sender: TObject);
procedure allStepsBtnClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure leftTreePaintPositionChange(Sender: TObject);
procedure printTree(t:TListElemPtr; levelNum :int);
procedure step0();
procedure step1();
procedure step2();
procedure step3(showTree : bool);
procedure step4();
procedure speedTestBtnClick(Sender: TObject);
private
bitmap: TBitmap;
public
{ Public declarations }
end;
{**
* автомат Мили (кодер)
*}
MealyAutomaton = class
private
R1 :int; // регистры сдвига
R2 :int;
R3 :int;
R4 :int;
// конструктор
constructor init;
public
// побитовый кодер
procedure coding(X1:int; X2:int; Y1:pint; Y2:pint; Y3:pint);
// инициализация регистров заданными значениями
procedure initByStr(val:string);
// текущее состояние регистров автомата
function state():string;
end;
{**
* декодер работающий по алгоритму Витерби
*}
TTreeHandler = class
public
pleft : TListElemPtr; // указатель на корневой узел сети
// вычисляет сумму по модулю 2 для двух строк
function xorStrings(val_1: string; val_2: string) : string;
// конструктор
constructor init;
// вычисление пути до узла
function calcWayToNode(parent: TNodeDataPtr; nodeVal:string; inputCode: string):int;
// создание корня
procedure creatRoot;
// создание узла сети
function createNode(prev:TListElemPtr; nodeVal:string; inputCode: string):TNodeDataPtr;
// вес вершины
function weightCalc(val: string) : int;
// помошник для функции canBeParent
function canBeParentHelper(childVal:string; parentVal:string):int;
// может ли ребенок с кодом childVal иметь родителя с кодом parentVal
function canBeParent(childVal:string; parentVal:string):int;
// Создание очередного уровня сети
procedure createLevel(temp:TListElemPtr; code:string);
// Удаление всех узлов сети
procedure deleteTree(pleft:TListElemPtr);
// декодирование
function decode() : string;
// инвертирование строки
function rotateString(val: string): string;
end;
var
myForm : TmyForm; // форма
mealyCoder : MealyAutomaton; // кодер
treeHandler : TTreeHandler; // декодер
implementation
{$R *.dfm}
// автомат Мили - НАЧАЛО
{**
* конструктор
*}
constructor MealyAutomaton.init;
begin
R1:=0;
R2:=0;
R3:=0;
R4:=0;
end;
{**
* инициализация регистров заданными значениями
*}
procedure MealyAutomaton.initByStr(val:string);
begin
R1:=StrToInt(val[1]);
R2:=StrToInt(val[2]);
R3:=StrToInt(val[3]);
R4:=StrToInt(val[4]);
end;
{**
* текущее состояние регистров автомата
*}
function MealyAutomaton.state():string;
begin
state := IntToStr(R1) + IntToStr(R2) + IntToStr(R3) + IntToStr(R4);
end;
{**
* побитовый кодер r=2/3
*}
procedure MealyAutomaton.coding(X1:int; X2:int; Y1:pint; Y2:pint; Y3:pint);
begin
Y1^ := X1 xor R2;
Y2^ := R2 xor X1 xor R4;
Y3^ := X1 xor X2 xor R4;
R2 := R1;
R4 := R3;
R1 := X1;
R3 := X2;
end;
// автомат Мили - КОНЕЦ
// декодер - НАЧАЛО
{**
* помошник для функции canBeParent
*}
function TTreeHandler.canBeParentHelper(childVal:string; parentVal:string):int;
var
res : int;
begin
res := 0;
if (childVal = '0'+parentVal[1]) then res := 1;
if (childVal = '1'+parentVal[1]) then res := 1;
canBeParentHelper := res;
end;
{**
* может ли ребенок с кодом childVal иметь родителя с кодом parentVal
*}
function TTreeHandler.canBeParent(childVal:string; parentVal:string):int;
var
res : int;
begin
res := 0;
if ((1 = canBeParentHelper(copy(childVal, 1, 2), copy(parentVal, 1, 2))) AND
(1 = canBeParentHelper(copy(childVal, 3, 2), copy(parentVal, 3, 2)))) then
begin
res := 1;
end;
canBeParent := res;
end;
{**
* вычисляет сумму по модулю 2 для двух строк
*}
function TTreeHandler.xorStrings(val_1: string; val_2: string) : string;
var
res : string;
i : int;
begin
if (length(val_1) <> length(val_2)) then
begin
res := '';
end
else
begin
for i:=1 to length(val_1) do
begin
if (val_1[i] = val_2[i]) then
begin
res:=res+'0'
end
else
begin
res:=res+'1';
end
end
end;
xorStrings := res;
end;
{**
* конструктор
*}
constructor TTreeHandler.init;
begin
pleft := NIL;
end;
{**
* вычисление пути до узла
*}
function TTreeHandler.calcWayToNode(parent: TNodeDataPtr; nodeVal:string; inputCode: string):int;
var
resultWay : int;
Y1:int;
Y2:int;
Y3:int;
nextState: string;
begin
mealyCoder.initByStr(parent^.val);
mealyCoder.coding(0, 0, @Y1, @Y2, @Y3);
if (mealyCoder.state <> nodeVal) then
begin
mealyCoder.initByStr(parent^.val);
mealyCoder.coding(0, 1, @Y1, @Y2, @Y3);
end;
if (mealyCoder.state <> nodeVal) then
begin
mealyCoder.initByStr(parent^.val);
mealyCoder.coding(1, 0, @Y1, @Y2, @Y3);
end;
if (mealyCoder.state <> nodeVal) then
begin
mealyCoder.initByStr(parent^.val);
mealyCoder.coding(1, 1, @Y1, @Y2, @Y3);
end;
nextState := IntToStr(Y1) + IntToStr(Y2) + IntToStr(Y3);
resultWay := parent^.way + WeightCalc(xorStrings(nextState, inputCode));
calcWayToNode := resultWay;
end;
{**
* создание корня
*}
procedure TTreeHandler.creatRoot;
var
i:int;
begin
new(pleft);
pleft^.pnext := NIL;
pleft^.pprev := NIL;
new(pleft^.nodes[0]);
pleft^.nodes[0]^.val := '0000';
pleft^.nodes[0]^.way := 0;
pleft^.nodes[0]^.minWayBelong := true;
pleft^.nodes[0]^.parent := NIL;
for i:=1 to 15 do
begin
pleft^.nodes[i] := NIL;
end;
end;
{**
* создание узла сети
*}
function TTreeHandler.createNode(
prev:TListElemPtr;
nodeVal:string;
inputCode: string
):TNodeDataPtr;
var
resultNode : TNodeDataPtr;
way : int;
tempWay : int;
parentIndex : int;
i:int;
begin
resultNode := NIL;
parentIndex := -1;
way := 0;
// ищем родителя узла по наименьшему пути к вершине
for i:=0 to 15 do
begin
if (prev^.nodes[i] <> NIL) then
begin
if (1 = canBeParent(nodeVal, prev^.nodes[i].val)) then
begin
if (-1 = parentIndex) then
begin
way := calcWayToNode(prev^.nodes[i], nodeVal, inputCode);
parentIndex := i;
end
else
begin
tempWay := calcWayToNode(prev^.nodes[i], nodeVal, inputCode);
if (tempWay < way) then
begin
way := tempWay;
parentIndex := i;
end
end
end
end
end;
// инициализируем вершину
if (-1 <> parentIndex) then
begin
new(resultNode);
resultNode^.val := nodeVal;
resultNode^.way := way;
resultNode^.minWayBelong := false;
resultNode^.parent := prev^.nodes[parentIndex];
end;
createNode := resultNode;
end;
{**
* вес вершины
*}
function TTreeHandler.weightCalc(val: string) : int;
var
res : int;
i : int;
begin
res := 0;
for i:=1 to length(val) do
begin
if (val[i] = '1') then
begin
res := res + 1;
end
end;
weightCalc := res;
end;
{**
* Создание очередного уровня
*}
procedure TTreeHandler.createLevel(temp:TListElemPtr; code:string);
var
newLevel : TListElemPtr;
i:int;
val:string;
begin
if((temp^.pnext <> NIL)) then
begin
CreateLevel(temp.pnext, code);
end
else
begin
new(newLevel);
temp^.pnext := newLevel;
temp^.code := code;
newLevel^.pnext := NIL;
newLevel^.pprev := temp;
for i:=0 to 15 do
begin
val := IntToBin(i);
while (length(val) > 4) do
begin
val := copy(val, 2, length(val) - 1)
end;
newLevel^.nodes[i] := createNode(temp, val, code);
end;
end
end;
{**
* Удаление всех узлов дерева
*}
procedure TTreeHandler.deleteTree(pleft:TListElemPtr);
begin
if (pleft <> NIL) then
begin
DeleteTree(pleft.pnext);
DISPOSE (pleft);
end;
end;
{**
* декодирование
*}
function TTreeHandler.decode() : string;
var
temp : TListElemPtr;
resultStr : string;
minWayNode : TNodeDataPtr;
i : int;
begin
temp := pleft;
while (temp^.pnext <> NIL) do
begin
temp := temp^.pnext;
end;
minWayNode := NIL;
for i:=0 to 15 do
begin
if (temp^.nodes[i] = NIL) then
begin
break;
end;
if ((minWayNode = NIL) OR (minWayNode^.way > temp^.nodes[i]^.way)) then
begin
minWayNode := temp^.nodes[i];
end;
end;
while (minWayNode^.parent <> NIL) do
begin
resultStr := resultStr + minWayNode^.val[3] + minWayNode^.val[1];
minWayNode^.minWayBelong := true;
minWayNode := minWayNode^.parent;
end;
decode := rotateString(resultStr);
end;
{**
* инвертирование строки
*}
function TTreeHandler.rotateString(val: string): string;
var
res : string;
strLen : int;
i : int;
begin
res := '';
strLen := length(val);
i := strLen;
while (i >= 1) do
begin
res := res + val[i];
i := i-1;
end;
rotateString := res;
end;
// декодер - КОНЕЦ
// общие функции - НАЧАЛО
{**
* преобразует стоку в двоичном виде в число
*}
function BinToInt(BinStr : string) : Int64;
var i : byte;
RetVar : Int64;
begin
BinStr := UpperCase(BinStr);
if BinStr[length(BinStr)] = 'B' then Delete(BinStr,length(BinStr),1);
RetVar := 0;
for i := 1 to length(BinStr) do
begin
if not (BinStr[i] in ['0','1']) then
begin
RetVar := 0;
Break;
end;
RetVar := (RetVar shl 1) + (byte(BinStr[i]) and 1) ;
end;
Result := RetVar;
end;
// общие функции - КОНЕЦ
// методы формы - НАЧАЛО
{**
* Создание формы
*}
procedure TmyForm.FormCreate(Sender: TObject);
begin
// инициализируем автомат мили
mealyCoder := MealyAutomaton.init();
// инициализируем декодер
treeHandler := TTreeHandler.init();
myForm.DoubleBuffered := true;
bitmap := TBitmap.Create;
randomize();
inputData.Clear();
inputData.Text := 'тест1.';
end;
{**
* перерисовка формы
*}
procedure TmyForm.FormPaint(Sender: TObject);
begin
printTree(treeHandler.pleft, 0);
end;
{**
* Отображение дерева
*}
procedure TmyForm.printTree(t:TListElemPtr; levelNum :int);
var
i : int;
node : TNodeDataPtr;
nodeParent : TNodeDataPtr;
leftPos : int;
topPos : int;
levelHeight : int;
levelWidth : int;
levelX : int;
levelY : int;
ellipse : int;
parentNodeY : int;
parentNodeX : int;
max : int;
val : string;
begin
leftPos := 60 - leftTreePaintPosition.Position;
topPos := 30;
levelHeight :=18;
levelWidth :=70;
ellipse :=9;
parentNodeX := 0;
parentNodeY := 0;
// очищаем канву
bitmap.Width := myForm.Width;
bitmap.Height := myForm.Height;
bitmap.Canvas.Brush.Color := {clWhite}clBtnFace;
bitmap.Canvas.Pen.Style := psSolid;
bitmap.Canvas.Pen.Color := clBlack;
bitmap.Canvas.FillRect(Rect(0,0,myForm.Width,myForm.Height));
// Рекурсивное прохождение заканчивается на пустом поддереве
while (t <> NIL) do
begin
levelX := leftPos + levelWidth*levelNum;
for i:=0 to 15 do
begin
if (t^.nodes[i] <> NIL)then
begin
levelY := topPos + levelHeight*i;
node := t^.nodes[i];
// рисуем связь с родителем
nodeParent := node^.parent;
if (nodeParent <> NIL) then
begin
parentNodeY := BinToInt(nodeParent.val);
parentNodeY := topPos + levelHeight*parentNodeY;
parentNodeX := levelX-levelWidth;
// выделяем минимальный путь
if (node^.minWayBelong) then
begin
bitmap.Canvas.Pen.Color := clRed;
bitmap.Canvas.Pen.Width :=2;
end
else
begin
bitmap.Canvas.Pen.Color := clBlack;
bitmap.Canvas.Pen.Width :=1;
end;
bitmap.Canvas.MoveTo(levelX, levelY);
bitmap.Canvas.LineTo(parentNodeX, parentNodeY);
end;
bitmap.Canvas.Pen.Color := clBlack;
bitmap.Canvas.Pen.Width :=1;
// рисуем текущий узел
bitmap.Canvas.Ellipse(levelX-ellipse, levelY-ellipse, levelX+ellipse, levelY+ellipse);
bitmap.Canvas.TextOut(levelX-7, levelY-6, IntToStr(node^.way));
// перерисовывам родителя
if (nodeParent <> NIL) then
begin
bitmap.Canvas.Ellipse(parentNodeX-ellipse, parentNodeY-ellipse, parentNodeX+ellipse, parentNodeY+ellipse);
bitmap.Canvas.TextOut(parentNodeX-7, parentNodeY-6, IntToStr(nodeParent^.way));
end;
end;
// номер уровня
bitmap.Canvas.TextOut(levelX-7, topPos-6 + levelHeight*16, IntToStr(levelNum+1));
// декодируемый код
bitmap.Canvas.TextOut(levelX-7+ trunc(levelWidth/2), 10, t^.code);
end;
// рисуем следующий уровень
t := t^.pnext;
levelNum := levelNum+1;
end;
if (treeHandler.pleft <> NIL) then
begin
bitmap.Canvas.FillRect(Rect(0,0,40,myForm.Height));
for i:=0 to 15 do
begin
val := IntToBin(i);
while (length(val) > 4) do
begin
val := copy(val, 2, length(val) - 1)
end;
bitmap.Canvas.TextOut(10, topPos-6 + levelHeight * i, val);
end;
myForm.Canvas.Draw(0,0,bitmap);
max := levelNum * levelWidth - myForm.Width + 40;
if (max > 0) then
begin
leftTreePaintPosition.Visible := true;
leftTreePaintPosition.Max := max;
end
else
begin
leftTreePaintPosition.Visible := false;
end
end
else
begin
leftTreePaintPosition.Visible := false;
end;
end;
{**
* преобразование строки в двоичный код
*}
procedure TmyForm.step0();
var
sym : char;
i : int;
j : int;
str : string;
begin
step0Data.Text := '';
for i := 1 to length(inputData.Text) do
begin
sym := inputData.Text[i];
str := '';
for j:=0 to 7 do
begin
if (int(sym) and (1 shl j) > 0) then str :='1'+str
else str :='0'+str;
end;
step0Data.Text := step0Data.Text + str;
end;
step0Label.Caption := 'Сообщение в двоичном коде ('+IntToStr(length(step0Data.Text))+' бит)';
end;
{**
* кодирование строки с помощью автомата мили
*}
procedure TmyForm.step1();
var
y1 : int; // Выходы автомата Мили
y2 : int;
y3 : int;
res : string; // Результат кодирования
i : int;
x1 : int;
x2 : int;
begin
res := '';
mealyCoder.init();
i := 1;
while(i < length(step0Data.Text)) do
begin
if ((step0Data.Text[i] = '0') OR (step0Data.Text[i] = '1')) then
begin
x1 := int(step0Data.Text[i])-int('0');
x2 := int(step0Data.Text[i+1])-int('0');
mealyCoder.Coding(x1, x2, @y1, @y2, @y3);
res := res + IntToStr(y1)+IntToStr(y2)+IntToStr(y3);
i := i+2;
end;
end;
step1Data.Text := res;
step1Label.Caption := 'Закодированное сообщение ('+IntToStr(length(step1Data.Text))+' бит)';
end;
{**
* имитация канала связи
*}
procedure TmyForm.step2();
var
i : int;
j : int;
errorMultiplicity : int;
errorProbability : int;
errorInterval : int; // промежуток, в котором возможно появление пачки ошибок
errorPosition : int; // местоположение ошибки
str : string;
maxErrors : int; // максимальное количество ошибок
errorCount : int; // счетчик количества ошибок
begin
errorInterval := 1;
errorMultiplicity := StrToInt(errorMultiplicityBox.Text);
errorProbability := trunc(StrToFloat(errorProbabilityBox.Text) * 100);
// очищаем стили
step2Data.SelStart := 1;
step2Data.SelLength := length(step2Data.Text);
step2Data.SelAttributes.Color := clBlack;
step2Data.SelAttributes.Style := [];
step2Data.Lines.Clear();
str := step1Data.Text;
randomize();
maxErrors := round(length(str) * (errorProbability/100));
errorCount := 0;
i:=1;
while ((i <= length(str)) AND (maxErrors > 0)) do
begin
if (errorCount >= maxErrors) then
begin
break;
end;
if (random(99) + 1 <= errorProbability) then
begin
errorPosition := 0;
// меняем 1 на 0 и 0 на 1 (т.е. генерируем ошибку)
for j:=i+errorPosition to i+errorPosition+errorMultiplicity - 1 do
begin
if (j > length(str)) then
begin
break;
end;
if (str[j] = '0') then
begin
str[j] := '1'
end
else
begin
str[j] := '0';
end;
errorCount := errorCount + 1;
i := i + 1;
end;
i := i - 1;
// стараемся сделать так, чтобы ошибки не "слепливались"
if ((errorProbability <> 100) AND (random(99) + 1 > errorProbability)) then
begin
i := i + 1;
end;
end;
i := i + errorInterval;
end;
step2Data.Text := str;
step2Label.Caption := 'После прохождения канала ('+IntToStr(length(step2Data.Text))+' бит)';
// выделяем ошибочные символы
for i:=1 to length(str) do
begin
if (str[i] <> step1Data.Text[i])then
begin
step2Data.SelStart := i-1;
step2Data.SelLength := 1;
step2Data.SelAttributes.Color := clFuchsia;
step2Data.SelAttributes.Style := [fsUnderline, fsBold];
end;
end
end;
{**
* декодирование в двоичный код
*}
procedure TmyForm.step3(showTree : bool);
var
code : string;
codeLen : int;
i : int;
begin
code := step2Data.Text;
codeLen := length(code);
if (codeLen > 0) then
begin
// удаление дерева (если уже был запуск декодера)
treeHandler.DeleteTree(treeHandler.pleft);
treeHandler.pleft := NIL;
// Инициализация дерева
treeHandler.CreatRoot();
// строим дерево декодера
i := 1;
while (i < codeLen) do
begin
treeHandler.createLevel(treeHandler.pleft, copy(code, i, 3));
i := i+3;
end;
// выводим результат декодирования
step3Data.Text := treeHandler.decode();
if (showTree) then
begin
// рисуем дерево декодера
printTree(treeHandler.pleft, 0);
end;
end;
end;
{**
* перевод из двоичного кода в строку
*}
procedure TmyForm.step4();
var
str : string;
i : int;
j : int;
sym : int;
errorsCount : int;
begin
str := '';
i := 1;
while (i < length(step3Data.Text)) do
begin
sym := 0;
for j:=0 to 7 do
begin
sym := (sym shl 1) + (byte(step3Data.Text[i+j]) and 1) ;
end;
str := str + char(sym);
i := i+8;
end;
step4Data.Text := str;
errorsCount := 0;
for i:=1 to length(step3Data.Text) do
begin
if (step0Data.Text[i] <> step3Data.Text[i]) then
begin
errorsCount := errorsCount + 1;
end;
end;
allBitsLabel.Caption := IntToStr(length(step3Data.Text));
errorBitsLabel.Caption := IntToStr(errorsCount);
trueBitsLabel.Caption := IntToStr(length(step3Data.Text) - errorsCount);
end;
{**
* кнопка "закодировать"
*}
procedure TmyForm.step1BtnClick(Sender: TObject);
begin
step0();
step1();
end;
{**
* кнопка "канал связи"
*}
procedure TmyForm.step2BtnClick(Sender: TObject);
begin
step2();
end;
{**
* кнопка "декодировать"
*}
procedure TmyForm.step3BtnClick(Sender: TObject);
begin
step3(true);
step4();
end;
{**
* кнопка "все шаги сразу"
*}
procedure TmyForm.allStepsBtnClick(Sender: TObject);
begin
step0();
step1();
step2();
step3(true);
step4();
end;
{**
* прокрутка отображения дерева
*}
procedure TmyForm.leftTreePaintPositionChange(Sender: TObject);
begin
printTree(treeHandler.pleft, 0);
end;
{**
* тестирование быстродействия кодера/декодера
*}
procedure TmyForm.speedTestBtnClick(Sender: TObject);
var
i : integer;
j : integer;
DateTime1 : TDateTime;
DateTime2 : TDateTime;
time : int;
begin
{ тестирование быстродействиея кодера}
i := 250;
while i <= 1000 do
begin
inputData.Lines.Clear();
for j:=0 to i do
begin
if (random(1) = 1) then inputData.Text := inputData.Text + '1'
else inputData.Text := inputData.Text + '0';
end;
DateTime1 := Now;
step0() ;
DateTime2 := Now;
time := round(MilliSecondsBetween(DateTime1, DateTime2) / 8);
coderSeries.AddXY(i * 8, time);
i := i+250;
end;
{ тестирование быстродействиея декодера}
i := 250;
while i <= 4000 do
begin
step2Data.Lines.Clear();
for j:=0 to i do
begin
if (random(1) = 1) then step2Data.Text := step2Data.Text + '1'
else step2Data.Text := step2Data.Text + '0';
end;
DateTime1 := Now;
step3(false);
DateTime2 := Now;
time := round(MilliSecondsBetween(DateTime1, DateTime2) / 8);
decoderSeries.AddXY(i, time);
i := i+500;
end;
// удаление дерева
treeHandler.DeleteTree(treeHandler.pleft);
treeHandler.pleft := NIL;
inputData.Lines.Clear();
step0Data.Lines.Clear();
step1Data.Lines.Clear();
step2Data.Lines.Clear();
step3Data.Lines.Clear();
step4Data.Lines.Clear();
inputData.Text := 'ау';
end;
// методы формы - КОНЕЦ
end.