平行運算作業需對大型矩陣求逆,驗證平行優勢需大規模資料集。隨機產生的矩陣多半不可逆(行列式為 0),導致求逆失敗。本文實作「單位矩陣 + 有限次初等列變換」策略,保證產生可逆矩陣,並解決溢位與分布均勻問題。
n×n 單位矩陣(對角線 1,其餘 0)。int16_t 範圍(-32768~32767)是否溢位,若溢位則改用除法縮小數值(/4)保持穩定。#include
#include
#include
#include // UINT16_MAX
void getIdentityMatrix(int n, int **a);
void getInvertibleMatrix(int n, int **a);
int putInvertibleMatrixIntoFile(int n, int **a);
void printInvertibleMatrix(int n, int **a);
void freeMatrix(int n, int **a);
int main() {
int n, flag;
printf("請輸入方陣階數: ");
scanf("%d", &n);
int **matrix = malloc(n * sizeof(int *));
for (int i = 0; i < n; ++i) matrix[i] = malloc(n * sizeof(int));
printf("輸入 0 產生單位矩陣,1 產生可逆矩陣: ");
scanf("%d", &flag);
getIdentityMatrix(n, matrix);
if (flag == 1) getInvertibleMatrix(n, matrix);
putInvertibleMatrixIntoFile(n, matrix);
printInvertibleMatrix(n, matrix);
freeMatrix(n, matrix);
return 0;
}
void freeMatrix(int n, int **a) {
for (int i = 0; i < n; ++i) free(a[i]);
free(a);
}
void getIdentityMatrix(int n, int **a) {
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
a[i][j] = (i == j) ? 1 : 0;
}
void getInvertibleMatrix(int n, int **a) {
srand((unsigned)time(NULL));
int times = rand() % 1000;
printf("將執行 %d 次列變換\n", times);
int *temp = malloc(n * sizeof(int));
for (int t = 0; t < times; ++t) {
int mainRow = rand() % n;
// 產生處理後的主列暫存
for (int k = 0; k < n; ++k) {
int factor = rand() % 5 - 10; // -10 ~ -6
long val = (long)a[mainRow][k] * factor;
// 溢位檢測 (int16_t 範圍)
if (val > INT16_MAX || val < -INT16_MAX - 1)
temp[k] = a[mainRow][k];
else
temp[k] = (int)val;
}
// 加到其他列
for (int j = 0; j < n; ++j) if (j != mainRow) {
for (int k = 0; k < n; ++k) {
long sum = (long)a[j][k] + temp[k];
if (sum > INT16_MAX || sum < -INT16_MAX - 1)
a[j][k] /= 4; // 縮小避免溢位
else
a[j][k] = (int)sum;
}
}
}
free(temp);
}
int putInvertibleMatrixIntoFile(int n, int **a) {
FILE *fp = fopen("input", "w");
if (!fp) return -1;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
fprintf(fp, "%d%s", a[i][j], (j == n-1) ? "" : "\t");
}
fputs("\n", fp);
}
fclose(fp);
return 1;
}
gcc -o invertible invertiblematrix.c
./invertible
# 輸入 5 並選 1,輸出 5x5 可逆矩陣至 input 檔
實測 5×5 矩陣執行 780 次變換,產生的矩陣經驗證可成功求逆。大規模矩陣(如 500×500)同樣適用,滿足平行運算資料需求。
double 型別並配合部分樞軸高斯消去法,進一步提升數值穩定性。.mtx),便於科學計算庫讀取。此專案展示如何以純 C 語言解決「隨機且可逆」矩陣生成問題,為後續高效能運算奠基。