Алгоритм Прима в C производит неправильный вывод - PullRequest
1 голос
/ 06 апреля 2020

Мне было поручено реализовать алгоритм Прима, чтобы найти MCST с использованием матрицы смежности для представления графа и структуры для хранения MCST. Программа принимает входной файл, применяет алгоритм и выводит остовное дерево с минимальной стоимостью. Я получил программу для ввода файла и вывода, но значения, которые я получаю, неверны и для меня выглядят как фиктивные.

Я предполагаю, что ошибка возникает либо в том, как я сохраняю входные данные файла в моем массиве, либо в самом алгоритме. Я потратил 12-15 часов на устранение этой проблемы и надеюсь, что кто-нибудь сможет дать вам представление. Программа написана на C и скомпилирована с make в формате ./a6 <file>. Я беру и сохраняю ввод данных в моей функции main (), а затем методы используются в порядке их вызова. Ниже приведен пример моего профессора. Первая строка содержит информацию о вводимых вершинах, а остальные строки содержат сами фактические данные.


input:
6 10 0 <<--(size, edges, start)
0 1 16 <<--(from, to, weight)
0 5 21
0 4 19
1 2 5
1 3 6
1 5 11
2 3 10
3 4 18
3 5 14
4 5 33
output:
0 1 16 <<--(first edge)
1 2 5
1 3 6
1 5 11
3 4 18
total cost: 56

Мой код:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h> /* for INT_MAX */

#define N 10 /* max matrix size is 10 x 10 */
#define INF 9999

int cost =  0;
typedef struct lnode {
    int fromv;
    int tov;
    int weight;
    struct lnode *next;
} lnode;

int insertnode(lnode **lst, int from, int to, int wt);
void prims(int amtrx[][N],int n, lnode **lst);
void printpaths(lnode **lst);
void freelist(lnode **lst);
int isValid(int a, int b, int select[]);

int insertnode(lnode **lst, int from, int to, int wt){
    lnode *newnode;
    newnode = (lnode *) malloc(sizeof(struct lnode));

    newnode->fromv = from;
    newnode->tov = to;
    newnode->weight = wt;
    newnode->next=NULL;

    if(*lst == NULL){
        newnode -> next = *lst;
        *lst = newnode;
    } else {

        lnode *current;
        current = *lst;
        while(current->next != NULL){
            current = current->next;
        }
        newnode->next = current->next;
        current->next = newnode;
    }

    return 1; 
}

int isValid(int a, int b, int select[]){
    if(a == b) return 0;
    if(select[a] == 0 && select[b] == 0) return 0;
    else if (select[a] == 1 && select[b] == 1) return 0;
    return 1;
}


void prims(int amtrx[][N], int n, lnode **lst){
    int i, j, row, col, edges_seen, min;
    int select[N] = {0};
    edges_seen = 0;
    select[n] = 1;
    while(edges_seen < N-1){
        min = INF;
        row = -1;
        col = -1;
        for(i = 0; i < N; i++) {
            for(j = 0; j < N; j++){
                if(amtrx[i][j] < min) {
                    if(isValid(i, j, select) == 1){
                        min = amtrx[i][j];
                        row = i;
                        col = j;
                    }
                }
            }
        }

        if(row != -1 && col != -1){
            select[col] = 1;
            select[row] = 1;
            cost = cost + min;
            insertnode(lst, row, col, min);
            edges_seen++;
        }
        for(i = 0; i < N; i++){
            printf("%3d", select[i]);
        }
        puts("\n\n");
    }

}

void printpaths(lnode **lst){
    lnode *current;
    current = *lst;
    while(current != NULL) {
        printf("%4i  ",current->fromv);
        printf("%4i  ", current->tov);
        printf("%4i \n", current->weight);

        current = current->next;
    }
    printf("\ntotal cost: %4i\n", cost);
}


void freelist(lnode **lst) {
    lnode *temp = NULL;
    while(*lst != NULL)
    {
        temp = *lst;
        *lst = (*lst)->next;
        free(temp);
    }
}




int main(int argc, char **argv){

    FILE *f = fopen(argv[1], "r");
    lnode *lst;
    lst = (lnode *)malloc(sizeof(struct lnode));
    int i, j, nsz, nedg, fr, to, vtx, wt;
    vtx = 1111;
    nedg = 999;
    nsz = 100;
    fscanf(f, "%d %d %d", &nsz, &nedg, &vtx);
    int amtrx[nsz][N];

    for(i = 0; i < nsz; i++){
            for(j = 0; j < nsz; j++){
                    amtrx[i][j] = INF;
            }
    }

    for(i = 0; i < nedg; i++){
        fscanf(f, "%d %d %d", &fr, &to, &wt);
        amtrx[fr][to] = wt;
        amtrx[to][fr] = wt;
    }

    fclose(f);
    prims(amtrx, vtx, &lst);
    printpaths(&lst);
    freelist(&lst);

    return EXIT_SUCCESS;

}

...