ЛИТЕРАТУРА
1. Теоретические основы информационной техники/Темников Ф.Е.и др.- М.:Энергия, 1971
2. Орлов В.А., Филлипов Л.И. Теория информации в упражнениях и задачах. - М.:Высш.шк., 1976
3. Сигорский В.П. Математический аппарат инженера - Киев:Техника, 1975
4. Солодов А.В. Теория информации и её
применение к задачам автоматического управления и контроля - М.: Наука, 1967.
2.3 ВЫВОД
Во второй части была рассмотрена модель распознавания, основанная на шаблонной классификации. Программное моделирование показало неплохие результаты. Модель распознаёт строку практически в 100% случаев при уровне помех до 40%. Однако данный подход может использоваться только в том случае, если заранее известно, что распознаваемые символы будут одинакового шрифта.
ПРИЛОЖЕНИЕ А
Текст программы моделирования канала связи.
Program final_of_work;
uses crt,graph;
const a=5;
b=0;
m=10+(a mod 6); {15}
r=trunc((m+a-b)/2); {10}
var
n, {n для (n,1) - кода}
temp,ent,out,symb,decode:byte; {буферы для кодирования}
p:array[1..m] of real; {вероятности}
p01,p10:real; {p единичной ошибки}
z,dl:array[1..m] of byte; {код, длина кода}
mask: array[1..8] of byte; {маски для декодирования}
data_n,data_p
:array[1..100] of integer; {данные для графика}
i,j, {счетчики}
count_of_errors, {счетчик ошибок восстановления}
dlina,sh, {длина массива сообщений}
count:integer; {счетчик для построения графика}
range,c,s,l:byte;
fl:boolean;
function flag(px:real):boolean;
{---осуществляет событие с вероятностью p---}
var ww,wq : word;
begin
ww := round(px * 100);
wq := random(100);
if ww > wq then flag := true else flag := false;
end;
procedure ver; {------------расчет вероятностей---------}
var s,i3,j3: integer;
tmp,s1:real;
begin
s:=0;tmp:=0; {вычисляем вероятности}
for j3:=1 to m do
s:=s+sqr(j3-r);
s:=s+m;
for i3:=1 to m do
p[i3]:=(1+sqr(i3-r))/s;
{-------упорядочиваем вероятности--------}
for i3:=1 to m-1 do {внешний цикл}
begin
tmp := p[i3]; {локальный максимум}
for j3:=i3 to m do
if p[j3] >= tmp then
begin
tmp := p[j3]; {максимум на i шаге}
s:=j3 {его номер}
end;
p[s] := p[i3]; {обмен}
p[i3] := tmp
end;
end;
procedure deranges; {----------внесение помех------------}
var tmp : byte;
c0,c1 : integer; {счетчики 0 и 1 для декодирования}
begin
out := 0; {выходной код после помех}
for i := 0 to 7 do {цикл по разрядам}
begin
c0 := 0; {сброс счетчиков}
c1 := 0;
tmp := (z[ent] shr i) and 1; {выделяем разряд}
for j := 1 to n do {цикл по разрядам (n,1)-кода}
case tmp of {определяемм помеху}
0 : if flag(p01) then inc(c1) else inc(c0);
1 : if flag(p10) then inc(c0) else inc(c1)
end;
if c1 > c0 then out := out or (1 shl i)
end; {вносим помеху в выходной код}
end;
procedure set_codes; {-----по алгоритму Шеннона - Фэно-----}
var i3,j2 : byte;
function numb(v:real):byte;{номер вероятности, находящейся}
var i2 : byte; {"" той, что передается как параметр}
begin
for i2 := 1 to m do {цикл по вероятностям}
if(v >= p[i2 + 1]) and (v <= p[i2]){если нашли границы}
then
numb := i2; {присваиваем номер "верхнего"}
end;
begin {-------------of procedure------------}
for i := 1 to m do {обнуляем коды и длины}
begin
z[i] := 0;
dl[i] := 0
end;
range := 8; {разряд - в максимальное значение}
c := 0; {счетчик по "вертикали" - на начало}
repeat {внешний цикл по кодам......}
if c = 0 {если в начале...}
then
dec(range); {... уменьшаем текущий разряд}
inc(c); {увеличиваем внутренний счетчик}
if (z[c] = z[c + 1]) and (c <= m)
{если два кода равны...}
then
begin {...то цикл деления}
fl := false; {флаг дальнейшего деления}
i := c; {"верхняя" граница}
j := c + 1; {"нижняя" граница}
if (z[j] = z[j + 1]) or (j + 1 < m)
{если ещё есть равные...}
then
fl := true; {...то ещё делим}
while fl do {пока можно делить...}
begin
inc(j); {...увеличиваем нижнюю границу}
if (z[j] <> z[j - 1]) or (j > m - 1) then
fl := false
end;
if((j - i) > 1) and (j < m)
{если > 2 элементов...}
then
dec(j); {...корректируем нижнюю границу}
s := numb((p[i] + p[j])/2); {делим}
if p[i] = p[j] {если два элемента...}
then
s := i; {середину - на "верхний"}
if j <= m {если не за пределами кодов...}
then
for l := i to j do {...цикл по группе}
if l <= s then {устанавливаем коды и длины}
begin
z[l] := z[l] or (1 shl range);
dl[l] := dl[l] + 1
end
else
dl[l] := dl[l] + 1;
if j < m then {устанавливаем текущий счетчик}
c := j
else
c := 0
end
else if c = m then c := 0;
until range = 0;{...пока не дойдем до последнего разряда}
{--------------инициализация масок--------------}
temp := 0;
for i := 1 to 8 do
begin
temp := temp or (1 shl (7 - (i - 1)));
mask[i] := temp
end
end;
function sourse:byte; {-----генерирует число из 1..15-----}
var cou : byte;
tu,ttu : real;
begin
cou := 1; {начальное значение}
ttu := p[cou]; {случайное число из 0..1}
tu := random;
while ttu < tu do begin {пока не превысили random...}
inc(cou);
ttu := ttu + p[cou]; {увеличиваем счетчик}
end;
sourse := cou; {присваиваем число из 1..15}
end;
procedure decoder; {---для неравномерного кода---}
var
code:byte;
begin
code:=out;
for i:=1 to 8 do {цикл со старшего разряда}
begin
temp:=code and mask[i]; {выделяем код}
for j:=1 to m do
if (temp=z[j]) and (i=dl[j]){если совпадает}
then
decode:=j; {...декодируем}
end;
end;
procedure graphiki; {-----------построение графика----------}
const x0=250; {начало координат}
y0=400;
var nn,ss,ii:integer;
sr:string;
driver,mode,errcode:integer;
begin
driver:=detect;
initgraph(driver, mode,''); {инициализация графики}
errcode:=graphResult;
if errcode<>grOk then
begin
Writeln(' Ошибка графики. ');
writeln(GraphErrorMSG(Errcode));
halt
end;
setcolor(white); {контуры фигур и текст}
line(x0,y0,x0,y0-300); {------ось y-----}
line(x0,y0,x0+200,y0); {------ось x-----}
SetTextStyle(DefaultFont, HorizDir, 1); {установка шрифта}
OutTextXY(x0,y0+40,'Количество повторений , n');
SetTextStyle(DefaultFont, VertDir, 1);
SetTextJustify(LeftText,TopText);{--способ выравнивания--}
OutTextXY(x0-50,180,'Количество ошибок , %');
SetTextStyle(DefaultFont, HorizDir, 1);
for i:=1 to 5 do
line(x0+i*35,y0,x0+i*35,y0-5);{делительные штрихи оси x}
outtextxy(x0+35,y0+10,'20');
outtextxy(x0+5*35,y0+10,'100');
for i:=1 to 4 do
line(x0,y0-i*65,x0+5,y0-i*65);{делительные штрихи оси y}
outtextxy(x0-20,y0-65,'15');
outtextxy(x0-20,y0-3*65,'45');
for nn:=1 to 33 do
begin {рисуем график}
setcolor(2);
line(x0+(nn+1)*5,round((y0-data_n[nn])),
x0+(nn+2)*5,round((y0-data_n[nn+1])));
end;
setcolor(15);
outtextxy(50,460,'Press any key...');
readkey;
ClearViewPort;
line(x0,y0,x0,y0-360); {------ось y-----}
line(x0,y0,x0+200,y0); {------ось x-----}
SetTextStyle(SmallFont, HorizDir, 5); {---установка шрифта--}
OutTextXY(x0,y0+40,'Значения p01 и p10 , %');
SetTextStyle(SmallFont, VertDir, 5);
SetTextJustify(LeftText,TopText); {-----способ выравнивания-----}
OutTextXY(x0-50,140,'Количество ошибок , %');
SetTextStyle(DefaultFont, HorizDir, 1);
for i:=1 to 5 do
line(x0+i*35,y0,x0+i*35,y0-5); {----делительные штрихи оси x---}
outtextxy(x0+35,y0+5,'20');
outtextxy(x0+5*35,y0+5,'100');
for i:=1 to 4 do
line(x0,y0-i*75,x0+5,y0-i*75); {----делительные штрихи оси y---}
outtextxy(x0-25,y0-75,'25');
outtextxy(x0-25,y0-2*75,'50');
outtextxy(x0-25,y0-3*75,'75');
outtextxy(x0-25,y0-4*75,'100');
{line(x0,y0-4*75,x0+200,y0-4*75);}
setcolor(2);
for nn:=1 to 13 do
{рисуем график}
line(x0+(nn+1)*12,round((y0-data_p[nn])),
x0+(nn+2)*12,round((y0-data_p[nn+1])));
end;
{=====================ОСНОВНОЙ БЛОК=======================}
Begin
clrscr;
p10:=0.2+0.02*a;
p01:=0.2+0.02*b;
randomize; {--инициализация генератора случайных чисел--}
ver; {инициализация и упорядочивание вероятностей}
set_codes; {--------инициализация кодов---------}
TextColor(15);
gotoxy(10,1);
write('ПАРАМЕТРЫ КАНАЛА :');
gotoxy(1,2);write('Вероятности одиночных ошибок :');
gotoxy(3,5);write('при передаче нуля : ',p01:4:3);
gotoxy(3,6);write('при передаче единицы : ',p10:4:3);
gotoxy(40,1);write('НЕРАВНОМЕРНЫЕ КОДЫ СООБЩЕНИЙ : ');
for i := 1 to m do {--------вывод кодов--------}
begin
gotoxy(45,1+i);
write(' z(',i,') = ');
gotoxy(55,1+i);
for j := 1 to dl[i] do
write((z[i] shr (8 - j)) and 1); {побитно}
end;
gotoxy(10,19);
write('Ввести длину передаваемого массива сообщений : ');
read(dlina);
write(' Ввести n для (n,1) - кода : ');
read(n);
count_of_errors := 0;
for sh := 1 to dlina do
begin {--------передача сообщений----------}
ent := sourse; {--случайное сообщение из ансамбля---}
deranges; {-----------внесение помех-----------}
decoder; {----декодирование двоичного кода----}
if ent <> decode then inc(count_of_errors);
end;
gotoxy(10,23);
write('РЕЗУЛЬТАТ ПЕРЕДАЧИ СООБЩЕНИЙ : ');
TextColor(12);
write( 'КОЛИЧЕСТВО ОШИБОК = ',count_of_errors);
TextColor(15);
gotoxy(10,24);
write('Please wait...');
{---------расчет count_of_errors для разных n-----------}
n := 0;count := 0;dlina := 100;
repeat
n := n + 3;
inc(count);
count_of_errors := 0;
for sh := 1 to dlina do
begin
ent := sourse;
deranges;
decoder;
if ent <> decode then inc(count_of_errors);
end;
data_n[count] := round(count_of_errors*3) ;
until n >= 96;
{---расчет count_of_errors для разных p01 и p10---}
n:=3;count:=0;dlina := 100;p01:=0;p10:=0;
repeat
p01:=p01+0.07;
p10:=p10+0.07;
inc(count);
count_of_errors := 0;
for sh := 1 to dlina do
begin
ent := sourse;
deranges;;
decoder;
if ent <> decode then inc(count_of_errors);
end;
data_p[count] := round(count_of_errors*3) ;
until p01 >= 0.98;
gotoxy(10,24);
writeln('Press any key to continue...');
readkey;
graphiki;
readkey;
closegraph;
End.
ПРИЛОЖЕНИЕ Б
Текст программы распознавания символов
Program Final_of_work;
uses graph;
const BiH=50; {-------высота картинки в пикселях------}
BiW=160; {-------ширина картинки в пикселях------}
stroka:array[1..10] of char=
('I','h','i','G','F','k','H','g','J','j');
{-----эталонная строка для установления соответствия-----}
type arr=array[1..BiW,1..BiH] of byte; {тип массива-картинки}
const
path0='work.bmp'; {путь к bmp-файлу с исходной строкой}
var file0,file1:file of byte; {файловые переменные для связи}
counter, {счетчик текущей позиции распознавания}
rasp:byte; {номер текущего распознанного символа}
f0, {массив с эталонной картинкой}
f:arr; {массив с картинкой, содержащей помехи}
x,y, {счетчики хода по массивам}
xmin, ymin,xmax, ymax , {минимально описанный прямоугольника}
xt, {текущая позиция x при движении по картинке}
xsav,{для сохранения текущего x при использовании корреляции}
i,j, {вспомогательные счетчики}
xm,xk,ym,yk,
{для сохранения текущего м.о.п. при использовании корреляции}
k,{счетчик шаблонов при использовании корреляции}
di,dj : integer;
{смещения шаблона и символа по x и y при наложении}
flag :boolean; {признак отображения на экране рамки}
kfmax, {глобальный максимум корреляции для символа}
max, {значение корреляции для текущего шаблона}
kf, {текущая переменная для вычисления корреляции}
smin:longint; {минимально возможная площадь шаблона}
Procedure Init_Graph_Mode; {-----инициализация графики-----}