정의
크라메르 공식(Cramer's Rule)이란?
수학 개념
Ax=b에서 x를 “행렬식”으로 푼다
일반형( n×n )
2×2에서의 구체 형태(가장 실전)
c x + d y = f
x = (ed - bf) / (ad - bc)
y = (af - ec) / (ad - bc)
알고리즘 관점
언제 크라메르 공식을 쓰고, 언제 피해야 하나
좋은 선택인 경우
피해야 하는 경우
구현
Java 구현 (2×2 / 3×3)
1) 2×2 크라메르 공식 (정수 기반)
public class Cramer2x2 {
static class Result {
final boolean unique; // det(A) != 0
final double x;
final double y;
Result(boolean unique, double x, double y) {
this.unique = unique;
this.x = x;
this.y = y;
}
}
// a x + b y = e
// c x + d y = f
static Result solve(double a, double b, double c, double d, double e, double f) {
double det = a * d - b * c; // det(A)
if (det == 0.0) {
return new Result(false, Double.NaN, Double.NaN);
}
double x = (e * d - b * f) / det; // det(A1)/det(A)
double y = (a * f - e * c) / det; // det(A2)/det(A)
return new Result(true, x, y);
}
public static void main(String[] args) {
// 12와 18 예시가 아니라, 단순 연립방정식 예시
// 2x + y = 5
// x - y = 1
Result r = solve(2, 1, 1, -1, 5, 1);
System.out.println(r.unique); // true
System.out.println(r.x + ", " + r.y); // x=2, y=1
}
}
2) 3×3 행렬식(det) + 크라메르(확장 형태)
public class Cramer3x3 {
// det of 3x3 matrix using Sarrus rule
static double det3(double[][] m) {
// m[0][0] m[0][1] m[0][2]
// m[1][0] m[1][1] m[1][2]
// m[2][0] m[2][1] m[2][2]
double a = m[0][0]*m[1][1]*m[2][2] + m[0][1]*m[1][2]*m[2][0] + m[0][2]*m[1][0]*m[2][1];
double b = m[0][2]*m[1][1]*m[2][0] + m[0][0]*m[1][2]*m[2][1] + m[0][1]*m[1][0]*m[2][2];
return a - b;
}
static double[][] replaceCol(double[][] A, double[] b, int col) {
double[][] M = new double[3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) M[i][j] = A[i][j];
M[i][col] = b[i];
}
return M;
}
// Ax=b, returns {x,y,z} when det(A) != 0, else null
static double[] solve(double[][] A, double[] b) {
double detA = det3(A);
if (detA == 0.0) return null;
double detX = det3(replaceCol(A, b, 0));
double detY = det3(replaceCol(A, b, 1));
double detZ = det3(replaceCol(A, b, 2));
return new double[]{ detX/detA, detY/detA, detZ/detA };
}
public static void main(String[] args) {
double[][] A = {
{ 2, 1, -1 },
{ -3, -1, 2 },
{ -2, 1, 2 }
};
double[] b = { 8, -11, -3 };
double[] ans = solve(A, b);
if (ans == null) {
System.out.println("No unique solution (det(A)=0).");
} else {
System.out.println(ans[0] + ", " + ans[1] + ", " + ans[2]); // 2, 3, -1
}
}
}
요약
체크리스트로 마무리