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

Практики(Вариант №7) / Практическая работа №6

.pdf
Скачиваний:
0
Добавлен:
23.02.2026
Размер:
451.93 Кб
Скачать

Приложение А

(обязательное) Код программы

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;

 

 

 

}

elseadjMatrix[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("Матрица смежности:"); Console.Write(" ");

for (int i = 0; i < numCities; i++) { Console.Write($"{i}\t");

}

Console.WriteLine();

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

{

11

 

 

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

 

 

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

 

 

{

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

 

 

 

 

 

 

Console.Write("INF\t");

 

 

}

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

 

}

Console.WriteLine();

}

 

 

 

 

 

// Алгоритм Дейкстры с исключением вершин

public (int distance, List<int> path) FindShortestPathWithAvoidance(int start, int end, int[] avoidedCities)

{// Проверка корректности входных данных

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

throw new ArgumentException("Неверные начальный или конечный город"); if (avoidedCities == null)

avoidedCities = new int[0];

// Массивы для хранения расстояний и предков 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;

 

= 0;

dist[start]

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

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] && !avoidedCities.Contains(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] && !avoidedCities.Contains(v) &&

 

 

 

 

 

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

 

 

{

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

 

 

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

 

 

 

 

 

}

prev[v] = u;

 

}

 

 

 

 

12

}

// Восстанавливаем путь List<int> path = new List<int>();

if (dist[end] != int.MaxValue / 2)

{int current = end; while (current != -1)

{path.Add(current); current = prev[current];

 

 

}

 

}

path.Reverse();

 

 

}

return (dist[end], path);

 

 

// Метод Флойда-Уоршелла для поиска всех кратчайших путей

public int[,] FloydWarshall()

{

int[,] dist = new int[numCities, numCities];

 

 

Array.Copy(adjMatrix, dist, numCities * numCities);

 

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

 

{

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

 

 

 

 

{

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

 

 

 

 

 

 

{

if (dist[i, k] != int.MaxValue / 2 && dist[k, j] != int.MaxValue / 2 &&

 

 

 

 

 

 

 

 

{

dist[i, j] > dist[i, k] + dist[k, j])

 

 

 

 

dist[i, j] = dist[i, k] + dist[k, j];

 

 

 

 

}

 

 

 

}

 

 

 

}

 

 

 

}

 

 

 

 

 

 

 

 

}return dist;

class Program

 

 

 

{

static void Main(string[] args)

 

 

{

try

 

 

 

 

 

 

 

 

 

 

 

 

{

Console.Write("Сколько городов (узлов)? ");

 

 

 

 

 

 

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

 

 

 

Graph graph = new Graph(numCities);

 

 

 

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();

13

 

 

 

 

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();

 

// Поиск кратчайшего пути с исключением городов

 

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

 

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

 

Console.Write("Введите конечный город: ");

 

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

пропуска): ");

Console.Write("Введите города для исключения (через запятую, Enter для

string avoidInput = Console.ReadLine();

 

 

int[] avoidedCities;

 

if (string.IsNullOrWhiteSpace(avoidInput))

 

{

avoidedCities = new int[0];

 

}

 

 

 

 

 

 

else

 

 

 

 

 

{

avoidedCities = avoidInput

 

 

 

 

 

.Split(',')

 

 

 

.Select(s => s.Trim())

 

 

 

.Where(s => !string.IsNullOrEmpty(s))

 

 

 

.Select(int.Parse)

 

}

 

.ToArray();

 

 

 

 

 

avoidedCities); var result = graph.FindShortestPathWithAvoidance(start, end,

 

if (result.distance == int.MaxValue / 2)

 

{

Console.WriteLine("Путь не существует!");

 

}

 

 

 

 

 

 

else

 

 

 

 

14

 

{

Console.WriteLine($"Кратчайшее расстояние: {result.distance}");

 

 

 

}

Console.WriteLine($"Путь: {string.Join(" -> ", result.path)}");

}

 

 

 

catch (Exception ex)

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

}} } }

15

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