Вы находитесь на странице: 1из 12

MINISTERUL EDUCAȚIEI ȘI CERCETĂRII AL REPUBLICII

MOLDOVA
Universitatea Tehnică a Moldovei
Facultatea Calculatoare, Informatică şi Microelectronică
Departamentul Inginerie Software și Automatică

RAPORT
Lucrare de laborator nr.4
la cursul „Matematica discretă”
Tema: Algortimul de cautare grafului de acoperire

A efectuat : St. gr. TI-228, Gurtovoi Maxim


A verificat: Asis.univ. Gaidarji Alina

1
Chișinău 2023

Содержание
Реализация и результаты...................................................................................................................3

Выводы..............................................................................................................................................18

2
Теория
Граф покрытия - это частный случай задачи о покрытии множества. В терминах теории графов, граф
покрытия представляет собой множество вершин в неориентированном графе, такое что каждое ребро
графа имеет хотя бы одну из его конечных вершин в этом множестве.
Алгоритм Прима - это жадный алгоритм нахождения минимального остовного дерева в связном
взвешенном неориентированном графе.

Формально, алгоритм Прима можно описать следующим образом:

1. Выбрать произвольную вершину и поместить ее в остовное дерево.


2. Найти ребро минимального веса, которое соединяет вершину остовного дерева с какой-то
еще не включенной вершиной, и добавить его в остовное дерево.
3. Повторять шаг 2, пока все вершины не будут включены в остовное дерево.

3
Реализация и результаты
Цель задачи:
Написать алгоритм поиска графика покрытия для заданного графа (будет использован

алгоритм Прима).

Код:
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
#include <stdlib.h>

#define INF 1e9

typedef struct Arc {


    int source;
    int dest;
    int weight;
} Arc;

typedef struct Graph {


    int nr_vertex;
    int nr_arc;
    Arc *arc;
} Graph;

Graph *create_graph(int nr_vertex, int nr_arc) {


    Graph* graph = NULL;
   
    graph = malloc(sizeof(struct Graph));
    graph->nr_vertex = nr_vertex;
    graph->nr_arc = nr_arc;
    graph->arc = malloc(nr_arc * sizeof(struct Arc));
   
    if (graph->arc){
        printf("\nDone\n");
        return graph;
    }
    printf("\nError\n");
    return NULL;
}

void init(Graph *graph) {


    if (graph) {
4
        for (int i = 0; i < graph->nr_arc; i++) {
            printf("\nArc %d:\n", i+1);
            printf("source: "); scanf("%d", &graph->arc[i].source);
            printf("destination: "); scanf("%d", &graph->arc[i].dest);
            printf("weight: "); scanf("%d", &graph->arc[i].weight);
        }
        return;
    }
    printf("\nError\n");
}

void print(Graph *graph) {


    if (graph) {
        for (int i = 0; i < graph->nr_arc; i++) {
            printf("%d - %d\tweight: %d\n", graph->arc[i].source, graph-
>arc[i].dest, graph->arc[i].weight);
        }
        return;
    }
    printf("\nError\n");
}

int __search_min_weight_arc(Graph *graph, bool *visited_arc, bool *visited_vertex)


{
    int min = INF, ind = -1;
    for (int i = 0; i < graph->nr_arc; i++) {
        if (!visited_arc[i] && graph->arc[i].weight < min) {
            if (!visited_vertex[graph->arc[i].source - 1] || !visited_vertex[graph-
>arc[i].dest - 1]) {
                if (visited_vertex[graph->arc[i].source - 1] ||
visited_vertex[graph->arc[i].dest - 1]) {
                    min = graph->arc[i].weight;
                    ind = i;
                }
            }
        }
    }
    return ind;
}

Graph *coverage(Graph *graph) {


    Graph *graph_prim = create_graph(graph->nr_vertex, graph->nr_vertex-1);
    if (!graph_prim) return NULL;
    bool visited_arc[graph->nr_arc], visited_vertex[graph->nr_vertex];
    int min = INF;
    int index = -1;
5
    for (int i = 0; i < graph->nr_arc; i++) visited_arc[i] = false;
    for (int i = 0; i < graph->nr_vertex; i++) visited_vertex[i] = false;

    for (int i = 0; i < graph->nr_arc; i++)


        if (graph->arc[i].weight < min) {
            min = graph->arc[i].weight;
            index = i;
        }

    for (int i = 0; i < graph->nr_vertex - 1; i++) {


        if (i) index = __search_min_weight_arc(graph, visited_arc, visited_vertex);
        if (index == -1) {
            return NULL;
            printf("\nError\n");
        }

        visited_arc[index] = true;
        visited_vertex[graph->arc[index].source - 1] = true;
        visited_vertex[graph->arc[index].dest - 1] = true;

        graph_prim->arc[i].source = graph->arc[index].source;
        graph_prim->arc[i].dest = graph->arc[index].dest;
        graph_prim->arc[i].weight = graph->arc[index].weight;

    }
    return graph_prim;
}

int main() {
    int nr_vertex = 0, nr_arc = 0, choice = -1;
    Graph *graph = NULL;
    Graph *graph_coverage = NULL;

    while(choice) {
        printf("1 - Init\n2 - Print\n3 - Create coverage graph\n");
        printf("5 - Free graphs.\n\n0 - Exit.\n");
        scanf("%d", &choice);
        switch (choice) {
        case 1:
            if (!graph) {
                printf("\nNr vertex: "); scanf("%d", &nr_vertex);
                printf("Nr arcs: "); scanf("%d", &nr_arc);
                graph = create_graph(nr_vertex, nr_arc);
                init(graph);

6
                break;
            }
            printf("\nError\n");
            break;
        case 2:
            print(graph);
            break;
        case 3:
            graph_coverage = coverage(graph);
            print(graph_coverage);
            break;
        case 4:
            if (graph) {
                free(graph->arc);
                free(graph);
                graph = NULL;
            }
            if (graph_coverage) {
                free(graph_coverage->arc);
                free(graph_coverage);
                graph_coverage = NULL;
            }
            break;
        case 0:
            if (graph) {
                free(graph->arc);
                free(graph);
                graph = NULL;
            }
            if (graph_coverage) {
                free(graph_coverage->arc);
                free(graph_coverage);
                graph_coverage = NULL;
            }
            break;
        default:
            printf("\nError\n");
            break;
        }
        system("pause");
        system("cls");
    }
    return 0;
}

7
Результаты
Введенный граф:

8
9
Граф покрытия:

10
Выводы
Граф покрытия (vertex cover) - это один из фундаментальных понятий теории графов и
находит широкое применение в различных областях, включая алгоритмы
оптимизации, теорию вычислительной сложности, анализ сетевых структур, а также в
задачах планирования и оптимизации в транспортных и логистических системах.
Одним из основных применений графа покрытия является решение задачи о
покрытии множества, которая возникает во многих областях, например, в
оптимизации расписания, теории кодирования и компьютерной графике. Кроме того,
граф покрытия используется для решения задач нахождения максимальной клики,
максимального независимого множества и других классических задач теории графов.

11
12

Вам также может понравиться