Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Болтушкин Л.С., группа 712-2, практика 6

.docx
Скачиваний:
0
Добавлен:
04.10.2024
Размер:
245.26 Кб
Скачать

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

Федеральное государственное бюджетное образовательное учреждение высшего образования

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

Кафедра комплексной информационной безопасности электронно-вычислительных систем (КИБЭВС)

ГРАФЫ

Отчет по практической работе №6

по дисциплине «Структуры данных»

Студент гр. 712-2 ___________ Л.С. Болтушкин ___________

Руководитель Доцент кафедры КИБЭВС

_______ __________ Е.Е. Лунёва

__________

Томск 2023

Задание

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

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

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

Вариант 6. По заданной системе дорог определить, есть ли в ней город, из которого можно добраться до каждого из остальных городов, проезжая не более N километров.

Содержание

Введение. 4

    1. Основная часть. 5

Заключение. 10

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

Введение

Целью данной практической работы является реализование возможности работы с графом N узлов, M ребер. Так, чтобы была возможность ввод графа и вывод графа - матрица смежности или весов.

В данной работе будет использоваться такой язык программирования как

С#.

      1. Основная часть

Для того, чтобы начать работу создадим класс "Graph", который представляет собой граф с N вершинами и M ребрами. Конструктор класса инициализирует переменные N и M, а также создает матрицу matrix с помощью метода Matrix() (рисунок 1.1).

Рисунок 1.1 - Создание класса "Graph"

Далее создаётся двумерный массив размером NxN и заполняет его случайными числами от 1 до 25. Условие count1 < M гарантирует, что будет заполнено только M ячеек массива. Если i равно j (i == j), то значение в данной ячейке устанавливается равным 0. Затем возвращается заполненный массив. (рисунок 1.2).

Рисунок 1.2 - Создание массива

Также необходимо прописать в программе метод Print(), который выводит матрицу весов на экран.

Метод использует двойной цикл (for) для доступа к элементам матрицы и выводит их значения на консоль. В конце каждой строки матрицы происходит переход на новую строку для более удобного отображения (рисунок 1.3).

Рисунок 1.3 - метод Print()

Далее мы должны реализовать следующий метод: "Ways", который принимает параметр way типа int. Он используется для проверки возможности добраться из одного узла во все города в графе, представленного матрицей смежности matrix размером N x N.

Для каждого узла i в графе, метод инициализирует переменную countW в 0 и затем перебирает все другие узлы k в графе.

Если i и k не равны, а также значение в матрице смежности matrix[i, k] не равно 0 и меньше или равно значению параметра way, то countW увеличивается на 1.

Если условие не выполняется, то цикл прерывается с помощью оператора break. После выборки всех узлов, проверяется, равно ли значение countW числу N - 1 (количество узлов в графе минус 1).

Если это условие выполняется, выводится сообщение, указывающее, что из узла i можно добраться во все города (рисунок 1.4)

Рисунок 1.4 - Метод "Ways"

Предпоследним действием мы реализуем алгоритм поиска кратчайшего пути в графе, ограниченного максимальной длиной пути maxDistance от начальной вершины start.

Создаём список shortestPath, который будет содержать вершины кратчайшего пути, а также создаём очередь. Начальная вершина start добавляется в очередь с расстоянием 0 и начальным путем, состоящим только из этой вершины. Далее выполняется основной цикл while (queue.Count > 0), который продолжает выполнение до тех пор, пока очередь не пуста. Затем происходит перебор соседних вершин в графе с помощью цикла for (int i = 0; i < N; i++).

Если все условия выполняются, создается новый путь newPath, который является копией текущего пути currentPath, но с добавленной вершиной i. Также

вычисляется новое расстояние newDistance, добавляя вес ребра между текущей и вершиной i к текущему расстоянию. Если новое расстояние newDistance не превышает maxDistance и длина пути newPath равна общему количеству вершин N, то это означает, что был найден путь, соответствующий заданным критериям (рисунок 1.6).

Рисунок 1.5 - Поиск наикратчайшего пути

И в последнем действие я создаю и инициализирую объект класса Graph с заданным количеством узлов и ребер. Затем алгоритм печатает граф, запрашивает величину пути от пользователя и вызывает метод Ways() класса Graph с переданным параметром "way".(рисунок 1.6)

Рисунок 1.6 - Создание и инициализация объекта класса Graph Результат работы кода представлен на рисунке 1.7.

Рисунок 1.7 - Результат работы кода В приложении А представлен листинг программы.

Заключение

В ходе выполнения данной лабораторной работы были реализованы возможности работы с графом N узлов, M ребер. Так, чтобы была возможность ввод графа и вывод графа - матрица смежности или весов.

Приложение А

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

using System;

using System.Collections.Generic; using System.Linq;

using System.Security.Cryptography;

namespace ShortestPath

{

class Program

{

class Graph

{

int N, M; int[,] matrix;

public Graph(int N, int M)

{

this.N = N; this.M = M;

matrix = Matrix(this.N, this.M);

}

private static int[,] Matrix(int N, int M)

{

int[,] ArrWays = new int[N, N]; Random rand = new Random(); int count1 = 0;

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

{

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

{

if (i == j)

{

ArrWays[i, j] = 0;

}

else

{

if (count1 < M)

{

ArrWays[i, j] = ArrWays[j, i] = rand.Next(1, 25); count1++;

}

}

}

}

return ArrWays;

}

public void Print()

{

Console.WriteLine("Матрица весов:"); for (int i = 0; i < N; i++)

{

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

{

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

}

Console.WriteLine();

}

Console.WriteLine();

}

public void Ways(int way)

{

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

{

int countW = 0;

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

{

if (i != k)

{

if (matrix[i, k] != 0 && matrix[i, k] <= way)

{

countW++;

}

else

{

break;

}

}

}

if (countW == N - 1)

Console.WriteLine($"Из города {i + 1} можно добраться во все города.");

}

}

private List<int> FindShortestPath(int start, int maxDistance)

{

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

Queue<(int node, int distance, List<int> path)> queue = new Queue<(int node, int distance, List<int> path)>();

queue.Enqueue((start, 0, new List<int> { start }));

while (queue.Count > 0)

{

var (currentNode, currentDistance, currentPath) = queue.Dequeue();

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

{

if (i != currentNode && matrix[currentNode, i] > 0 && currentDistance

+ matrix[currentNode, i] <= maxDistance && !currentPath.Contains(i))

{

var newPath = currentPath.ToList(); newPath.Add(i);

var newDistance = currentDistance + matrix[currentNode, i]; queue.Enqueue((i, newDistance, newPath));

if (newDistance <= maxDistance && newPath.Count == N)

{

shortestPath = newPath; return shortestPath;

}

}

}

}

return shortestPath;

}

}

static void Main(string[] args)

{

Console.Write("Количество узлов: "); int N = int.Parse(Console.ReadLine()); Console.Write("Количество ребер: "); int M = int.Parse(Console.ReadLine()); Graph graph = new Graph(N, M); Console.WriteLine(); Console.WriteLine();

graph.Print(); Console.Write("Величина пути: ");

int way = int.Parse(Console.ReadLine()); Console.WriteLine();

graph.Ways(way);

}

}

}