Мне было поручено реализовать алгоритм Прима, чтобы найти 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;
}