193 lines
7.1 KiB
Java
193 lines
7.1 KiB
Java
/*
|
||
This is java program to find the solution to the linear equations of any number of variables.
|
||
The class provides a simple implementation of the Gauss-Seidel method.
|
||
If the matrix isn’t diagonally dominant the program tries to convert it(if possible) by rearranging the rows.
|
||
*/
|
||
|
||
//This class provides a simple implementation of the GaussSeidel method for solving systems of linear equations.
|
||
//If the matrix isn't diagonally dominant the program tries to convert it(if possible) by rearranging the rows.
|
||
|
||
import java.io.BufferedReader;
|
||
import java.io.IOException;
|
||
import java.io.InputStreamReader;
|
||
import java.io.PrintWriter;
|
||
import java.util.Arrays;
|
||
import java.util.StringTokenizer;
|
||
|
||
public class Gauss_Seidel
|
||
{
|
||
public static final int MAX_ITERATIONS = 100;
|
||
private double[][] M;
|
||
public Gauss_Seidel(double [][] matrix)
|
||
{
|
||
M = matrix;
|
||
}
|
||
|
||
public void print()
|
||
{
|
||
int n = M.length;
|
||
for (int i = 0; i < n; i++)
|
||
{
|
||
for (int j = 0; j < n + 1; j++)
|
||
System.out.print(M[i][j] + " ");
|
||
System.out.println();
|
||
}
|
||
}
|
||
|
||
public boolean transformToDominant(int r, boolean[] V, int[] R)
|
||
{
|
||
int n = M.length;
|
||
if (r == M.length)
|
||
{
|
||
double[][] T = new double[n][n+1];
|
||
for (int i = 0; i < R.length; i++)
|
||
{
|
||
for (int j = 0; j < n + 1; j++)
|
||
T[i][j] = M[R[i]][j];
|
||
}
|
||
M = T;
|
||
return true;
|
||
}
|
||
for (int i = 0; i < n; i++)
|
||
{
|
||
if (V[i]) continue;
|
||
double sum = 0;
|
||
for (int j = 0; j < n; j++)
|
||
sum += Math.abs(M[i][j]);
|
||
if (2 * Math.abs(M[i][r]) > sum)
|
||
{
|
||
// diagonally dominant?
|
||
V[i] = true;
|
||
R[r] = i;
|
||
if (transformToDominant(r + 1, V, R))
|
||
return true;
|
||
V[i] = false;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
public boolean makeDominant()
|
||
{
|
||
boolean[] visited = new boolean[M.length];
|
||
int[] rows = new int[M.length];
|
||
Arrays.fill(visited, false);
|
||
return transformToDominant(0, visited, rows);
|
||
}
|
||
|
||
public void solve()
|
||
{
|
||
int iterations = 0;
|
||
int n = M.length;
|
||
double epsilon = 1e-15;
|
||
double[] X = new double[n]; // Approximations
|
||
double[] P = new double[n]; // Prev
|
||
Arrays.fill(X, 0);
|
||
while (true)
|
||
{
|
||
for (int i = 0; i < n; i++)
|
||
{
|
||
double sum = M[i][n]; // b_n
|
||
for (int j = 0; j < n; j++)
|
||
if (j != i)
|
||
sum -= M[i][j] * X[j];
|
||
// Update x_i to use in the next row calculation
|
||
X[i] = 1/M[i][i] * sum;
|
||
}
|
||
System.out.print("X_" + iterations + " = {");
|
||
for (int i = 0; i < n; i++)
|
||
System.out.print(X[i] + " ");
|
||
System.out.println("}");
|
||
iterations++;
|
||
if (iterations == 1)
|
||
continue;
|
||
boolean stop = true;
|
||
for (int i = 0; i < n && stop; i++)
|
||
if (Math.abs(X[i] - P[i]) > epsilon)
|
||
stop = false;
|
||
if (stop || iterations == MAX_ITERATIONS) break;
|
||
P = (double[])X.clone();
|
||
}
|
||
}
|
||
|
||
public static void main(String[] args) throws IOException
|
||
{
|
||
int n;
|
||
double[][] M;
|
||
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
|
||
PrintWriter writer = new PrintWriter(System.out, true);
|
||
System.out.println("Enter the number of variables in the equation:");
|
||
n = Integer.parseInt(reader.readLine());
|
||
M = new double[n][n+1];
|
||
System.out.println("Enter the augmented matrix:");
|
||
for (int i = 0; i < n; i++)
|
||
{
|
||
StringTokenizer strtk = new StringTokenizer(reader.readLine());
|
||
while (strtk.hasMoreTokens())
|
||
for (int j = 0; j < n + 1 && strtk.hasMoreTokens(); j++)
|
||
M[i][j] = Integer.parseInt(strtk.nextToken());
|
||
}
|
||
Gauss_Seidel gausSeidel = new Gauss_Seidel(M);
|
||
if (!gausSeidel.makeDominant())
|
||
{
|
||
writer.println("The system isn't diagonally dominant: " +
|
||
"The method cannot guarantee convergence.");
|
||
}
|
||
writer.println();
|
||
gausSeidel.print();
|
||
gausSeidel.solve();
|
||
}
|
||
}
|
||
|
||
/*
|
||
|
||
Enter the number of variables in the equation:
|
||
2
|
||
Enter the augmented matrix:
|
||
1 2 3
|
||
6 5 4
|
||
|
||
6.0 5.0 4.0
|
||
1.0 2.0 3.0
|
||
X_0 = {0.6666666666666666 1.1666666666666667 }
|
||
X_1 = {-0.30555555555555564 1.652777777777778 }
|
||
X_2 = {-0.7106481481481481 1.855324074074074 }
|
||
X_3 = {-0.8794367283950617 1.9397183641975309 }
|
||
X_4 = {-0.9497653034979425 1.9748826517489713 }
|
||
X_5 = {-0.9790688764574759 1.9895344382287379 }
|
||
X_6 = {-0.9912786985239483 1.9956393492619742 }
|
||
X_7 = {-0.9963661243849785 1.9981830621924892 }
|
||
X_8 = {-0.9984858851604077 1.9992429425802039 }
|
||
X_9 = {-0.9993691188168363 1.999684559408418 }
|
||
X_10 = {-0.9997371328403484 1.999868566420174 }
|
||
X_11 = {-0.9998904720168117 1.9999452360084058 }
|
||
X_12 = {-0.999954363340338 1.999977181670169 }
|
||
X_13 = {-0.9999809847251406 1.9999904923625702 }
|
||
X_14 = {-0.9999920769688085 1.9999960384844042 }
|
||
X_15 = {-0.9999966987370034 1.9999983493685016 }
|
||
X_16 = {-0.9999986244737512 1.9999993122368755 }
|
||
X_17 = {-0.9999994268640631 1.9999997134320315 }
|
||
X_18 = {-0.9999997611933598 1.9999998805966799 }
|
||
X_19 = {-0.9999999004972331 1.9999999502486165 }
|
||
X_20 = {-0.9999999585405137 1.9999999792702567 }
|
||
X_21 = {-0.999999982725214 1.999999991362607 }
|
||
X_22 = {-0.9999999928021724 1.9999999964010862 }
|
||
X_23 = {-0.999999997000905 1.9999999985004524 }
|
||
X_24 = {-0.999999998750377 1.9999999993751885 }
|
||
X_25 = {-0.9999999994793237 1.9999999997396618 }
|
||
X_26 = {-0.9999999997830514 1.9999999998915257 }
|
||
X_27 = {-0.9999999999096048 1.9999999999548024 }
|
||
X_28 = {-0.9999999999623352 1.9999999999811675 }
|
||
X_29 = {-0.9999999999843061 1.999999999992153 }
|
||
X_30 = {-0.9999999999934606 1.9999999999967302 }
|
||
X_31 = {-0.9999999999972751 1.9999999999986375 }
|
||
X_32 = {-0.9999999999988646 1.9999999999994322 }
|
||
X_33 = {-0.9999999999995268 1.9999999999997633 }
|
||
X_34 = {-0.9999999999998028 1.9999999999999014 }
|
||
X_35 = {-0.9999999999999176 1.9999999999999587 }
|
||
X_36 = {-0.9999999999999656 1.9999999999999827 }
|
||
X_37 = {-0.9999999999999855 1.9999999999999927 }
|
||
X_38 = {-0.9999999999999938 1.999999999999997 }
|
||
X_39 = {-0.9999999999999973 1.9999999999999987 }
|
||
X_40 = {-0.9999999999999988 1.9999999999999993 }
|
||
X_41 = {-0.9999999999999993 1.9999999999999996 } |