이 예에서 입력은 모든 크기 m*n, n*m의 두 행렬이고 출력은 두 행렬의 산물입니다. 임의의 크기 행렬의 곱셈을 계산할 때 Strassen 알고리즘이 사용됩니다. 이 프로그램은 자체적으로 작성되고 테스트되었습니다. 자유롭게 사용하십시오. 기본 알고리즘은 다음과 같습니다.
1. 제곱 매트릭스 (Square Matrix)의 경우 l = 2 ^ k, k가 정수이고 l <m 이도록 가장 큰 l을 찾으십시오. 측면 길이 L을 갖는 정사각형 매트릭스는 strassen 알고리즘을 사용하고 정사각형 매트릭스의 나머지 부분과 누락 된 부분은 무차별 힘 방법을 사용합니다.
2. 비 제곱 매트릭스의 경우 줄과 열에 따라 0을 추가하여 사각형 매트릭스로 만듭니다.
strassenmethodtest.java
패키지 매트릭스 알코리즘; java.util.scanner import; 공개 클래스 strassenmethodtest {private strassenmethod strassenmultiply; strassenmethodtest () {strassenmultiply = new strassenmethod (); } // 엔드 cons public static void main (String [] args) {스캐너 입력 = 새 스캐너 (System.In); System.out.println ( "첫 번째 행렬의 입력 행 크기 :"); int emerge = input.nextInt (); System.out.println ( "첫 번째 행렬의 입력 열 크기 :"); int acol = input.nextint (); System.out.println ( "두 번째 행렬의 입력 행 크기 :"); int browser = input.nextInt (); System.out.println ( "두 번째 행렬의 입력 열 크기 :"); int bcol = input.nextInt (); double [] [] a = 새로운 이중 [Arow] [Acol]; double [] [] b = 새로운 이중 [브로우] [bcol]; double [] [] c = 새로운 이중 [arow] [bcol]; System.out.println ( "행렬 A의 입력 데이터 :"); /*이 프로젝트의 뒷부분의 모든 코드에서 R은 행을 의미하며 C는 열을 의미합니다. */ for (int r = 0; r <arow; r ++) {for (int c = 0; c <acol; c ++) {system.out.printf ( "[%d] [%d] :", r, c); a [r] [c] = input.nextDouble (); } // END 내부 루프} // end loop system.out.println ( "매트릭스 B의 입력 데이터 :"); for (int r = 0; r <브라우저; r ++) {for (int c = 0; c <bcol; c ++) {system.out.printf ( "[%d] [%d] :", r, c); b [r] [c] = input.nextDouble (); } // 엔드 내부 루프} // 엔드 루프 strassenmethodtest 알고리즘 = new StrassenMethodTest (); c = algorithm.multiplyrectmatrix (a, b, come, acol, browser, bcol); // 계산 결과를 표시합니다. System.out.println ( "Matrix C :"); for (int r = 0; r <arow; r ++) {for (int c = 0; c <bcol; c ++) {system.out.printf ( "c [%d] [%d] :%f/n", r, c, c [c]); } // end inner loop} // 종료 해외 루프} // 종료 메인 // 정사각형이 아닌 행렬을 다루십시오 : 공개 이중 [] [] multiplyrectmatrix (double [] [] a, double [] b, int arow, int acol, int browser, int bcol) {if (arow! = bcol) // invalid retory new New New New New New 이중 [] [] {{0}}; double [] [] c = 새로운 이중 [arow] [bcol]; if (arow <acol) {double [] [] newa = new double [acol] [acol]; double [] [] newb = 새로운 이중 [브로우] [브로우]; int n = acol; for (int c = 0; c <acol; c ++) newa [r] [c] = 0.0; for (int c = 0; c <브라우저; c ++) newb [r] [c] = 0.0; for (int c = 0; c <bcol; c ++) newb [r] [c] = b [r] [c]; Double [] [] C2 = MultiplySquareMatrix (Newa, Newb, N); for (int c = 0; c <bcol; c ++) c [r] [c] = c2 [r] [c]; } // if if (arow == acol) c = multiplySquarematrix (a, b, 접근); else {int n = arow; double [] [] newa = new double [arow] [arow]; double [] [] newb = 새로운 이중 [bcol] [bcol]; for (int c = 0; c <arow; c ++) newa [r] [c] = 0.0; for (int c = 0; c <bcol; c ++) newb [r] [c] = 0.0; for (int c = 0; c <acol; c ++) newa [r] [c] = a [r] [c]; (int c = 0; c <bcol; c ++) newb [r] [c] = b [r] [c]; Double [] [] C2 = MultiplySquareMatrix (Newa, Newb, N); for (int c = 0; c <bcol; c ++) c [r] [c] = c2 [r] [c]; } // End Else else return c; } // 종료 방법 // 사각형 행렬 인 행렬을 다루십시오. public double [] [] multiplysquarematrix (double [] [] a2, double [] [] b2, int n) {double [] [] c2 = new double [n] [n]; (int c = 0; c <n; c ++) c2 [r] [c] = 0; if (n == 1) {c2 [0] [0] = a2 [0] [0] * b2 [0] [0]; 반환 c2; } // int exp2k = 2 인 경우 종료; while (exp2k <= (n / 2)) {exp2k *= 2; } // 엔드 루프 if (exp2k == n) {c2 = strassenmultiply.strassenmultiplymatrix (a2, b2, n); 반환 c2; } // End Else // "가장 큰"strassen 행렬 : double [] [] [] a = new double [6] [exp2k] [exp2k]; double [] [] [] b = 새로운 이중 [6] [exp2k] [exp2k]; double [] [] [] c = 새로운 이중 [6] [exp2k] [exp2k]; for (int r = 0; r <exp2k; r ++) {for (int c = 0; c <exp2k; c ++) {a [0] [r] [c] = a2 [r] [c]; B [0] [R] [C] = B2 [R] [C]; } // 엔드 내부 루프} // 엔드 아웃터 루프 c [0] = strassenmultiply.strassenmultiplymatrix (a [0], b [0], exp2k); (int c = 0; c <exp2k; c ++) c2 [r] [c] = c [0] [r] [c]; int middle = exp2k / 2; for (int r = 0; r <middle; r ++) {for (int c = exp2k; c <n; c ++) {a [1] [r] [c -exp2k] = a2 [r] [c]; b [3] [r] [c -exp2k] = b2 [r] [c]; } // END 내부 루프} // 엔드 엔드 외부 루프 (int r = exp2k; r <n; r ++) {for (int c = 0; c <middle; c ++) {a [3] [r -exp2k] [c] = a2 [r] [c]; B [1] [R -Exp2K] [C] = B2 [R] [C]; } // END 내부 루프} // 엔드 엔터리 루프 (int r = middle; r <exp2k; r ++) {for (int c = exp2k; c <n; c ++) {a [2] [r -middle] [c -exp2k] = a2 [r] [c]; B [4] [R- 중간] [C -Exp2K] = B2 [R] [C]; } // END 내부 루프} // 엔드 엔드 외부 루프 (int r = exp2k; r <n; r ++) {for (int c = middle; c <n -exp2k+1; c ++) {a [4] [r -exp2k] [c -middle] = a2 [r] [c]; B [2] [R -Exp2K] [C -Middle] = B2 [R] [C]; } // END 내부 루프} // 엔드 엔드 외부 루프 (int i = 1; i <= 4; i ++) c [i] = multiplyrectmatrix (a [i], b [i], middle, a [i] .length, a [i] .length, middle); / * 매트릭스 곱셈의 규칙에 따라 "가장 큰 2^K 제곱의 최종 결과를 계산합니다. */ for (int row = 0; row <exp2k; row ++) {for (int col = 0; col <exp2k; col ++) {for (int k = exp2k; k <n; k ++) {c2 [col] [row] [a2 [k] a2] *. B2 [k] [col];} // end loop} // end 내부 루프} // ong onh loop // 나머지를 해결하기 위해 나머지를 해결합니다. a2 [row] [k] * b2 [k] [row] ;/ 엔드 내부 루프} // (int row = exp2k; row <n; row ++) {(int col = 0; col <exp2k; col ++) {for (int k = 0; k <n; k ++) c2 [row] [a2 [k] * b2. } // END 내부 루프} // 엔드 해외 루프 리턴 C2 ;/ 엔드 메소드} // END 클래스 Strassenmethod.java
패키지 매트릭스 알코리즘; java.util.scanner import; 공개 클래스 strassenmethod {private double [] [] [] [] a = new Double [2] [2] [] []; Private Double [] [] [] [] B = New Double [2] [2] []; Private Double [] [] [] [] C = New Double [2] [2] []; /*//이 클래스 테스트를위한 코드 : public static void main (String [] args) {스캐너 입력 = 새 스캐너 (System.In); System.out.println ( "행렬의 입력 크기 :"); int n = input.nextInt (); double [] [] a = 새로운 이중 [n] [n]; double [] [] b = 새로운 이중 [n] [n]; double [] [] c = 새로운 이중 [n] [n]; System.out.println ( "행렬 A의 입력 데이터 :"); for (int r = 0; r <n; r ++) {for (int c = 0; c <n; c ++) {system.out.printf ( "[%d] [%d] :", r, c); a [r] [c] = input.nextDouble (); } // END 내부 루프} // end loop system.out.println ( "매트릭스 B의 입력 데이터 :"); for (int r = 0; r <n; r ++) {for (int c = 0; c <n; c ++) {system.out.printf ( "[%d] [%d] :", r, c); b [r] [c] = input.nextDouble (); } // 엔드 내부 루프} // 엔드 루프 strassenmethod 알고리즘 = new strassenMethod (); c = algorithm.StrassenMultiplymatrix (a, b, n); System.out.println ( "매트릭스 C :"); for (int r = 0; r <n; r ++) {for (int c = 0; c <n; c ++) {system.out.printf ( "c [%d] [%d] :%f/n", r, c [r] [c]); } // 엔드 내부 루프} // 엔드 아웃터 루프} // 종료 메인*/public double [] [] strassenmultiplymatrix (double [] [] a2, double b2 [], int n) {double [] [] c2 = new double [n] [n]; // 행렬 초기화 : for (int colindex = 0; colindex <n; colindex ++) c2 [rowindex] [colindex] = 0.0; if (n == 1) C2 [0] [0] = A2 [0] [0] * B2 [0] [0]; // "매트릭스를 2 * 2 부분으로 슬라이스한다 : outh [] [] [] [] [] a = new double [2] [2] [n / 2] [n / 2]; double [] [] [] [] [] [2] [2] [n / 2] [n / 2]; double [] [] [] [] c = new double [2] [n / 2]; r <n / 2; B [0] [0] [C] [R] [C] [R] = B2 [N / 2 + C]; }. [1], n) = Minusmatrix (b [1] [0], n; A [1], N) = B [1] [1] [1], N = MinusMatrix (A [1] [0], N; Double [N] [N] = Strassenmultiplymatrix (A [0], S [0], N); strassenmultiplymatrix (A [1] [1], s [3], n) = strassenmultiplymatrix (s [5], n) = Strassenmultiplymatrix (s [6], n); C [0] [0] = MinusMatrix (P [4], P [3], P [1], N), P [5], N) = AddMatrix (P [0], P [1], N] minusmatrix (addmatrix (p [4], p [0], n), p [2], p [6], n); C2 [N / 2 + C] = [R] [C] [C] [0] [C2] [C] = C [1] [0] [N / 2 + C] [1] 내부 루프} // 엔드 외부 루프} // End C2 ;/ addmatrix (double [] [] a, double [] b, int n) {double c [] [n; r++); c ++) [c] = [c] [r] [c]; = 0;이 기사가 모든 사람이 Java 프로그래밍을 배우는 데 도움이되기를 바랍니다.