Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Практики(Вариант №1) / Практическая работа №6.odt
Скачиваний:
0
Добавлен:
23.02.2026
Размер:
357.8 Кб
Скачать

Министерство науки и высшего образования Российской Федерации Федеральное государственное автономное образовательное учреждение высшего образования

«ТОМСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ СИСТЕМ УПРАВЛЕНИЯ И РАДИОЭЛЕКТРОНИКИ» (ТУСУР)

Кафедра безопасности информационных систем (БИС)

ГРАФЫ Отчет по практической работе №6 по дисциплине «Структуры данных»

Студент гр.

________

__.__.2025

Принял

Преподаватель

кафедры КИБЭВС

________ Е.Е. Лунева

__.__.2025

Задание

Реализовать возможность работы с графом N узлов, M ребер. Выберете самостоятельно структуру. Обеспечьте следующие интерфейсные методы:

  • ввод графа (можно случайным образом,можно вводить с клавиатуры) НЕДОПУСТИМО работать только с конечным числом ребер и узлов. Приложение должно позволять вводить разные графы. 

  • вывод графа - матрица смежности или весов

    Вариант 1. Задана система дорог. Определить кратчайшие пути из одного города (задавать из какого) ко всем другим. Восстановить путь.

Оглавление

Задание 2

Введение 4

1 ХОД РАБОТЫ 5

Заключение 9

Приложение А 10

    Введение

Целью работы является реализация программы для работы с графами, представляющими систему дорог с переменным числом узлов и рёбер. Программа позволяет вводить графы случайным образом или с клавиатуры и выводить матрицу смежности или весов. Основное внимание уделяется нахождению города с максимальной суммой кратчайших расстояний до остальных городов.

    1 Ход работы

В работе реализуется ориентированный граф и матрица смежности.

Ориентированный граф — В ориентированном графе рёбра имеют направление, что означает, что если есть ребро от узла A к узлу B, то это не подразумевает наличие ребра от B к A.

Матрица смежности — это квадратная матрица, которая используется для представления графа. Если граф содержит N узлов, матрица будет размером NxN.

Graph – инициализирует граф с заданным количеством городов, проверяет, чтобы количество городов было больше нуля, создает матрицу смежности, устанавливая расстояние между городами на 0 для одного и того же города и на очень большое значение для всех остальных пар. (рис .1)

Рисунок 1 — Graph

AddEdge – добавляет двустороннюю дорогу между двумя городами с указанным расстоянием. (рис. 2)

Р исунок 2 — AddEdge

PrintAdjMatrix — выводит матрицу смежности на экран. (рис. 3)

Рисунок 3 — PrintAdjMatrix

ReconstructPath - Восстанавливает конкретный маршрут между двумя городами на основе результатов алгоритма Дейкстры. (рис. 4)

Р исунок 4 — ReconstructPath

PrintAllShortestPaths - Отображает все кратчайшие пути из заданного города с расстояниями и полными маршрутами. (рис. 5)

Р исунок 5 — PrintAllShortestPaths

Заключение

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

Приложение а

(обязательное)

Код программы

using System;

using System.Collections.Generic;

using System.Linq;

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;

adjMatrix[v, u] = weight;

}

// Автоматическая генерация графа

public void GenerateRandomGraph(int maxEdges, int maxWeight = 100)

{

Random rand = new Random();

int edgesAdded = 0;

// Гарантируем связность графа

for (int i = 1; i < numCities; i++)

{

int weight = rand.Next(1, maxWeight + 1);

AddEdge(i - 1, i, weight);

edgesAdded++;

}

// Добавляем случайные рёбра

while (edgesAdded < maxEdges && edgesAdded < numCities * (numCities - 1) / 2)

{

int u = rand.Next(0, numCities);

int v = rand.Next(0, numCities);

int weight = rand.Next(1, maxWeight + 1);

if (u != v && adjMatrix[u, v] == int.MaxValue / 2)

{

AddEdge(u, v, weight);

edgesAdded++;

}

}

}

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

public void PrintAdjMatrix()

{

Console.WriteLine("Матрица смежности:");

Console.Write(" ");

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

{

Console.Write($"{i}\t");

}

Console.WriteLine();

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

{

Console.Write($"{i}: ");

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

{

if (adjMatrix[i, j] == int.MaxValue / 2)

Console.Write("INF\t");

else

Console.Write(adjMatrix[i, j] + "\t");

}

Console.WriteLine();

}

}

// Алгоритм Дейкстры для поиска кратчайших путей из одного города ко всем другим

public (int[] distances, int[] predecessors) Dijkstra(int start)

{

if (start < 0 || start >= numCities)

throw new ArgumentException("Неверный начальный город");

int[] dist = new int[numCities];

int[] prev = new int[numCities];

bool[] visited = new bool[numCities];

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

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

{

dist[i] = int.MaxValue / 2;

prev[i] = -1;

}

dist[start] = 0;

// Основной цикл алгоритма Дейкстры

for (int count = 0; count < numCities - 1; count++)

{

// Находим вершину с минимальным расстоянием

int u = -1;

int minDist = int.MaxValue / 2;

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

{

if (!visited[i] && dist[i] < minDist)

{

minDist = dist[i];

u = i;

}

}

if (u == -1) break;

visited[u] = true;

// Обновляем расстояния до соседей

for (int v = 0; v < numCities; v++)

{

if (!visited[v] && adjMatrix[u, v] != int.MaxValue / 2 &&

dist[u] + adjMatrix[u, v] < dist[v])

{

dist[v] = dist[u] + adjMatrix[u, v];

prev[v] = u;

}

}

}

return (dist, prev);

}

// Восстановление пути от start до end

public List<int> ReconstructPath(int start, int end, int[] predecessors)

{

List<int> path = new List<int>();

if (predecessors[end] == -1 && start != end)

return path; // Путь не существует

int current = end;

while (current != -1)

{

path.Add(current);

current = predecessors[current];

}

path.Reverse();

// Проверяем, что путь действительно начинается с start

if (path.Count > 0 && path[0] == start)

return path;

else

return new List<int>();

}

// Вывод всех кратчайших путей из заданного города

public void PrintAllShortestPaths(int start)

{

var (distances, predecessors) = Dijkstra(start);

Console.WriteLine($"\nКратчайшие пути из города {start}:");

Console.WriteLine("Город | Расстояние | Путь");

Console.WriteLine("---------------------------");

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

{

if (i == start) continue;

if (distances[i] == int.MaxValue / 2)

{

Console.WriteLine($"{i} | Нет пути | -");

}

else

{

List<int> path = ReconstructPath(start, i, predecessors);

string pathStr = path.Count > 0 ? string.Join(" -> ", path) : "Нет пути";

Console.WriteLine($"{i} | {distances[i],-10} | {pathStr}");

}

}

}

}

class Program

{

static void Main(string[] args)

{

try

{

Console.WriteLine("=== ГЕНЕРАТОР СЛУЧАЙНЫХ ГРАФОВ ===");

// Ввод количества городов

Console.Write("Введите количество городов: ");

int numCities = int.Parse(Console.ReadLine());

Graph graph = new Graph(numCities);

Console.WriteLine("\nВыберите способ создания графа:");

Console.WriteLine("1 - Автоматическая генерация");

Console.WriteLine("2 - Ручной ввод");

Console.Write("Ваш выбор: ");

int choice = int.Parse(Console.ReadLine());

if (choice == 1)

{

// Автоматическая генерация

Console.Write("Введите максимальное количество дорог: ");

int maxEdges = int.Parse(Console.ReadLine());

Console.Write("Введите максимальную длину дороги (по умолчанию 100): ");

string maxWeightInput = Console.ReadLine();

int maxWeight = string.IsNullOrEmpty(maxWeightInput) ? 100 : int.Parse(maxWeightInput);

graph.GenerateRandomGraph(maxEdges, maxWeight);

Console.WriteLine("Граф успешно сгенерирован!");

}

else if (choice == 2)

{

// Ручной ввод

Console.Write("Сколько дорог добавить? ");

int numRoads = int.Parse(Console.ReadLine());

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;

Console.WriteLine($"Дорога {u}-{v} длиной {weight} добавлена.");

}

catch (Exception ex)

{

Console.WriteLine($"Ошибка: {ex.Message}. Повторите ввод.");

}

}

}

}

else

{

Console.WriteLine("Неверный выбор.");

return;

}

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

Console.WriteLine("\n" + new string('=', 50));

graph.PrintAdjMatrix();

// Поиск кратчайших путей

Console.WriteLine("\n" + new string('=', 50));

Console.Write("Введите начальный город для поиска кратчайших путей: ");

int startCity = int.Parse(Console.ReadLine());

graph.PrintAllShortestPaths(startCity);

}

catch (Exception ex)

{

Console.WriteLine($"Произошла ошибка: {ex.Message}");

}

Console.WriteLine("\nНажмите любую клавишу для выхода...");

Console.ReadKey();

}

}

Томск 2025

Соседние файлы в папке Практики(Вариант №1)