
Построение эффективного кода по методу Шеннона-Фано.
Построение эффективного кода по методу Шеннона-Фано сводится к следующей процедуре:
множество сообщений располагают в порядке убывания вероятностей;
первоначальный ансамбль кодируемых сигналов разбивают на две группы таким образом, чтобы суммарные вероятности сообщений обеих групп были по возможности равны;
одной группе присваивается символ 0 , другой группе - символ 1;
каждую из подгрупп делят на две группы так, чтобы их суммарные вероятности были по возможности равны;
одним подгруппам каждой из групп вновь присваивают 0, а другим ‑ 1, в результате чего получают вторые цифры кода. Затем каждую из четырех подгрупп вновь делят на равные части и т.д. до тех пор, пока в каждой из подгрупп остается по одной букве.
В качестве примера построим код Шеннона - Фано, в котором вероятности появления букв подчиняются закону, представленному в таблице.
Выводы:
Число элементарных символов на букву сообщения с распределением вероятностей появления букв по закону Р=2-i возрастает в порядк5 убывания вдроятностѵй как натуральный ряд чисел.
Кодовые слова одинаковой вероятности появления имеют равную длину.
Для ансамблей равновероятных сообщений эффективным является равномерный код.
Коды, представляющие первичные алфавиты с неравномерным распределением символов, имеющие минимальную среднюю длину во вторичном алфавите, называется оптимальными неравномерными кодами (ОНК).
Эффективность ОНК оценивают с помощью коэффициента статистического сжатия
который
характеризует уменьшение количества
двоичных знаков на символ сообщения
при использовании ОНК по сравнению с
применением методов нестатистического
кодирования. Кроме того, используют
коэффициент относительной эффективности
который показывает, насколько используется
статистическая избыточность передаваемого
сообщения. Для рассмотренного примера
Ксс=1.1;
Коэ=1
.
2.Требования к программному изделию
2.1.Требования к функциональным характеристикам
Разработанная программа пригодна для исследования метода кодирования Шеннона - Фано.
2.2. Контроль входной и выходной информации.
Принимая входную информацию (исходные данные для расчетов) от пользователя, программа фильтрует входную информацию перед ее обработкой. При поступлении ошибочной информации или информации, не удовлетворяющей ограничительным критериям, становится невозможной обработка всего потока входной информации. В этом случае пользователю сообщается о некорректном вводе входной информации и предоставляется возможность повторного ввода.
3.Описание программы
3.1. Интерфейс пользователя
На рисунке показан внешний вид программы при запуске
Рис. 3
Рабочее окно программы, как видно из рисунка, состоит из нескольких textBox, куда вводятся данные.
Также в программе находится поле для изображения закодированного сообщения.
4.Результаты и листинг программы
4.1. Листинг программы:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication13
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
label6.Text = "";
label8.Text = "";
dataGridView2.Rows.Clear();
dataGridView1.Rows.Clear();
int n = int.Parse(textBox1.Text);
string[] mass1 = new string[n];
for (int i = 0; i < n; i++)
{
mass1[i] = dataGridView3.Rows[i].Cells[0].Value.ToString();
label6.Text += mass1[i];
}
string[] mass2 = new string[9] { "А", "Б", "В", "Г", "Д", "Е", "Ё", "Ж", "З" };
int count1 = 0;
int count2 = 0;
int count3 = 0;
int count4 = 0;
int count5 = 0;
int count6 = 0;
int count7 = 0;
int count8 = 0;
int count9 = 0;
dataGridView1.Rows.Clear();
for (int i = 0; i < n; i++)
{
if (mass1[i] == mass2[0]) count1++;
else if (mass1[i] == mass2[1]) count2++;
else if (mass1[i] == mass2[2]) count3++;
else if (mass1[i] == mass2[3]) count4++;
else if (mass1[i] == mass2[4]) count5++;
else if (mass1[i] == mass2[5]) count6++;
else if (mass1[i] == mass2[6]) count7++;
else if (mass1[i] == mass2[7]) count8++;
else if (mass1[i] == mass2[8]) count9++;
}
double[] fn = new double[9];
double[] mass3 = new double[9] { count1, count2, count3, count4, count5, count6, count7, count8, count9 };
Array.Sort(mass3,mass2);
for (int i = 0; i < 9; i++)
{
dataGridView1.Rows.Add(mass2[i], mass3[i]);
}
for (int i = 0; i < 9; i++)
{
fn[i] = Math.Round(mass3[i]/20,2);
dataGridView1.Rows[i].Cells[2].Value = fn[i];
}
////
int m = 3;
for (int i = 0; i < 9; i++)
{
if ((mass3[8]!=0)&(m<4)&(mass3[8]!=mass3[i]))
dataGridView1.Rows[8].Cells[m].Value = 1;
dataGridView1.Rows[8].Cells[11].Value = dataGridView1.Rows[8].Cells[3].Value.ToString();
}
m = 4;
for (int i = 0; i < 9; i++)
{
for (int k = 3; k <= m; k++)
{
if (mass3[7] != 0)
dataGridView1.Rows[7].Cells[k].Value = 0;
}
if ((mass3[7] != 0) & (m < 5) & (mass3[7] != mass3[i]))
dataGridView1.Rows[7].Cells[m].Value = 1;
dataGridView1.Rows[7].Cells[11].Value = dataGridView1.Rows[7].Cells[3].Value.ToString() + dataGridView1.Rows[7].Cells[4].Value.ToString();
}
m = 5;
for (int i = 0; i < 9; i++)
{
for (int k = 3; k <= m; k++)
{
if (mass3[6] != 0)
dataGridView1.Rows[6].Cells[k].Value = 0;
}
if ((mass3[6] != 0) & (m < 6) & (mass3[6] != mass3[i]))
dataGridView1.Rows[6].Cells[m].Value = 1;
dataGridView1.Rows[6].Cells[11].Value = dataGridView1.Rows[6].Cells[3].Value.ToString() + dataGridView1.Rows[6].Cells[4].Value.ToString()
+ dataGridView1.Rows[6].Cells[5].Value.ToString();
}
m = 6;
for (int i = 0; i < 9; i++)
{
for (int k = 3; k <= m; k++)
{
if (mass3[5] != 0)
dataGridView1.Rows[5].Cells[k].Value = 0;
}
if ((mass3[5] != 0) & (m < 7) & (mass3[5] != mass3[i]))
dataGridView1.Rows[5].Cells[m].Value = 1;
dataGridView1.Rows[5].Cells[11].Value = dataGridView1.Rows[5].Cells[3].Value.ToString() + dataGridView1.Rows[5].Cells[4].Value.ToString()
+ dataGridView1.Rows[5].Cells[5].Value.ToString() + dataGridView1.Rows[5].Cells[6];
}
m = 7;
for (int i = 0; i < 9; i++)
{
for (int k = 3; k <= m; k++)
{
if (mass3[4] != 0)
dataGridView1.Rows[4].Cells[k].Value = 0;
}
if ((mass3[4] != 0) & (m < 8) & (mass3[4] != mass3[i]))
dataGridView1.Rows[4].Cells[m].Value = 1;
dataGridView1.Rows[4].Cells[11].Value = dataGridView1.Rows[4].Cells[3].Value.ToString() + dataGridView1.Rows[4].Cells[4].Value.ToString()
+ dataGridView1.Rows[4].Cells[5].Value.ToString() + dataGridView1.Rows[4].Cells[6].Value.ToString()
+ dataGridView1.Rows[4].Cells[7].Value.ToString();
}
m = 8;
for (int i = 0; i < 9; i++)
{
for (int k = 3; k <= m; k++)
{
if (mass3[3] != 0)
dataGridView1.Rows[3].Cells[k].Value = 0;
}
if ((mass3[3] != 0) & (m < 9) & (mass3[3] != mass3[i]))
dataGridView1.Rows[3].Cells[m].Value = 1;
dataGridView1.Rows[3].Cells[11].Value = dataGridView1.Rows[3].Cells[3].Value.ToString() + dataGridView1.Rows[3].Cells[4].Value.ToString()
+ dataGridView1.Rows[3].Cells[5].Value.ToString() + dataGridView1.Rows[3].Cells[6].Value.ToString()
+ dataGridView1.Rows[3].Cells[7].Value.ToString() + dataGridView1.Rows[3].Cells[8].Value.ToString();
}
m = 9;
for (int i = 0; i < 9; i++)
{
for (int k = 3; k <= m; k++)
{
if (mass3[2] != 0)
dataGridView1.Rows[2].Cells[k].Value = 0;
}
if ((mass3[2] != 0) & (m < 10) & (mass3[2] != mass3[i]))
dataGridView1.Rows[2].Cells[m].Value = 1;
dataGridView1.Rows[2].Cells[11].Value = dataGridView1.Rows[2].Cells[3].Value.ToString() + dataGridView1.Rows[2].Cells[4].Value.ToString()
+ dataGridView1.Rows[2].Cells[5].Value.ToString() + dataGridView1.Rows[2].Cells[6].Value.ToString()
+ dataGridView1.Rows[2].Cells[7].Value.ToString() + dataGridView1.Rows[2].Cells[8].Value.ToString()
+ dataGridView1.Rows[2].Cells[9].Value.ToString();
}
m = 10;
for (int i = 0; i < 9; i++)
{
for (int k = 3; k <= m; k++)
{
if (mass3[1] != 0)
dataGridView1.Rows[1].Cells[k].Value = 0;
}
if ((mass3[1] != 0) & (m < 11) & (mass3[1] != mass3[i]))
dataGridView1.Rows[1].Cells[m].Value = 1;
dataGridView1.Rows[1].Cells[11].Value = dataGridView1.Rows[1].Cells[3].Value.ToString() + dataGridView1.Rows[1].Cells[4].Value.ToString()
+ dataGridView1.Rows[1].Cells[5].Value.ToString() + dataGridView1.Rows[1].Cells[6].Value.ToString()
+ dataGridView1.Rows[1].Cells[7].Value.ToString() + dataGridView1.Rows[1].Cells[8].Value.ToString()
+ dataGridView1.Rows[1].Cells[9].Value.ToString() + dataGridView1.Rows[1].Cells[10].Value.ToString();
}
m = 11;
for (int i = 0; i < 9; i++)
{
for (int k = 3; k <= m; k++)
{
if (mass3[0]!=0)
dataGridView1.Rows[0].Cells[k].Value = 0;
}
dataGridView1.Rows[0].Cells[11].Value = dataGridView1.Rows[0].Cells[3].Value.ToString() + dataGridView1.Rows[0].Cells[4].Value.ToString()
+ dataGridView1.Rows[0].Cells[5].Value.ToString() + dataGridView1.Rows[0].Cells[6].Value.ToString()
+ dataGridView1.Rows[0].Cells[7].Value.ToString() + dataGridView1.Rows[0].Cells[8].Value.ToString()
+ dataGridView1.Rows[0].Cells[9].Value.ToString() + dataGridView1.Rows[0].Cells[10].Value.ToString();
}
//////////////
for (int i = 0; i < 9; i++)
{
dataGridView2.Rows.Add(mass1[i]);
for (int j = 0; j < 9; j++)
{
if (dataGridView2.Rows[i].Cells[0].Value.ToString() == dataGridView1.Rows[j].Cells[0].Value.ToString())
dataGridView2.Rows[i].Cells[1].Value = dataGridView1.Rows[j].Cells[11].Value;
}
label8.Text += dataGridView2.Rows[i].Cells[1].Value.ToString();
}
//////////////
}
}
}
4.2. Результат:
Рис. 4