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

Программная инженерия. Курсовые / Код к курсовой Сети связи (с пояснениями)

.txt
Скачиваний:
0
Добавлен:
04.01.2026
Размер:
16.68 Кб
Скачать
#include <algorithm>
#include <ctime>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <limits>
#include <numeric>
#include <sstream>
#include <string>
#include <vector>

// Глобальные переменные для изменения пропускной способности и точности
int deltaCapacity, accuracy;

using namespace std;

using FloatType = long double;

// Функция алгоритма Флойда-Уоршелла для нахождения кратчайших путей
void floydWarshall(vector<vector<FloatType>> &distMatrix, vector<vector<int>> &pathMatrix) {
    int size = distMatrix.size();

    // Инициализация матрицы путей
    for (int i = 0; i < size; ++i) {
        iota(pathMatrix[i].begin(), pathMatrix[i].end(), 1);
    }

    // Основной цикл алгоритма Флойда-Уоршелла
    for (int k = 0; k < size; ++k) {
        for (int i = 0; i < size; ++i) {
            for (int j = 0; j < size; ++j) {
                if (i != j && i != k && j != k) {
                    FloatType newDist = distMatrix[i][k] + distMatrix[k][j];
                    if (newDist < distMatrix[i][j]) {
                        distMatrix[i][j] = newDist;
                        pathMatrix[i][j] = pathMatrix[i][k];
                    }
                }
            }
        }
    }
}

// Функция для расчета интенсивностей нагрузки на линиях связи сети
// Принимает матрицу трафика и матрицу кратчайших путей между узлами
vector<vector<FloatType>> calculateLoadIntensity(const vector<vector<FloatType>> &trafficMatrix, vector<vector<int>> &pathMatrix) {
    // Получаем размер матрицы (количество узлов в сети)
    int size = trafficMatrix.size();
    
    // Создаем матрицу для хранения интенсивностей нагрузок
    // Изначально заполняем нулями
    vector<vector<FloatType>> loadIntensityMatrix(size, vector<FloatType>(size, 0));

    // Проходим по всем парам узлов в сети
    for (int i = 0; i < size; ++i) {        // i - узел-источник
        for (int j = 0; j < size; ++j) {    // j - узел-получатель
            // Добавляем нагрузку на первый участок пути от узла i
            loadIntensityMatrix[i][pathMatrix[i][j] - 1] += trafficMatrix[i][j];
            
            // Проходим по всем промежуточным узлам пути от i до j
            // k - текущий узел пути, начиная с первого после источника
            // Цикл продолжается, пока не достигнем узла назначения j
            for (int k = pathMatrix[i][j] - 1; k != j; k = pathMatrix[k][j] - 1) {
                // Добавляем нагрузку на каждый следующий участок пути
                loadIntensityMatrix[k][pathMatrix[k][j] - 1] += trafficMatrix[i][j];
            }
        }
    }

    // Возвращаем заполненную матрицу интенсивностей нагрузок
    return loadIntensityMatrix;
}

// Генерация матрицы потоков на основе матрицы нагрузок
vector<vector<int>> generateStreamMatrix(vector<vector<FloatType>> &loadIntensityMatrix, FloatType qualityFactor) {
    int size = loadIntensityMatrix.size();
    FloatType maxProbability = 1.0 - qualityFactor;
    vector<vector<int>> streamMatrix(size, vector<int>(size, 0));

    // Заполнение матрицы потоков
    for (int i = 0; i < size; ++i) {
        for (int j = 0; j < size; ++j) {
            if (loadIntensityMatrix[i][j] != 0) {
                int streams = 1;
                FloatType probability = 1, intensity = loadIntensityMatrix[i][j], numerator = intensity, sum = intensity;

                // Расчет потоков согласно требуемой вероятности качества
                while (probability > maxProbability) {
                    ++streams;
                    numerator = (numerator / streams) * intensity;
                    sum += numerator;
                    probability = numerator / sum;
                }

                streamMatrix[i][j] = streams;
            }
        }
    }

    return streamMatrix;
}

// Вычисление задержек на основе матриц путей, трафика и пропускной способности
void calculateDelays(const vector<vector<int>> &pathMatrix, const vector<vector<int>> &trafficMatrix, const vector<vector<FloatType>> &capacityMatrix, vector<vector<FloatType>> &delayMatrix, FloatType packetLength) {
    int size = delayMatrix.size();

    // Инициализация задержек для прямых путей
    for (int i = 0; i < size; ++i) {
        for (int j = 0; j < size; ++j) {
            if (pathMatrix[i][j] == j + 1 && i != j) {
                delayMatrix[i][j] = (8.0 * packetLength) / (capacityMatrix[i][j] - trafficMatrix[i][j]);
            } else {
                delayMatrix[i][j] = 0;
            }
        }
    }

    // Добавление задержек для непрямых путей
    for (int i = 0; i < size; ++i) {
        for (int j = 0; j < size; ++j) {
            if (pathMatrix[i][j] != j + 1) {
                delayMatrix[i][j] += delayMatrix[i][pathMatrix[i][j] - 1];
                for (int k = pathMatrix[i][j] - 1; k != j; k = pathMatrix[k][j] - 1) {
                    delayMatrix[i][j] += delayMatrix[k][pathMatrix[k][j] - 1];
                }
            }
        }
    }
}

// Вычисление целевой функции для оптимизации
FloatType calculateObjective(const vector<vector<FloatType>> &delayMatrix, FloatType targetDelay) {
    FloatType objective = 0;

    // Подсчет отклонения задержек от целевого значения
    for (const auto &row : delayMatrix) {
        for (const auto &delay : row) {
            objective += (delay - targetDelay / 2) * (delay - targetDelay / 2);
        }
    }
    return objective;
}

// Оптимизация матрицы пропускных способностей
vector<vector<FloatType>> optimizeCapacityMatrixSub(const vector<vector<int>> &pathMatrix, const vector<vector<int>> &trafficMatrix, vector<vector<FloatType>> &capacityMatrix, FloatType targetDelay, FloatType packetLength) {
    int bestI = 0, bestJ = 0, size = capacityMatrix.size();
    FloatType minObjective = 1e+10, bestObjective = minObjective;
    vector<vector<FloatType>> delayMatrix(size, vector<FloatType>(size, 0));

    // Итеративная оптимизация пропускных способностей
    while (true) {
        for (int i = 0; i < size; ++i) {
            for (int j = 0; j < size; ++j) {
                if (capacityMatrix[i][j] != 0) {
                    capacityMatrix[i][j] += deltaCapacity;
                    calculateDelays(pathMatrix, trafficMatrix, capacityMatrix, delayMatrix, packetLength);
                    capacityMatrix[i][j] -= deltaCapacity;

                    FloatType objective = calculateObjective(delayMatrix, targetDelay);
                    if (objective < bestObjective) {
                        bestObjective = objective;
                        bestI = i;
                        bestJ = j;
                    }
                }
            }
        }

        if (bestObjective < minObjective) {
            capacityMatrix[bestI][bestJ] += deltaCapacity;
            minObjective = bestObjective;
        } else {
            break;
        }
    }

    return delayMatrix;
}

// Проверка успешности оптимизации
bool isOptimizationSuccessful(const vector<vector<FloatType>> &delayMatrix, FloatType targetDelay) {
    return find_if(delayMatrix.begin(), delayMatrix.end(), [&targetDelay](const auto &row) {
        return any_of(row.begin(), row.end(), [&targetDelay](auto delay) { return delay > targetDelay / 2; }) != 0;
    }) == delayMatrix.end();
}

// Основная функция оптимизации пропускных способностей
pair<FloatType, vector<vector<FloatType>>> optimizeCapacityMatrix(const vector<vector<int>> &pathMatrix, const vector<vector<int>> &trafficMatrix, vector<vector<FloatType>> &capacityMatrix, FloatType targetDelay, FloatType packetLength, bool optimizeTargetDelay) {
    auto currentTargetDelay = targetDelay, delayStep = targetDelay / accuracy;
    auto delayMatrix = optimizeCapacityMatrixSub(pathMatrix, trafficMatrix, capacityMatrix, targetDelay, packetLength);

    // Итеративная оптимизация с возможной корректировкой целевой задержки
    while (optimizeTargetDelay && !isOptimizationSuccessful(delayMatrix, currentTargetDelay) && (targetDelay -= delayStep) > 1e-20) {
        delayMatrix = optimizeCapacityMatrixSub(pathMatrix, trafficMatrix, capacityMatrix, targetDelay, packetLength);
    }

    return make_pair(targetDelay, delayMatrix);
}

// Функция для вывода вектора
template <class T>
void printVector(ostream &os, const vector<T> &vec) {
    for (const auto &elem : vec) os << elem << ' ';
    os << endl << endl;
}

// Функция для вывода матрицы
template <class T>
void printMatrix(ostream &os, const vector<vector<T>> &matrix) {
    for (const auto &row : matrix) {
        for (const auto &elem : row) os << elem << ' ';
        os << endl;
    }
    os << endl;
}

int main() {
    // Начало измерения времени выполнения
    auto start = clock();
    int numNodes, initialTraffic, optimizeFlag;
    FloatType baseIntensity, packetLength, qualityFactor, targetDelay;
    ifstream inputFile("input2.txt");

    // Проверка открытия входного файла
    if (!inputFile.is_open()) {
        cout << "Ошибка открытия файла 'input2.txt'" << endl;
        return 1;
    }

    // Чтение данных из файла
    stringstream dataStream;
    while (!inputFile.eof()) {
        string line;
        getline(inputFile, line);
        dataStream << line.substr(0, line.find(';')) << ' ';
    }
    inputFile.close();

    // Инициализация параметров
    dataStream >> numNodes >> baseIntensity >> initialTraffic >> packetLength >> qualityFactor >> targetDelay >> optimizeFlag >> deltaCapacity >> accuracy;
    vector<FloatType> subscribers(numNodes, 0);
    for (auto &subscriber : subscribers) dataStream >> subscriber;
    vector<vector<FloatType>> distanceMatrix(numNodes, vector<FloatType>(numNodes, 0));
    for (auto &row : distanceMatrix) {
        for (auto &dist : row) dataStream >> dist;
    }

    cout << "Пожалуйста, подождите..." << endl;
    ofstream outputFile("output2.txt");

    // Проверка открытия выходного файла
    if (!outputFile.is_open()) {
        cout << "Ошибка открытия файла 'output2.txt'" << endl;
        return 2;
    }

    outputFile << setprecision(numeric_limits<FloatType>::digits10);

    // Вычисление интенсивностей трафика
    outputFile << "1. Интенсивности производимого в узлах сети трафика" << endl;
    vector<FloatType> trafficIntensities(subscribers);
    transform(trafficIntensities.begin(), trafficIntensities.end(), trafficIntensities.begin(), [&baseIntensity](auto val) { return val * baseIntensity; });
    printVector(outputFile, trafficIntensities);

    // Вычисление коэффициентов распределения трафика
    outputFile << "2. Коэффициенты распределения трафика по направлениям связи" << endl;
    auto totalIntensity = accumulate(trafficIntensities.begin(), trafficIntensities.end(), 0.L);
    vector<FloatType> distributionCoefficients(trafficIntensities);
    transform(distributionCoefficients.begin(), distributionCoefficients.end(), distributionCoefficients.begin(), [&totalIntensity](auto val) { return val / totalIntensity; });
    printVector(outputFile, distributionCoefficients);

    // Создание матрицы интенсивностей трафика
    outputFile << "3. Матрица интенсивностей трафика в направлениях связи" << endl;
    vector<vector<FloatType>> trafficMatrix(numNodes, vector<FloatType>(numNodes, 0));
    for (int i = 0; i < numNodes; ++i) {
        for (int j = 0; j < numNodes; ++j) {
            trafficMatrix[i][j] = trafficIntensities[i] * distributionCoefficients[j];
        }
    }
    printMatrix(outputFile, trafficMatrix);

    // Нахождение кратчайших путей и расстояний
    vector<vector<FloatType>> shortestDistMatrix(distanceMatrix);
    vector<vector<int>> shortestPathMatrix(numNodes, vector<int>(numNodes, 0));
    floydWarshall(shortestDistMatrix, shortestPathMatrix);
    outputFile << "4.1. Матрица кратчайших расстояний между вершинами графа" << endl;
    printMatrix(outputFile, shortestDistMatrix);
    outputFile << "4.2. Матрица кратчайших маршрутов между вершинами графа" << endl;
    printMatrix(outputFile, shortestPathMatrix);

    // Вычисление интенсивности нагрузки
    outputFile << "5. Матрица интенсивностей нагрузок на линиях связи" << endl;
    auto loadIntensityMatrix = calculateLoadIntensity(trafficMatrix, shortestPathMatrix);
    printMatrix(outputFile, loadIntensityMatrix);

    // Генерация матрицы потоков
    outputFile << "6. Матрица потоков" << endl;
    auto streamMatrix = generateStreamMatrix(loadIntensityMatrix, qualityFactor);
    printMatrix(outputFile, streamMatrix);

    // Расчет матрицы интенсивности трафика
    outputFile << "7. Матрица интенсивности трафика ПД для линий связи" << endl;
    vector<vector<int>> trafficIntensityMatrix(streamMatrix);
    for (auto &row : trafficIntensityMatrix) {
        transform(row.begin(), row.end(), row.begin(), [&initialTraffic](auto val) { return val * initialTraffic; });
    }
    printMatrix(outputFile, trafficIntensityMatrix);

    // Создание матрицы пропускных способностей
    outputFile << "8. Матрица пропускных способностей (бит/с)" << endl;
    vector<vector<FloatType>> capacityMatrix(numNodes, vector<FloatType>(numNodes, 0));
    for (int i = 0; i < numNodes; ++i) {
        for (int j = 0; j < numNodes; ++j) {
            capacityMatrix[i][j] = (trafficIntensityMatrix[i][j]) ? (trafficIntensityMatrix[i][j] + (8.0 * packetLength) / targetDelay) : 0;
        }
    }
    printMatrix(outputFile, capacityMatrix);

    cout << "1-8 Time: " << (clock() - start) / 1000.0 << " s." << endl;
    start = clock();

    // Оптимизация матрицы пропускных способностей
    auto optimizationResult = optimizeCapacityMatrix(shortestPathMatrix, trafficIntensityMatrix, capacityMatrix, targetDelay, packetLength, static_cast<bool>(optimizeFlag));
    outputFile << "9. Матрица задержек" << endl;
    printMatrix(outputFile, optimizationResult.second);
    outputFile << "10. Матрица оптимизированных пропускных способностей (бит/с)" << endl;
    printMatrix(outputFile, capacityMatrix);
    outputFile << "Оптимизированная T: " << optimizationResult.first << endl;
    outputFile.close();

    cout << "Opt. Time: " << (clock() - start) / 1000.0 << " s." << endl;
    cout << "Работа завершена!" << endl;
}