
Министерство науки и высшего образования Российской Федерации
Федеральное государственное бюджетное образовательное учреждение высшего образования
ТОМСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ СИСТЕМ УПРАВЛЕНИЯ И РАДИОЭЛЕКТРОНИКИ (ТУСУР)
Кафедра безопасности информационных систем (БИС)
Графы
Отчет по практической работе №6
по дисциплине «Структуры данных»
Студент гр. 733-1
_______ Сметанников Д.Е
_______
Принял:
преподаватель КИБЭВС
_______ Д.Р. Уразаев
_______
Задание
Реализовать возможность работы с графом N узлов, M ребер. Выберете самостоятельно структуру. Обеспечьте следующие интерфейсные методы:
ввод графа (можно случайным образом,можно вводить с клавиатуры) НЕДОПУСТИМО работать только с конечным числом ребер и узлов. Приложение должно позволять вводить разные графы.
вывод графа - матрица смежности или весов
Вариант 7. Задана система дорог. Найти такой город, для которого сумма кратчайших расстояний до остальных городов максимальна.
Содержание
Задание 2
1 Введение 4
2 Ход работы 5
Заключение 9
Приложение А 10
Введение
Целью работы является реализация программы для работы с графами, представляющими систему дорог с переменным числом узлов и рёбер. Программа позволяет вводить графы случайным образом или с клавиатуры и выводить матрицу смежности или весов. Основное внимание уделяется нахождению города с максимальной суммой кратчайших расстояний до остальных городов.
Ход работы
В работе реализуется ориентированный граф и матрица смежности.
Ориентированный граф — В ориентированном графе рёбра имеют направление, что означает, что если есть ребро от узла A к узлу B, то это не подразумевает наличие ребра от B к A.
Матрица
смежности
— это квадратная матрица, которая
используется для представления графа.
Если граф содержит N
узлов, матрица будет размером NxN.
G
raph
–
инициализирует
граф с заданным количеством городов,
проверяет, чтобы количество городов
было больше нуля, создает матрицу
смежности, устанавливая расстояние
между городами на 0 для одного и того же
города и на очень большое значение для
всех остальных пар.
(рис
.1)
Р
исунок
1 —
Graph
AddEdge
– добавляет ребро между двумя городами
с заданным весом, проверяет корректность
индексов и положительность веса,
устанавливает расстояние в матрице
смежности для ориентированного графа
(рис.
2)
Р
исунок
2 — AddEdge
PrintAdjMatrix — выводит матрицу смежности на экран (рис. 3)
Рисунок 3 — PrintAdjMatrix
FloydWarshall – реализует алгоритм Флойда-Уоршелла для нахождения кратчайших расстояний между всеми парами городов, создаёт новую матрицу расстояний, копируя данные из матрицы смежности и обновляя значения, если обнаруживаются более короткие пути через промежуточные города (рис. 4)
Р
исунок
4 — FloydWarshall
FindCityWithMaxTotalDistance — вычисляет город с максимальной суммой кратчайших расстояний до всех остальных, вызывает метод FloydWarshall для получения кратчайших расстояний, суммирует расстояния для каждого города и обновляет максимальные значения, если найден город с большей суммой (рис. 5)
Рисунок 5 — FindCityWithMaxTotalDistance
Заключение
В ходе работы была успешно реализована программа для анализа графов дорожной сети. Выполнены задачи по вводу, выводу и поиску города с максимальными кратчайшими расстояниями. Это может быть полезным для оптимизации транспортных маршрутов.
Приложение А
(обязательное)
class Graph
{
private int[,] adjMatrix;
private int numCities;
public Graph(int numCities)
{
if (numCities <= 0)
{
throw new ArgumentException("Количество городов должно быть больше нуля.");
}
this.numCities = numCities;
adjMatrix = new int[numCities, numCities];
for (int i = 0; i < numCities; i++) // делаем матрицу смежности
{
for (int j = 0; j < numCities; j++)
{
if (i == j)
adjMatrix[i, j] = 0;
else
adjMatrix[i, j] = int.MaxValue / 2; // берем половину максимального значения, чтобы избежать переполнения
}
}
}
public void AddEdge(int u, int v, int weight)
{
if (u >= numCities || v >= numCities || u < 0 || v < 0) // проверка индексов
{
throw new IndexOutOfRangeException("Ошибка! Указанный город не существует.");
}
if (weight <= 0) // проверка индексов
{
throw new ArgumentException("Расстояние между городами должно быть положительным числом.");
}
adjMatrix[u, v] = weight; // добавление ребра в матрицу для ориентированного графа
}
public void PrintAdjMatrix()
{
Console.WriteLine("Матрица смежности:");
for (int i = 0; i < numCities; i++)
{
for (int j = 0; j < numCities; j++)
{
if (adjMatrix[i, j] == int.MaxValue / 2)
Console.Write("!\t");
else
Console.Write(adjMatrix[i, j] + "\t");
}
Console.WriteLine();
}
}
public int[,] FloydWarshall()
{
int[,] dist = new int[numCities, numCities];
for (int i = 0; i < numCities; i++) // копируем данные из матрицы смежности в матрицу расстояний
{
for (int j = 0; j < numCities; j++)
{
dist[i, j] = adjMatrix[i, j];
}
}
for (int k = 0; k < numCities; k++) // применяем алгоритм Флойда-Уоршелла
{
for (int i = 0; i < numCities; i++)
{
for (int j = 0; j < numCities; j++)
{
if (dist[i, j] > dist[i, k] + dist[k, j])
{
dist[i, j] = dist[i, k] + dist[k, j];
}
}
}
}
return dist;
}
public int FindCityWithMaxTotalDistance()
{
int[,] dist = FloydWarshall();
int maxCity = -1;
int maxDistance = -1;
for (int i = 0; i < numCities; i++) // проходим по каждой строке матрицы расстояний
{
int sumDistance = 0;
for (int j = 0; j < numCities; j++) // суммируем расстояния до всех остольных городов
{
if (i != j && dist[i, j] != int.MaxValue / 2)
{
sumDistance += dist[i, j];
}
}
if (sumDistance > maxDistance) // обновляем значение города с большей суммой расстояний
{
maxDistance = sumDistance;
maxCity = i;
}
}
return maxCity;
}
}
class Program
{
static void Main(string[] args)
{
Console.Write("Сколько городов (узлов)? ");
int numCities = int.Parse(Console.ReadLine());
Console.Write("Сколько дорог (рёбер)? ");
int numRoads = int.Parse(Console.ReadLine());
Graph graph = new Graph(numCities);
for (int i = 1; i <= numRoads; i++)
{
bool running = true;
while (running)
{
try
{
Console.WriteLine($"Ввод для дороги {i}: введите начальный город, конечный город и расстояние в формате X,Y,Z");
string input = Console.ReadLine();
string[] parts = input.Split(',');
if (parts.Length != 3)
{
throw new FormatException("Неверный формат ввода. Используйте формат X,Y,Z.");
}
int u = int.Parse(parts[0]);
int v = int.Parse(parts[1]);
int weight = int.Parse(parts[2]);
graph.AddEdge(u, v, weight);
running = false;
}
catch (FormatException ex)
{
Console.WriteLine($"Ошибка формата: {ex.Message}. Повторите ввод.");
}
catch (ArgumentException ex)
{
Console.WriteLine($"Ошибка аргумента: {ex.Message}. Повторите ввод.");
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine($"Ошибка индекса: {ex.Message}. Повторите ввод.");
}
}
}
graph.PrintAdjMatrix();
int city = graph.FindCityWithMaxTotalDistance();
if (city != -1)
{
Console.WriteLine($"Город с максимальной суммой кратчайших расстояний до остальных городов: {city}");
}
else
{
Console.WriteLine("Не удалось найти такой город.");
}
}
}
Томск 2024