Автор работы: Пользователь скрыл имя, 12 Февраля 2012 в 21:42, контрольная работа
Дан неориентированный взвешенный граф G (V,E). Веса всех рёбер неотрицательны. Указана некоторая стартовая вершина a и конечная вершина u. Требуется написать программу, которая находит кратчайшее расстояние и выводит кратчайший путь от вершины a до вершины u.
1 Постановка задачи 3
2 Анализ задачи, выбор способа представления данных 4
3 Алгоритмы решения задачи 5
4 Реализация программы 6
4.1 Именованные константы 6
4.2 Функции 6
5 Руководство пользователя 8
Список использованных источников. 8
Содержание
Дан
неориентированный взвешенный граф
G (V,E). Веса всех рёбер неотрицательны.
Указана некоторая стартовая вершина
a и конечная вершина u. Требуется
написать программу, которая находит кратчайшее
расстояние и выводит кратчайший путь
от вершины a
до вершины u.
В результате анализа условия задачи было решено представить граф G (V,E) с помощью матрицы B размером , которая состоит из элементов таких что:
В
программе матрицу B будем хранить в
двумерном динамическом массиве размером
.
Введем следующие обозначения:
Приведем
описание алгоритма решения поставленной
задачи (см. алгоритм 1):
Алгоритм 1 – Алгоритм Дейкстры
Присвоим
Для всех и отличных от
Присвоим
Пока
Пусть - вершина с минимальным
Для всех таких что
если то
измен
измен
Для хранения чисел будем использовать массив чисел, а для хранения принадлежности элемента множеству - массив булевых переменных.
В
начале алгоритма расстояние для
начальной вершины полагается равным
нулю, а все остальные расстояния
заполняются большим
На каждом шаге цикла мы ищем вершину с минимальным расстоянием и флагом равным нулю. Затем мы устанавливаем в ней флаг 1 и проверяем все соседние с ней вершины. Если до соседней вершины расстояние больше, чем сумма расстояния до текущей вершины и длины ребра, то уменьшаем его. Цикл завершается, когда флаги всех вершин становятся равны 1, либо когда у всех вершин с флагом 0 . Последний случай возможен, если и только если граф G несвязан.
Программа,
решающая поставленную задачу, была реализована
в среде разработки Visual Studio 2005 на
языке программирования С++.
4.1
Именованные константы
Разработанная
программа включает именованные константы,
перечисленные в таблице 1:
Таблица 1 – Именованные константы
Определение константы | Назначение константы |
сonst int INF = 1000000 | Обозначает бесконечность |
4.2
Функции
Основные
функции, используемые в программе,
сведены в таблицу 2.
Таблица 2 – Основные функции
Объявление функции | Назначение функции |
void PrintShortestPathDistance (double* CurLenght, int Index); | Функция, осуществляющая печать кратчайшего расстояния, которое хранится в массиве CurLenght по индексу Index. |
void PrintShortestPath (int* AncestorsArray,int SourceVertex, int EventualVertex); | Функция, осуществляющая вывод кратчайшего пути на консоль из массива AncestorsArray. SourceVertex – стартовая вершина. EventualVertex – конечная вершина. |
void SearchShortestPath (double* CurLenght, double** AdjacencyMatrix, int* AncestorsArray, bool* Used, int AmountOfVertex); | Функция, осуществляющая поиск кратчайшего расстояния и кратчайшего пути на заданном графе. CurLenght – массив для хранения текущего расстояния до каждой вершины. AdjacencyMatrix – двумерный массив в котором хранится матрица, характеризующая данный граф. AncestorsArray – массив, в который для каждой вершины , кроме стартовой, сохраняется номер вершины, являющейся предпоследней в кратчайшем пути до . Used – булевский массив для хранения посещенных вершин. AmountOfVertex – количество вершин. По окончании работы функции в массиве CurLenght содержится кратчайшее расстояния, а в массиве AncestorsArray – кратчайший путь. |
int main () | Главная функция программы. Осуществляет ввод исходных данных. |
Программа вводит входные данные из текстового файла input.txt. В первую строку входного файла необходимо ввести количество вершин в графе. Во вторую строку вводится (через пробел) начальная вершина и конечная. Далее вводится матрица, характеризующая граф (все элементы матрицы разделяются пробелом).
После запуска программы на экране компьютера отобразится консольное окно с результатом.
Приложение
А – Текст программы
// Подключаем заголовочный файл для работы со стандартными потоками cin и cout
#include "iostream"
// Подключаем
заголовчный файл для работы
с потоковыми файловыми
#include "fstream"
using namespace std;
const int INF = 1000000;
void PrintShortestPathDistance (double* CurLenght, int Index)// Функция осуществляет вывод кратчайшего расстояния
{
cout << "Shortest path distance : " << endl;
cout << CurLenght [Index] << endl;
}
void PrintShortestPath (int* AncestorsArray,int SourceVertex,int EventualVertex) // Функция осуществляет вывод кратчайшего пути
{
cout << EventualVertex << " <-- ";
for (int i = EventualVertex - 1; AncestorsArray[i] != SourceVertex; i = AncestorsArray[i - 1])
cout << AncestorsArray[i] << " <-- ";
cout << SourceVertex << endl;
}
void SearchShortestPath (double* CurLenght,double** AdjacencyMatrix,int* AncestorsArray,bool* Used,int AmountOfVertex)// Функция поиска кратчайшего расстояния и пути
{
for (int i = 0; i < AmountOfVertex; i++)
{
// Поиск вершины
до которой расстояние
int MinIndex = AmountOfVertex;
for (int j = 0; j < AmountOfVertex; j++)
{
if (CurLenght [j] <= CurLenght [MinIndex] && !Used [j])
}
// Если минимальной выбрана вершина расстояние до которой равно бесконечности то выходим из цикла
if (CurLenght [MinIndex] == INF)
break;
// Обозначаем текущую вершину как посещенную
Used [MinIndex] = true;
// Релаксация
for (int j = 0; j < AmountOfVertex; j++)
{
if (AdjacencyMatrix [MinIndex][j]!= 0 && !Used [j] && (CurLenght[MinIndex] + AdjacencyMatrix [MinIndex][j] < CurLenght [j]))
{
// Улучшаем расстояние до выбранной вершины
CurLe
// Сохраняем предыдущую вершину для выбранной
Ances
}
}
}
}
int main ()
{
ifstream f ("input.txt");
int
AmountOfVertex,SourceVertex,
// Вводим количество вершин
f >> AmountOfVertex;
// Вводим начальную и конечную вершину
f >> SourceVertex >> EventualVertex;
//Массив для хранения текущей длины до каждой вершины
double* CurLenght = new double [AmountOfVertex + 1];
//
Устанавливаем расстояние до
каждой вершины равное
for (int i = 0; i < AmountOfVertex + 1; i++)
CurLenght [i] = INF;
//
Расстояние до начальной
CurLenght [SourceVertex - 1] = 0;
// Матрица смежности
double** AdjacencyMatrix = new double* [AmountOfVertex];
for (int i = 0; i < AmountOfVertex; i++)
AdjacencyMatrix [i] = new double [AmountOfVertex];
// Считываем матрицу смежности
for (int i = 0; i < AmountOfVertex; i++)
for (int j = 0; j < AmountOfVertex; j++)
f >> AdjacencyMatrix [i][j];
// Булевый массив для хранения посещенных вершин
bool* Used = new bool [AmountOfVertex];
// На данном этапе все вершины являются непосещенными
for (int i = 0; i < AmountOfVertex; i++)
Used [i] = false;
// Массив предков
int* AncestorsArray = new int [AmountOfVertex];
//
Полагаем что предыдущей
AncestorsArray[
//
Вызываем функцию поиска
SearchShortestPath
(CurLenght,AdjacencyMatrix,
// Выводим кратчайшее расстояние
PrintShortestPathDistan
// Выводим кратчайший путь, если вершина не изолированна, в противном случае сообщаем об этом
if (AncestorsArray[EventualVertex - 1] >= 0)
{
cout << "Shortest path : " << endl;
PrintShortestPath (AncestorsArray,SourceVertex,
}
else cout << "Vertex isolated" << endl;
// Освобождаем память
delete[] CurLenght;
for (int i = 0; i < AmountOfVertex; i++)
delete[] AdjacencyMatrix [i];
delete[] AdjacencyMatrix;
delete[] Used;
delete[] AncestorsArray;
return 0;
}