Скачиваний:
0
Добавлен:
22.09.2026
Размер:
292 Кб
Скачать
☆

Приложение. Листинг программных модулей

#include <iostream>

#include <chrono>

#include <random>

#include <fstream>

#include <vector>

#include <climits>

#include <windows.h>

using namespace std;

using namespace chrono;

const int INF = INT_MAX / 2;  // избегаем переполнения при сложении

// Генерация случайного графа

vector<vector<int>> generate_sparse_graph(int n, int avg_deg = 6) {

    vector<vector<int>> g(n, vector<int>(n, INF));

    for (int i = 0; i < n; i++) g[i][i] = 0;

    random_device rd;

    mt19937 gen(rd());

    uniform_int_distribution<> vertex_dist(0, n-1);

    uniform_int_distribution<> weight_dist(1, 100);

   

    int target_edges = n * avg_deg / 2;  

    int edges_added = 0;

   

    while (edges_added < target_edges) {

        int u = vertex_dist(gen);

        int v = vertex_dist(gen);

        if (u != v && g[u][v] == INF) {

            int w = weight_dist(gen);

            g[u][v] = g[v][u] = w;

            edges_added++;

        }

    }

    return g;

}

// Алгоритм Флойда-Уоршелла

void floyd_warshall(vector<vector<int>>& dist) {

    int n = dist.size();

    for (int k = 0; k < n; ++k) {

        for (int i = 0; i < n; ++i) {

            if (dist[i][k] == INF) continue;

            for (int j = 0; j < n; ++j) {

                if (dist[k][j] == INF) continue;

                int new_d = dist[i][k] + dist[k][j];

                if (new_d < dist[i][j])

                    dist[i][j] = new_d;

            }

        }

    }

}

// Алгоритм Дейкстры

vector<int> dijkstra(const vector<vector<int>>& graph, int start) {

    int n = graph.size();

    vector<int> dist(n, INF);

    vector<bool> visited(n, false);

    dist[start] = 0;

   

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

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

        int u = -1;

        int min_dist = INF;

        for (int i = 0; i < n; ++i) {

            if (!visited[i] && dist[i] < min_dist) {

                min_dist = dist[i];

                u = i;

            }

        }

        if (u == -1) break;  // остальные вершины недостижимы

        visited[u] = true;

       

        for (int v = 0; v < n; ++v) {

            if (!visited[v] && graph[u][v] != INF) {

                int new_d = dist[u] + graph[u][v];

                if (new_d < dist[v])

                    dist[v] = new_d;

            }

        }

    }

    return dist;

}

int main() {

    SetConsoleOutputCP(CP_UTF8);

    SetConsoleCP(CP_UTF8);

   

    // Параметры эксперимента

    const int START_VERTICES = 100;

    const int MAX_VERTICES = 1000;

    const int STEP = 50;          // шаг увеличения числа вершин

    const int REPEATS = 5;        // сколько раз замеряем для каждого размера

    const int AVG_DEGREE = 6;     // средняя степень вершины

   

    ofstream fout("results.csv");

    fout << "Vertices,Floyd_ms,Dijkstra_ms\n";

   

    cout << "Сравнение алгоритмов Флойда-Уоршелла и Дейкстры\n";

    cout << "Граф разреженный (средняя степень " << AVG_DEGREE << ")\n";

    cout << "Каждая точка усреднена по " << REPEATS << " запускам\n\n";

   

    for (int n = START_VERTICES; n <= MAX_VERTICES; n += STEP) {

        cout << "Тестирование для n = " << n << " ... " << flush;

       

        double total_time_floyd = 0.0;

        double total_time_dijkstra = 0.0;

       

        for (int rep = 0; rep < REPEATS; ++rep) {

            // Генерируем граф

            vector<vector<int>> graph = generate_sparse_graph(n, AVG_DEGREE);

           

            // Флойд-Уоршелл

            vector<vector<int>> graph_floyd = graph;  // копия

            auto start_time = high_resolution_clock::now();

            floyd_warshall(graph_floyd);

            auto end_time = high_resolution_clock::now();

            total_time_floyd += duration_cast<milliseconds>(end_time - start_time).count();

           

            // Дейкстра

            start_time = high_resolution_clock::now();

            for (int s = 0; s < n; ++s) {

                vector<int> dist = dijkstra(graph, s);

            }

            end_time = high_resolution_clock::now();

            total_time_dijkstra += duration_cast<milliseconds>(end_time - start_time).count();

        }

       

        double avg_floyd = total_time_floyd / REPEATS;

        double avg_dijkstra = total_time_dijkstra / REPEATS;

       

        cout << " Флойд: " << avg_floyd << " ms, Дейкстра (n запусков): " << avg_dijkstra << " ms\n";

        fout << n << "," << avg_floyd << "," << avg_dijkstra << "\n";

    }

   

    fout.close();

    cout << "\nРезультаты сохранены в results.csv\n";

    cout << "Для построения графика откройте файл в Excel или Google Sheets\n";

   

    return 0;

}

Соседние файлы в папке Отчёты Дагаев