一、利用for循环解多元一次方程
package day4_01;
public class Demo1 {
/**
* 利用for循环解决三元一次方程
* 2X-7=y
* 5X+3Y+2Z=3
* 3X+Z=7
*
* 解答:x=2 y=-3 z=1
* 缺点:具有局限性,结果必须是整数,且考虑循环的范围(即值的可能范围)
* 解决办法:1.int min = -Integer. 效率极其低下
* 2.设置初始值,当不满足情况下,改变循环条件
*/
public static void test1(){
int max=Integer.MAX_VALUE;
int min=-Integer.MIN_VALUE;
for (int x=min; x<max; x++) {
for (int y=min; y<max; y++) {
for (int z=min; z<max; z++) {
if((y==2*x-7) && (5*x+3*y+2*z==3) && (3*x+z==7)){
System.out.println("x="+x+"\ty="+y+"\tz="+z);
}
}
}
}
}
public static void test2(){
int max = 10;
int min = -10;
ok: for(;;){
for (int x=min; x<max; x++) {
for (int y=min; y<max; y++) {
for (int z=min; z<max; z++) {
if((y==2*x-7) && (5*x+3*y+2*z==3) && (3*x+z==7)){
System.out.println("x="+x+"\ty="+y+"\tz="+z);
break ok;
}
}
}
}
max += 10;//扩大范围
min -= 10;//扩大范围
}
}
public static void main(String[] args) {
//test1();//会卡住
test2();
}
}
测试结果为:
x=2 y=-3 z=1
二、利用矩阵解多元一次方程
package day4_03;
import java.text.DecimalFormat;
public class GaussUtil {
/**
* 该工具类用于计算多元一次方程组
* @param
* equ-方程的个数
* var-变量的个数
* array--增广矩阵
* result[]-用于保存方程组的解
*/
/**
*
* @return 通过返回值判断该方程组解的情况
* 1.一个解(有效方程个数=变量个数) =0
* 2.无解(有效方程个数>变量个数) -1
* 3.多个解(有效方程个数<变量个数) >0
*/
public static int GaussFunction(int equ,int var,int[][] array,double[] result){
DecimalFormat df = new DecimalFormat("#.00");
//定义程序中使用到的变量
int i,j,k,max_r,temp,num1,num2,gcdtemp,lcmtemp,ta,tb;
int col = 0; //从第1列开始处理
for(k=0;k<equ && col<var;k++,col++){ //循环处理增广矩阵中的各行
max_r = k; //用于记录当前列中绝对值最大数所在的行
for(i=k+1;i<equ;i++){
if(Math.abs(array[i][col])>Math.abs(array[max_r][col])){
max_r = i;
}
}
if(max_r != k){ //若最大值不是当前行,则将当前行与最大值所在行交换
for(j=k;j<var+1;j++){
temp = array[k][j];
array[k][j] = array[max_r][j];
array[max_r][j] = temp;
}
}
//经过以上变换后判断当前col,k的元素是否为0,若为0,则说明col列第k行以下全是0
//直接不用处理该列,继续下一列(但是要保持k不变,col+1)
if(array[k][col] == 0){
k--;
continue;
}
//将该列(col)中k行以下元素变换为0
for(i=k+1;i<equ;i++){
if(array[i][col] != 0){//该元素不为0时才进行变换,否则跳到下一行
num1 = Math.abs(array[i][col]);//获取该元素的绝对值
num2 = Math.abs(array[k][col]);
while(num2 != 0){ //求最大公约数
temp = num2;
num2 = num1 % num2;
num1 = temp;
}
gcdtemp=num1; //最大公约数(gcdtemp,lcmtemp都是整数)
lcmtemp=(Math.abs(array[i][col]) * Math.abs(array[k][col]))/gcdtemp;//最小公倍数
ta = lcmtemp/Math.abs(array[i][col]);
tb=lcmtemp/Math.abs(array[k][col]);
if(array[i][col]*array[k][col]<0){ //如果两数符号不同
tb = -tb;
}
//开始消元
for(j=col;j<var+1;j++){
array[i][j] = array[i][j]*ta - array[k][j]*tb;
}
}
}
}//到此变换完成上三角矩阵 (对角线以下元素均为0)
/**
System.out.println("****************");
//用于测试输出的矩阵即相关数据
for(int m=0;m<array.length;m++){
for(int n=0;n<array[m].length;n++){
System.out.print(array[m][n]+" ");
}
System.out.println();
}
System.out.println("k="+k);
System.out.println("col="+col);
System.out.println("****************");
*/
//对得到的矩阵进行判断
/**
* 判断最后一行,最后一列的该元素(即常数矩阵的最后一个元素)
* 若为0,则表示该方程无解,返回-1
* 例如 {3, 1,-4,2}
* {3, 4,-1,3}
* {6, 8,-2,4}
* 后面两个方程无解,此时会执行前面的k--,造成k和col的值不相等
* 变换后的结果为
* {6, 8,-2, 4}
* {0,-6,-6, 0}
* {0, 0, 0, 2}
* array[i][col]=array[2][3]=2 retutn -1 无解;
*/
for(i=k;i<equ;i++){
if(array[i][col] != 0){
return -1;
}
}
/**
* 变量var个数大于变换后矩阵中有效方程的个数
* 则有无穷多个解 return var - k;
* 例如 {3, 1,-4,2}
* {3, 4,-1,3}
* {6, 8,-2,6}
* 后面两个方程化简后是相同的,相当于一个方程
* 变换后的结果为
* {6, 8,-2, 6}
* {0,-6,-6,-2}
* {0, 0, 0, 0}
* 通过前面代码过滤掉了无解的情况,若此时k<var,则说明
* 有效方程个数少于变量个火,有无穷多个解
*/
if(k<var){
return var - k;
}
/**
* 通过以上过滤,则说明方程有唯一解
* 通过下面代码对方程进行求解
* 例 {7, 2, 6,-4}
* {3, 5,-4, 0}
* {4,-1, 5,-5}
* 变换后
* {7, 2, 6, -4}
* {0, 29,-46, 12}
* {0, 0,-371,-371}
* 此时 k=3 col=3
*/
for(i=var-1;i>=0;i--){//从最后一个变量计算
temp = array[i][var];//获取该变量的系数
for(j=i+1;j<var;j++){
if(array[i][j] != 0){
temp-=array[i][j]*result[j];
}
}
double d = (double)temp/array[i][i];//为了使结果更准确采用double类型保存
result[i] = Double.parseDouble(df.format(d));
}
return 0;//有唯一解
}
//测试类
public static void main(String[] args) {
//传入参数---方程个数 equ=3 变量个数var=3
int[][] arr = new int[][]{
{2, 1, -1,2},
{1, 2,-1, 5},
{1,-1, 2,-7}
};
int equ = arr.length;
int var = arr[0].length-1;
double[] result = new double[var];
//输出传入的参数查看结果
//System.out.println(equ+" "+var+" "+result.length);//3 3 3
//调用高斯函数
int type = GaussFunction(equ,var,arr,result);
switch(type){
case -1:
System.out.println("方程无解");
break;
case 0:
System.out.println("该方程的解为:");
for(int i=0;i<result.length;i++){
System.out.println("x"+(i+1)+"="+result[i]);
}
break;
default:
System.out.println("该方程有无穷多解! 自由变量数量为:"+type);
}
}
}
测试结果如下:
该方程的解为:
x1=-1.0
x2=2.0
x3=-2.0