Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
курсач дискретка.docx
Скачиваний:
2
Добавлен:
01.04.2025
Размер:
170.39 Кб
Скачать

Алгоритм Дейкстры

//Алгоритм Дейкстры

#include <iostream>

#include <string>

using std::cin;

using std::cout;

using std::string;

//Количество вершин

int n;

//Матрица стоимостей

//Расстояние между вершинами - положительное число

//Отсутствие ребра между вершинами - 0

int **C;

//Число, превышающее максимальный элемент матрицы(аналог бесконечности)

int max;

//Вычисление max

void SetMax()

{

max=0;

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

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

max=max+C[i][j];

max=max+1;

}

//Проверка на наличие числа num в массиве

bool in_arr(int num, int *arr)

{

bool result=false;

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

if (arr[i]==num)

result=true;

return result;

}

//Перевод числа в строку

string inttostr(int num)

{

char buf[10];

itoa(num, buf, 10);

return string(buf);

}

int main()

{

cout << "Number of vertexes:" << "\n";

cin >> n;

//Номер вершины-источника

int a;

cout << "Main vertex: " << "\n";

cin >> a;

a--;

cout << "Vertexes: " << "\n";

//Ввод матрицы стоимостей

C = new int*[n];

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

C[i] = new int[n];

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

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

cin >> C[i][j];

cout << "\n";

SetMax();

//Вершины, помеченные, как посещенные

int *S=new int[n-1];

//Кратчайшие расстояния к вершинам из вершины-источника

int *D=new int[n];

//Последние промежуточные вершины на маршруте

int *P=new int[n];

//Вспомогательные переменные

int w,min;

//Инициализация S(Ни одна вершина еще не посещена)

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

{

S[k]=-1;

}

S[0]=a;

//Инициализация P и D

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

{

if (C[a][i]==0)

D[i]=max;

else

D[i]=C[a][i];

P[i]=a;

}

//Алгоритм Дейкстры

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

{

min=max;

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

{

//Если расстояние до k меньше текущего минимального и при этом

//k еще не посещена и не является вершиной-источником, то установить

//новый минимум

if (D[k]<min && !in_arr(k,S) && k!=a)

{

w=k;

min=D[k];

}

}

if (min==max) break;

//Вершина i посещена

S[i]=w;

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

{

//Если вершина j не посещена и путь от нее до текущей вершины w существует

//и расстояние от a до j >= сумме расстояний от a до w и от w до j,

//то установить новое расстояние от a до j

if (!in_arr(j,S) && C[w][j]!=0 && (D[w]+C[w][j])<=D[j])

{

P[j]=w;

D[j]=D[w]+C[w][j];

}

}

}

//Вывод результатов

int t;

string str;

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

{

if (i!=a && C[P[i]][i]!=0)

{

str=inttostr(i+1);

t=P[i];

do

{

if (str!=inttostr(i+1))

t=P[t];

str=str+">-"+inttostr(t+1);

}

while (t!=a);

str = string(str.rbegin(),str.rend());

cout << str << " = " << inttostr(D[i]) <<"\n";

}

}

delete[] S;

delete[] P;

delete[] D;

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

delete[] C[i];

delete[] C;

}

Генерация кода Фано

#include <iostream>

#include <string>

using std::cin;

using std::cout;

using std::string;

//Массив символов

char* A;

//Массив частот

double* F;

//Размер массивов

int size;

//Функция для поиска кода для каждой буквы

//ch - '0' или '1', последний добавленный бит

//full - полный текущий код буквы(строка из нулей и единиц)

//start, end - интервал

void Next(char ch, string full, int start, int end)

{

//Половина суммы всех частот и сумма частот, не превышающая hS

double hS,S;

//Счетчик

int m;

//Строка для записи кода числа

string str;

str=full+ch;

//Если размер интервала равен 1, то код сгенерирован, вывести его

if(start==end)

{

cout << A[start] << " = " << str << " ";

return;

}

//Нахождение половины суммы всех частот

hS=0;

for(int i=start;i<=end;i++)

hS=hS+F[i];

hS=hS/2;

//Поиск позиции, примерно делящей алфавит на две части

S=0;

int i=start;

m=i;

while((S+F[i]<hS) && (i<end))

{

S=S+F[i];

i++;

m++;

}

//Генерация следующей части кода для первой части массива

Next('1', str, start, m);

//Генерация следующей части кода для второй части массива

Next('0', str, m+1, end);

}

//Сортировка массивов

//(алгоритм требует наличия невозрастающей последовательности частот)

void Sort()

{

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

{

int k=i;

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

if (F[j]>F[k])

k=j;

if (i!=k)

{

char t = A[i];

A[i]=A[k];

A[k]=t;

double temp = F[i];

F[i]=F[k];

F[k]=temp;

}

}

}

int main()

{

//Создание массивов

cout << "Size: ";

cin >> size;

if(size<=0)

return 0;

A = new char[size];

F = new double[size];

//Ввод букв

cout << "Input letters:";

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

{

cin>>A[i];

}

//Ввод частот

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

{

cout << "Frequency for " << A[i] << ": ";

cin >> F[i];

}

//Сортировка

Sort();

//Начало генерации кода

Next(' ',"", 0, size-1);

return 0;

}