discr_rgz_1
.pdfМинистерство Образования и Науки РФ Новосибирский Государственный Технический Университет
Кафедра ПМт
Расчётно-графическая работа по дисциплине
«Дискретная математика и математическая логика»
Факультет: |
ПМИ |
Группа: |
ПМИ-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