Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

discr_rgz_1

.pdf
Скачиваний:
6
Добавлен:
27.03.2015
Размер:
109.77 Кб
Скачать

Министерство Образования и Науки РФ Новосибирский Государственный Технический Университет

Кафедра ПМт

Расчётно-графическая работа по дисциплине

«Дискретная математика и математическая логика»

Факультет:

ПМИ

Группа:

ПМИ-22

Студент:

Суслов А. В.

Преподаватели:

Ступаков И. М.

 

Рояк М. Э.

Вариант:

13

Новосибирск

2013

1. Условие

Дана порождающая матрица и вектор, длина которого кратна длине сообщения. Выдать вектор декодированных сообщений с исправлением ошибок. Для неисправимых ошибок выдать сообщения

2.Анализ

2.1Дано:

2.2Результат:

2.3Основные отношения между входными и выходными данными задачи:

2

3. Структуры данных, используемые для представления исходных данных и результатов задачи

3.1 Внутреннее представление:

struct born { bool **A; int k, n;

};

struct table

{

int **A; int m, n; };

typedef bool* vect;

3.2 Внешнее представление:

Входные данные содержатся в файле input.txt. Первая строка содержит два целочисленных значения, разделённых пробелом – число строк k и число столбцов n в порождающей матрице. Следующие k строк содержат по n символов – ‘0’ или ‘1’, являющихся элементами порождающей матрицы. Последняя строка содержит вектор закодированных сообщений - сколько угодно длинную, но кратную n последовательность символов ‘0’ и ‘1’.

Выходные данные выводятся на экран с помощью стандартного ввода/вывода и представляют собой вектор декодированных и исправленных сообщений, а также список сообщений об ошибках декодирования тех сообщений, которые не удалось исправить.

4. Укрупнённый алгоритм решения задачи

int sy = bornToVect(Gt, v); // получаем синдром умножением матрицы контроля чётности на вектор

if(sy != 0) { // если синдром не равен 0

int k = 0;

for(int i = 1; i < T->m; i++)

if(T->A[i][(T->n - 1)] == sy) k = i; // ищем лидера смежного класса

if(k != 0 && wt(T->A[k][0]) == 1) c ^= T->A[k][0]; // и если произошла единственная ошибка, исправляем её

}

r = decode(int2vect(c, Gt->n), len); // декодируем сообщение как обычно

3

5. Текст кода программы

bvect.h:

/*

* bvect v0.1 by Str1ker */

#ifndef bvect_h

#define bvect_h

struct born

{

bool **A; int k, n;

};

struct table

{

int **A; int m, n;

};

typedef bool* vect;

long filesize(FILE *f); // gets the filesize of an open file void destructDA(born *M); // cleans up dynamic memory

int vect2int(vect v, int n); // converts internal vect type to integer char *vect2char(vect v, int n); // converts internal vect type to string vect int2vect(int v, int n); // converts integer to internal vect type bool vectToVect(vect a, vect b, int n); // multiples two binary vectors int bornToVect(born *G, vect v); // multiples born matrix to vector

bool isBorn(born *G); // checks whether matrix is born or not

int wt(int v); // returns a 'weight' - count of '1' binary chars in a integer born *makeGt(born *G); // makes a matrix of even control from the born matrix table *buildTable(born *G, born *Gt); // makes a table. Syndroms included! vect decode(vect v, int n); // decodes message WITHOUT error checking

vect decodeCaring(born *Gt, table *T, vect v); // decodes message using table

#endif

4

bvect.cpp:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include "bvect.h"

long filesize(FILE *f)

{

long cur = ftell(f); fseek(f, 0, SEEK_END); long r = ftell(f); fseek(f, cur, SEEK_SET); return r;

}

void destructDA(born *M)

{

for(int i = 0; i < M->k; i++) delete M->A[i];

delete M->A; delete M;

M = NULL;

}

int vect2int(vect v, int n)

{

int r = 0;

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

{

r += (v[n - i - 1] ? b : 0); b *= 2;

}

return r;

}

char *vect2char(vect v, int n)

{

char *s = new char[n + 1]; for(int i = 0; i < n; i++)

s[i] = (int)v[i] + '0';

s[n] = '\0';

return s;

}

vect int2vect(int v, int n)

{

vect r = new bool[n];

char *s = new char[n + 1]; itoa(v, s, 2);

int l = strlen(s); if(l > n) return NULL;

for(int i = 0; i < l; i++)

r[i + n - l] = (s[i] == '1');

for(int i = 0; i < n - l; i++) r[i] = 0;

delete s; return r;

}

bool vectToVect(vect a, vect b, int n)

{

bool s = 0, r = 0;

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

r ^= (bool)(a[i] * b[i]);

return r;

}

5

int bornToVect(born *G, vect v)

{

int b = 1; int w = 0;

for(int i = G->k - 1; i >= 0; i--)

{

int r = (vectToVect(G->A[i], v, G->n)) ? b : 0; w += r;

b *= 2;

}

fprintf(stderr, "BORN * %s = %d\n", vect2char(v, G->n), w); return w;

}

bool isBorn(born *G)

{

for(int i = 0; i < G->k; i++) // checking for A(i) for(int j = 0; j < G->k; j++)

if((i == j) != G->A[i][j]) return false;

return true;

}

born *makeGt(born *G)

{

born *Gt = new born; // matrix for even control Gt->k = G->n - G->k;

Gt->n = G->n;

Gt->A = new bool *[Gt->k];

for(int i = 0; i < Gt->k; i++)

{

Gt->A[i] = new bool[Gt->n];

for(int j = 0; j < Gt->n; j++)

{

if(j < G->k)

Gt->A[i][j] = G->A[j][i + G->k];

else

if(i + G->k == j) Gt->A[i][j] = 1;

else

Gt->A[i][j] = 0;

}

}

return Gt;

}

vect decode(vect v, int n)

{

vect s = new bool[n]; for(int i = 0; i < n; i++)

s[i] = v[i];

return s;

}

int wt(int v)

{

char *s = new char[33]; // int - 2^32 + sign itoa(v, s, 2);

int r = 0;

for(int i = 0; i < strlen(s); i++)

{

if(s[i] == '1') r++;

}

delete s; return r;

}

table *buildTable(born *G, born *Gt)

{

6

//this value (2^k) is useful to build C and make a table int m = 1;

for(int i = 0; i < G->k; i++) m *= 2;

//this value (2^n) is useful to make a table

int q = 1;

for(int i = 0; i < G->n; i++) q *= 2;

//this value (2^n-k) means leaders count int bn = 1;

for(int i = 0; i < (G->n - G->k); i++) bn *= 2;

//building S and C

int *S = new int[G->k]; for(int i = 0; i < G->k; i++)

{

S[i] = vect2int(G->A[i], G->n);

}

int *C = new int[m];

for(int k = 0; k < m; k++)

{

int a = k; C[k] = 0;

for(int i = 0; i < G->k; i++)

{

if(a % 2 == 1)

C[k] ^= S[i];

a /= 2;

}

fprintf(stderr, "#%d - %s(%d)\n", k, vect2char(int2vect(C[k], G->n), G->n),

C[k]);

}

// making table

table *T = new table; T->m = bn; // rows T->n = m + 1; // cols

// filling table with zero values, T->A[i][m] means column with syndrom T->A = new int* [bn];

for(int i = 0; i < bn; i++)

{

T->A[i] = new int[m + 1]; for(int j = 0; j <= m; j++)

T->A[i][j] = 0;

}

// list of available values bool *Tb = new bool[q]; for(int i = 0; i < q; i++)

Tb[i] = 1;

for(int j = 0; j < m; j++) // setting C as the first row

{

T->A[0][j] = C[j]; Tb[C[j]] = 0;

}

for(int i = 1; i < bn; i++) // getting all next leaders

{

int cl = q - 1, cw = G->n; // max weight for(int k = q - 1; k >= 0; k--)

{

if(Tb[k] && wt(k) < cw) // if good free value found

{

cl = k;

cw = wt(k);

}

}

7

T->A[i][0] = cl;

Tb[cl] = 0;

for(int j = 1; j < m; j++)

{

T->A[i][j] = C[j] ^ T->A[i][0]; Tb[T->A[i][j]] = 0;

}

}

delete Tb, S, C;

for(int i = 0; i < bn; i++) // syndroms

T->A[i][m] = bornToVect(Gt, int2vect(T->A[i][0], Gt->n));

for(int i = 0; i < bn; i++)

{

for(int j = 0; j <= m; j++) fprintf(stderr, "%2d ", T->A[i][j]);

fprintf(stderr, "\n");

}

return T;

}

vect decodeCaring(born *Gt, table *T, vect v) // decoded and fixed, NULL if can't fix

{

int len = Gt->n - Gt->k; bool *r = new bool[len]; int c = vect2int(v, Gt->n);

// checking for errors

int sy = bornToVect(Gt, v); if(sy != 0)

{

int k = 0;

for(int i = 1; i < T->m; i++) if(T->A[i][(T->n - 1)] == sy) k = i;

if(k != 0) // mistake found

{

fprintf(stderr, "Mistake found in code %s [syndrom: %d, leader: %s]\n", vect2char(v, Gt->n), sy, vect2char(int2vect(T->A[k][0], Gt->n), Gt->n));

if(wt(T->A[k][0]) == 1) // if only 1 bit is corrupted

{

c ^= T->A[k][0]; // adding leader to vector

fprintf(stderr, "> Fixed to: %s\n", vect2char(int2vect(c, Gt-

>n), Gt->n));

}

else

{

delete r; return NULL;

}

}

}

r = decode(int2vect(c, Gt->n), len); return r;

}

8

main0.cpp:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include "bvect.h"

void input(char *path, born *G, vect &s, int &len)

{

FILE *f = fopen(path, "rb");

fscanf(f, "%d %d\n", &(G->k), &(G->n));

if(G->A != NULL) destructDA(G);

G->A = new bool *[G->k]; for(int i = 0; i < G->k; i++)

{

G->A[i] = new bool[G->n]; for(int j = 0; j < G->n; j++)

G->A[i][j] = (fgetc(f) == '1' ? 1 : 0);

fscanf(f, "\n");

}

len = filesize(f) - ftell(f); s = new bool[len];

for(int i = 0; i < len; i++) s[i] = (fgetc(f) == '1');

fclose(f);

}

void show(born *G, FILE *f = stdout)

{

for(int i = 0; i < G->k; i++)

{

for(int j = 0; j < G->n; j++) fprintf(f, "%d", G->A[i][j]);

fprintf(f, "\n");

}

}

int main()

{

born *G = new born; // born matrix G->A = NULL; //

int len = 0; // length of vector vect v = NULL; // long long vector

vect d = NULL; // decoded and fixed vector vect s = NULL; // decoded message

FILE *f = freopen("debug.txt", "w", stderr); // debug info goes there

input("input.txt", G, v, len); show(G, f);

if(!isBorn(G))

{

printf("Matrix is NOT born\n"); system("pause");

exit(2);

}

if(len % G->n) len -= len % G->n; d = new bool[len];

fprintf(stderr, "Vector[%d]: %s\n", len, vect2char(v, len));

int ms = len / G->n;

born *Gt = makeGt(G); show(Gt, f);

table *T = buildTable(G, Gt);

for(int i = 0; i < ms; i++)

9

{

s = decodeCaring(Gt, T, v + sizeof(bool) * i * G->n); if(s != NULL)

{

for(int j = 0; j < G->k; j++) printf("%d", s[j]);

delete s;

}

else

printf("Incorrigible error in code %s\n", vect2char(v + sizeof(bool)

* i * G->n, G->n));

printf("\n");

}

fclose(f);

system("pause"); return 0;

}

10

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]