kruskal 알고리즘 code=3221225477(access violation error)

조회수 497회
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define MAX_VERTICES 10000
#define MAX_EDGES 5000000 

#define HEAP_EMPTY(n) (!n)
#define LINE_SIZE  100
#define HEAP_FULL(n) (n == MAX_EDGES)


typedef struct {
  int weight;
  int node1;
  int node2;
} element;

int n_heap = 0;

element min_heap[MAX_EDGES];
int parent_array[MAX_VERTICES];

element delete_min_heap(int *n) {
  /* delete element with the highest key from the heap */
  int parent, child;
  element item, temp;
  if(HEAP_EMPTY(*n)) {
    fprintf(stderr, "The heap is empty");
    exit(1);
  }
  /* save value of the element with the largest key */
  item = min_heap[1];
  /* use the last element in the heap to adjust heap */
  temp = min_heap[(*n)--];
  parent = 1;
  child = 2;
  while(child <= *n) {
    /* find the larger child of the current parent */
    if((child < *n) && (min_heap[child].weight > min_heap[child+1].weight)) child++;
    if(temp.weight <= min_heap[child].weight) break;
    /* move to the next lower level */
    min_heap[parent] = min_heap[child];
    parent = child;
    child *= 2;
  }
  min_heap[parent] = temp;

  return item;
}

void insert_min_heap(element item, int *n) {

  int i;
  if(HEAP_FULL(*n)) {
    fprintf(stderr, "The heap is full.\n");
    exit(1);
  }
  i = ++(*n);
  while((i != 1) && (item.weight < min_heap[i/2].weight)) {
    min_heap[i] = min_heap[i/2];
    i /= 2;
  }
  min_heap[i] = item;
}

int simpleFind(int i) {
    for( ; parent_array[i] >= 0; i = parent_array[i])
        ;
    return i;

}

void weightedUnion(int i, int j) {
    int temp = parent_array[i] + parent_array[j];
    if(parent_array[i] > parent_array[j]) {
        parent_array[i] = j;
        parent_array[j] = temp;
    } else {
        parent_array[j] = i;
        parent_array[i] = temp;
    }

}

void main(int argc, char **argv) {  //argc = argument 개수 argv argument list

    //if(argc != 2) {
      //printf("No input file is given or Two many input files are given.\n");

      //exit(0);
    //}
    clock_t start = clock();
    FILE *fp1 = fopen("input_large.txt", "r"); //replace to argv[1]
    if(fp1 == NULL) {
        printf("The input file does not exist.\n");
        exit(0);
    }

    char *command_line;
    char buffer[LINE_SIZE];
    int cost;
    int n_connected;
    start = clock();
    int line_num= 0;
    int num_edges;
    int num_vertices;


    while (!feof(fp1)) {  //한줄 씩 입력받기
        element edge;
        command_line = fgets(buffer, sizeof(buffer), fp1);
        if(line_num == 0) {num_vertices = atoi(command_line);}
        else if(line_num == 1) {num_edges = atoi(command_line);}
        else {
            int vertex_from = atoi(strtok(command_line, " "));
            int vertex_to = atoi(strtok(NULL, " "));
            int weigth = atoi(strtok(NULL, " "));

            edge.node1 = vertex_from;
            edge.node2 = vertex_to;
            edge.weight = weigth;

            insert_min_heap(edge, &n_heap);

        }
        line_num++;
  }
  fclose(fp1);

  int i = 0;
  for(i = 0; i< num_vertices; i++) { parent_array[i]=-1;}
  element edge = delete_min_heap(&n_heap);


  int j = 0;
  cost = 0;
  n_connected =0;

  while((n_heap >= 0) && (n_connected != num_vertices)) {
    printf("%d %d\n", n_connected, n_heap); 연결된 vertices와 남은 힙 원소 개수 
    int node1 = edge.node1;
    int node2 = edge.node2;
    if(j == 0)  {
      weightedUnion(node1, node2);
      cost += edge.weight;
      //printf("%d %d %d\n",node1, node2, edge.weight);
      n_connected += 2;
      j++;
    }
    else if ( simpleFind(node1) != simpleFind(node2)) {
      weightedUnion(node1, node2);
      cost += edge.weight;
      //printf("%d %d %d\n",node1, node2, edge.weight);
      n_connected++;
    }
    edge = delete_min_heap(&n_heap);

  }

  printf("END\n");
  printf("COST%d\n", cost);
  printf("num vertices %d connected %d\n", num_vertices, n_connected);
  if(n_connected < num_vertices) printf("DISCONNECTED\n");
  if(n_connected == num_vertices) printf("CONNECTED\n");



  clock_t end = clock();
  double time_spent = (double)(end - start) / CLOCKS_PER_SEC;
  printf("output written to hw3_result.txt\n");
  printf("running time :%lf\n", time_spent);
}


실행결과
....
1339 4998660
1340 4998659
1341 4998658
1342 4998657
1343 4998656
1344 4998655
1345 4998

...
1657 4998343
1658 4998342
1659 4998341
1660 4998340
1661 49까지 출력
힙의 사이즈가 클 경우는

인풋 파일이 작은 경우에는 문제없이 코스트와 잘 나오지만 파일이 500000개의 Edges를 다뤄야하는데 이 경우에 이렇게 exited with code=3221225477 in 2.043 seconds의 메세지를 보내고 멈추는데 도데체 어디서 이러는지 모르겠어요....

  • (•́ ✖ •̀)
    알 수 없는 사용자
  • 이왕이면 input_large.txt 파일의 내용을 간략하게라도 올려주심이 좋을듯 싶어요. 유동욱 2021.12.2 14:24
  • 2777 6915 1 이런식으로 노드1 노드2 weight이게 한 5000000줄 있습니다. 계속 돌려보니 메모리 사용량 같은데...힙에서 원소 다 뽑는 것은 문제가 없으나 유니온 하는 루프에서 왜인지 모르겠지만 종료가 되네요. 그리고 동적할당을 써보니 1738까지 뽑히고 또 어떤 방법을 쓰면 1138까지 뽑히다가 멈추는데...c에 계산량이 너무 많아지면 멈추나요?? 알 수 없는 사용자 2021.12.2 16:58
  • 아니요 계산량이 많다고 멈추지 않습니다. "access violation error" 가 발생했다는건 잘못 된 메모리 주소에 접근했다는 거고, 위 코드는 input_large.txt의 내용에 따라 어느 위치의 메모리에 접근할지가 결정되는데 노드1과 노드2의 값은 코드 내에서 인덱스로 사용되는데 이게 5천을 넘어 갔을 때 해당 문제가 발생할 수 있을거 같네요. 유동욱 2021.12.2 17:05

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)