Практики(Вариант №1) / Практическая работа №6
.pdf}
// Добавляем случайные рёбра
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
