Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
курсач надин 2.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
878.59 Кб
Скачать

6. Приложение №2. Текст программы.

#include <iostream>

#include <vector>

#include <time.h>

#include <algorithm>

using namespace std;

//Структура "ребро"

struct line

{

//Начало ребра, конец ребра и вес ребра

int a, b, weight;

};

//Структура "вершина"

struct point

{

vector<line> lines;//Список ребер, выходящих из вершины

bool flag;//Определяет, посещена ли вершина

};

void printGraph(int **mas, int size)

{

cout << endl;

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

{

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

{

cout << mas[i][j] << " ";

}

cout << endl;

}

}

int random(int min, int max)

{

return min + (rand() % (int)(max - min + 1));

}

//ТЕСТ ПРОВОДИЛСЯ НА ЭТОМ МАССИВЕ

//{ 0, 2, 2, 0}

//{ 2, 0, 0, 3}

//{ 2, 0, 0, 1}

//{ 0, 3, 1, 0}

int main()

{

srand(time(NULL)); //Включаем генерацию случайного числа на основании текущего времени

int Vcount = -1; //Кол-во вершин графа

int Lcount = -1; //Кол-во ребер графа

int **graphArr; //Двумерный массив вершин и расстояний между ними(что-то типа матрицы смежности. не помню, как правильно называется)

point *points; //Массив вершин с указанием ребер, которые исходят из соответствующей вершины

setlocale(LC_ALL, "Russian");

cout << endl << "Введите количество вершин в графе (число, большее единицы) : ";

do

{

cin >> Vcount;

}

while(Vcount <= 1);

//Создаем матрицу смежности и заполняем её нулями

points = new point[Vcount];

graphArr = new int*[Vcount];

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

{

graphArr[i] = new int[Vcount];

}

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

{

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

{

graphArr[i][j] = 0;

}

}

do

{

//Считываем ребра и записываем в матрицу

cout << endl << "Введите количество ребер.\n"

<< "Внимание : чтобы построить путь, необходимо, чтобы граф имел одну компоненту связности. Поэтому количество ребер\n"

<< "должно быть не менее, чем " << Vcount - 1 << endl;

do

{

cin >> Lcount;

}

while(Lcount < Vcount - 1);

}

while(Lcount < 1);

cout << endl

<< "Введите название и вес каждого ребра в виде : <вершина1> <вершина2> <вес>\nНумерация вершин начинается с единицы!)"

<< endl;

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

{

int a, b, weight;

cout << endl << "\tРебро" << i + 1 << " : ";

cin >> a >> b >> weight;

graphArr[a - 1][b - 1] = weight;

graphArr[b - 1][a - 1] = weight;

}

//Создаем массив вершин из матрицы смежности

points = new point[Vcount];

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

{

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

{

if(graphArr[i][j] != 0)

{

line temp;

temp.a = i;

temp.b = j;

temp.weight = graphArr[i][j];

points[i].lines.push_back(temp);

points[i].flag = false;

}

}

}

vector<point> path;//здесь будет храниться путь

int cp = random(0, Vcount - 1);

int SUM = 0;

path.push_back(points[cp]);

points[cp].flag = true;

while(path.size() != Vcount)

{

//Найдем кратчайшее ребро. Для этого пройдем по всем вершинам, уже включенным в путь и переберем их ребра.

//Для каждой вершины найдем свое кратчайшее ребро, затем сравним кратчайшие ребра из всех вершин, включенных в путь и

//выберем минимальное из них. Далее, будем смотреть в какую вершину приведет нас это ребро. Перейдем в эту вершину, пометив

//её как пройденную и повторим действия.

line global_min_line; // <-- наше искомое кратчайшее ребро

global_min_line.weight = 100000000; // вес минимального ребра

int psize = path.size();

for(int pit = 0; pit < psize; pit++)

{

line local_min_line; // <-- кратчайшее ребро для текущей вершины

local_min_line.weight = 100000000; // вес текущего минимального ребра

int lsize = path[pit].lines.size();

for(int lit = 0; lit < lsize; lit++)

{

//если нашлось ребро легче, то текущему минимальному ребру присваиваем его параметры

//также проверим, не ведет ли это ребро в уже пройденную вершину. В этом случае игнорируем его.

if(path[pit].lines[lit].weight < local_min_line.weight && !points[path[pit].lines[lit].b].flag)

{

local_min_line.a = path[pit].lines[lit].a;

local_min_line.b = path[pit].lines[lit].b;

local_min_line.weight = path[pit].lines[lit].weight;

}

}

if(local_min_line.weight < global_min_line.weight)

global_min_line = local_min_line;

}

//Добавляем в путь ту вершину, которой кончается кратчайшее ребро

path.push_back(points[global_min_line.b]);

points[global_min_line.b].flag = true;

SUM += global_min_line.weight;

}

//Вывод на экран результатов (кратчайший путь и стоимость пути)

cout << endl << "path : ";

for(int i = 0; i < path.size() - 1; i++)

cout << path[i].lines[0].a + 1 << "-->";

cout << path[path.size() - 1].lines[0].a + 1 << endl;

cout << endl << "cost = " << SUM << endl;

system("pause");

return 0;

}