矩陣相乘問題(分治法求解)
阿新 • • 發佈:2018-11-23
採用蠻力+分治進行求解:
矩陣相乘公式:
程式碼:
public class Matrix { //初始化一個隨機nxn階矩陣 public static int[][] initializationMatrix(int n){ int[][] result = new int[n][n]; for(int i = 0;i < n;i++){ for(int j = 0;j < n;j++){ result[i][j] = (int)(Math.random()*10); //採用隨機函式隨機生成1~10之間的數 } } return result; } //蠻力法求解兩個nxn和nxn階矩陣相乘 public static int[][] BruteForce(int[][] p,int[][] q,int n){ int[][] result = new int[n][n]; for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ result[i][j] = 0; for(int k=0;k<n;k++){ result[i][j] += p[i][k]*q[k][j]; } } } return result; } //分治法求解兩個nxn和nxn階矩陣相乘 public static int[][] DivideAndConquer(int[][] p,int[][] q,int n){ int[][] result = new int[n][n]; //當n為2時,返回矩陣相乘結果 if(n == 2){ result = BruteForce(p,q,n); return result; } //當n大於3時,採用採用分治法,遞迴求最終結果 if(n > 2){ int m = n/2; int[][] p1 = QuarterMatrix(p,n,1); int[][] p2 = QuarterMatrix(p,n,2); int[][] p3 = QuarterMatrix(p,n,3); int[][] p4 = QuarterMatrix(p,n,4); // System.out.println(); // System.out.print("矩陣p1值為:"); // PrintfMatrix(p1,m); // System.out.println(); // System.out.print("矩陣p2值為:"); // PrintfMatrix(p2,m); // System.out.println(); // System.out.print("矩陣p3值為:"); // PrintfMatrix(p3,m); // System.out.println(); // System.out.print("矩陣p4值為:"); // PrintfMatrix(p4,m); int[][] q1 = QuarterMatrix(q,n,1); int[][] q2 = QuarterMatrix(q,n,2); int[][] q3 = QuarterMatrix(q,n,3); int[][] q4 = QuarterMatrix(q,n,4); int[][] result1 = QuarterMatrix(result,n,1); int[][] result2 = QuarterMatrix(result,n,2); int[][] result3 = QuarterMatrix(result,n,3); int[][] result4 = QuarterMatrix(result,n,4); result1 = AddMatrix(DivideAndConquer(p1,q1,m),DivideAndConquer(p2,q3,m),m); result2 = AddMatrix(DivideAndConquer(p1,q2,m),DivideAndConquer(p2,q4,m),m); result3 = AddMatrix(DivideAndConquer(p3,q1,m),DivideAndConquer(p4,q3,m),m); result4 = AddMatrix(DivideAndConquer(p3,q2,m),DivideAndConquer(p4,q4,m),m); result = TogetherMatrix(result1,result2,result3,result4,m); } return result; } //獲取矩陣的四分之一,並決定返回哪一個四分之一 public static int[][] QuarterMatrix(int[][] p,int n,int number){ int rows = n/2; //行數減半 int cols = n/2; //列數減半 int[][] result = new int[rows][cols]; switch(number){ case 1 : { // result = new int[rows][cols]; for(int i=0;i<rows;i++){ for(int j=0;j<cols;j++){ result[i][j] = p[i][j]; } } break; } case 2 : { // result = new int[rows][n-cols]; for(int i=0;i<rows;i++){ for(int j=0;j<n-cols;j++){ result[i][j] = p[i][j+cols]; } } break; } case 3 : { // result = new int[n-rows][cols]; for(int i=0;i<n-rows;i++){ for(int j=0;j<cols;j++){ result[i][j] = p[i+rows][j]; } } break; } case 4 : { // result = new int[n-rows][n-cols]; for(int i=0;i<n-rows;i++){ for(int j=0;j<n-cols;j++){ result[i][j] = p[i+rows][j+cols]; } } break; } default: break; } return result; } //把均分為四分之一的矩陣,聚合成一個矩陣,其中矩陣a,b,c,d分別對應原完整矩陣的四分中1、2、3、4 public static int[][] TogetherMatrix(int[][] a,int[][] b,int[][] c,int[][] d,int n){ int[][] result = new int[2*n][2*n]; for(int i=0;i<2*n;i++){ for(int j=0;j<2*n;j++){ if(i<n){ if(j<n){ result[i][j] = a[i][j]; } else result[i][j] = b[i][j-n]; } else{ if(j<n){ result[i][j] = c[i-n][j]; } else{ result[i][j] = d[i-n][j-n]; } } } } return result; } //求兩個矩陣相加結果 public static int[][] AddMatrix(int[][] p,int[][] q,int n){ int[][] result = new int[n][n]; for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ result[i][j] = p[i][j]+q[i][j]; } } return result; } //控制檯輸出矩陣 public static void PrintfMatrix(int[][] matrix,int n){ for(int i=0;i<n;i++){ System.out.println(); for(int j=0;j<n;j++){ System.out.print("\t"); System.out.print(matrix[i][j]); } } } public static void main(String args[]){ int[][] p = initializationMatrix(8); int[][] q = initializationMatrix(8); System.out.print("矩陣p初始化值為:"); PrintfMatrix(p,8); System.out.println(); System.out.print("矩陣q初始化值為:"); PrintfMatrix(q,8); int[][] bf_result = BruteForce(p,q,8); System.out.println(); System.out.print("蠻力法計算矩陣p*q結果為:"); PrintfMatrix(bf_result,8); int[][] dac_result = DivideAndConquer(p,q,8); System.out.println(); System.out.print("分治法計算矩陣p*q結果為:"); PrintfMatrix(dac_result,8); } }