1. Trang chủ
  2. » Giáo Dục - Đào Tạo

BÁO cáo bài tập lớn lý thuyết thông tin

12 361 1

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 12
Dung lượng 424,19 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Giả sử ta muốn truyền một đoạn tin nhắn có nội dung là “aaaabbbbcccc” bằng mã Ascii thì chúng ta cần 8 bit cho một ký tự, như vậy cần đến 96 bit để mã hóa được đoạn tin nhắn trên.. Vì vậ

Trang 1

TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI

VIỆN ĐIỆN TỬ - VIỄN THÔNG

          

BÁO CÁO BÀI TẬP LỚN

Lý thuyết thông tin

Giảng viên hướng dẫn : Thầy Nguyễn Hữu Phát Nhóm sinh viên thực hiện : Phan Việt Nam – 20193036

Trần Đức Tin – 20193134

Tháng 1/2022

Trang 2

I GIỚI THIỆU CHUNG VỀ ĐỀ TÀI

Trong Lý thuyết thông tin, mã thống kê tối ưu được thực hiện tại nguồn nhằm giải quyết vấn đề thứ nhất của hệ thống truyền tin đó là tốc độ truyền tin Giả sử ta muốn truyền một đoạn tin nhắn có nội dung là “aaaabbbbcccc” bằng mã Ascii thì chúng ta cần 8 bit cho một

ký tự, như vậy cần đến 96 bit để mã hóa được đoạn tin nhắn trên Vì vậy chúng ta cần tìm ra một phương pháp mã hóa nhằm tăng tốc độ truyền tin, để làm được điều đó, người ta làm giảm chiều dài trung bình của từ mã bằng cách các từ mã có xác suất nhỏ thì có chiều dài lớn và từ mã có xác suất lớn thì chiều dài nhỏ

Kết hợp quá trình học tập môn Lý thuyết thông tin, nhóm chúng

em nhận thấy hai phương pháp mã hóa theo Shannon và Huffman có tính dụng cao, nó giúp mã hóa thông tin, nén dữ liệu dựa trên tần suất xuất hiện của các ký tự cần mã hóa sao cho dung lượng sau khi mã hóa được giảm bớt nhằm tối ưu mục đích lưu trữ Vì vậy, chúng em quyết định lựa chọn 2 phương pháp mã hóa này làm chủ đề cho bài tập lớn

II NỘI DUNG ĐỀ TÀI

1 Các định lý và thông số của mã thống kê

 Định lý 1: Trong hệ nhị phân, entropy của nguồn luôn nhỏ hơn

hoặc bằng chiều dài trung bình của từ mã:

 Định lý 2: Trong hệ nhị phân, người ta luôn tìm được bộ mã thỏa mãn tính chất tối ưu với chiều dài trung bình nằm trong khoảng []

Để đánh giá tính hiệu quả của mã thống kê, người ta đưa ra thông số

hệ số nén thông qua tỷ lệ:

Trang 3

2 Bài toán: Cho nguồn tin X = {x , x , x , x , x ,…} với xác suất 1 2 3 4 5

tương ứng là P(X)={p(x ), p(x ), p(x ), p(x ), p(x ), …} Thực hiện mã1 2 3 4 5

hóa nguồn tin trên

2.1 Mã hóa theo Shannon

a Thuật toán

 Bước 1: Sắp xếp các nguồn tin theo thứ tự xác suất giảm dần

 Bước 2: Thay xác suất p(xi)=Pi

Trong đó

 Bước 3: Chuyển P từ dạng thập phân sang nhị phân tương ứngi

 Bước 4: Xác định chiều dài l : H(x ) l H(x ) + 1i i i i

 Bước 5: Lấy phần sau dấu phảy có chiều dài bằng li

b Code

Các khối trong code bao gồm:

 Khối nhập thông tin đầu vào: 2 phương thức nhập

+ Nhập theo xác suất + Nhập theo tần số

void Source ( float x[], int n)

{

cout<< " Moi ban chon phuong thuc nhap: " <<endl;

cout<< " 1 Nhap duoi dang xac suat: " <<endl;

cout<< " 2 Nhap duoi dang tan so: " <<endl;

int c;

check_Number(c);

if (c == 1

{

cout<< " Moi ban nhap xac suat: " <<endl;

for ( int i = ; i <n; i ++ )

{

do

{

cout<< " x[ " << i<< " ]: " ;

check_Float(x[i]);

}

Trang 4

while (x[i] <= 0 ||x[i] >= 1 );

}

}

if (c != 1

{

float sum1 = ;

cout<< " Moi ban nhap tan so: " <<endl;

for ( int i = ; i <n; i ++ )

{

cout<< " x[ " << i<< " ]: " ;

check_Float(x[i]);

}

for ( int i = ; i <n; i ++ )

{

sum1 +=x[i];

}

for ( int i = ; i <n; i ++ )

{

x[i] =x[i] / sum1;

}

}

}

 Khối kiểm tra điều kiện: Dữ liệu nhập vào có thỏa mãn hay không bao gồm các hàm: check_Number(), check_Float(), check()

- Hàm check_Number(): Đảm bảo số nguồn đầu vào phải là số

nguyên:

void check_Number( int n)

{

int check = scanf( " %d " , &n);

//Nhap lai neu la chu hoac so < 1

while (check != 1 || n< )

{

if (check != ){

cout<< " Khong phai so! " <<endl;

} else {

cout<< " So nhap phai >= 1 " <<endl;

}

fflush(stdin);

cout<< " Nhap lai: "

check = scanf ( " %d " &n);

}

};

Trang 5

- Hàm check_Float(): Đảm bảo các xác suất nhập vào phải ở dạng

số thực:

void check_Float ( float& n)

{

int check = scanf( " %f " , &n);

while (check != )

{

cout<< " Nhap sai! " <<endl;

fflush(stdin);

cout<< " Nhap lai: "

check = scanf ( " %f " &n);

}

};

- Hàm Check(): Hàm này kiểm tra xem sau khi nhập xác suất vào thì tổng các xác suất đầu vào có bằng 1 hay không:

bool Check ( float x[], int n, float s)

{

s= ;

for ( int i = ; i <n; i ++ )

{

s+=x[i];

}

if (s== 1 ) return true ;

else return false ;

}

 Khối sắp xếp và chuyển xác suất

Trong bài này, cụ thể ta sẽ sắp xếp theo thứ tự giảm dần:

// Hàm s p x p theo giá tr xác su t gi m d n ắ ế ị ấ ả ầ

void Sort( float x[], int n)

{

float temp;

for ( int i = 0 ; i < n - 1 ; i ++ )

{

for ( int j = i + 1 ; j < n; j ++ )

{

if (x[i] < x[j]){

Trang 6

// Hoan vi 2 so a[i] va a[j]

temp = x[i];

x[i] = x[j];

x[j] = temp;

}

}

}

}

Tiếp theo, thay xác suất p(xi)=Pi , với P = :i

// Hàm tính xác su t c ng d n ấ ộ ồ

void Xacsuat ( float x[], float p[], int n)

{

p[ ] 0 = ;

for ( int i = ; i <n; i ++ )

{

p[i] =p[i - 1 +x[i - ];

}

}

 Khối mã hóa

void Binary ( float l[], float l1[], float p[], float p1[], string str[],

int n)

{

for ( int i = ; i <n; i ++ )

{

p1[i] =p[i];

l1[i] =l[i];

while (l1[i] > )

{

if (p1[i] * >= 1

{

str[i] += " " 1 ;

p1[i] =p1[i] * - ;

}

else

{

p1[i] =p1[i] * ;

str[i] += " " 0 ;

}

l1[i] ;

}

}

}

Trong khối này, ta sẽ sử dụng mảng chuỗi str[] để lưu trữ giá trị sau khi mã hóa xác suất P , l[] và l1[] là 2 mảng để truyền vào độ dài từi

mã l còn 2 mảng p[] và p1[] là xác suất sau khi cộng dồn của cáci

Trang 7

từ mã đó Chúng ta mã hóa bằng cách chuyển P từ cơ số 10 sangi

dạng nhị phân theo quy tắc lấy xác suất p1[i] x 2, nếu p1[i]x2 mà nhỏ hơn 1 thì bit đó bằng 0 Nếu p1[i]x2 ≥1 thì bit đó gán giá trị là

1 sau đó gán p1[i]= p1[i]x2-1 Tiếp tục thực hiện như trên cho đến khi chuỗi có độ dài bằng với l1[i] thì dừng lại, chuỗi thu được chính là từ mã cần mã hóa

 Khối tính chiều dài trung bình

// Hàm tính chi u dài trung bình ề

float AverageLength( float x[], float l[], int n)

{

float sum1 = ;

for ( int i = ; i <n; i ++ )

{

sum1 +=x[i] *l[i];

}

return sum1;

}

 Khối tính entropy

// Hàm tính entropy

float Entropy( float x[], int n)

{

float sum = ;

for ( int i = ; i <n; i ++ )

{

sum +=-x[i] * log(x[i]) / log( );

}

return sum;

}

c Kết quả: Như vậy với phương pháp mã hóa theo Shannon, đoạn tin nhắn “aaaabbbbcccc” nêu ra trong phần I sẽ chỉ cần 24 bit (so với 96 bit khi mã hóa bằng Ascii) để mã hóa

2.2 Mã hóa theo Huffman

a Thuật toán theo sơ đồ cây

 Bước 1: Sắp xếp các nguồn tin theo thứ tự xác suất tăng dần hoặc giảm dần

Trang 8

 Bước 2: Chọn hai tin có xác suất nhỏ nhất, gán 1 tin cho bit 0, tin còn lại cho bit 1

 Bước 3: Cộng xác suất của 2 tin đó lại ta thu được tin mới và xác suất mới

 Bước 4: Nếu chỉ còn lại 1 tin thì dừng lại, nếu không quay lại bước 2

 Bước 5: Đọc từ mã từ dưới lên

b Code

Các khối trong code bao gồm:

 Khối nhập thông tin đầu vào: 2 phương thức nhập

+ Nhập dữ liệu đầu vào

int n;

cout<< " So ky tu: " check_Number(n);

char s[ 100 ];

cout << " Nhap Ky tu: " <<endl ;

for ( int i = ;i < n;i ++ )

{

cin>>s[i];

if (check_character(s,i) == false ){

system( cls " );

cout<< " Da co ky tu trung! " <<endl;

cout<< " Ban da nhap: "

for ( int k = ;k < i;k ++ )

{

cout<<s[k];

}

cout<< " \n Moi Nhap tiep: " <<endl;

i ;

}

};

cout<< " Da nhap xong ky tu! " <<endl;

+ Nhập theo xác suất

label:

float xs[ 100 ],sum = ;

cout << " Nhap Xac Suat: " <<endl ;

Trang 9

for ( int i = ;i < n;i ++ )

{

check_Float(xs[i]);

sum = sum xs[i]; +

}

if (sum != ){

cout<< " Ban nhap sai xac suat! " <<endl;

goto label;

}

XS insert end ( (XS), begin (xs), begin (xs) + n);

cout<< " Da nhap xong xac suat! " <<endl;

+ Nhập theo tần số

cout << " Nhap tan so: " <<endl ;

// sum: tong cac ky tu

float xs[ 100 ],sum;

for ( int i = ;i < n;i ++ )

{

check_Number(Tanso[i]);

sum sum Tanso[i] = + * 1.0 ;

}

for ( int i = ;i < n;i ++ )

{

xs[i] = float ((Tanso[i] * 1.0 ) (sum * 1.0 ));

}

XS insert end ( (XS), begin (xs), begin (xs) n); +

 Khối kiểm tra điều kiện: Dữ liệu nhập vào có thỏa mãn hay không

void check_Number( int n)

{

int check = scanf( " %d " , &n);

//Nhap lai neu la chu hoac so < 1

while (check != 1 || n< )

{

if (check != ){

cout<< " Khong phai so! " <<endl;

} else {

cout<< " So nhap phai >= 1 " <<endl;

}

fflush(stdin);

cout<< " Nhap lai: "

check = scanf ( " %d " &n);

}

};

Trang 10

Khối này kiểm tra nhằm đảm bảo số nguồn đầu vào phải là số nguyên dương

void check_Float ( float& n)

{

int check = scanf( " %f " , &n);

while (check != )

{

cout<< " Nhap sai! " <<endl;

fflush(stdin);

cout<< " Nhap lai: "

check = scanf ( " %f " &n);

}

};

Khối này đảm bảo xác suất nhập vào phải là số thực

bool check_character( char s[], int n)

{

for ( int i = ;i <n;i ++ )

{

for ( int j = + i 1 ;j < +n 1 ;j ++ )

{

if (s[i] ==s[j])

{

fflush(stdin);

return false ;

}

}

}

return true ;

}

Khối này đảm bảo sao cho các nguồn nhập vào không bị trùng

 Khối tạo cây

void Tao_Cay ( vector < char > KyTu, vector < float > XSuat, vector <Li> L,

size_t size)

{

Node* left;

Node* right;

//

priority_queue <Node* , vector <Node*> , compare minHeap;

//

for (size_t i = 0 ; i < size; ++ i)

Trang 11

{

minHeap.push(new Node(KyTu[ ], i XSuat[ ])); i

}

//

while (minHeap.size() != )

{

left = minHeap.top();

minHeap.pop();

right = minHeap.top();

minHeap.pop();

top = new Node( ' ' $ , left -> XacSuat right + -> XacSuat);

top -> left left; =

top -> right right; =

minHeap.push(top);

};

print_Code(minHeap.top(), "" ,L);

}

Cây nhị phân được tạo ra dựa trên hàng đợi ưu tiên

priority_queue với thứ tự ưu tiên được thể hiện trong struct compare:

struct compare

{

bool operator() (Node* l, Node* r)

{

return (l-> XacSuat > r-> XacSuat);

}

};

Theo quy tắc trên, ta sẽ tạo ra được một cây Huffman hoàn chỉnh và với mỗi node được tạo ra bằng cách cộng xác suất của

2 node có xác suất nhỏ nhất, ta sẽ gán cho node đó một ký hiệu

để thuận tiện cho việc đọc ($)

 Khối mã hóa

void In_Ma (Node* root, string str, vector <Li> &L)

{

if (root == NULL)

return ;

if (root-> KyTu == ' ' $ )

Trang 12

{

In_Ma(root-> left, str + " " 0 ,L);

In_Ma(root-> right, str + " " 1 ,L);

}

if (root-> KyTu != ' ' $ )

{

char s = root-> KyTu;

Li new_Li(s,str);

L.push_back(new_Li);

In_Ma(root-> left, str + " " 0 ,L);

In_Ma(root-> right, str + " " 1 ,L);

}

};

Khối này thực chất là khối đọc thông tin từ cây Huffman đã được tạo trước đó theo quy tắc, xét từ nút có giá trị xác suất bằng 1 từ cây Huffman, đi về phía tay trái thì chuỗi cộng thêm

0, đi về phía tay phải thì chuỗi cộng thêm 1 Từ đó ta sẽ thu được thông tin sau khi mã hóa của các nguồn đầu vào

 Khối tính chiều dài trung bình và entropy

for ( int i = ;i < KyTu.size();i ++ )

{

H += ( float ) - XacSuat[ ] i * log(XacSuat[ ] / log( );

Ltb += ( float ) XacSuat[ ] i * L i [ ].L.length();

}

c Kết quả: Như vậy với phương pháp mã hóa theo Huffman, đoạn tin nhắn “aaaabbbbcccc” nêu ra trong phần I sẽ chỉ cần 20 bit (so với 96 bit khi mã hóa bằng Ascii) để mã hóa

III LỜI KẾT

Qua bài tập lớn Lý Thuyết Thông Tin này, chúng em đã hiểu và nắm rõ hơn kiến thức về 2 phương pháp mã hóa Shannon và Huffman cũng như củng cố và nhớ lại các kiến thức về ngôn ngữ lập trình C++ Lời cuối cùng, chúng xem xin chân thành cảm ơn thầy Nguyễn Hữu Phát đã giảng dạy và giúp đỡ chúng em nhiệt tình trong quá trình học tập Chúng em xin kính chúc thầy luôn mạnh khỏe và công tác tốt

Ngày đăng: 25/04/2022, 14:02

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w