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

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

.pdf
Скачиваний:
0
Добавлен:
23.02.2026
Размер:
499.96 Кб
Скачать
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");

 

 

}

elseConsole.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;

11

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;

}

elsereturn 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}

| Нет

пути

| -");

}

 

 

 

 

12

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.");}

 

13

 

 

 

 

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

}

 

 

 

 

 

14

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