簡體   English   中英

Kruskal算法的C ++實現

[英]C++ implementation of Kruskal's algorithm

我正在嘗試實現Kruskal的算法。 這是我正在使用的結構的地圖:

g =邊緣陣列,它保持左端和右端以及邊緣的重量;

c =記憶conex成分的數組; c [N] =我們在其中找到第N個頂點的conex分量;

a =記憶MST的數組;

m = nr個頂點;

n = nr個節點。

以下代碼存在兩個問題:

1)對於以下輸入,它輸出MST的成本是18 (這是錯誤的,成本實際上是14 ):

7(= m)

6(= n)

1 2 9

1 3 5

1 4 2

2 3 7

3 5 3

4 6 1

5 6 1

2)逐步編譯代碼不會產生任何錯誤,雖然程序的實際執行在某些時候停止,我認為它是在打印MST的成本時。

謝謝你的幫助! 這是代碼:

#include<stdio.h>
#include<stdlib.h>
#define grafMAX 101

FILE *fin = fopen("grafin.txt","r");
FILE *fout = fopen("grafout.txt","w");

struct Vertex{
    int first,last,Cost;
};

void read_graf(Vertex **g, int *c, int &m, int &n){
    int x,y,w;
    fscanf(fin,"%d%d",&m,&n);
    *g = (Vertex *)malloc(m*sizeof(Vertex));
    for(int i=1;i<=m;++i){
        fscanf(fin,"%d%d%d",&x,&y,&w);
        (*g+i)->first = x;
        (*g+i)->last = y;
        (*g+i)->Cost = w;
    }
    for(int i=1;i<=n;++i)
        c[i] = i;
}

int costMST(Vertex *g, int *a, int n){
    int MST = 0;
    for(int i=1;i<n;++i)
        MST += g[a[i]].Cost;
    return MST;
}

void Kruskal(Vertex *g, int *c, int *a, int n){
    int nr = 0, mini, maxi;
    for(int i=1;nr<n-1;++i)
        if(c[g[i].first] != c[g[i].last]){
            a[++nr] = i;
            if(c[g[i].first] < c[g[i].last]){
                mini = c[g[i].first];
                maxi = c[g[i].last];
            }
            else{
                maxi = c[g[i].first];
                mini = c[g[i].last];
            }
            for(int j=1;j<=n;++j)
                if(c[j] == maxi)
                    c[j] = mini;
        }
}

inline int cmp(const void *a, const void *b){
    return (((Vertex *)a)->Cost - ((Vertex *)b)->Cost);
}

int a[grafMAX], c[grafMAX];

int main(){
    Vertex *g;
    int m, n;
    read_graf(&g,c,m,n);
    qsort(g,m,sizeof(Vertex),cmp);
    Kruskal(g,c,a,n);
    fprintf(fout,"The cost of the MST is: %d.\n",costMST(g,a,n));
    fclose(fin);
    fclose(fout);
    return 0;
}

你的代碼中有很多錯誤,我認為因為你是從1而不是0對你的頂點進行編號。其中一個錯誤導致它崩潰,我認為另一個導致錯誤的結果產生。

我將所有內部編號更改為基於0並且已經使其工作。 我重命名了你的變量,因為它們被非常荒謬地命名(你稱之為Vertex是一個邊緣),我無法理解它們的代碼。

我擔心我失去了改變的所有內容,但是如果你將它與原始代碼進行比較,我希望你能看到我做了什么。

請注意,我添加了一些調試行。 當你無法弄清楚你的代碼在做什么時,只需打印相關的變量,你很快就會發現問題所在。

#include<stdio.h>
#include<stdlib.h>
#define grafMAX 101

FILE *fin = fopen("grafin.txt","r");
FILE *fout = fopen("grafout.txt","w");

struct Edge {
    int first,last,Cost;
};

void read_graf(Edge **g, int *components, int &num_edges, int &num_vertices){
    int x,y,w;
    fscanf(fin,"%d %d",&num_edges,&num_vertices);
    *g = (Edge *)malloc(num_edges*sizeof(Edge));
    for(int i=0;i<num_edges;++i){
        fscanf(fin,"%d %d %d",&x,&y,&w);
        (*g+i)->first = x - 1;
        (*g+i)->last = y - 1;
        (*g+i)->Cost = w;
    }
    for(int i=0;i< num_vertices;++i)
        components[i] = i;
}

int costMST(Edge *edges, int *answer, int num_edges){
    int MST = 0;
    for(int i=0;i<num_edges;++i)
        MST += edges[answer[i]].Cost;
    return MST;
}

void print_components(const int* components, int num_components) 
{
    for (int i = 0; i < num_components; i++) {
        printf("Vertex %d is in component %d\n", i, components[i]);
    }
    putchar('\n');
}

void print_edge(const Edge& edge, int index)
{
    printf("Edge %d connecting %d to %d with weight %d", index, edge.first, edge.last, edge.Cost);
}

void Kruskal(Edge *edges, int *components, int *answer, int num_edges, int num_vertices){
    int nr = 0, mini, maxi;
    for(int i=0;i<num_edges && nr < num_vertices - 1;++i) {
        printf("Considering ");
        print_edge(edges[i], i);
        putchar('\n');
        if(components[edges[i].first] != components[edges[i].last]){
            printf("Adding ");
            print_edge(edges[i], i);
            putchar('\n');
            answer[nr++] = i;
            if(components[edges[i].first] < components[edges[i].last]){
                mini = components[edges[i].first];
                maxi = components[edges[i].last];
            }
            else{
                maxi = components[edges[i].first];
                mini = components[edges[i].last];
            }
            for(int j=0;j<num_vertices;++j)
                if(components[j] == maxi)
                    components[j] = mini;
            print_components(components, num_vertices);
        }
        else {
            printf("Rejecting ");
            print_edge(edges[i], i);
            putchar('\n');
        }
    }
}

inline int cmp(const void *a, const void *b){
    return (((Edge *)a)->Cost - ((Edge *)b)->Cost);
}

int answer[grafMAX], components[grafMAX];

int main(){
    Edge *edges;
    int num_edges, num_vertices;
    read_graf(&edges,components,num_edges,num_vertices);
    qsort(edges,num_edges,sizeof(Edge),cmp);
    Kruskal(edges,components,answer,num_edges,num_vertices);
    fprintf(fout,"The cost of the MST is: %d.\n",costMST(edges,answer,num_vertices - 1));
    fclose(fin);
    fclose(fout);
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM