쉬트라센 알고리즘 행렬곱셈 계산하는 코드 동적할당 읽기 액세스 오류.
조회수 816회
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
void inMatrix(int[][1024], char *fname);
void outMatrix(int[][1024], char *fname);
void Matrixadd(int[][1024], int[][1024], int[][1024]);
void Matrixsub(int[][1024], int[][1024], int[][1024]);
void Matrixmul(int[][1024], int[][1024], int[][1024]); //단순한 알고리즘으로 구하는 행렬의 곱셈 함수
int threshold(int n); //임계값을 구하는 함수
void Strassen(int n, int[][1024], int[][1024], int[][1024]); //쉬트라센 알고리즘으로 구하는 행렬의 곱셈 함수
int result1[1024][1024];
int result2[1024][1024];
int matrix1[1024][1024];
int matrix2[1024][1024];
int a11[1024][1024], a12[1024][1024], a21[1024][1024], a22[1024][1024];
int b11[1024][1024], b12[1024][1024], b21[1024][1024], b22[1024][1024];
int c11[1024][1024], c12[1024][1024], c21[1024][1024], c22[1024][1024];
int m1[1024][1024], m2[1024][1024], m3[1024][1024], m4[1024][1024], m5[1024][1024], m6[1024][1024], m7[1024][1024];
int tmp1[1024][1024], tmp2[1024][1024];
int main() {
int start, end;
char fname1[50], fname2[50];
printf("matrix1 행렬에 입력할 파일명을 입력하세요. : ");
scanf("%s", &fname1);
printf("matrix2 행렬에 입력할 파일명을 입력하세요. : ");
scanf("%s", &fname2);
inMatrix(matrix1, fname1);
inMatrix(matrix2, fname2);
start = clock();
Matrixmul(matrix1, matrix2, result1);
end = clock();
printf("Navie 방식의 결과 시간 : %f ms\n", (double)(end - start));
start = clock();
Strassen(1024, matrix1, matrix2, result2);
end = clock();
printf("Strassen 방식의 결과 시간 : %f ms\n", (double)(end - start));
outMatrix(result1,"Naive result.txt");
outMatrix(result2, "Strassen result.txt");
printf("결과가 Naive result.txt와 Strassen result.txt 파일에 저장되었습니다.\n");
}
void inMatrix(int matrix[][1024], char *fname) {
FILE *fin;
fin = fopen(fname, "rb"); //바이너리 파일로 파일은 연다
char *arr = NULL;
int idx = 0;
if (fin == NULL) {
printf("파일명이 없습니다.\n");
return;
}
for (int i = 0; i < 1024; i++)
for (int j = 0; j < 1024; j++) {
matrix[i][j] = arr[idx];
idx++;
}
fclose(fin);
free(arr);
}
void outMatrix(int matrix[][1024], char *fname) {
FILE *fout;
fout = fopen(fname, "wt");
for (int i = 0; i < 1024; i++) {
for (int j = 0; j < 1024; j++)
fprintf(fout, "%d ", matrix[i][j]);
fprintf(fout, "\n");
}
}
void Matrixadd(int matrix1[][1024], int matrix2[][1024], int result[][1024]) {
for (int i = 0; i < 1024; i++)
for (int j = 0; j < 1024; j++)
result[i][j] = matrix1[i][j] + matrix2[i][j]; //행렬을 더함
}
void Matrixsub(int matrix1[][1024], int matrix2[][1024], int result[][1024]) {
for (int i = 0; i < 1024; i++)
for (int j = 0; j < 1024; j++)
result[i][j] = matrix1[i][j] - matrix2[i][j]; //행렬을 뺌
}
void Matrixmul(int matrix1[][1024], int matrix2[][1024], int result[][1024]) {
for(int i=0;i<1024;i++)
for (int j = 0; j < 1024; j++) {
result[i][j] = 0;
for (int k = 0; k < 1024; k++)
result[i][j] += matrix1[i][k] * matrix2[k][j]; //행렬을 곱함
}
}
int threshold(int n) {
int threshold;
double t = floor(log(n) / log(2) - 6);
threshold = (int)floor(n / pow(2.0, t)) + 1;
return threshold;
}
void Strassen(int n, int matrix1[][1024], int matrix2[][1024], int result[][1024]) {
/*int a11[1024][1024], a12[1024][1024], a21[1024][1024], a22[1024][1024];
int b11[1024][1024], b12[1024][1024], b21[1024][1024], b22[1024][1024];
int c11[1024][1024], c12[1024][1024], c21[1024][1024], c22[1024][1024];
int m1[1024][1024], m2[1024][1024], m3[1024][1024], m4[1024][1024], m5[1024][1024], m6[1024][1024], m7[1024][1024];
int tmp1[1024][1024], tmp2[1024][1024];*/
if (n <= threshold(n)) //임계값을 넘지 않으면
Matrixmul(matrix1, matrix2, result); //일반적인 행렬곱셈으로 계산
else {
for (int i = 0; i < n / 2; i++) { //행렬의 부분을 나눠줌
for (int j = 0; j < n / 2; j++) {
a11[i][j] = matrix1[i][j];
a12[i][j] = matrix1[i][j + n / 2];
a21[i][j] = matrix1[i + n / 2][j];
a22[i][j] = matrix1[i + n / 2][j + n / 2];
b11[i][j] = matrix1[i][j];
b12[i][j] = matrix1[i][j + n / 2];
b21[i][j] = matrix1[i + n / 2][j];
b22[i][j] = matrix1[i + n / 2][j + n / 2];
}
}
//m1=(a11+a22)*(b11+b22)
Matrixadd(a11, a22, tmp1);
Matrixadd(b11, b22, tmp2);
Strassen(n / 2, tmp1, tmp2, m1);
//m2=(a21+a22)*b11
Matrixadd( a21, a22, tmp1);
Strassen(n / 2, tmp1, b11, m2);
//m3=a11*(b12+b22)
Matrixadd(b12, b22, tmp2);
Strassen(n / 2, a11, tmp2, m3);
//m4=a22*(b21+b11)
Matrixadd(b21, b11, tmp2);
Strassen(n / 2, a22, tmp2, m4);
//m5=(a11+a12)*b22
Matrixadd(a11, a12, tmp1);
Strassen(n / 2, tmp1, b22, m5);
//m6=(a21-a11)*(b11+b12)
Matrixsub(a21, a11, tmp1);
Matrixadd(b11, b12, tmp2);
Strassen(n / 2, tmp1, tmp2, m6);
//m7=(a12-a22)*(b21+b22)
Matrixsub(a12, a22, tmp1);
Matrixadd(b21, b22, tmp2);
Strassen(n / 2, tmp1, tmp2, m7);
//c11=m1+m4-m5+m7
Matrixadd(m1, m4, tmp1);
Matrixadd(m5, m7, tmp2);
Matrixsub(tmp1, tmp2, c11);
//c12=m3+m5
Matrixadd(m3, m5, c12);
//c21=m2+m4
Matrixadd(m2, m4, c21);
//c22=m1+m3-m2+m6
Matrixadd(m1, m3, tmp1);
Matrixadd(m2, m6, tmp2);
Matrixsub(tmp1, tmp2, c22);
for (int i = 0; i < n / 2; i++) {
for (int j = 0; j < n / 2; j++) {
result[i][j] = c11[i][j];
result[i][j + n / 2] = c12[i][j];
result[i + n / 2][j] = c21[i][j];
result[i + n / 2][j + n / 2] = c22[i][j];
}
}
}
}
실행을 시키면 파일 이름을 입력받는 부분까지만 실행이 됩니다. 디버깅을 시키면
'예외가 throw됨: 읽기 액세스 위반입니다. arr이(가) 0x1110112였습니다.'
이렇게 뜹니다. 동적할당에 문제가 있는 것 같은데 어떻게 수정을 해야될지 모르겠어요. 도와주세요.
-
(•́ ✖ •̀)
알 수 없는 사용자 - 〉
댓글 입력